Board index » cppbuilder » Serialize Object, Streaming Object in VCL

Serialize Object, Streaming Object in VCL

: "Yugo Shimada" <yu...@d1.dion.ne.jp> wrote:

Quote
>Since I am not sure how I should do serialization of my class
>with VCL, my code might be wrong...  

I am not even certain that the code does what you want.

Quote
>TFileStream *stream = new TFileStream("AAA.txt", fmCreate);

It is very unusual to create a file stream of your own. If you really want
to stream a descendant of TComponent (as part of the VCL), you usually
override  DefineProperties  and perform your reading writing with the
methods provided there.

If you just want to write the state of an object to disk, you might want
to overload the stream insertion and extraction operators (>> andd <<),
which is the more C++-like way of serializing.

--
General information:
  * Post to the right group - http://www.borland.com/newsgroups/
    * Do not cross- or multipost
      * Research at http://www.mers.com/searchsite.html

Stefan Hoffmeister - http://www.econos.de/
(TeamB - http://www.teamb.com/)

 

Re:Serialize Object, Streaming Object in VCL


Hi,

I got one sample code of doing the serialization of user-defined class with
VCL
as below.
Although I put the override routine for GetChildren() in the code, it does
not
got called. Since I am not sure how I should do serialization of my class
with VCL,
my code might be wrong...  Could someone point it out ?

Best regards,
Yugos
Yu...@d1.dion.ne.jp

#include <vcl.h>
#pragma hdrstop

#include "serialize.h"
#pragma package(smart_init)
#pragma resource "*.dfm"

// My Class supporting streaming...
class TAbc : public TComponent {
private:
    AnsiString a;    // member 1
    int ia;             // member 2

private:
    void __fastcall SetA(AnsiString ax)    { a = ax;};
    void __fastcall SetI(int ax)                { ia = ax;};
    AnsiString __fastcall GetA()              { return a; };
    int __fastcall GetI()                        { return ia; };

public:
    virtual __fastcall TAbc(TComponent * AOwner);
    virtual void __fastcall GetChildren(TGetChildProc Proc);

__published:
    __property AnsiString aa = { read=GetA, write=SetA, nodefault };
    __property int i = { read=GetI, write=SetI, nodefault };

Quote
};

TForm1 *Form1;

TAbc *abc;

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
TFileStream *stream = new TFileStream("AAA.txt", fmCreate);

    abc = new TAbc(Owner);

    abc->aa = "String value";
    abc->i = 100;

    stream->WriteComponent((TComponent *)abc);

    delete stream;
    delete abc;

    abc = new TAbc(Owner);

    stream = new TFileStream("AAA.txt", fmOpenReadWrite);

    stream->ReadComponent((TComponent *)abc);

    delete stream;

    return;

Quote
}

__fastcall TAbc::TAbc(TComponent * AOwner): TComponent(AOwner)
{

Quote
}

void __fastcall TAbc::GetChildren(TGetChildProc Proc) // nobody call me!?
{
    for( int i = 0 ; i < ComponentCount ; i++ )
        Proc(Components[i]);
Quote
}

Re:Serialize Object, Streaming Object in VCL


Thank you for your responding.

Stefan Hoffmeister (TeamB) <Stefan.Hoffmeis...@Econos.de> wrote in message
news:le2i6sgflen3dalfpmkrc7vpeuj201s3t1@4ax.com...

Quote
> : "Yugo Shimada" <yu...@d1.dion.ne.jp> wrote:

> >Since I am not sure how I should do serialization of my class
> >with VCL, my code might be wrong...

> I am not even certain that the code does what you want.

> >TFileStream *stream = new TFileStream("AAA.txt", fmCreate);

> It is very unusual to create a file stream of your own. If you really want
> to stream a descendant of TComponent (as part of the VCL), you usually
> override  DefineProperties  and perform your reading writing with the
> methods provided there.

