Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Сохранение/загрузка Persistent'a в поток [D5]


Страницы:   1 2

jack128 ©   (2004-08-15 15:40:00) 

Есть иерархия объетов. Нужно что бы все объкты иерархии могли сохронять себя поток. Так как иерархия весь обширная (порядка 50 классов) , то писать методы SaveToStream/LoadFromStream для каждого класса несколько лениво, решил использовать RTTI.  Сейчас это выглядит так:

type
 TReaderCrack = class(TReader)
 public
   procedure DefineProperty(const Name: string;
     ReadData: TReaderProc; WriteData: TWriterProc;
     HasData: Boolean); override;
   procedure DefineBinaryProperty(const Name: string;
     ReadData, WriteData: TStreamProc;
     HasData: Boolean); override;
 end;
 TWriterCrack = class(TWriter);
 TPersistentCrack = class(TPersistent);

procedure SavePersistent(Stream: TStream; Instance: TPersistent);
var
 PropList: PPropList;
 PropCount: Integer;
 Writer: TWriterCrack;
 i: Integer;
begin
 Assert(Assigned(Instance), 'Object must be not nil');
 PropCount := GetTypeData(Instance.ClassInfo).PropCount;
 GetMem(PropList, SizeOf(PPropInfo) * PropCount);
 try
   PropCount := GetPropList(Instance.ClassInfo, tkProperties - [tkClass], PropList);
   if PropCount = 0 then exit;
   Writer := TWriterCrack.Create(Stream, 1024);
   try
     Writer.WriteListBegin;
     for i := 0 to PropCount - 1 do
       if IsStoredProp(Instance, PropList[i]) then
         Writer.WriteProperty(Instance, PropList[i]);
     Writer.WriteListEnd;
     TPersistentCrack(Instance).DefineProperties(Writer);
   finally
     Writer.Free;
   end;
 finally
   FreeMem(PropList);
 end;
end;

procedure LoadPersistent(Stream: TStream; Instance: TPersistent);
var
 Reader: TReaderCrack;
begin
 Assert(Assigned(Instance), 'Object must be not nil');
 Reader := TReaderCrack.Create(Stream, 1024);
 try
   Reader.ReadListBegin;
   while not Reader.EndOfList do
     Reader.ReadProperty(Instance);
   Reader.ReadListEnd;
   TPersistentCrack(Instance).DefineProperties(Reader);
 finally
   Reader.Free;
 end;
end;

{ TReaderCrack }

procedure TReaderCrack.DefineBinaryProperty(const Name: string; ReadData,
 WriteData: TStreamProc; HasData: Boolean);
var
 Count: LongInt;
 ms: TMemoryStream;
begin
 if not (Assigned(ReadData) and HasData) then Exit;
 CheckValue(vaBinary);
 ms := TMemoryStream.Create;
 try
   Read(Count, SizeOf(Count));
   ms.Size := Count;
   Read(ms.Memory^, Count);
   ReadData(ms);
 finally
   ms.Free;
 end;
end;

procedure TReaderCrack.DefineProperty(const Name: string;
 ReadData: TReaderProc; WriteData: TWriterProc; HasData: Boolean);
var
 SavePos: Integer;
begin
 if not (Assigned(ReadData) and HasData) then Exit;
 SavePos := Position;
 if not SameText(Name, ReadStr) then
 begin
   Position := SavePos;
   Exit;
 end;
 ReadData(Self);
end;
Но у меня сильное впечатление, чтоо туплю. Задача, думаю достаточно распростронённая и, наверника есть какое нить стандартное решение. По крайней мере без переписывания TReader'a ??


GuAV   (2004-08-15 16:05:00) [21]

Сейчас, когда сделал классом, ещё больше сходство ;-)
Да я понимаю то же самое, но
> компонент оверхед неплохой накатывает..
, а тут ничего лишнего только то что мне нужно.


jack128   (2004-08-15 16:02:00) [22]


> Я когда решил юзать RTTI напрямую TypInfo юзал
> вот тут вылаживал идею, правда сейчас уже всё переделал,
> интересно - выложу.
> http://www.delphimaster.ru/cgi-bin/forum.pl?id=1091963555&n=0

глянь в исходники ридера и райтера и увидишь приметно тоже самое ;-)


jack128   (2004-08-15 15:59:00) [23]

э-э-э-э-э... Не хочется.. Объектов много, тысячи/десятки тысяч..А компонент оверхед неплохой накатывает..


GuAV   (2004-08-15 15:59:00) [24]


> решил использовать RTTI

Я когда решил юзать RTTI напрямую TypInfo юзал
вот тут вылаживал идею, правда сейчас уже всё переделал, интересно - выложу.
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1091963555&n=0


GuAV   (2004-08-15 15:52:00) [25]

Юзай наследника TComponent.
Если считаешь, что TComponent - это VCL, то TPersistent - это тоже VCL.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо