Archive Template - PowerPoint by lwa19935

VIEWS: 17 PAGES: 45

More Info
									The Boost Serialization
       Library
           Robert Ramey
      Santa Barbara, California
         ramey@rrsd.com

           March 6, 2008
What is “Serialization”
// create class instance
const gps_position g(35, 59, 24.567f);

// save data to archive
{
      // create and open a standard stream
      std::ofstream ofs("filename");
      // use it to build and archive
      boost::archive::text_oarchive oa( ofs   );
      // write class instance to archive
      oa << g;
      // on leaving scope
      // destructors close output stream
}
What is “De-serialization”
// ... some time later restore the class instance
// to its original state
gps_position newg;
{
     // create and open standard stream
     // for file input
     std::ifstream ifs("filename");
     // and attach it to an input archive
     boost::archive::text_iarchive ia( ifs );
     // read class state from archive
     ia >> newg;
     // on leaving scope
     // destructors close input stream
}
    Saving Archive Summary
if oa is an output or saving archive, the
   following operations must be supported for
   all serializable types.
• oa << x
• oa & x
Both of these operations save data item x to
 the archive oa
    Loading Archive Summary
if ia is an input or loading archive, the
   following operations must be supported for
   all serializable types.
• ia >> x
• ia & x
Both of these operations load data item x
 from the archive ia
• binary_oarchive / binary_iarchive
   - Smallest
   - Fastest
   - Non-portable
• text_oarchive / text_iarchive
   – Larger
   – Slower
   – Portable
• xml_oarchive / xml_iarchive
   – Largest
   – Slowest
   – Portable
          Serializable Types
• a primitive type.
• a class type and one of the following has
  been declared
  – a free function serialize
  – a class member function serialize
• a pointer to a Serializable type.
• a reference to a Serializable type.
• a native C++ Array of a Serializable type.
  Making a class type serializable
     with a member function
class my_class {
  friend serialization::access
  int a;
  template<class Archive>
  void serialize(
      Archive & ar,
      const unsigned int version
   ){
     ar & a;
  }
};
  Making a class type serializable
       with a free function

class my_class {
  friend serialization::access;
  int a;
};
A Free Function serialize
template<class Archive>
inline void serialize(
   Archive & ar,
   my_class & t,
   const unsigned int version
){
   ar & t.a;
}
class gps_position
{
private:
   int degrees;
   int minutes;
   float seconds;
   friend class boost::serialization::access;
   template<class Archive>
   void serialize(Archive & ar, const unsigned int version)
   {
         ar & degrees;
         ar & minutes;
         ar & seconds;
   }
public:
   gps_position(){};
   gps_position(int d, int m, float s) :
         degrees(d), minutes(m), seconds(s)
   {}
};
// create class instance
const gps_position g(35, 59, 24.567f);

// save data to archive
{
      // create and open a standard stream
      std::ofstream ofs("filename");
      // use it to build and archive
      boost::archive::text_oarchive oa( ofs   );
      // write class instance to archive
      oa << g;
      // on leaving scope
      // destructors close output stream
}
 Other topics for class serialization
• Serializing base class information
• Class versioning
• Splitting serialization function into separate
  load/save functions
Serializing base class information
#include <boost/serialization/base_object.hpp>

// includes the following
template<class Base, class Derived>
Base & base_object(Derived &d);
…
{
    // invoke serialization of the base class
    ar & base_object<base_class_of_T>(*this);
    // save/load class member variables
    ar & member1;
    ar & member2;
}
     Class versioning(continued)
#include <boost/serialization/version.hpp>

class my_class {
   int member1;
   int member2; // add new member added here
   template<class Archive>
   void serialization(
       Archive & ar,
       const unsigned int version
   );
};
// specify class version
BOOST_CLASS_VERSION(my_class, 2)
             Class versioning
