Bug in serialization example /boost/libs/serialization/example/portable_binary_oarchive.hpp

Hi, According to the boost web site, this mailing list is the preferred way to report bugs, so I subscribed and send you this: I believe the example /boost/libs/serialization/example/portable_binary_oarchive.hpp doesn't work correctly. On my platform, Mac OS X, the endian conversion is performed. For a small negative number (say -42l), the endian conversion results in a big negative number (-687865857). The size, however, is computed _before_ the endian conversion, so it is 1 (one) in this case, which is not high enough to hold the converted long. I guess the solution is to do the endian conversion first, then the size computation. That seems to work for me. Based on the 1_33_1 sources, my version of save_impl is now: void save_impl(long l){ // we choose to use litle endian #ifdef BOOST_BIG_ENDIAN char * first = static_cast<char *>(static_cast<void *>(& l)); char * last = first + sizeof(l) - 1; for(;first < last;++first, --last) { char x = *last; *last = *first; *first = x; } #endif long ll = l; char size = 0; do{ ll >>= 8; ++size; }while(ll != -1 && ll != 0); os.put(size); save_binary(& l, size); } I hope this helps in improving the example. Regards, Stefan van den Oord

Well, its definately a mistake. But I'm wondering if the real solution is to left fill the value when loading with 0xff ? Think about this. This would: a) leave current archives working. b) keep portable binary archives as small as possible Robert Ramey Stefan van den Oord wrote:
Hi,
According to the boost web site, this mailing list is the preferred way to report bugs, so I subscribed and send you this:
I believe the example /boost/libs/serialization/example/portable_binary_oarchive.hpp doesn't work correctly. On my platform, Mac OS X, the endian conversion is performed. For a small negative number (say -42l), the endian conversion results in a big negative number (-687865857). The size, however, is computed _before_ the endian conversion, so it is 1 (one) in this case, which is not high enough to hold the converted long.
I guess the solution is to do the endian conversion first, then the size computation. That seems to work for me. Based on the 1_33_1 sources, my version of save_impl is now:
void save_impl(long l){ // we choose to use litle endian #ifdef BOOST_BIG_ENDIAN char * first = static_cast<char *>(static_cast<void *>(& l)); char * last = first + sizeof(l) - 1; for(;first < last;++first, --last) { char x = *last; *last = *first; *first = x; } #endif
long ll = l; char size = 0; do{ ll >>= 8; ++size; }while(ll != -1 && ll != 0); os.put(size);
save_binary(& l, size); }
I hope this helps in improving the example.
Regards,
Stefan van den Oord _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

As a matter of fact, I already ran into other issues with that solution I suggested. I didn't really give this much thought yet, but would it be an idea to pass the size of the type to save_impl, just as you do to load_impl, and then use that real size instead of a computed size? That way, the numbers take up the same number of bytes in the archive as they do in memory, but that seems more than acceptable. I also think it's a compatible change, because existing archives have the sizes stored in the archive. On re-save, the archive would of course change, but that's ok. Left-filling is something that crossed my mind as well, but it seems like going through a lot of trouble to save a few bytes. (Is 0xff the only problematic value?) I don't have a strong opinion about this, and it's not my speciality. I'll accept any solution you come up with :) Stefan On 6/23/06, Robert Ramey <ramey@rrsd.com> wrote:
But I'm wondering if the real solution is to left fill the value when loading with 0xff ?

Stefan van den Oord wrote:
As a matter of fact, I already ran into other issues with that solution I suggested.
I didn't really give this much thought yet, but would it be an idea to pass the size of the type to save_impl, just as you do to load_impl, and then use that real size instead of a computed size?
The problem is that the "real size" may be different between the sending and receiving machines. I tweaked portable_binary_iarchive to properly sign extend negative values which I believe solves the problem - I havn't tested it yet though. Robert Ramey

Ok, I'll check out the changes and verify if they work for me. I'll let you know. Stefan On 6/26/06, Robert Ramey <ramey@rrsd.com> wrote:
Stefan van den Oord wrote:
As a matter of fact, I already ran into other issues with that solution I suggested.
I didn't really give this much thought yet, but would it be an idea to pass the size of the type to save_impl, just as you do to load_impl, and then use that real size instead of a computed size?
The problem is that the "real size" may be different between the sending and receiving machines. I tweaked portable_binary_iarchive to properly sign extend negative values which I believe solves the problem - I havn't tested it yet though.
Robert Ramey
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Robert Ramey
-
Stefan van den Oord