Boost logo

Boost-Commit :

From: ramey_at_[hidden]
Date: 2007-09-27 00:44:21


Author: ramey
Date: 2007-09-27 00:44:15 EDT (Thu, 27 Sep 2007)
New Revision: 39569
URL: http://svn.boost.org/trac/boost/changeset/39569

Log:
improvements to extended type info system - unfortunately, these break the export.
Added:
   branches/serialization_next_release/boost/libs/serialization/example/portable_binary_archive.hpp (contents, props changed)
   branches/serialization_next_release/boost/libs/serialization/example/portable_binary_iarchive.cpp (contents, props changed)
   branches/serialization_next_release/boost/libs/serialization/example/portable_binary_oarchive.cpp (contents, props changed)
Text files modified:
   branches/serialization_next_release/boost/libs/serialization/example/Jamfile.v2 | 5
   branches/serialization_next_release/boost/libs/serialization/example/demo_portable_archive.cpp | 44 ++++++-
   branches/serialization_next_release/boost/libs/serialization/example/portable_binary_iarchive.hpp | 213 +++++++++++++++++++++------------------
   branches/serialization_next_release/boost/libs/serialization/example/portable_binary_oarchive.hpp | 207 +++++++++++++++++++++++---------------
   4 files changed, 276 insertions(+), 193 deletions(-)

Modified: branches/serialization_next_release/boost/libs/serialization/example/Jamfile.v2
==============================================================================
--- branches/serialization_next_release/boost/libs/serialization/example/Jamfile.v2 (original)
+++ branches/serialization_next_release/boost/libs/serialization/example/Jamfile.v2 2007-09-27 00:44:15 EDT (Thu, 27 Sep 2007)
@@ -7,7 +7,8 @@
 # See http://www.boost.org/libs/serialization for the library home page.
 
 project libs/serialization/example
- : requirements <dependency>../build//boost_serialization
+ : id serialization_test
+ : requirements <library>../build//boost_serialization
     ;
 
 rule demo_bsl_run ( demo-name : othersources * : requirements * )
@@ -45,7 +46,7 @@
     [ demo_bsl_run demo_fast_archive ]
     [ demo_bsl_run demo_pimpl : demo_pimpl_A ]
     [ demo_bsl_run demo_polymorphic : demo_polymorphic_A ]
- [ demo_bsl_run demo_portable_archive ]
+ [ demo_bsl_run demo_portable_archive : portable_binary_iarchive portable_binary_oarchive ]
     [ demo_bsl_run demo_shared_ptr ]
     [ demo_bsl_run demo_xml ]
     [ demo_bsl_run demo_xml_save ]

Modified: branches/serialization_next_release/boost/libs/serialization/example/demo_portable_archive.cpp
==============================================================================
--- branches/serialization_next_release/boost/libs/serialization/example/demo_portable_archive.cpp (original)
+++ branches/serialization_next_release/boost/libs/serialization/example/demo_portable_archive.cpp 2007-09-27 00:44:15 EDT (Thu, 27 Sep 2007)
@@ -10,7 +10,6 @@
 // should pass compilation and execution
 #include <sstream>
 
-#define BOOST_ARCHIVE_SOURCE
 #include "portable_binary_oarchive.hpp"
 #include "portable_binary_iarchive.hpp"
 
@@ -20,30 +19,36 @@
 namespace std{ using ::rand; }
 #endif
 
-// the following is required to be sure the "EXPORT" works if it is used
-#define CUSTOM_ARCHIVE_TYPES portable_binary_oarchive,portable_binary_iarchive
-
 class A
 {
     friend class boost::serialization::access;
+ char c;
     int i;
+ int i2; // special tricky case to check sign extension
     unsigned int ui;
     long l;
     unsigned long ul;
     template<class Archive>
     void serialize(Archive & ar, const unsigned int /* version */){
- ar & i & ui & l & ul ;
+ ar & c & i & i2 & ui & l & ul ;
     }
 public:
     bool operator==(const A & rhs) const {
         return
- i == rhs.i && ui == rhs.ui && l == rhs.l && ul == rhs.ul
+ c == rhs.c
+ && i == rhs.i
+ && i2 == rhs.i2
+ && ui == rhs.ui
+ && l == rhs.l
+ && ul == rhs.ul
         ;
     }
     A() :
+ c(std::rand()),
         i(std::rand()),
+ i2(0x80),
         ui(std::rand()),
- l(std::rand()),
+ l(std::rand() * std::rand()),
         ul(std::rand())
     {}
 };
