Re: [Boost-users] Serialization newbie needs help
Obviously, I can just switch to a different serialization library (e.g. s11n).
I believe that library also has serialization of pointers
Darn it! Foiled at every turn! :-) If that is the case, maybe you might consider updating/clarifying the "Overview -> Other implementations" section of the docs. There you imply that s11n doesn't do this. (Maybe it didn't back when you wrote the docs.)
But as much as possible, I would like to stick with
whatever is most "standard". And as part of the Boost family, I'm guessing that boost::serialization is top dog here. Would that be right? Is this library included in any of the proposed C++ standards (TR2, C++0x)?
This serialization library will never be part of any C++ standard.
Oh. That's disappointing. Why not? Too much bureaucracy involved?
Because normally one doesn't want to change data while its being saved one will typically have something like the following in his program.
FileSave(const MyData & md){ // create archive oa << md; // no need for "const cast" because md is already "const" ... }
Okay. That makes a lot of sense. Let me ask another newbie question, about how to get data in and out of an archive. I have to work with legacy C-based code that delivers/accepts data in a char* buffer. My code to serialize data into and out of this buffer is both convoluted and inefficient. It looks something like this: my_class mc; void read_from_cbuffer(const char* buf, const size_t buf_sz) { std::string buf_str(buf, buf_sz); std::istringstream iss(buf_str); boost::archive::text_iarchive ia(iss); ia >> mc; } void write_to_cbuffer(char** buf_p, size_t* buf_sz_p) { std::ostringstream oss; boost::archive::text_oarchive oa(oss); oa << mc; *buf_p = new char[oss.str().size()]; memcpy(*buf_p, oss.str().c_str(), oss.str().size()); *buf_sz_p = oss.str().size(); } Any suggestions about how this can be done better? Thanks, -- Dominick
Dominick Layfield wrote:
Obviously, I can just switch to a different serialization library (e.g. s11n).
I believe that library also has serialization of pointers
Darn it! Foiled at every turn! :-)
If that is the case, maybe you might consider updating/clarifying the "Overview -> Other implementations" section of the docs. There you imply that s11n doesn't do this. (Maybe it didn't back when you wrote the docs.)
I went back an looked at the s11n website. The documents weren't available online and I didn't want to download them so in fact I don't know whether or not that system supports pointer serialization.
But as much as possible, I would like to stick with
whatever is most "standard". And as part of the Boost family, I'm guessing that boost::serialization is top dog here. Would that be right? Is this library included in any of the proposed C++ standards (TR2, C++0x)?
This serialization library will never be part of any C++ standard.
Oh. That's disappointing. Why not? Too much bureaucracy involved?
Of course that's a large part of it. Though bureacracy is too perjorative. Any standardization effort requires a huge effort. In this case it would be bad enough for the API. But someone would insist that standardization cover format of the particular archives so they would be dragged in as well. Which would make the effort gigantic. And to what benefit? Standardization for libraries which wrap varying operating system features whose api and implemention can vary widely has a lot of benefits. This applies to libraries like filesystem, threading etc. But for standard code which which is open source with a boost license which can be compiled on a standard conforming compiler, the whole standardization effort offers additional benefit for the extra work.
Let me ask another newbie question, about how to get data in and out of an archive. I have to work with legacy C-based code that delivers/accepts data in a char* buffer. My code to serialize data into and out of this buffer is both convoluted and inefficient. It looks something like this:
my_class mc;
void read_from_cbuffer(const char* buf, const size_t buf_sz) { std::string buf_str(buf, buf_sz); std::istringstream iss(buf_str); boost::archive::text_iarchive ia(iss); ia >> mc; }
void write_to_cbuffer(char** buf_p, size_t* buf_sz_p) { std::ostringstream oss; boost::archive::text_oarchive oa(oss); oa << mc; *buf_p = new char[oss.str().size()]; memcpy(*buf_p, oss.str().c_str(), oss.str().size()); *buf_sz_p = oss.str().size(); }
Any suggestions about how this can be done better?
The real easy way is just to use a binary_object which saves/loads a specified number of bytes. so the above would look like: void write_to_cbuffer(char* buf_p, size_t* buf_sz_p) { // note only one * std::ostringstream oss; boost::archive::text_oarchive oa(oss); oa << binary_object(bf_sz_p, mc); } void read_from_cbuffer(const char* buf, const size_t buf_sz) { std::istringstream iss(buf_str); boost::archive::text_iarchive ia(iss); ia >> binary_object(buf_sz, buf) } Of course you wouldn't get things like locale/character set transformation that you can get with other i/o but this is faster and most don't need it. Robert Ramey
Hi! Robert Ramey schrieb:
The real easy way is just to use a binary_object which saves/loads a specified number of bytes. so the above would look like:
void write_to_cbuffer(char* buf_p, size_t* buf_sz_p) { // note only one * std::ostringstream oss; boost::archive::text_oarchive oa(oss); oa << binary_object(bf_sz_p, mc); } void read_from_cbuffer(const char* buf, const size_t buf_sz) { std::istringstream iss(buf_str); boost::archive::text_iarchive ia(iss); ia >> binary_object(buf_sz, buf) }
You got this one mixed up. The char array is not something to serailize but it is the storage to searialize to. The "read_from_cbuffer" function does *read* the cbuffer and construct a my_class instance out of it by using serialization. The "write_to_cbuffer" serializes a my_class instance an stores the result in the cbuffer. I can think of using the old strstream class to read from the buffer or take something from Boost.IOStreams. And writing could be faster if you use a std::deque wrapped with IOStreams and later on std::copy this into a char array (instead of memcpy). A deque has usually better performance on push_back than a vector or string, I guess. But then I don't know the internals of a stringstream. Frank
Frank Birbacher wrote:
Hi!
Robert Ramey schrieb:
The real easy way is just to use a binary_object which saves/loads a specified number of bytes. so the above would look like:
void write_to_cbuffer(char* buf_p, size_t* buf_sz_p) { // note only one * std::ostringstream oss; boost::archive::text_oarchive oa(oss); oa << binary_object(bf_sz_p, mc); } void read_from_cbuffer(const char* buf, const size_t buf_sz) { std::istringstream iss(buf_str); boost::archive::text_iarchive ia(iss); ia >> binary_object(buf_sz, buf) }
You got this one mixed up. The char array is not something to serailize but it is the storage to searialize to. The "read_from_cbuffer" function does *read* the cbuffer and construct a my_class instance out of it by using serialization. The "write_to_cbuffer" serializes a my_class instance an stores the result in the cbuffer.
I can think of using the old strstream class to read from the buffer or take something from Boost.IOStreams. And writing could be faster if you use a std::deque wrapped with IOStreams and later on std::copy this into a char array (instead of memcpy). A deque has usually better performance on push_back than a vector or string, I guess. But then I don't know the internals of a stringstream.
I've used boost::IOStreams to do exactly this, for both over the wire transmission and using the Windows clipboard for cut/paste drag/drop operations. Jeff Flinn
participants (4)
-
Dominick Layfield
-
Frank Birbacher
-
Jeff Flinn
-
Robert Ramey