Opened 13 years ago
Last modified 13 years ago
#3447 new Bugs
After destruction binary_iarchive seeks to the end of file
Reported by: | Owned by: | Robert Ramey | |
---|---|---|---|
Milestone: | Component: | serialization | |
Version: | Boost 1.39.0 | Severity: | Problem |
Keywords: | sync file stream basic_binary_iprimitive archive binary_iarchive serialization | Cc: |
Description
After destruction binary_iarchive seeks to the end of file. This is occured because boost::archive::basic_binary_iprimitive (the ancestor of binary_iarchive) calls std::basic_streambuf::sync in destructor. Calling 'sync' on a file streambuf seeks to the end of file.
This is bad, because it lead to skipping of unread input data!
I think calling 'sync' is a bad idea (and this call should be removed), but if it is necessary, then the documentation must clearly note that using a file streambuf with binary_iarchive skips to the end of the file.
Example:
std::ifstream is( ARCHIVE_FILE_NAME, std::ios::binary ); int i; { boost::archive::binary_iarchive ar( is, boost::archive::no_header ); ar >> i; std::cout << "Pos after read: " << is.tellg() << std::endl; } std::cout << "Pos after dtor: " << is.tellg() << std::endl;
Output:
Pos after read: 4 Pos after dtor: 11
(sizeof(int) is 4, archive file length is 11)
Note that it has always been my idea that serialized data could be embedded into another stream. I think the question you've raised touches upon this.
note the comment at line # 174 of basic_binary_iprimitive.hpp
some libraries including stl and libcomo fail if the buffer isn't flushed before the code_cvt facet is changed. I think this is a bug. We explicity invoke sync to when we're done with the streambuf to work around this problem. Note that sync is a protected member of stream buff so we have to invoke it through a contrived derived class.
this suggests that the "sync" was only added in response to some other difficulty. Take another look at this problem and tell me what you think.
Robert Ramey