[serialization][portable-binary archive] Data not byte-swapped across architectures
Hello: I am attempting to use the boost serialization portable-binary archive. The 2 architectures I am working on are: 1. Intel on MS-Windows/Mac OS X 2. PowerPC on Mac OS X The version of portable-binary that I am using is from the Trunk. The attached sample code shows that an integer I serialize on PPC and then unserialize on Intel is not byte-swapped. And similarly, an integer I serialize on Intel is not byte-swapped on PPC. It does not appear to be a OS issue, because the data is unserialized properly from a MS-Windows Intel system to a Mac OS X Intel system, and vise versa. Another manifestation of this occurs when I serialize a large container, like a vector for example. The code has an exception because the size of the container is not byte-swapper. I can provide example code for this as well. This experience leads me to believe either: 1. The portable binary is not functioning properly with Mac OS X PPC or 2. I am not using the portable-binary archive properly, either configuration or code. It is not clear if I need to archive in a specific endian-ness and then manually detect the architecture and byte-swap if necessary. Or if all of that is handled automatically by the portable-binary archive. Advise on this issue would be greatly appreciated. Best regards, Jon Kroll Ann Arbor Michigan ========================================================================= BUILD: Windows: MS-Visual Studio 2005 Mac OS X: g++ test_portable_binary.cpp portable_binary_iarchive.cpp portable_binary_oarchive.cpp -o test_portable_binary -I/Volumes/..../boost_1_35_0/ -L/Volumes/..../boost_1_35_0/stage/lib/ -lboost_serialization-mt-1_35 CODE: ======================================================== #include "boost/archive/portable_binary_oarchive.hpp" #include "boost/archive/portable_binary_iarchive.hpp" #include <vector> #include <sstream> #include <fstream> #include <iostream> #include <string> namespace { bool isIntelArch() { char endianTest[2] = { 1, 0 }; return (*(short *) endianTest == 1); } bool isPPCArch() { return !isIntelArch(); } } int main(int argc, char* argv[]) { if (false) // generate test file { std::string fileName; if (isPPCArch()) fileName = "PPC_portableBinaryLargeInt.ser"; else if (isIntelArch()) fileName = "Intel_portableBinaryLargeInt.ser"; int val = 16000; // 0x3E80 std::ofstream os(fileName.c_str(), std::ios::binary); portable_binary_oarchive oa(os); oa & val; return 0; } int unserializedVal = 0; { std::string fileName; if (isPPCArch()) fileName = "Intel_portableBinaryLargeInt.ser"; else if (isIntelArch()) fileName = "PPC_portableBinaryLargeInt.ser"; std::ifstream is(fileName.c_str(), std::ios::binary); portable_binary_iarchive ia(is); ia & unserializedVal; } if (0x3E80 == unserializedVal) { return 0; // This is the correct result! } if (0x803E == unserializedVal) { return -1; // This is an error, the value is not byte-swapped } if (0 == unserializedVal) { return -1; // This is an error, nothing got unserialized } return 0; }
Hello: Fortunately I am in good shape now. With the help of a friend we managed to track down a bug in the version of the portable_binary_oarchive.cpp that we had from back in June. In the save_impl method it was &'ing m_flags & endian_little if on BIG_ENDIAN. When I then grabbed the very latest the version in the trunk this bug was fixed. I also found, in the example code, that you need to specify the endianness you want to use to create your archives on serialization. best regards, Jon Kroll Ann Arbor Michigan U.S.A.
participants (2)
-
Jon C. Kroll
-
Jon Kroll