Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.07.02;
Скачать: CL | DM;

Вниз

Сохранение коллекции в потоке.   Найти похожие ветки 

 
learner ©   (2006-05-21 00:44) [0]

Здравствуйте !
Пытаюсь сохранять коллекцию в потоке.
Все работает. Св-ва записываються и считываються правильно.
Беда в том, что при записи св-в коллекции из потока, новый Item
все время записываеться в Items[0] (см. ***)
Как это можно исправить ?

procedure Obj_ToStream(Obj:TObject; Strm:TStream);
var
i,j:integer;
PropNum:DWord;
TypeInf:PTypeInfo;
PropInfo:PPropInfo;
TypeData:PTypeData;
PropList:PPropList;
PropObject:TObject;
PropName,PropValue:string;
begin
TypeInf:=Obj.ClassInfo;
if (TypeInf=nil) or (TypeInf^.Kind<>tkClass) then Exit;
TypeData:=GetTypeData(TypeInf);
PropNum:=TypeData^.PropCount;
if PropNum=0 then
 if (Obj is TCollection) then
  begin
   Strm_AddDWord(TCollection(Obj).Count,Strm);
   for i:=0 to TCollection(Obj).Count-1 do
    begin
     Obj_ToStream(TCollection(Obj).Items[i],Strm);
    end;
   Exit;
  end
 else Exit;
GetMem(PropList,PropNum*SizeOf(PPropInfo));
try
 GetPropInfos(TypeInf,PropList);
 for i := 0 to PropNum - 1 do
  begin
   PropName:=PropList^[i]^.Name;
   TypeInf:=PropList^[i]^.PropType^;
   case TypeInf^.Kind of
    tkInteger,tkChar,tkEnumeration,tkFloat,tkString,tkSet,tkWChar,tkLString,tkWStrin g,tkVariant:
     begin
      PropValue:=GetPropValue(Obj,PropName,True);
      Strm_AddPropValue(PropName,PropValue,Strm);
     end;
    tkClass:
     begin
      Strm_WriteString(PropName,Strm);
      PropInfo:=PropList^[i];
      PropObject:=GetObjectProp(Obj,PropInfo);
      if Assigned(PropObject) then
       ...
        if (PropObject is TCollection) then
         begin
          Obj_ToStream(PropObject,Strm);
          Strm_AddDWord(TCollection(PropObject).Count,Strm);
          for j:=0 to TCollection(PropObject).Count-1 do
           begin
            Obj_ToStream(TCollection(PropObject).Items[j],Strm);
           end;
         end
        else
         if (PropObject is TPersistent) then Obj_ToStream(PropObject,Strm);
       end;
     end;
  end;
finally
 FreeMem(PropList,PropNum*SizeOf(PPropInfo));
end;
end;

procedure Obj_FromStream(Obj:TObject; Strm:TStream);
var
i,j,Ind,PropNum:integer;
TypeInf:PTypeInfo;
PropInfo:PPropInfo;
TypeData:PTypeData;
PropList:PPropList;
PropObject:TObject;
PropName,PropValue:string;

function FindProperty(Name:string):integer;
var
 i:integer;
begin
 Result := -1;
 for i:=0 to PropNum-1 do
  if CompareText(PropList^[i]^.Name,Name)=0 then
   begin
    Result:=i;
    Break;
   end;
 end;

begin
TypeInf:=Obj.ClassInfo;
if (TypeInf=nil) or (TypeInf^.Kind<>tkClass) then Exit;
TypeData:=GetTypeData(TypeInf);
PropNum:=TypeData^.PropCount;
if PropNum=0 then
 if (Obj is TCollection) then
  begin
   Strm.Read(Ind,SizeOf(DWord));
   for i:=0 to Ind-1 do
    begin
     Obj_FromStream(TCollection(Obj).Add,Strm);<<-- Вот здесь пишеться не в Items[i],  а в Items[0] ***
    end;
   Exit;
  end
 else Exit;