#include <boost/serialization/version.hpp>
template<class Archive>
void serialization(
   Archive & ar,
   const unsigned int version
){
   // save/load class member variables
   ar & member1;
   // if its a recent version of the class
   if(1 < version)
       // save/load recently added class members
       ar & member2;
}
Splitting serialization function(1)
template<class Archive>
void my_class::serialize(Archive & ar, const unsigned
   int version
){
   if(Archive::is_saving::value){
       ar << ... ; // append data to archive
       ar << crc(this, sizeof(*this); // append a crc
   }
   else{
       unsigned int crc_value;
       ar >> ...; // read data from archive
       ar >> crc_value; // read the crc
       if(crc_value != crc(this, sizeof(*this))
             throw crc_exception();
   }
}
Splitting serialization function(2)
template<class Archive>
void my_class::save(
   Archive & ar, const unsigned int version
) const {
   ar << ... ; // append data to archive
   ar << crc(this, sizeof(*this)// append a crc for this class to
   archive
}

template<class Archive>
void my_class::load(
   Archive & ar, const unsigned int version
){
   unsigned int crc_value;
   ar >> ...; // read data from archive
   ar >> crc_value;
   if(crc_value != crc(this, sizeof(*this))
        throw crc_exception();
}

BOOST_SERIALIZATION_SPLIT_MEMBER()
// create array of positions
const gps_position g_array[] = {
      gps_position(35,59, 23.123),
      gps_position(36,58, 23.123),
};
// save data to archive
{
      // create and open a standard stream
      std::ofstream ofs("filename");
      // use it to build and archive
      boost::archive::text_oarchive oa( ofs   );
      // write class instance to archive
      oa << g_array;
      // on leaving scope
      // destructors close output stream
}
// create a pointer to a gps position
const gps_position g = gps_position(35,59, 23.123;
const gps_position * g_ptr = & g;

// save it (and the data it points to) to the archive
{
      // create and open a standard stream
      std::ofstream ofs("filename");
      // use it to build and archive
      boost::archive::text_oarchive oa(ofs);
      // write class instance being pointed to
      // to the archive
      oa << g_ptr;
      // on leaving scope
      // destructors close output stream
}
// load a saved pointer
gps_position * g_ptr;

// create new data and load pointer to it
{
      // create and open a standard stream
      std::ifstream ifs("filename");
      // use it to build and archive
      boost::archive::text_iarchive ia(ifs);
      // allocate space for a gps_position on the heap
      // and load data from the archive into it
      ia >> g_ptr;
      // on leaving scope
      // destructors close output stream
}
           To serialize a pointer
• A new object instance has to be allocated on the
  heap.
• Then the data can loaded into it from the archive.
• Addresses of data serialized on through pointers
  must be tracked so that if the same data is saved
  twice, only one instance of the data is created
  during load. This is referred to as “tracking”. It is
  (usually) handled automatically by the library.
         Polymorphic pointers
• The data from the most derived class is
  serialized.
• Since serialization code for these classes is
  never explicitly referred to in the program,
  special precautions must be take to ensure that
  the serialization code is included in executable
  module.
• Available methods are “registration” and “export”
              Registration
class derived_one : public base {
  ...
  virtual ~derived_one();
};

main(){
  ...
  ar.template register_type<derived_one>();
  base *b;
  ...
  ar & b;
}
                  Export
#include <boost/serialization/export.hpp>
class derived_one : public base {
  ...
  virtual ~derived_one();
};

BOOST_CLASS_EXPORT(derived_one)

main(){
  ...
  base *b;
  ...
  ar & b;
}
       Serialization Wrappers
class bus_stop
{
  …
  gps_position latitude;
  …
};

Produces the following output in an xml archive:

<latitude class_id="9" tracking_level="0">
  <degrees>34</degrees>
  <minutes>135</minutes>
  <seconds>52.560001</seconds>
</latitude>
          Other wrappers are:
• binary_objects
  Serialize data an opaque binary block.
• array
  Serialize an array exploiting special array
   handling
• BOOST_STRONG_TYPEDEF
  Create a type alias. Used to temporarily assign
   a serialization trait (described below)
          Serialization Wrappers
template<class T>
struct nvp :
   public std::pair<const char *, T *>,
   public wrapper_traits<nvp<T> >
{
   …
   template<class Archive>
   void serialization(
      Archive & ar,
      const unsigned int
   ){
      ar & *(this->second);
   }
   template<class Archive>
   BOOST_SERIALIZATION_SPLIT_MEMBER()
};
  Special xml_archive Override

xml_oarchive &
xml_operator::operator <<(const nvp<T> & t){
  *this << t.first;     // output name of item
  *this << *(t.second); // output value of item
  return & this;
}
        Serialization Wrappers(2)
class bus_stop
{
   …
   gps_position latitude;
   template<class Archive>
   void serialize(Archive &ar, const unsigned int version){
       ar & BOOST_SERIALIZATION_NVP(name)
   }
};
          Serialization Traits

Attributes assigned to types which affect the
  serialization of that type.
                     Version

BOOST_CLASS_VERSION(
    class name,
    version number
)
      Implementation Level
• not_serializable
• primitive_type
• object_serializable
• object_class_info

BOOST_CLASS_IMPLEMENTATION(
    class name,
    implementation level
)
              Object Tracking
• track_never
• track_selectively
• track_always

BOOST_CLASS_TRACKING(
    class name, tracking level
)
                  Export key
BOOST_CLASS_EXPORT(
    class name
)
BOOST_CLASS_EXPORT_GUID(
    class name,
    "class_external_identifier“
)
     Saving Archive Concept
• is_saving
• is_loading
• oa << x
• oa & x
• save_binary(u, count)
• register_type<T>() / register_type(u)
• library_version()
     Saving Archive Concept
• is_saving
• is_loading
• oa << x
• oa & x
• save_binary(u, count)
• register_type<T>() / register_type(u)
• library_version()
   Saving Archive Implementation
#include <boost/archive/detail/common_oarchive.hpp>

class trivial_oarchive : public
   boost::archive::detail::common_oarchive<
       trivial_oarchive
   >
{
   friend class boost::archive::save_access;
   template<class T>
   void save(T & t);
public:
   void save_binary(
       const void *address,
       std::size_t count
   );
};
           Archive Implementation
                           interface_iarchive
basic_iarchive
                           <text_iarchive>



             common_iarchive
             <text_iarchive>



            basic_text_iarchive            basic_text_iprimitive
            <text_iarchive>                <basic_istream>




                         text_iarchive_impl
                         <text_iarchive>


                           text_iarchive
Archives are implemented as templates

• Code is regenerated and compiled for each
  combination of archive class and data type.
• Much inline code may be replicated.
• If serialization code is placed in a DLL, the
  main motivations for using a DLL is defeated.
                   Code in DLL
#include <boost/archive/polymorphic_iarchive.hpp>
#include <boost/archive/polymorphic_iarchive.hpp>

#include "A.hpp"

// explicitly instantiate code for polymorphic archive
template void A::serialize<polymorphic_iarchive>(
   polymorphic_iarchive,
   const unsigned int
);
template void A::serialize<polymorphic_oarchive>(
   polymorphic_oarchive,
   const unsigned int
);
             Code in main line
#include <boost/archive/polymorphic_text_iarchive.hpp>
#include "A.hpp"

int main(int argc, char* argv[])
{
  A a;
  std::stringstream ss;
  // instantiate archive which inherits polymorphic
  // interface and the normal text archive implementation
  polymorphic_text_iarchive oa(ss);
  polymorphic_iarchive & ia_interface = ia;
  ia_interface << a;
}
                           interface_iarchive
Polymorphic                <polymorphic_iarchive>


 Archives
                          polymorphic_iarchive_impl



text_iarchive_impl          polymorphic_iarchive
<text_iarchive>


          polymorphic_iarchive_route
          <text_iarchive_impl<
             text_iarchive
             >
          >



           polymorphic_text_iarchive

								
To top