Board index » delphi » Best approach to object serialization

Best approach to object serialization


2004-07-22 12:20:34 AM
delphi7
Hi,
What would be best way in Delphi (not .Net) to serialize objects? What
I'd like to do is to be able to store my objects to a file and reload
them back. No database is involved.
Is there any helpful libraries to make things easier?
Which ever file format is suitable, human readable format would be
nice tough, possible XML or YAML..
 
 

Re:Best approach to object serialization

Harri Vartiainen writes:
Quote
Hi,

What would be best way in Delphi (not .Net) to serialize objects? What
I'd like to do is to be able to store my objects to a file and reload
them back. No database is involved.

Is there any helpful libraries to make things easier?

Which ever file format is suitable, human readable format would be
nice tough, possible XML or YAML..
if you need automatic serialization of published properties you can use
QuickRTTI written by Mike Johnson:
www.bigattichouse.com/quickrtti.zip
Or, if you don't mind to derive your objects from a special common class you
can use the EOS library. It is based on the same quickRTTI xml
serialization mechanism, with the ability to serialize object containers (a
simple containers library is included), and to store and retrieve from xml
associations between objects.
sourceforge.net/projects/camelos
homepage:
camelos.sourceforge.net
I suggest you to get the latest version from the cvs. A new release with
some bigger refactorings will be out in a couple of days.
Ciao, Dean.
 

Re:Best approach to object serialization

Dean Zobec writes:
Quote
I suggest you to get the latest version from the cvs. A new release with
some bigger refactorings will be out in a couple of days.
I've decided to make things easier: release 0.9.3 is now available:
prdownloads.sourceforge.net/camelos/EOS-0.9.3.tar.gz?download
Ciao, Dean.
 

Re:Best approach to object serialization

Quote
Hi,

What would be best way in Delphi (not .Net) to serialize objects? What
I'd like to do is to be able to store my objects to a file and reload
them back. No database is involved.

Is there any helpful libraries to make things easier?

Which ever file format is suitable, human readable format would be
nice tough, possible XML or YAML..
Back in days when I used to do real delphi programming... I got around this
problem using 2 operations on my target Object/class which looked something
like this.
Class TABC = Class
Private
FX : Integer;
FY : String;
Public
Function Save(writer: TWriter): Boolean;
Function Load(reader: TReader): Boolean;
End;
Function TABC .Load(reader: TReader): Boolean;
Begin
FX := reader.ReadInteger;
FY := reader.ReadString;
Result := True;
End;
Function TABC .Save(writer: TWriter): Boolean;
Begin
writer.WriteInteger(FX);
writer.WriteString(FY);
Result := True;
End;
In order to save the data to a file create an FileStreem & an writer.
var
F: TFileStream;
writer : TWriter
abcObj : TABC;
F := TFileStream.Create('C:\ABC.Dat', fmCreate)
writer := TWriter.Create(S, 4096);
abcObj.Save(writer)
F.Free;
I am very sure its not a best approach... but it did help.
regards
Kiran
 

Re:Best approach to object serialization

On Wed, 21 Jul 2004 20:34:38 +0200, writes:
Quote
Harri Vartiainen writes:
if you need automatic serialization of published properties you can use
QuickRTTI written by Mike Johnson:
www.bigattichouse.com/quickrtti.zip

