Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. MFC Serialization Questions..

MFC Serialization Questions..

Scheduled Pinned Locked Moved C / C++ / MFC
c++jsonquestion
9 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    montiee
    wrote on last edited by
    #1

    I'm sure the answer is obvious but I can't seem to work it out. I have a created a class (called Cemu) which is tagged as serializable via MFC's macros. Now in Cemu there consist a couple of CString's which I want to serialize. To complicate matters I have a list of Cemu entries stored in CemuList. What I have done when I want to dump the list to the file is loop through CemuList and call the serialize() method I created in Cemu which in turn writes out the CStrings I want to a file. That process seems to work just fine by examining the file afterwards. What I'm have trouble with is de-serializing. My initial stab at it is below but that doesn't work. while (file.GetPosition() < file.GetLength()) { client = new Cemu; client->Serialize(archive); CemulList.AddTail(*client); } The file containing the data has 2 Cemu serialised entries and what I'm finding is that only one gets read in. My interpretation was that the act of serializing the Cemu would move the file pointer along correctly, ie a total of 2 times but I'm missing something. Can point me in the right direction? Cheers!

    RaviBeeR T C 3 Replies Last reply
    0
    • M montiee

      I'm sure the answer is obvious but I can't seem to work it out. I have a created a class (called Cemu) which is tagged as serializable via MFC's macros. Now in Cemu there consist a couple of CString's which I want to serialize. To complicate matters I have a list of Cemu entries stored in CemuList. What I have done when I want to dump the list to the file is loop through CemuList and call the serialize() method I created in Cemu which in turn writes out the CStrings I want to a file. That process seems to work just fine by examining the file afterwards. What I'm have trouble with is de-serializing. My initial stab at it is below but that doesn't work. while (file.GetPosition() < file.GetLength()) { client = new Cemu; client->Serialize(archive); CemulList.AddTail(*client); } The file containing the data has 2 Cemu serialised entries and what I'm finding is that only one gets read in. My interpretation was that the act of serializing the Cemu would move the file pointer along correctly, ie a total of 2 times but I'm missing something. Can point me in the right direction? Cheers!

      RaviBeeR Offline
      RaviBeeR Offline
      RaviBee
      wrote on last edited by
      #2

      jbem wrote:

      Can point me in the right direction?

      See this[^] article. /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com

      G M 2 Replies Last reply
      0
      • M montiee

        I'm sure the answer is obvious but I can't seem to work it out. I have a created a class (called Cemu) which is tagged as serializable via MFC's macros. Now in Cemu there consist a couple of CString's which I want to serialize. To complicate matters I have a list of Cemu entries stored in CemuList. What I have done when I want to dump the list to the file is loop through CemuList and call the serialize() method I created in Cemu which in turn writes out the CStrings I want to a file. That process seems to work just fine by examining the file afterwards. What I'm have trouble with is de-serializing. My initial stab at it is below but that doesn't work. while (file.GetPosition() < file.GetLength()) { client = new Cemu; client->Serialize(archive); CemulList.AddTail(*client); } The file containing the data has 2 Cemu serialised entries and what I'm finding is that only one gets read in. My interpretation was that the act of serializing the Cemu would move the file pointer along correctly, ie a total of 2 times but I'm missing something. Can point me in the right direction? Cheers!

        T Offline
        T Offline
        ToxickZero
        wrote on last edited by
        #3

        One of the ways that I've gotten around this is by outputting the number of elements in the list before outputting the list. Then reading that number at load time to see how many elements are getting ready to get read:

        int numElements;

        if( ar.IsStoring() )
        {
            numElements = \_yourList.GetCount();
            ar << numElements;
        
            POSITION pos = \_yourList.GetHeadPosition();
            while( pos )
            {
                YourType currElement = \_yourList.GetNext( pos );
                currElement.Serialize( ar );
            }
        }
        else
        {
            \_yourList.RemoveAll();  // clear list
        
            ar >> numElements;      // get number of forthcoming elements
            for( int i = 0; i < numElements; ++i )
            {
                YourType newElement;
                newElement.Serialize( ar );
        
                \_yourList.AddTail( newElement );
            }
        }
        

        That's untested code, but you should get the idea. -- modified at 15:34 Friday 30th December, 2005

        M 1 Reply Last reply
        0
        • RaviBeeR RaviBee

          jbem wrote:

          Can point me in the right direction?

          See this[^] article. /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com

          G Offline
          G Offline
          Garth J Lancaster
          wrote on last edited by
          #4

          Nice work Ravi - Ive just pointed your work out to a Larry Mills, 2 posts above this one :-) 'g' -- modified at 21:35 Friday 30th December, 2005

          1 Reply Last reply
          0
          • RaviBeeR RaviBee

            jbem wrote:

            Can point me in the right direction?

            See this[^] article. /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com

            M Offline
            M Offline
            montiee
            wrote on last edited by
            #5

            Thanks Ravi. I initially saw these primers and had a bit of a read through all 3 of them so thanks for putting the effort in to write them up. The thing I have a problem and which I was trying to avoid was having to store the number of items in the actual file. It seemed rather logical to me that if you know the way you stored data for a class you should be able to serialize chunks which would automatically walk the file in the right increments via the archive buffer till EOF on deserialization. I guess not. So the thing I get out of all this is that if you have a list of objects of a type that you want to serialize then there is no other way than to store the number of objects as the first item if you ever want to recreate that list of objects ever again. I guess CArchive has no concept, that is exposed to the user, of file position based on what it has serialized just more like a buffer position internally.

            RaviBeeR 1 Reply Last reply
            0
            • T ToxickZero

              One of the ways that I've gotten around this is by outputting the number of elements in the list before outputting the list. Then reading that number at load time to see how many elements are getting ready to get read:

              int numElements;

              if( ar.IsStoring() )
              {
                  numElements = \_yourList.GetCount();
                  ar << numElements;
              
                  POSITION pos = \_yourList.GetHeadPosition();
                  while( pos )
                  {
                      YourType currElement = \_yourList.GetNext( pos );
                      currElement.Serialize( ar );
                  }
              }
              else
              {
                  \_yourList.RemoveAll();  // clear list
              
                  ar >> numElements;      // get number of forthcoming elements
                  for( int i = 0; i < numElements; ++i )
                  {
                      YourType newElement;
                      newElement.Serialize( ar );
              
                      \_yourList.AddTail( newElement );
                  }
              }
              

              That's untested code, but you should get the idea. -- modified at 15:34 Friday 30th December, 2005

              M Offline
              M Offline
              montiee
              wrote on last edited by
              #6

              Thanks ToxickZero. Same solution as Ravi offered also and works fine as I just implemented it. Pity you need to keep track of the number of elements when serializing. Wish it could be done in a more dynamic fashion but it seems as it is not to be.

              1 Reply Last reply
              0
              • M montiee

                Thanks Ravi. I initially saw these primers and had a bit of a read through all 3 of them so thanks for putting the effort in to write them up. The thing I have a problem and which I was trying to avoid was having to store the number of items in the actual file. It seemed rather logical to me that if you know the way you stored data for a class you should be able to serialize chunks which would automatically walk the file in the right increments via the archive buffer till EOF on deserialization. I guess not. So the thing I get out of all this is that if you have a list of objects of a type that you want to serialize then there is no other way than to store the number of objects as the first item if you ever want to recreate that list of objects ever again. I guess CArchive has no concept, that is exposed to the user, of file position based on what it has serialized just more like a buffer position internally.

                RaviBeeR Offline
                RaviBeeR Offline
                RaviBee
                wrote on last edited by
                #7

                jbem wrote:

                avoid was having to store the number of items in the actual file

                This is a VBT (very bad thing :)) because it enforces the dependency that the collection be the last (or only) data stored in the file.

                jbem wrote:

                CArchive has no concept, that is exposed to the user, of file position based on what it has serialized just more like a buffer position internally

                Correct. And nor should it, since it's really just a stream (that may be part of another stream). That's where the power of object oriented serialization comes in. If you later choose to embed your collection in another object, you don't need to change your collection serialization code as it's location agnostic. /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com

                1 Reply Last reply
                0
                • M montiee

                  I'm sure the answer is obvious but I can't seem to work it out. I have a created a class (called Cemu) which is tagged as serializable via MFC's macros. Now in Cemu there consist a couple of CString's which I want to serialize. To complicate matters I have a list of Cemu entries stored in CemuList. What I have done when I want to dump the list to the file is loop through CemuList and call the serialize() method I created in Cemu which in turn writes out the CStrings I want to a file. That process seems to work just fine by examining the file afterwards. What I'm have trouble with is de-serializing. My initial stab at it is below but that doesn't work. while (file.GetPosition() < file.GetLength()) { client = new Cemu; client->Serialize(archive); CemulList.AddTail(*client); } The file containing the data has 2 Cemu serialised entries and what I'm finding is that only one gets read in. My interpretation was that the act of serializing the Cemu would move the file pointer along correctly, ie a total of 2 times but I'm missing something. Can point me in the right direction? Cheers!

                  C Offline
                  C Offline
                  Cliff Hatch
                  wrote on last edited by
                  #8

                  Hi jbem I'm not sure that your conclusion that you have to keep track of the number of items in the list is correct. The list classes contain Serialize functions, and if you use these they keep track for you. A while back I was builiding a simulator that contained a recursive structure of models and submodels, similar to your Cemu class. My class was CModel, of type CModelObject. It contained a list, m_ModelList, pointing to the submodels (also of type CModel). m_ModelList was of type CModelList, declared as follows: typedef CTypedPtrList<CObList, CModelObject*> CModelList; And the CModel Serialize function was: void CModel::Serialize(CArchive & ar) { CModelObject::Serialize(ar); //Serialize/de-serialize the submodels m_ModelList.Serialize(ar); if (ar.IsStoring()) { ar << m_Name << m_Notes << m_AtomOrMacroNotes; } else { ar >> m_Name >> m_Notes >> m_AtomOrMacroNotes; } } The function saves the properties of the particular CModel object, m_Name, m_Notes, etc., and those defined in the base clase, CModelObject - and it saves the submodels by calling m_ModelList.Serialise(ar). When de-serializing, this call reinstates the list and all its associated objects. I've stripped a lot of detail out of the example, but amongst the model properties there were also pointers to other models - so there were very many mutually recursive references, and I remember being concerned about how to tie all this back together on de-serialization. I was pleasantly suprised to find that the serialization mechanism looked after all of this for me automatically. I think it is an elegant system and a credit to its designers. It seems that all the user has to do is make sure that things are serialized and de-serialized in the same order. Best Regards Cliff -- modified at 6:58 Sunday 1st January, 2006

                  C 1 Reply Last reply
                  0
                  • C Cliff Hatch

                    Hi jbem I'm not sure that your conclusion that you have to keep track of the number of items in the list is correct. The list classes contain Serialize functions, and if you use these they keep track for you. A while back I was builiding a simulator that contained a recursive structure of models and submodels, similar to your Cemu class. My class was CModel, of type CModelObject. It contained a list, m_ModelList, pointing to the submodels (also of type CModel). m_ModelList was of type CModelList, declared as follows: typedef CTypedPtrList<CObList, CModelObject*> CModelList; And the CModel Serialize function was: void CModel::Serialize(CArchive & ar) { CModelObject::Serialize(ar); //Serialize/de-serialize the submodels m_ModelList.Serialize(ar); if (ar.IsStoring()) { ar << m_Name << m_Notes << m_AtomOrMacroNotes; } else { ar >> m_Name >> m_Notes >> m_AtomOrMacroNotes; } } The function saves the properties of the particular CModel object, m_Name, m_Notes, etc., and those defined in the base clase, CModelObject - and it saves the submodels by calling m_ModelList.Serialise(ar). When de-serializing, this call reinstates the list and all its associated objects. I've stripped a lot of detail out of the example, but amongst the model properties there were also pointers to other models - so there were very many mutually recursive references, and I remember being concerned about how to tie all this back together on de-serialization. I was pleasantly suprised to find that the serialization mechanism looked after all of this for me automatically. I think it is an elegant system and a credit to its designers. It seems that all the user has to do is make sure that things are serialized and de-serialized in the same order. Best Regards Cliff -- modified at 6:58 Sunday 1st January, 2006

                    C Offline
                    C Offline
                    Cliff Hatch
                    wrote on last edited by
                    #9

                    It just occurred to me that I may have misread your question. I thought you meant that your Cemulist was a member of Cemu, comprising a recursive structure. Apologies if I have caused any confusion. I would still suggest the same solution though. You could try calling the list's Serialize function from within the Serialize function of whatever object contains the Cemulist, in the same way as I did with m_ModelList. The serialize functions of the list classes invoke the serialize functions of all the things the list points to, so they save the whole structure. I imagine they also write out the number of items, but this is unseen by the user.

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups