[serialization] how to retreive true_type from an archive ?

Hello. Context: ------- I use the boost serialization library to save and load objects of a system. I defined practices around this lib, and so I always serialize from a base class (every class serializable inherits from ISerializable). As a consequence, the true_type (i.e. the most derived type) is different from the this_type (i.e. ISerializable) and the true_type is stored in the archives. My question: ----------- How to retreive this true_type (as the string written in the archive), only from the archive object? I developp just a little bit: ---------------------------- Let's have this class tre: ISerializable <|-- B <|-- D If I do : B* b = new D(); b->SaveToFile(path); // <= this will do the serialization ar & this (this being a ISerializable*) I obtain an archive where it is written the true_type "D" (whatever the type of the archive : txt, bin or xml). With the b object and this code : const boost::serialization::extended_type_info & true_type = * boost::serialization::type_info_implementation<ISerializable>::type ::get_const_instance().get_derived_extended_type_info(*b); I have what I want in true_type.get_key(), i.e : "D". I can verify that "D" is written in every archive storing b. My question again : how, only with an archive object (construct from the archive file without error), car I retrieve this key? Tanks for any help. Nicolas.

nico wrote:
Hello.
Context: ------- I use the boost serialization library to save and load objects of a system. I defined practices around this lib, and so I always serialize from a base class (every class serializable inherits from ISerializable).
I don't see that this practice is necessary. I'm not sure it's desirable either. The serialization library goes to great lengths to make this unnecessary. Having said that, I don't know that there's anything wrong with it. It's off topic - but just thought I'd mention it.
As a consequence, the true_type (i.e. the most derived type) is different from the this_type (i.e. ISerializable) and the true_type is stored in the archives.
correct.
My question: ----------- How to retreive this true_type (as the string written in the archive), only from the archive object?
I developp just a little bit: ---------------------------- Let's have this class tre:
ISerializable <|-- B <|-- D
If I do : B* b = new D(); b->SaveToFile(path); // <= this will do the serialization ar & this (this being a ISerializable*)
I obtain an archive where it is written the true_type "D" (whatever the type of the archive : txt, bin or xml).
With the b object and this code : const boost::serialization::extended_type_info & true_type = * boost::serialization::type_info_implementation<ISerializable>::type ::get_const_instance().get_derived_extended_type_info(*b);
I have what I want in true_type.get_key(), i.e : "D".
I can verify that "D" is written in every archive storing b.
My question again : how, only with an archive object (construct from the archive file without error), car I retrieve this key?
I think I understand the question - maybe. As the library is written, the inquiry into the the type of object is part of the loading process and off hand I don't see how one could "look ahead" without actually loading the object. You might be able to write some code which would "look ahead" but I have no idea what it would entail. why do you want to do this? What is the context? Robert Ramey
Tanks for any help.
Nicolas.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Thanks for your answer Robert . I answer some of your remarks / questions : Robert Ramey wrote
I don't see that this practice is necessary. I'm not sure it's desirable either. The serialization library goes to great lengths to make this unnecessary. Having said that, I don't know that there's anything wrong with it. It's off topic - but just thought I'd mention it.
Indeed this is not the way the library is supposed to be used, I guess. But I work with a team of about 15 developers, and it had been a pain to maintain our set of serialized objects. One saved a pointer to Image object in an archive, another try to load it to a shared_ptr<Image> in a test. One saved a sharerd_ptr<Image> in the application, and a tool ImageViewer expect to deserialize an Image... And so on... So obviously we must take care about the type serialized. But in fact it has really been a bag of hurt, and just asking to use shared_pointer for instance for all serialization stuff was not enough! Finally with a set of rules to respect when we make a class serializable it simplified our daily. A serializable class must virtually publicly inherit from a base class ISerializable which declares SaveToFile and LoadFromFile and all objects (of class C) are serialized as C*, and the deserialization returns a shared_ptr<C>. Robert Ramey wrote
I think I understand the question - maybe. As the library is written, the inquiry into the the type of object is part of the loading process and off hand I don't see how one could "look ahead" without actually loading the object.
You might be able to write some code which would "look ahead" but I have no idea what it would entail.
why do you want to do this? What is the context?
Here my purpose is our product upgrade. The backward compatibility is mainly ensured with the boost serialization class version management. But in rare occasions, the class structure can change and so we can't deserialize old archive. In that cases the backward compatibility is ensure by executables we provide with the upgrader, and they transform our archives. And I'm trying to get the name of the true_type in the archive to retrieve the executable : it has the same name. I guess it's possible, as the boost archive code itself can instantiate an object of true_type when deserialization is done. Nicolas. -- View this message in context: http://boost.2283326.n4.nabble.com/serialization-how-to-retreive-true-type-f... Sent from the Boost - Dev mailing list archive at Nabble.com.

nico wrote:
Thanks for your answer Robert .
I answer some of your remarks / questions :
Robert Ramey wrote
I don't see that this practice is necessary. I'm not sure it's desirable either. The serialization library goes to great lengths to make this unnecessary. Having said that, I don't know that there's anything wrong with it. It's off topic - but just thought I'd mention it.
Indeed this is not the way the library is supposed to be used, I guess. But I work with a team of about 15 developers, and it had been a pain to maintain our set of serialized objects. One saved a pointer to Image object in an archive, another try to load it to a shared_ptr<Image> in a test. One saved a sharerd_ptr<Image> in the application, and a tool ImageViewer expect to deserialize an Image... And so on...
So obviously we must take care about the type serialized. But in fact it has really been a bag of hurt, and just asking to use shared_pointer for instance for all serialization stuff was not enough! Finally with a set of rules to respect when we make a class serializable it simplified our daily. A serializable class must virtually publicly inherit from a base class ISerializable which declares SaveToFile and LoadFromFile and all objects (of class C) are serialized as C*, and the deserialization returns a shared_ptr<C>.
Hmmm, wouldn't the same result of getting everyone on the same page be obtained just by requiring intrusive serialization without the requirement of a common base class? In other words, I think the same result could have been obtained by prohibiting non-obtrusive serialization within your group. Actually, this is pretty much equivalent to what using a common base class does. It's not that I'm critcising the practice but I'm just trying to understand it. One of the goals of the serialization library is to ecapsulate the method of serialization into each type so that it is always carried from application to application along with the other type implementation code.
Here my purpose is our product upgrade. The backward compatibility is mainly ensured with the boost serialization class version management. But in rare occasions, the class structure can change and so we can't deserialize old archive. In that cases the backward compatibility is ensure by executables we provide with the upgrader, and they transform our archives. And I'm trying to get the name of the true_type in the archive to retrieve the executable : it has the same name. I guess it's possible, as the boost archive code itself can instantiate an object of true_type when deserialization is done.
so what you'd like is someting like if( ar.next_type == ?) ar >> t; I see this as hard to implement even from within the library. Now if you had serialized your objects as ar & boost::optional(t) Then you'd be done. Of course you might need a time machine. Robert Ramey
Nicolas.
participants (2)
-
nico
-
Robert Ramey