views:

106

answers:

4

I need to store multiple objects (most of them are TObject/non persistent) to a TMemoryStream, save the stream to disk and load it back. The objects need to be streamed one after each other. Some kind of universal container.

At the moment I put all properties/fields/variables of an object into a record and save the record to stream. But I intend to use functions file WriteInterger, WriteString (see below), WriteBoolean, etc functions to save/load data from stream.

StreamReadString(CONST MemStream: TMemoryStream): string; 
StreamWriteString(CONST MemStream: TMemoryStream; s: string);

However, it seems that I need to rewrite a lot of code. One of the many examples is TStringList.LoadFromStream that will not work so it needs to be rewritten. This is because TStringList needs to be the last object in the stream (it reads from current position to the end of the stream).

Anybody knows a library that provide basic functionality like this?


I am using Delphi 7 so RTTI is not that great.

+1  A: 

Which Delphi version? Delphi 2010 has new RTTI functionality, so you can use DeHL which has "Full generic serialization for all included types and collections".

André
Sorry. I forgot to add: Delphi 7.
Altar
Ok, then you could try "http://opensource.hitsoft-it.com/display/HitXMLe/General+Description" (we use that in D2007 for serialization to xml)
André
A: 

Why not use XML?

  1. Write an XSD for the XML that defines the XML.
  2. Generate a Delphi unit form that XSD using the XML Data Binding Wizard.
  3. Put a bunch of your objects into that XML
  4. Save the XML to disk (or stream it to some other medium)

For more info on XML and the XML Data Binding Wizard see this answer.

Edit:

Just map your objects to the interfaces/objects generated from the XSD; or use the objects/interfaces that have been generated.

That is usually far easier than hooking into the Delphi streaming mechanism (by either writing TPersistent wrappers with published properties around your objects, going the DefineBinaryProperty way, or the TReader/TWriter/DefineProperty way).

--jeroen

Jeroen Pluimers
Will this XML work with non-published properties and non persistent classes such as TObject?I am also concern about the size of the file generated which may be several times larger that a binary file.
Altar
Wow: someone surely dislikes XML and downvoted me :-)
Jeroen Pluimers
+2  A: 

Have you thought about using TReader and TWriter to fill your streams.

Nige.
+1  A: 

See related post here

Btw, Delphi7 also has RTTI support, otherwise your forms (.dfm) could not be loaded :-)
If you use published properties, RTTI will work for you "out of the box".
Otherwise you have to do it yourself with a

procedure DefineProperties(Filer: TFiler); override;

You can take a look at how it's implemented in:

procedure TDataModule.DefineProperties(Filer: TFiler);

These are the only ways for object serialization.
But you could also try records: if you do not use array(strings are also arrays of char) or object properties, you can directly save and load a record to memory (stream, file, etc). I use this in my AsmProfiler to be able to read and write many (small) results very fast (array of record with some integer values can be saved and loaded with one Move/CopyMemory call!).

André
At the moment I put all properties/fields/variables of an object into a record and save the record to stream. But I intend to use my 'WriteInterger', 'WriteString', 'WriteBoolean', etc functions to save/load data from stream.
Altar