Or, if you don't mind to derive your objects from a special common class
you
can use the EOS library. It is based on the same quickRTTI xml
serialization mechanism, with the ability to serialize object containers
(a
simple containers library is included), and to store and retrieve from
xml
Well, I am also looking for an easy way to store complex data hierarchies.
As I understand you EOS demands the inheritance of my objects from a
common class. This wouldn't work well with my code. So, QuickRTTi would be
another idea. But I always thought QuickRTTi also demands the inheritance
of the classes from a specific ancestor (TXMLAware or sth, I don't
remember it right now) ?!?
Most of my data objects are interfaced. Maybe someone has an alternative
for interfaced classes which doesn't force me to inherit from a specific
class.
That would be wonderful. To write all datahandling myself is very
tiresome. :(
Fingolfin
 

Re:Best approach to object serialization

Fingolfin <XXXX@XXXXX.COM>wrote in news:opsbj2kn1mjmbejq@doriath:
Quote
Most of my data objects are interfaced. Maybe someone has an
alternative for interfaced classes which doesn't force me to inherit
from a specific class.
You can try adding the M+ directive and checking out HTTPRIO unit for an
example of using RTTI with Interfaces. You can also include the M+
directive to include RTTI for any class, even those not derived from
TPersistant.
--
Iman
 

Re:Best approach to object serialization

Fingolfin <XXXX@XXXXX.COM>wrote in news:
Quote
So, QuickRTTi would be another idea. But I always thought QuickRTTi
also demands the inheritance of the classes from a specific ancestor
(TXMLAware or sth, I don't remember it right now) ?!?
Not necessary, you can use a QuickRTTI enabler for serialization without
deriving from TXMLAware.
Quote
Most of my data objects are interfaced. Maybe someone has an
alternative for interfaced classes which doesn't force me to inherit
from a specific class.
Maybe someday I will find the time to refactor EOS to use an interface
instead of a common class.
Ciao, Dean
 

Re:Best approach to object serialization

Quote
You can try adding the M+ directive and checking out HTTPRIO unit for an
example of using RTTI with Interfaces. You can also include the M+
directive to include RTTI for any class, even those not derived from
TPersistant.
Thanks, M+ works like charm so far. I also read in the help about
IInvokable what should have the same effect like M+ but would look nicer
in the code. In my test though my classes which implemented an interface
derived from IInvokable didn't generate RTTI ?!?
Do you have any ideas on that matter?
Thanks in advance,
Fingolfin
 

Re:Best approach to object serialization

Fingolfin <XXXX@XXXXX.COM>wrote in news:opsbnno4b0jmbejq@doriath:
Quote
Do you have any ideas on that matter?
Post some code.
Iman
 

Re:Best approach to object serialization

On Sat, 24 Jul 2004 20:44:54 +0200, Fingolfin writes:
Quote
Thanks, M+ works like charm so far. I also read in the help about
IInvokable what should have the same effect like M+ but would look nicer
in the code. In my test though my classes which implemented an interface
derived from IInvokable didn't generate RTTI ?!?

Do you have any ideas on that matter?
Interfaces derived from IInvokable (or with $M+) don't generate
traditional RTTI. There is a unit for this if you look at the SOAP
implementation you should get to it, eventually.
One disadvantage with interface RTTI is that the interface has to be
registered somewhere so that you can reach the RTTI (There is no
method like TObject.ClassInfo) and you have to know what interface is
being implemented unlike objects where you do not need to know the
class details to find out which properties are published.
--
Marc Rohloff [TeamB]
marc rohloff at myrealbox dot com
 

Re:Best approach to object serialization

Harry,
Personnally, I have done this two slightly different ways:
Method 1:
Make your distributed objects descendant from TPersistent and make the
properties you want to stream published then you can use the unit posted
further down in this message to stream your objects in/out in DFM format.
In the base of my objects, I have put in an AsText class that allows me to
retrieve the text representation of the object.
This works well as the VCL knows how to stream it is objects in/out, but the
audience that can use your objects can be limited to Delphi programmers.
Mind you, if you are developing this for yourself, it doesn't really matter.
Method 2:
I'm currently writing my own personal OPF which I wanted to be portable. So
what I have done is build classes/objects that know how to stream themselves
as XML. Here again, the base object has a function called asXML which knows
how to stream the object out. An object can contain string properties or
other objects and they all understand how to stream each other out in the
correct sequence.
In this design, you need a factory that will be able to recreate the object
by parsing the XML which is a bit slower, but it gives me the portability
that I want.
Regards,
Steffan
P.S.: Here is the unit I was talking about earlier:
unit uCompStream;
{
Delphi component streaming unit
Author: David W. Body / Big Creek Software
E-mail address: XXXX@XXXXX.COM
Original Version: August 4, 1997
Last Updated: August 4, 1997
This code is hereby placed in the public domain.
}
interface
uses Classes;
function ComponentToString(Component: TComponent): string;
function StringToComponent(Value: string): TComponent;
function ComponentToVariant(Component: TComponent): Variant;
function VariantToComponent(Value: Variant): TComponent;
implementation
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;
function ComponentToVariant(Component: TComponent): Variant;
var
BinStream: TMemoryStream;
Data: Pointer;
begin
BinStream := TMemoryStream.Create;
try
BinStream.WriteComponent(Component);
Result := VarArrayCreate([0, BinStream.Size - 1], varByte);
Data := VarArrayLock(Result);
try
Move(BinStream.Memory^, Data^, BinStream.Size);
finally
VarArrayUnlock(Result);
end;
finally
BinStream.Free;
end;
end;
function VariantToComponent(Value: Variant): TComponent;
var
BinStream: TMemoryStream;
Data: Pointer;
begin
BinStream := TMemoryStream.Create;
try
Data := VarArrayLock(Value);
try
BinStream.WriteBuffer(Data^, VarArrayHighBound(Value, 1) + 1);
finally
VarArrayUnlock(Value);
end;
BinStream.Seek(0, soFromBeginning);
Result := BinStream.ReadComponent(nil);
finally
BinStream.Free;
end;
end;
end.
"Harri Vartiainen" <XXXX@XXXXX.COM>writes
Quote
Hi,

What would be best way in Delphi (not .Net) to serialize objects? What
I'd like to do is to be able to store my objects to a file and reload
them back. No database is involved.

Is there any helpful libraries to make things easier?

Which ever file format is suitable, human readable format would be
nice tough, possible XML or YAML..