Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > writecomponent


Автор: Гость_guest 24.11.2004, 14:24
как вычислить размер получившегося сериализованного класса после writecomponent ???

Автор: Alex 25.11.2004, 00:36
Цитата
сериализованного класса

Что вы под этим понимаете?

Автор: Гость_guest 25.11.2004, 08:45
Ну есть к примеру класс:
Код

TTest = class(TComponent)

Я его сериализую применяя:
Код

Stream.WriteComponent(TTest)

Так вот нужно чтобы Stream.Size <= MaxSize !!!! Соответственно, нужно знать как зависит Stream.Size от класса TTest, к примеру если так есть поля integer, string, collection ???

Автор: Jureth 25.11.2004, 09:38
попробуй Sizeof (TTest)

Автор: Гость_guest 25.11.2004, 12:10
не катит
Результат не правильный, и яркий пример тому тип string !!!!, а использовать string[размер] я не могу

Автор: Alex 25.11.2004, 14:38
длина строки вычисляется как Length(s)

Автор: Гость_guest 25.11.2004, 14:48
Да не в этом дело....
А к том что при сериализации добавляется имя property и его содержимое, да плюс символы управляющие какие-то
Вопрос в том как узнать какой получится размер потока ???

Автор: Alex 25.11.2004, 15:03
Вот выдержка из хелпа
Цитата
This example shows how to use the built-in component streaming support to convert any component into a string and convert that string back into a component.
Код

function ComponentToString(Component: TComponent): string;

var
 BinStream:TMemoryStream;
 StrStream: TStringStream;
 s: string;
begin
 BinStream := TMemoryStream.Create;
 try
   StrStream := TStringStream.Create(s);
   try
     BinStream.WriteComponent(Component);
     BinStream.Seek(0, soFromBeginning);
     ObjectBinaryToText(BinStream, StrStream);
     StrStream.Seek(0, soFromBeginning);
     Result:= StrStream.DataString;
   finally
     StrStream.Free;

   end;
 finally
   BinStream.Free
 end;
end;

function StringToComponent(Value: string): TComponent;
var
 StrStream:TStringStream;
 BinStream: TMemoryStream;
begin
 StrStream := TStringStream.Create(Value);
 try
   BinStream := TMemoryStream.Create;
   try
     ObjectTextToBinary(StrStream, BinStream);
     BinStream.Seek(0, soFromBeginning);
     Result := BinStream.ReadComponent(nil);

   finally
     BinStream.Free;
   end;
 finally
   StrStream.Free;
 end;
end;



Если ты здесь не найдешь ответа на свой вопрос, то объясняй всю задачу, только по РУССКИ

Автор: p0s0l 25.11.2004, 15:29
Запиши TTest в промежуточный поток (ms : TMemoryStream), у этого потока возьми размер (ms.Size)... Если он больше, чем нужно, то записывай в Stream только часть ms ( s.WriteBuffer(ms.memory^, MaxSize); )...
Или тоже не про то говорю ? smile

Автор: Гость_guest 25.11.2004, 15:46
p0s0l ты говоришь именно про то...
но вопрос не про то как прочитать нужный размер, а как этот размер вычислить заранее имея всего лишь класс !!!!???
Как происходит сериализация надо понять.... что пишется ???

Автор: p0s0l 25.11.2004, 17:20
Компонент в поток пишется так:
1.Вначале пишется сигнатура TPF0
2.Имя класса (строка)
3.Имя компонента (строка)
4.Иногда пишется префикс с флагом
5.Пишутся published свойства
6.Конец (два нулевых байта)

Строки пишутся так:
<длина строки (1 байт)> <сама строка>

Свойство пишется в том случае, если спецификатор stored этого свойства = True, и свойство либо не имеет default значение (директива nodefault), либо его значение отличается от default-значения...
Left и Top свойства пишутся всегда.
Своства пишутся в таком формате:
1.Имя свойства (строкой, т.е. еще размер имени вначале)
2.TValueType (1 байт)
3.Значение (разное кол-во байт)

Например, запись свойства Tag:
Если значение = 0 (default), то оно не пишется...
Иначе, пишется вначале имя свойства:
3TAG (здесь 3 - это не символ, а значение байта)
Далее пишется значение свойства:
1) Если значение <= 255, то пишется так:
$02 $xx ($02 = vaInt8, тип значения, $xx - значение)
2) Если значение > 255, но <= 65535, то:
$03 $xxxx ($03 = vaInt16)
3) И т.д.

Короче, подсчитать размер вручную, програмно - дело непростое... Вовсю юзать RTTI придётся...
И в итоге напишешь то же самое, что сделали Borland.
Не легче ли сохранить в поток и узнать размер ?

Если хочешь узнать подробнее - в Project Options вруби "Use debug DCU's" и пошагово в отладчике просмотри, что делается при записи компонента в поток...

Автор: Гость_guest 26.11.2004, 10:07
Пасиб

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)