@@ -62,6 +67,31 @@
         portable_binary_iarchive pbia(ss);
         pbia >> a1;
     }
+ if(! (a == a1))
+ return 1;
+
+ ss.clear();
+ {
+ portable_binary_oarchive pboa(ss, endian_big);
+ pboa << a;
+ }
+ {
+ portable_binary_iarchive pbia(ss, endian_big);
+ pbia >> a1;
+ }
+ if(! (a == a1))
+ return 1;
+
+ ss.clear();
+ {
+ portable_binary_oarchive pboa(ss, endian_big);
+ pboa << a;
+ }
+ {
+ portable_binary_iarchive pbia(ss, endian_big);
+ pbia >> a1;
+ }
+
     return !(a == a1);
 }
 

Added: branches/serialization_next_release/boost/libs/serialization/example/portable_binary_archive.hpp
==============================================================================
--- (empty file)
+++ branches/serialization_next_release/boost/libs/serialization/example/portable_binary_archive.hpp 2007-09-27 00:44:15 EDT (Thu, 27 Sep 2007)
@@ -0,0 +1,42 @@
+#ifndef PORTABLE_BINARY_ARCHIVE_HPP
+#define PORTABLE_BINARY_ARCHIVE_HPP
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/pfto.hpp>
+#include <boost/static_assert.hpp>
+
+#include <climits>
+#if CHAR_BIT != 8
+#error This code assumes an eight-bit byte.
+#endif
+
+#include <boost/archive/basic_archive.hpp>
+#include <boost/detail/endian.hpp>
+
+enum portable_binary_archive_flags {
+ endian_big = 0x4000,
+ endian_little = 0x8000
+};
+
+//#if ( endian_big <= boost::archive::flags_last )
+//#error archive flags conflict
+//#endif
+
+inline void
+reverse_bytes(char size, char *address){
+ char * first = address;
+ char * last = first + size - 1;
+ for(;first < last;++first, --last){
+ char x = *last;
+ *last = *first;
+ *first = x;
+ }
+}
+
+#endif // PORTABLE_BINARY_ARCHIVE_HPP

