[serialization] EOF marker?
Is there a way to serialize an unknown number of items and then read them back? In essence, I'd like to do this: Ignore the variables being serialized, these are pointers to base classes, they go in and out just fine. try { ofstream ofs(fileName.c_str(),ios::binary); portable_binary_oarchive oa(ofs); //boost::archive::text_oarchive oa(ofs); oa<<qdc <<qdf <<qdenv <<qdmsg <<qsd <<qdfc <<qdce; } catch(boost::archive::archive_exception& ae) { cout<<ae.what(); } try { ifstream ifs(fileName.c_str(),ios::binary); portable_binary_iarchive ia(ifs); //boost::archive::text_iarchive ia(ifs); while( true ) { ia>>qdc2; cout<<qdc2->GetElementDebugType()<<endl; delete qdc2; qdc2=NULL; } } catch(boost::archive::archive_exception& ae) { cout<<ae.what(); } catch( std::exception& e) { cout<<e.what(); } What happens is that an exception gets tossed with this message: 5 2 14 1 3 18 Access violation - no RTTI data! The numbers are correct, those are the elements that got serialized. I'd like to do something like: while( ia ) { Ia>>qdc2; } But there is no () operator on an portable_binary_iarchive . I tried to do the test on the input stream, but that didn't work either. I don't know how many elements there are because I'm writing them as I go, I don't want to catch that exception as the EOF marker, because it really isn't the correct exception for that. I tried walking through the serialization code to see where it actually reads a byte stream form the file... but I'm apparently not smart enough to unravel that much templated Macro awesomeness. :) Larry E. Ramey
On Mon, Apr 15, 2013 at 02:59:01PM +0000, Ramey, Larry wrote:
Is there a way to serialize an unknown number of items and then read them back? In essence, I'd like to do this:
Ignore the variables being serialized, these are pointers to base classes, they go in and out just fine.
try { ofstream ofs(fileName.c_str(),ios::binary); portable_binary_oarchive oa(ofs); //boost::archive::text_oarchive oa(ofs);
oa<<qdc <<qdf <<qdenv <<qdmsg <<qsd <<qdfc <<qdce;
*snip*
while( true ) { ia>>qdc2; cout<<qdc2->GetElementDebugType()<<endl; delete qdc2; qdc2=NULL; }
} catch(boost::archive::archive_exception& ae) { cout<<ae.what(); } catch( std::exception& e) { cout<<e.what(); }
To my knowledge, S11n expects the code that reads the data to be aware of the exact order, count and types of things in the serialized stream. This means that if you want a sequence of variable length, you need to serialize and deserialize data from which you can derive the extents of the sequence. You might be able to piggyback on existing logic if you put all your objects in a standard library container like a list or vector and serialize _that_. Otherwise, count the objects and write a sized integer denoting the count, or write a sentinel object that you can use to find the end of the sequence. Depending on your actual use case and types involved, one may be easier than the other. -- Lars Viklund | zao@acc.umu.se
To my knowledge, S11n expects the code that reads the data to be aware of the exact order, count and types of things in the serialized stream. This means that if you want a sequence of variable length, you need to serialize and deserialize data from which you can derive the extents of the sequence. You might be able to piggyback on existing logic if you put all your objects in a standard library container like a list or vector and serialize _that_. Otherwise, count the objects and write a sized integer denoting the count, or write a sentinel object that you can use to find the end of the sequence. Depending on your actual use case and types involved, one may be easier than the other. -- Lars Viklund | zao@acc.umu.se _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users I can't count the object because I don't know how many I'm going to write. I am dumping debug elements as time passes... it it not know a priori how many will get dumped. You are saying, make my OWN EOF class. Yeah, I could do something like that. (why didn't I think of that myself?)
On Mon, Apr 15, 2013 at 04:34:47PM +0000, Ramey, Larry wrote:
To my knowledge, S11n expects the code that reads the data to be aware of the exact order, count and types of things in the serialized stream.
This means that if you want a sequence of variable length, you need to serialize and deserialize data from which you can derive the extents of the sequence.
You might be able to piggyback on existing logic if you put all your objects in a standard library container like a list or vector and serialize _that_.
Otherwise, count the objects and write a sized integer denoting the count, or write a sentinel object that you can use to find the end of the sequence.
Depending on your actual use case and types involved, one may be easier than the other.
-- Lars Viklund | zao@acc.umu.se _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I can't count the object because I don't know how many I'm going to write. I am dumping debug elements as time passes... it it not know a priori how many will get dumped.
You are saying, make my OWN EOF class. Yeah, I could do something like that. (why didn't I think of that myself?)
Another reasonably lightweight thing you could do would be that instead of just writing the object, you write a single or few-byte identifier indicating the category of the following object. Or if the context is sufficiently narrow, write a bool indicating whether you're out of objects, so your stream would be something like: { false, obj0, false, obj1, false, obj2, true } -- Lars Viklund | zao@acc.umu.se
participants (2)
-
Lars Viklund
-
Ramey, Larry