GetMem(PropList,PropNum*SizeOf(PPropInfo));
try
 GetPropInfos(TypeInf,PropList);
 PropName:=Strm_ReadString(Strm);
 Ind:=FindProperty(PropName);
 if Ind=-1 then Exit;
 TypeInf:=PropList^[Ind]^.PropType^;
 case TypeInf^.Kind of
  tkInteger,tkChar,tkEnumeration,tkFloat,tkString,tkSet,tkWChar,tkLString,tkWStrin g,tkVariant:
   begin
    PropValue:=Strm_ReadString(Strm);
    SetPropValue(Obj,PropName,PropValue);
   end;
    tkClass:
     begin
      PropInfo:=PropList^[Ind];
      PropObject:=GetObjectProp(Obj,PropInfo);
      if Assigned(PropObject) then
       ...
        if (PropObject is TCollection) then
         begin
          Obj_FromStream(PropObject,Strm);
          Strm.Read(Ind,SizeOf(DWord));
          for i:=0 to Ind-1 do
           begin
            for j:=0 to TCollection(PropObject).Count-1 do Obj_FromStream(TCollection(PropObject).Add,Strm);
           end;
         end
        else
         if (PropObject is TPersistent) then Obj_FromStream(PropObject,Strm);
     end;
 end;
finally
 FreeMem(PropList,PropNum*SizeOf(PPropInfo));
end;
if Strm.Position<Strm.Size then Obj_FromStream(Obj,Strm);
end;


 
Мефисто   (2006-05-21 09:24) [1]

>> Obj _FromStream(TCollection(Obj).Add,Strm);

Как я понимаю производится рекурсивный вызов.

Только почему?

TCollection(Obj).Add

а не

TCollection(Obj).Items[I]

P.S.
Особо в реализацию кода не всматривался :)


 
pargo ©   (2006-05-21 09:51) [2]

Мефисто   (21.05.06 9:24) [1]
Если, вместо TCollection(Obj).Add
использовать TCollection(Obj).Items[I] то происходит то же самое.


 
jack128 ©   (2006-05-21 13:40) [3]


type
 TDBGridColumns = class(TCollection);

type
 TColumnsWrapper = class(TComponent)
 private
   FColumns: TDBGridColumns;
 published
   property Columns: TDBGridColumns read FColumns write FColumns;
 end;

procedure TDBGridColumns.SaveToStream(S: TStream);
var
 Wrapper: TColumnsWrapper;
begin
 Wrapper := TColumnsWrapper.Create(nil);
 try
   Wrapper.Columns := Self;
   S.WriteComponent(Wrapper);
 finally
   Wrapper.Free;
 end;
end;

procedure TDBGridColumns.LoadFromStream(S: TStream);
var
 Wrapper: TColumnsWrapper;
begin
 Wrapper := TColumnsWrapper.Create(nil);
 try
   Wrapper.Columns := FGrid.CreateColumns;
   S.ReadComponent(Wrapper);
   Assign(Wrapper.Columns);
 finally
   Wrapper.Columns.Free;
   Wrapper.Free;
 end;
end;


 
learner ©   (2006-05-21 15:16) [4]

jack128 ©   (21.05.06 13:40) [3]
Спасибо, работает.



Страницы: 1 вся ветка

Текущий архив: 2006.07.02;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.047 c
2-1150178919
Хой
2006-06-13 10:08
2006.07.02
Оператор inherited


2-1149773308
Serzh
2006-06-08 17:28
2006.07.02
System Tray


15-1149329379
DirectX
2006-06-03 14:09
2006.07.02
последний на сегодня directX


2-1149830550
graf
2006-06-09 09:22
2006.07.02
И снова вопрос о FTP


2-1150378187
Megabyte
2006-06-15 17:29
2006.07.02
Связь клиента с сервером по интернету