[Serialization, XML] - how to avoid another encoding level
Hi, i am working with MICO and use boost::serialization (XML) for import/export of CORBA functions IN/OUT parameters, because i have an XML formatted configuration for the data to use for CORBA service invocations. One of the problems was, that some of the MICO are template'd. E.g. a data type holding a number of digits (e.g. telephone #no) is encoded in MICO as: template <class T, int TID, int max> class BoundedSequenceTmpl { ... } ... using basic <class T> = CORBA::Short for digits (e.g.). 1st i used ToString(...)/fromString(...) functions to be able to save&load such to/from boost archives. And this worked - though it had the little drawback, that i needed to use additional variables in load() & save() to handle it this way. But then next it came up, that some other CORBA data types use the BoundedSequenceTempl<> as well, but for _more complex_ <class T> - e.g. BoundedSequenceTempl<> of BoundedSequenceTempl<>. For that i created a version of serialize(), save() & load() like this: template<class Archive, class T, int TID, int max> void serialize(Archive & ar, BoundedSequenceTmpl<T, TID, max> &p, const unsigned int version) { split_free(ar, p, version); } template<class Archive,class T, int TID, int max> void save(Archive & ar, const BoundedSequenceTmpl<T, TID, max> &p, const unsigned int version) { unsigned long length = p.length(); ar & make_nvp("length", length); for (unsigned long i = 0; i < length; ++i) { std::ostringstream name; name << "item_" << i; ar & make_nvp(name.str(), p[i]); } } template<class Archive, class T, int TID, int max> void load(Archive & ar, BoundedSequenceTmpl<T, TID, max> &p, const unsigned int version) { unsigned long length; ar & make_nvp("length", length); p.length(length); for (unsigned long i = 0; i < length; ++i) { std::ostringstream name; name << "item_" << i; ar & make_nvp(name.str(), p[i]); } } then i thought i can get rid of the formerly used ToString(...)/FromString(...) helpers and replace them by overloaded versions of the new (more generic) load() & save() variants dedicated for this BoundedSequenceTempl<...>. Like this: #if 0 // This was intended to make obsolete MicoVector_to_string(...) & // MicoVector_from_string(...) // kind of "template specialization" for the ones above // for BoundedSequenceTmpl<...> of types, which we don't want // to be spread out any further // // But i couldn't make this work. // Means: it compiles. But it implies another XML encoding level // - which is not what i want template<class Archive, int TID, int max> void serialize(Archive & ar, BoundedSequenceTmpl<CORBA::Short, TID, max> &p, const unsigned int version) { split_free(ar, p, version); } template<class Archive, int TID, int max> void save (Archive & ar, const BoundedSequenceTmpl<CORBA::Short, TID, max> &p, const unsigned int version) { std::ostringstream ostream; for (unsigned long i=0; i<p.length(); ++i) { ostream << p[i]; } // tried this, but it didn't work (compilation failed): ar & str; // so i tested this option std::string str(ostream.str()); ar & make_nvp("hallo", str); // CREATES ANOTHER ENCODING LEVEL :-( } template<class Archive, int TID, int max> void load (Archive & ar, BoundedSequenceTmpl<CORBA::Short, TID, max> &p, const unsigned int version) { ... } #endif But that created me another level of encoding - which i don't want. E.g. having a superior encoder: template<class Archive> void save(Archive & ar, const DeleteHlrSubscriber_s &pInstance, const unsigned int version) { std::string simsi; std::string smsisdn; MicoVector_to_string(pInstance.imsi, simsi); MicoVector_to_string(pInstance.msisdn, smsisdn); // ar & make_nvp("imsi", simsi); // replace by the next... // this worked, but see above (the by "#if 0" disabled stuff) ar & make_nvp("imsi", pInstance.imsi); ar & make_nvp("msisdn", smsisdn); ar & make_nvp( "attach_imsi", pInstance.attach_imsi); } using pInstance.imsi directly (which is a BoundedSequenceTmpl<CORBA::Short>()) resulted in: <imsi> // dropped boost::serializations internal XML attributes here <hallo>SomeString</hallo> </imsi> But I would like to have this one <imsi>SomeString</imsi> How can i do that? Thanks! Best regards! Frank _______________________________________________________________ SMS schreiben mit WEB.DE FreeMail - einfach, schnell und kostenguenstig. Jetzt gleich testen! http://f.web.de/?mc=021192
What you want to do is to derive your own variation of xml_oarchive with special handling for this special type. Actually I'm amazed you've got this far trying to match an external format without doing this. Look in the document under Case Studies/deriving from an archive and the example demo_fast_archive which shows how to do this. Robert Ramey Frank Bergemann wrote:
using pInstance.imsi directly (which is a BoundedSequenceTmpl<CORBA::Short>()) resulted in:
<imsi> // dropped boost::serializations internal XML attributes here <hallo>SomeString</hallo> </imsi>
But I would like to have this one
<imsi>SomeString</imsi>
How can i do that?
Thanks!
Best regards!
Frank
_______________________________________________________________ SMS schreiben mit WEB.DE FreeMail - einfach, schnell und kostenguenstig. Jetzt gleich testen! http://f.web.de/?mc=021192
Robert Ramey schrieb:
What you want to do is to derive your own variation of xml_oarchive with special handling for this special type. Actually I'm amazed you've got this far trying to match an external format without doing this.
me too :-)
Look in the document under Case Studies/deriving from an archive and the example demo_fast_archive which shows how to do this.
- thanks for the hint, i'll check this. Up to now i could at least get rid of the separate ToString() FromString() functions - temporary accepting the additional nesting level. BTW: Another way, which i tried to fix the originally reported problem, was to public derive from class boost::serialization::nvp and using a conversion constructor in the derived one for my data type: // a sub-class to nvp, which has a conversion c'tor for my troublesome // BoundedSequenceTmpl<CORBA::Short, TID, max> class MyNVP : public boost::serialization::nvp<std::string> { public: template <int TID, int max> MyNVP(const char *name, BoundedSequenceTmpl<CORBA::Short, TID, max> &p) { LOG_DEBUG("### enter conversion c'tor"); // try to make it work _somehow_ // - don't care about performance yet std::string stringified; std::ostringstream ostream; for (unsigned long i=0; i<p.length(); ++i) { ostream << p[i]; } stringified = ostream.str(); boost::serialization::nvp<std::string>(name, stringified); }; } ; I thought the idea is ok - but the compiler disagreed - i couldn't create an instance of MyNVP(?!) Best regards! Frank
Robert Ramey
Frank Bergemann wrote:
using pInstance.imsi directly (which is a BoundedSequenceTmpl<CORBA::Short>()) resulted in:
<imsi> // dropped boost::serializations internal XML attributes here <hallo>SomeString</hallo> </imsi>
But I would like to have this one
<imsi>SomeString</imsi>
How can i do that?
Thanks!
Best regards!
Frank
_______________________________________________________________ SMS schreiben mit WEB.DE FreeMail - einfach, schnell und kostenguenstig. Jetzt gleich testen! http://f.web.de/?mc=021192
of course i will check the way you proposed... Because my other attempt (mentioned above) implies to use a new defined MyNVP - which burdens the user to make a difference. It was just as a matter of interest (this public derive from boost::serialization::nvp thing) \Frank
participants (2)
-
Frank Bergemann
-
Robert Ramey