Great!, if you have sample codes, I will be happy...
I am seeking out such codes that show how object serialize should be
done with VCL in deja.com. I could see many questions related in object
serializing there, but I could not see specified answers ...

Quote
> If you just want to write the state of an object to disk, you might want
> to overload the stream insertion and extraction operators (>> andd <<),
> which is the more C++-like way of serializing.

I just wanted to read/write my object from/to the disk as you supposed and
have been looking into the way to do serialization with VCL for these days.
Of couse, it is not hard to do implement of object serializing by myself
although,
if VCL has been supporting object serialization scheme like MFC CArchive,
I prefer to take advantage of it.

Quote

> --
> General information:
>   * Post to the right group - http://www.borland.com/newsgroups/
>     * Do not cross- or multipost
>       * Research at http://www.mers.com/searchsite.html

> Stefan Hoffmeister - http://www.econos.de/
> (TeamB - http://www.teamb.com/)

Thanks,
Yugos
Yu...@d1.dion.ne.jp

Re:Serialize Object, Streaming Object in VCL


: "Yugo Shimada" <yu...@d1.dion.ne.jp> wrote:

Quote
>if VCL has been supporting object serialization scheme like MFC CArchive,
>I prefer to take advantage of it.

Well, the "__published" keyword determines streaming.

In short, every __property that is declared __published will automatically
be streamed (except if the stored property modifier is false, of course)

In case you *don't* want to use the convenience of going via __published,
you will have to use DefineBinaryProperty or DefineProperty. Please read
the documentation for each of the methods and classes that I use in the
source code below.

Apologies for the weird line breaks in the following code example; this is
only done to avoid even stranger line breaks from the newsreader.

***********************************************

#include <vcl.h>
#include <memory>
#pragma hdrstop

class TestClass : public TComponent
{
  private:
    typedef TComponent inherited;

  // This member is streamed automatically
  // just due to using a __published __property
  private:
    int FAutoHandled;

  __published:
    __property int AutoHandled =
      { read = FAutoHandled, write = FAutoHandled };

  // This member we will "stream manually"
  private:
    static const int ArraySize = 100;
    int FManuallyHandled[ArraySize];

    void __fastcall LoadTheProperty(TStream* Stream);
    void __fastcall WriteTheProperty(TStream* Stream);

  protected:
    virtual void __fastcall DefineProperties(TFiler* Filer);

  // Just to show off:
  public:
    virtual __fastcall TestClass(TComponent*) :
      TComponent(NULL)
      { /* nothing */ }

    virtual __fastcall ~TestClass(void)
      {
        ShowMessage("Class has been destroyed");
      }

    void InitializeSomeData(void)
      {
        FAutoHandled = 42;

        memset(FManuallyHandled, sizeof(FManuallyHandled), 0);
        FManuallyHandled[0] = 123;
        FManuallyHandled[ArraySize-1] = 321;
      };

    void ShowData(void)
      {
        ShowMessage( "FAutoHandled = " + IntToStr(FAutoHandled) );
        ShowMessage( "FManuallyHandled = " +
                     IntToStr(FManuallyHandled[0]) + ", " +
                     IntToStr(FManuallyHandled[ArraySize-1]) );
      }

Quote
};

void __fastcall TestClass::LoadTheProperty(TStream* Stream)
{
  Stream->ReadBuffer(FManuallyHandled, sizeof(FManuallyHandled));

Quote
}

void __fastcall TestClass::WriteTheProperty(TStream* Stream)
{
  Stream->WriteBuffer(FManuallyHandled, sizeof(FManuallyHandled));

Quote
}

void __fastcall TestClass::DefineProperties(TFiler* Filer)
{
  inherited::DefineProperties(Filer);

  // Note: here we use DefineBinaryProperty; make
  // sure you have a look at DefineProperty, too.
  Filer->DefineBinaryProperty("SomethingWeHandled",
    LoadTheProperty, WriteTheProperty, true);

Quote
}

#pragma argsused
int main(int argc, char* argv[])
{
  const AnsiString FileName = "C:\\Test";
  Classes::RegisterClass(__classid(TestClass));

  std::auto_ptr<TestClass> test;
  test.reset(new TestClass(NULL));

  test->InitializeSomeData();
  test->ShowData();

  ShowMessage("Writing");
  WriteComponentResFile(FileName, test.get());
  test.reset(0);

  TestClass* temp;
  ShowMessage("Reading back");
  temp = static_cast<TestClass*>(ReadComponentResFile(FileName, NULL));
  test.reset(temp);

  test->ShowData();

  return 0;

Quote
}

--
General information:
  * Post to the right group - http://www.borland.com/newsgroups/
    * Do not cross- or multipost
      * Research at http://www.mers.com/searchsite.html

Stefan Hoffmeister - http://www.econos.de/
TeamB - http://www.teamb.com/

Re:Serialize Object, Streaming Object in VCL


Hi Stefan,

I have been off for a month and now back here.

That's what I've been eager to see !!
I also checked into the 'DefineProperty' method and could stream
in/out several types with TReader and TWriter.

I much appreciate for your advice,
Yugos
Yu...@d1.dion.ne.jp

In article <6mvr6s4mraqt762klklj7t5edd47lrr...@4ax.com>,
  "Stefan Hoffmeister (TeamB)" <Stefan.Hoffmeis...@Econos.de> wrote:

Quote
> : "Yugo Shimada" <yu...@d1.dion.ne.jp> wrote:

> >if VCL has been supporting object serialization scheme like MFC
CArchive,
> >I prefer to take advantage of it.

> Well, the "__published" keyword determines streaming.

> In short, every __property that is declared __published will
automatically
> be streamed (except if the stored property modifier is false, of
course)

> In case you *don't* want to use the convenience of going via
__published,
> you will have to use DefineBinaryProperty or DefineProperty. Please
read
> the documentation for each of the methods and classes that I use in
the
> source code below.

> Apologies for the weird line breaks in the following code example;
this is
> only done to avoid even stranger line breaks from the newsreader.

> ***********************************************

Sent via Deja.com http://www.deja.com/
Before you buy.

Re:Serialize Object, Streaming Object in VCL


Hi Stefan,

I have been off for a month and now back here.

That's what I've been eager to see !!
I also checked into the 'DefineProperty' method and could stream in/out
several types with TReader and TWriter.

I much appreciate for your advice,
Yugos
Yu...@d1.dion.ne.jp

PS.
I had posted this messages last week from Deja.com but it cannot be on the
borland server.
So I re-posted again by connetting to borland server directly. It's
strange...

Stefan Hoffmeister (TeamB) <Stefan.Hoffmeis...@Econos.de> wrote in message
news:6mvr6s4mraqt762klklj7t5edd47lrru44@4ax.com...

Quote
> : "Yugo Shimada" <yu...@d1.dion.ne.jp> wrote:

> >if VCL has been supporting object serialization scheme like MFC CArchive,
> >I prefer to take advantage of it.

> Well, the "__published" keyword determines streaming.

> In short, every __property that is declared __published will automatically
> be streamed (except if the stored property modifier is false, of course)

> In case you *don't* want to use the convenience of going via __published,
> you will have to use DefineBinaryProperty or DefineProperty. Please read
> the documentation for each of the methods and classes that I use in the
> source code below.

> Apologies for the weird line breaks in the following code example; this is
> only done to avoid even stranger line breaks from the newsreader.

> ***********************************************

> #include <vcl.h>
> #include <memory>
> #pragma hdrstop

> class TestClass : public TComponent
> {
>   private:
>     typedef TComponent inherited;

>   // This member is streamed automatically
>   // just due to using a __published __property
>   private:
>     int FAutoHandled;

>   __published:
>     __property int AutoHandled =
>       { read = FAutoHandled, write = FAutoHandled };

>   // This member we will "stream manually"
>   private:
>     static const int ArraySize = 100;
>     int FManuallyHandled[ArraySize];

>     void __fastcall LoadTheProperty(TStream* Stream);
>     void __fastcall WriteTheProperty(TStream* Stream);

>   protected:
>     virtual void __fastcall DefineProperties(TFiler* Filer);

>   // Just to show off:
>   public:
>     virtual __fastcall TestClass(TComponent*) :
>       TComponent(NULL)
>       { /* nothing */ }

>     virtual __fastcall ~TestClass(void)
>       {
>         ShowMessage("Class has been destroyed");
>       }

>     void InitializeSomeData(void)
>       {
>         FAutoHandled = 42;

>         memset(FManuallyHandled, sizeof(FManuallyHandled), 0);
>         FManuallyHandled[0] = 123;
>         FManuallyHandled[ArraySize-1] = 321;
>       };

>     void ShowData(void)
>       {
>         ShowMessage( "FAutoHandled = " + IntToStr(FAutoHandled) );
>         ShowMessage( "FManuallyHandled = " +
>                      IntToStr(FManuallyHandled[0]) + ", " +
>                      IntToStr(FManuallyHandled[ArraySize-1]) );
>       }

> };

> void __fastcall TestClass::LoadTheProperty(TStream* Stream)
> {
>   Stream->ReadBuffer(FManuallyHandled, sizeof(FManuallyHandled));
> }

> void __fastcall TestClass::WriteTheProperty(TStream* Stream)
> {
>   Stream->WriteBuffer(FManuallyHandled, sizeof(FManuallyHandled));
> }

> void __fastcall TestClass::DefineProperties(TFiler* Filer)
> {
>   inherited::DefineProperties(Filer);

>   // Note: here we use DefineBinaryProperty; make
>   // sure you have a look at DefineProperty, too.
>   Filer->DefineBinaryProperty("SomethingWeHandled",
>     LoadTheProperty, WriteTheProperty, true);
> }

> #pragma argsused
> int main(int argc, char* argv[])
> {
>   const AnsiString FileName = "C:\\Test";
>   Classes::RegisterClass(__classid(TestClass));

>   std::auto_ptr<TestClass> test;
>   test.reset(new TestClass(NULL));

>   test->InitializeSomeData();
>   test->ShowData();

>   ShowMessage("Writing");
>   WriteComponentResFile(FileName, test.get());
>   test.reset(0);

>   TestClass* temp;
>   ShowMessage("Reading back");
>   temp = static_cast<TestClass*>(ReadComponentResFile(FileName, NULL));
>   test.reset(temp);

>   test->ShowData();

>   return 0;
> }

> --
> General information:
>   * Post to the right group - http://www.borland.com/newsgroups/
>     * Do not cross- or multipost
>       * Research at http://www.mers.com/searchsite.html

> Stefan Hoffmeister - http://www.econos.de/
> TeamB - http://www.teamb.com/

Re:Serialize Object, Streaming Object in VCL


: "Yugo Shimada" <yu...@d1.dion.ne.jp> wrote:

Quote
>I had posted this messages last week from Deja.com but it cannot be on the
>borland server.

Correct. As the information at http://www.borland.com/newsgroups/ clearly
says, you must connect directly to the Borland server in order to post
here.

Yugo, a note: please do not quote complete messages (130 lines!), as this
is rather annoying and not helpful at all. Please remove all text that you
do not explicitly refer to - see the newsgroups guidelines and netiquette
at http://www.borland.com/newsgroups/

Thank you very much for not quoting needlessly in the future.

--
General information:
  * Post to the right group - http://www.borland.com/newsgroups/
    * Do not cross- or multipost
      * Research at http://www.mers.com/searchsite.html

Stefan Hoffmeister - http://www.econos.de/
TeamB - http://www.teamb.com/

Other Threads