Newsgroup: it.comp.lang.delphi
Titolo: classe "container" che consenta lo streaming su file

Ciao a tutti.
Premetto che sono abbastanza nuovo a persistenza, RTTI, streaming di
oggetti e tutto quanto concerne l'argomento. Potrei cadere facilmente
:P in sfondoni :D
Volevo realizzare una classe container che mi consentisse lo streaming
su file, e senza ricorrere a TCollection, ma incapsulando un "oggetto
container". Ma come fare?
Il riferimento è questo articolo (spero il link sia corretto) :
http://www.atug.com/andypatterns/collections.htm
Volevo seguire l'approccio che l'articolo definisce "light-weight",
perche' ad una prima occhiata non mi piace la rigidita' del pattern
TCollection. Posizione opinabilissima, per carita', forse studiandomelo
un po' meglio finisce che lo preferisco.
Ad ogni modo, volendo scegliere una classe-lista, ma pensando allo
streaming, mi sembra (correggetemi se sbaglio) che l'unica possibilita'
sia TStringList: non esiste cioe' una classe che contenga solo oggetti,
come TList o TObjectList, e che derivi da TPersistent o TComponent.
Ho scritto questa piccola classe:
  TGPSCollection = class(TComponent)
  private
    fbase: TStringList;
  public
    procedure addDataToentry(id, newd: string);
    function getEntryOldestData(id: string; var res: string): boolean;
    constructor Create;
    destructor Destroy; override;
  published
    property base: TStringList read fbase write fbase;
  end;
[...]
procedure TGPSCollection.addDataToentry;
var i: integer;
begin
  i := fbase.IndexOf(id);
  case i of
    -1:
      begin
        fbase.AddObject(id, TStringList.Create);
        TStringList(fbase.Objects[fbase.Count - 1]).Add(newd);
      end;
    else
      TStringList(fbase.Objects[i]).Add(newd);
  end;
end;
[...]
destinata ad associare (mediante fbase) a ciascuna stringa-id
un'ulteriore TStringList.
Compio queste operazioni:
1) Creo un oggetto coll di classe TGPSCollection;
2) in esso pongo un'entry, associando (per es.) all'id 'pincopallino'
una TStringList in cui inserisco una prima stringa;
3) lo "serializzo" mediante (TFileStream.WriteComponent(coll))
salvandolo su un file;
Quando però lo deserializzo dal file su cui l'ho scritto, se faccio:
i := fbase.indexOf('pincopallino');
allora i = 0 (cioe', come auspicabile, la stringa viene reperita), ma
fbase.Objects[i] risulta nil.
Cioè (spero di farmi capire): la TStringList esterna viene
effettivamente "serializzata"; quelle associate agli id no. Eppure
TStringList deriva da TComponent.
Dove sbaglio?
Chiedetemi pure chiarimenti se (come presumo) mi sono spiegato male.
Ciao e grazie a tutti

 TStringList deriva da TComponent.
per capire perchè una TStringList figlia di un'altra TStringList non venga 
serializzata con TFileStream.WriteComponent bisogna andare a vedere cosa fa 
TStream.WriteComponent, e di conseguenza TStream.WriteDescendent, e di 
conseguenza TWriter.WriteDescendent, quindi TWriter.WriteComponent, che ci 
porta a TComponent.WriteState e in definitiva a TWriter.WriteData e anche 
TWriter.WriteProperties.
Specie questi ultimi metodi fanno abbondante uso di RTTI e (presumo) fanno 
lo streaming solo delle proprietà published.
Dai anche un'occhiata al framework EOS curato da Uberto Barbini, Dean Zobec 
e altri ( 
http://camelos.sourceforge.net
 ) per la serializzazione su file 
XML degli oggetti o anche un mio post del 22/9/2006 su it.comp.lang.dephi 
nel thread "Dubbi (probabilmente da nubbio) su struttura di una 
applicazione"
-- 
Mauro Falzari
"Qual'è la migliore salsa del mondo? La fame".
  (Miguel de Cervantes Saavedra, 1547-1616)