Added: branches/serialization_next_release/boost/libs/serialization/example/portable_binary_iarchive.cpp
==============================================================================
--- (empty file)
+++ branches/serialization_next_release/boost/libs/serialization/example/portable_binary_iarchive.cpp 2007-09-27 00:44:15 EDT (Thu, 27 Sep 2007)
@@ -0,0 +1,130 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// portable_binary_iarchive.cpp
+
+// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <istream>
+#include <string>
+//#include <cstring> // memcpy
+
+#include <boost/detail/endian.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/archive/archive_exception.hpp>
+
+#include "portable_binary_iarchive.hpp"
+
+void
+portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){
+ char size;
+ l = 0;
+ this->primitive_base_t::load(size);
+
+ if(0 == size){
+ return;
+ }
+
+ bool negative = (size < 0);
+ if(negative)
+ size = -size;
+
+ if(size > maxsize)
+ boost::throw_exception(
+ portable_binary_iarchive_exception()
+ );
+
+ char * cptr = reinterpret_cast<char *>(& l);
+ #ifdef BOOST_BIG_ENDIAN
+ cptr += (sizeof(boost::intmax_t) - size);
+ #endif
+ this->primitive_base_t::load_binary(cptr, size);
+
+ #ifdef BOOST_BIG_ENDIAN
+ if(m_flags & endian_little)
+ #else
+ if(m_flags & endian_big)
+ #endif
+ reverse_bytes(size, cptr);
+
+ if(negative)
+ l = -l;
+}
+
+void
+portable_binary_iarchive::load_override(
+ boost::archive::class_name_type & t, int
+){
+ std::string cn;
+ cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
+ load_override(cn, 0);
+ if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
+ boost::throw_exception(
+ boost::archive::archive_exception(
+ boost::archive::archive_exception::invalid_class_name)
+ );
+ std::memcpy(t, cn.data(), cn.size());
+ // borland tweak
+ t.t[cn.size()] = '\0';
+}
+
+void
+portable_binary_iarchive::init(unsigned int flags){
+ if(0 == (flags & boost::archive::no_header)){
+ // read signature in an archive version independent manner
+ std::string file_signature;
+ * this >> file_signature;
+ if(file_signature != boost::archive::ARCHIVE_SIGNATURE())
+ boost::throw_exception(
+ boost::archive::archive_exception(
+ boost::archive::archive_exception::invalid_signature
+ )
+ );
+ // make sure the version of the reading archive library can
+ // support the format of the archive being read
+ boost::archive::version_type input_library_version;
+ * this >> input_library_version;
+
+ // extra little .t is to get around borland quirk
+ if(boost::archive::ARCHIVE_VERSION() < input_library_version.t)
+ boost::throw_exception(
+ boost::archive::archive_exception(
+ boost::archive::archive_exception::unsupported_version
+ )
+ );
+
+ #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
+ this->set_library_version(input_library_version);
+ //#else
+ //#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
+ //detail::
+ //#endif
+ boost::archive::detail::basic_iarchive::set_library_version(
+ input_library_version
+ );
+ #endif
+ }
+ unsigned char x;
+ load(x);
+ m_flags = x << CHAR_BIT;
+}
+
+// explicitly instantiate for this type of text stream
+#include <boost/archive/impl/archive_pointer_iserializer.ipp>
+#include <boost/archive/impl/basic_binary_iprimitive.ipp>
+
+namespace boost {
+namespace archive {
+
+template class detail::archive_pointer_iserializer<portable_binary_iarchive> ;
+template class basic_binary_iprimitive<
+ portable_binary_iarchive,
+ std::istream::char_type,
+ std::istream::traits_type
+> ;
+
+} // namespace archive
+} // namespace boost

Modified: branches/serialization_next_release/boost/libs/serialization/example/portable_binary_iarchive.hpp
==============================================================================
--- branches/serialization_next_release/boost/libs/serialization/example/portable_binary_iarchive.hpp (original)
+++ branches/serialization_next_release/boost/libs/serialization/example/portable_binary_iarchive.hpp 2007-09-27 00:44:15 EDT (Thu, 27 Sep 2007)
@@ -6,31 +6,42 @@
 # pragma once
 #endif
 
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4244 )
+#endif
+
 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
 // portable_binary_iarchive.hpp
 
-// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
+// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com .
 // Use, modification and distribution is subject to the Boost Software
 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
 // See http://www.boost.org for updates, documentation, and revision history.
 
-#include <ostream>
-#include <boost/archive/binary_iarchive.hpp>
-#include <boost/detail/endian.hpp>
+#include <istream>
+#include <boost/serialization/string.hpp>
+#include <boost/archive/archive_exception.hpp>
+#include <boost/archive/basic_binary_iprimitive.hpp>
+#include <boost/archive/detail/common_iarchive.hpp>
+#include <boost/archive/shared_ptr_helper.hpp>
+#include <boost/archive/detail/register_archive.hpp>
+
+#include "portable_binary_archive.hpp"
 
 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
 // exception to be thrown if integer read from archive doesn't fit
 // variable being loaded
-class portable_binary_archive_exception :
+class portable_binary_iarchive_exception :
     public virtual boost::archive::archive_exception
 {
 public:
     typedef enum {
         incompatible_integer_size
     } exception_code;
- portable_binary_archive_exception(exception_code c = incompatible_integer_size )
+ portable_binary_iarchive_exception(exception_code c = incompatible_integer_size )
     {}
     virtual const char *what( ) const throw( )
     {
@@ -46,130 +57,132 @@
 };
 
 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
-// "Portable" input binary archive. This is a variation of the native binary
-// archive. it addresses integer size and endienness so that binary archives can
-// be passed across systems. Note:floating point types not addressed here
+// "Portable" input binary archive. It addresses integer size and endienness so
+// that binary archives can be passed across systems. Note:floating point types
+// not addressed here
 class portable_binary_iarchive :
- // don't derive from binary_iarchive !!!
- public boost::archive::binary_iarchive_impl<
- portable_binary_iarchive,
+ public boost::archive::basic_binary_iprimitive<
+ portable_binary_iarchive,
         std::istream::char_type,
         std::istream::traits_type
>,
+ public boost::archive::detail::common_iarchive<
+ portable_binary_iarchive
+ >
+ ,
     public boost::archive::detail::shared_ptr_helper
-{
- typedef boost::archive::binary_iarchive_impl<
- portable_binary_iarchive,
+ {
+ typedef boost::archive::basic_binary_iprimitive<
+ portable_binary_iarchive,
         std::istream::char_type,
         std::istream::traits_type
- > archive_base_t;
- typedef boost::archive::basic_binary_iprimitive<
- portable_binary_iarchive,
- std::ostream::char_type,
- std::ostream::traits_type
> primitive_base_t;
+ typedef boost::archive::detail::common_iarchive<
+ portable_binary_iarchive
+ > archive_base_t;
 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 public:
 #else
     friend archive_base_t;
     friend primitive_base_t; // since with override load below
- friend class boost::archive::basic_binary_iarchive<portable_binary_iarchive>;
+ friend class boost::archive::detail::interface_iarchive<
+ portable_binary_iarchive
+ >;
     friend class boost::archive::load_access;
+protected:
 #endif
- void load_impl(long & l, char maxsize){
- char size;
- this->archive_base_t::load(size);
- if(size > maxsize)
- throw portable_binary_archive_exception() ;
- l = 0;
- load_binary(& l, size);
- // 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
-
- // extend sign if necessary
- if((l >> (size - 1) * 8) & 0x80){
- l |= (-1 << (size * 8));
- }
- }
+ unsigned int m_flags;
+ void load_impl(boost::intmax_t & l, char maxsize);
+
     // default fall through for any types not specified here
     template<class T>
     void load(T & t){
+ boost::intmax_t l;
+ load_impl(l, sizeof(T));
+ // use cast to avoid compile time warning
+ t = static_cast<T>(l);
+ }
+ void load(std::string & t){
         this->primitive_base_t::load(t);
     }
- void load(unsigned short & t){
- long l;
- load_impl(l, sizeof(unsigned short));
- // use cast to avoid compile time warning
- t = static_cast<unsigned short>(l);
+ #ifndef BOOST_NO_STD_WSTRING
+ void load(std::wstring & t){
+ this->primitive_base_t::load(t);
     }
- void load(short & t){
- long l;
- // use cast to avoid compile time warning
- load_impl(l, sizeof(short));
- t = static_cast<short>(l);
+ #endif
+ void load(float & t){
+ this->primitive_base_t::load(t);
+ // floats not supported
+ //BOOST_STATIC_ASSERT(false);
     }
- void load(unsigned int & t){
- long l;
- load_impl(l, sizeof(unsigned int));
- t = l;
- }
- void load(int & t){
- long l;
- load_impl(l, sizeof(int));
- t = l;
- }
- void load(unsigned long & t){
- long l;
- load_impl(l, sizeof(unsigned long));
- t = l;
- }
- void load(long & t){
- long l;
- load_impl(l, sizeof(long));
- t = l;
+ void load(double & t){
+ this->primitive_base_t::load(t);
+ // doubles not supported
+ //BOOST_STATIC_ASSERT(false);
+ }
+ void load(char & t){
+ this->primitive_base_t::load(t);
+ }
+ void load(unsigned char & t){
+ this->primitive_base_t::load(t);
+ }
+ // intermediate level to support override of operators
+ // fot templates in the absence of partial function
+ // template ordering
+ typedef boost::archive::detail::common_iarchive<portable_binary_iarchive>
+ detail_common_iarchive;
+ template<class T>
+ void load_override(T & t, BOOST_PFTO int){
+ this->detail_common_iarchive::load_override(t, 0);
     }
+ void load_override(boost::archive::class_name_type & t, int);
+ // binary files don't include the optional information
+ void load_override(
+ boost::archive::class_id_optional_type & /* t */,
+ int
+ ){}
+
+ void init(unsigned int flags);
 public:
     portable_binary_iarchive(std::istream & is, unsigned flags = 0) :
- archive_base_t(
- is,
- flags | boost::archive::no_header // skip default header checking
- )
+ primitive_base_t(
+ * is.rdbuf(),
+ 0 != (flags & boost::archive::no_codecvt)
+ ),
+ archive_base_t(flags),
+ m_flags(0)
     {
- // use our own header checking
- if(0 != (flags & boost::archive::no_header)){
- this->archive_base_t::init(flags);
- // skip the following for "portable" binary archives
- // boost::archive::basic_binary_oprimitive<derived_t, std::ostream>::init();
- }
+ init(flags);
     }
-};
 
-// explicitly instantiate for this type of text stream
-#include <boost/archive/impl/basic_binary_iarchive.ipp>
-#include <boost/archive/impl/archive_pointer_iserializer.ipp>
-#include <boost/archive/impl/basic_binary_iprimitive.ipp>
-
-namespace boost {
-namespace archive {
-
-template class binary_iarchive_impl<
- portable_binary_iarchive,
- std::istream::char_type,
- std::istream::traits_type
->;
-template class detail::archive_pointer_iserializer<portable_binary_iarchive> ;
+ portable_binary_iarchive(
+ std::basic_streambuf<
+ std::istream::char_type,
+ std::istream::traits_type
+ > & bsb,
+ unsigned int flags
+ ) :
+ primitive_base_t(
+ bsb,
+ 0 != (flags & boost::archive::no_codecvt)
+ ),
+ archive_base_t(flags),
+ m_flags(0)
+ {
+ init(flags);
+ }
+};
 
-} // namespace archive
-} // namespace boost
+// required by export in boost version > 1.34
+#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
+ BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive)
+#endif
 
+// required by export in boost <= 1.34
 #define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive
 
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
 #endif // PORTABLE_BINARY_IARCHIVE_HPP

Added: branches/serialization_next_release/boost/libs/serialization/example/portable_binary_oarchive.cpp
==============================================================================
--- (empty file)
+++ branches/serialization_next_release/boost/libs/serialization/example/portable_binary_oarchive.cpp 2007-09-27 00:44:15 EDT (Thu, 27 Sep 2007)
@@ -0,0 +1,96 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// portable_binary_oarchive.cpp
+
+// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com .
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <ostream>
+#include <boost/detail/endian.hpp>
+#include "portable_binary_oarchive.hpp"
+
+void
+portable_binary_oarchive::save_impl(
+ const boost::intmax_t l,
+ const char maxsize
+){
+ char size = 0;
+
+ if(l == 0){
+ this->primitive_base_t::save(size);
+ return;
+ }
+
+ boost::intmax_t ll;
+ bool negative = (l < 0);
+ if(negative)
+ ll = -l;
+ else
+ ll = l;
+
+ do{
+ ll >>= CHAR_BIT;
+ ++size;
+ }while(ll != 0);
+
+ this->primitive_base_t::save(
+ static_cast<char>(negative ? -size : size)
+ );
+
+ if(negative)
+ ll = -l;
+ else
+ ll = l;
+ char * cptr = reinterpret_cast<char *>(& ll);
+ #ifdef BOOST_BIG_ENDIAN
+ cptr += (sizeof(boost::intmax_t) - size);
+ if(m_flags & endian_big)
+ reverse_bytes(size, cptr);
+ #else
+ if(m_flags & endian_big)
+ reverse_bytes(size, cptr);
+ #endif
+ this->primitive_base_t::save_binary(cptr, size);
+}
+
+void
+portable_binary_oarchive::init(unsigned int flags) {
+ if(m_flags == (endian_big | endian_little)){
+ boost::throw_exception(
+ portable_binary_oarchive_exception()
+ );
+ }
+ if(0 == (flags & boost::archive::no_header)){
+ // write signature in an archive version independent manner
+ const std::string file_signature(
+ boost::archive::ARCHIVE_SIGNATURE()
+ );
+ * this << file_signature;
+ // write library version
+ const boost::archive::version_type v(
+ boost::archive::ARCHIVE_VERSION()
+ );
+ * this << v;
+ }
+ save(static_cast<unsigned char>(m_flags >> CHAR_BIT));
+}
+
+// explicitly instantiate for this type of text stream
+#include <boost/archive/impl/archive_pointer_oserializer.ipp>
+#include <boost/archive/impl/basic_binary_oprimitive.ipp>
+
+namespace boost {
+namespace archive {
+
+template class detail::archive_pointer_oserializer<portable_binary_oarchive> ;
+template class basic_binary_oprimitive<
+ portable_binary_oarchive,
+ std::ostream::char_type,
+ std::ostream::traits_type
+> ;
+
+} // namespace archive
+} // namespace boost

Modified: branches/serialization_next_release/boost/libs/serialization/example/portable_binary_oarchive.hpp
==============================================================================
--- branches/serialization_next_release/boost/libs/serialization/example/portable_binary_oarchive.hpp (original)
+++ branches/serialization_next_release/boost/libs/serialization/example/portable_binary_oarchive.hpp 2007-09-27 00:44:15 EDT (Thu, 27 Sep 2007)
@@ -6,6 +6,11 @@
 # pragma once
 #endif
 
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4244 )
+#endif
+
 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
 // portable_binary_oarchive.hpp
 
@@ -17,9 +22,38 @@
 // See http://www.boost.org for updates, documentation, and revision history.
 
 #include <ostream>
+#include <boost/serialization/string.hpp>
 #include <boost/archive/archive_exception.hpp>
-#include <boost/archive/binary_oarchive.hpp>
-#include <boost/detail/endian.hpp>
+#include <boost/archive/basic_binary_oprimitive.hpp>
+#include <boost/archive/detail/common_oarchive.hpp>
+#include <boost/archive/detail/register_archive.hpp>
+
+#include "portable_binary_archive.hpp"
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// exception to be thrown if integer read from archive doesn't fit
+// variable being loaded
+class portable_binary_oarchive_exception :
+ public virtual boost::archive::archive_exception
+{
+public:
+ typedef enum {
+ invalid_flags
+ } exception_code;
+ portable_binary_oarchive_exception(exception_code c = invalid_flags )
+ {}
+ virtual const char *what( ) const throw( )
+ {
+ const char *msg = "programmer error";
+ switch(code){
+ case invalid_flags:
+ msg = "cannot be both big and little endian";
+ default:
+ boost::archive::archive_exception::what();
+ }
+ return msg;
+ }
+};
 
 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
 // "Portable" output binary archive. This is a variation of the native binary
@@ -27,65 +61,36 @@
 // be passed across systems. Note:floating point types not addressed here
 
 class portable_binary_oarchive :
- // don't derive from binary_oarchive !!!
- public boost::archive::binary_oarchive_impl<
- portable_binary_oarchive,
+ public boost::archive::basic_binary_oprimitive<
+ portable_binary_oarchive,
         std::ostream::char_type,
         std::ostream::traits_type
+ >,
+ public boost::archive::detail::common_oarchive<
+ portable_binary_oarchive
>
 {
- typedef boost::archive::binary_oarchive_impl<
- portable_binary_oarchive,
- std::ostream::char_type,
- std::ostream::traits_type
- > archive_base_t;
     typedef boost::archive::basic_binary_oprimitive<
- portable_binary_oarchive,
+ portable_binary_oarchive,
         std::ostream::char_type,
         std::ostream::traits_type
> primitive_base_t;
+ typedef boost::archive::detail::common_oarchive<
+ portable_binary_oarchive
+ > archive_base_t;
 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 public:
 #else
     friend archive_base_t;
     friend primitive_base_t; // since with override save below
- friend class boost::archive::basic_binary_oarchive<portable_binary_oarchive>;
+ friend class boost::archive::detail::interface_oarchive<
+ portable_binary_oarchive
+ >;
     friend class boost::archive::save_access;
+protected:
 #endif
- void save_impl(const long l){
- long ll = l;
- char size = 0;
- if(l < 0){
- // make sure that enough of data is output
- // to include a high order bit indicating the sign
- char x;
- do{
- x = static_cast<char>(ll);
- ll >>= 8;
- ++size;
- }while(ll != -1 && x < 0);
- }
- else{
- do{
- ll >>= 8;
- ++size;
- }while(ll != 0);
- }
-
- this->archive_base_t::save(size);
-
- // 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
- save_binary(& l, size);
- }
+ unsigned int m_flags;
+ void save_impl(const boost::intmax_t l, const char maxsize);
     // add base class to the places considered when matching
     // save function to a specific set of arguments. Note, this didn't
     // work on my MSVC 7.0 system so we use the sure-fire method below
@@ -94,60 +99,94 @@
     // default fall through for any types not specified here
     template<class T>
     void save(const T & t){
+ save_impl(t, sizeof(T));
+ }
+ void save(const std::string & t){
         this->primitive_base_t::save(t);
     }
- void save(const short t){
- save_impl(t);
+ #ifndef BOOST_NO_STD_WSTRING
+ void save(const std::wstring & t){
+ this->primitive_base_t::save(t);
     }
- void save(const unsigned short t){
- save_impl(t);
+ #endif
+ void save(const float & t){
+ this->primitive_base_t::save(t);
+ // floats not supported
+ //BOOST_STATIC_ASSERT(false);
     }
- void save(const unsigned int t){
- save_impl(t);
+ void save(const double & t){
+ this->primitive_base_t::save(t);
+ // doubles not supported
+ //BOOST_STATIC_ASSERT(false);
     }
- void save(const int t){
- save_impl(t);
+ void save(const char & t){
+ this->primitive_base_t::save(t);
     }
- void save(const unsigned long t){
- save_impl(t);
+ void save(const unsigned char & t){
+ this->primitive_base_t::save(t);
     }
- void save(const long t){
- save_impl(t);
+
+ // default processing - kick back to base class. Note the
+ // extra stuff to get it passed borland compilers
+ typedef boost::archive::detail::common_oarchive<portable_binary_oarchive>
+ detail_common_oarchive;
+ template<class T>
+ void save_override(T & t, BOOST_PFTO int){
+ this->detail_common_oarchive::save_override(t, 0);
     }
+ // explicitly convert to char * to avoid compile ambiguities
+ void save_override(const boost::archive::class_name_type & t, int){
+ const std::string s(t);
+ * this << s;
+ }
+ // binary files don't include the optional information
+ void save_override(
+ const boost::archive::class_id_optional_type & /* t */,
+ int
+ ){}
+
+ void init(unsigned int flags);
 public:
     portable_binary_oarchive(std::ostream & os, unsigned flags = 0) :
- archive_base_t(
- os,
- flags | boost::archive::no_header // skip default header checking
- )
+ primitive_base_t(
+ * os.rdbuf(),
+ 0 != (flags & boost::archive::no_codecvt)
+ ),
+ archive_base_t(flags),
+ m_flags(flags & (endian_big | endian_little))
     {
- // use our own header checking
- if(0 != (flags & boost::archive::no_header)){
- this->archive_base_t::init(flags);
- // skip the following for "portable" binary archives
- // boost::archive::basic_binary_iprimitive<derived_t, std::ostream>::init();
- }
+ init(flags);
+ }
+
+ portable_binary_oarchive(
+ std::basic_streambuf<
+ std::ostream::char_type,
+ std::ostream::traits_type
+ > & bsb,
+ unsigned int flags
+ ) :
+ primitive_base_t(
+ bsb,
+ 0 != (flags & boost::archive::no_codecvt)
+ ),
+ archive_base_t(flags),
+ m_flags(0)
+ {
+ init(flags);
     }
 };
 
-#include <boost/archive/impl/basic_binary_oarchive.ipp>
-#include <boost/archive/impl/archive_pointer_oserializer.ipp>
-#include <boost/archive/impl/basic_binary_oprimitive.ipp>
-
-namespace boost {
-namespace archive {
-
-// explicitly instantiate for this type of binary stream
-template class binary_oarchive_impl<
- portable_binary_oarchive,
- std::ostream::char_type,
- std::ostream::traits_type
->;
-template class detail::archive_pointer_oserializer<portable_binary_oarchive> ;
 
-} // namespace archive
-} // namespace boost
+// required by export in boost version > 1.34
+#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
+ BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_oarchive)
+#endif
 
+// required by export in boost <= 1.34
 #define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES portable_binary_oarchive
 
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
 #endif // PORTABLE_BINARY_OARCHIVE_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk