Brian Silverman | 8867871 | 2018-08-04 23:56:48 -0700 | [diff] [blame^] | 1 | <!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| 2 | <html> |
| 3 | <!-- |
| 4 | (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . |
| 5 | Use, modification and distribution is subject to the Boost Software |
| 6 | License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
| 7 | http://www.boost.org/LICENSE_1_0.txt) |
| 8 | --> |
| 9 | <head> |
| 10 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| 11 | <link rel="stylesheet" type="text/css" href="../../../boost.css"> |
| 12 | <link rel="stylesheet" type="text/css" href="style.css"> |
| 13 | <title>Serialization - Serialization Wrappers</title> |
| 14 | </head> |
| 15 | <body link="#0000ff" vlink="#800080"> |
| 16 | <table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header"> |
| 17 | <tr> |
| 18 | <td valign="top" width="300"> |
| 19 | <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3> |
| 20 | </td> |
| 21 | <td valign="top"> |
| 22 | <h1 align="center">Serialization</h1> |
| 23 | <h2 align="center">Serialization Wrappers</h2> |
| 24 | </td> |
| 25 | </tr> |
| 26 | </table> |
| 27 | <hr> |
| 28 | <dl class="page-index"> |
| 29 | <dt><a href="#binaryobjects">Binary Objects</a> |
| 30 | <dt><a href="#arrays">Arrays</a> |
| 31 | <dt><a href="#strong_type"><code style="white-space: normal">BOOST_STRONG_TYPEDEF</code></a> |
| 32 | <dt><a href="#collection_size_type">Collection Sizes</a> |
| 33 | <dt><a href="#nvp">Name-Value Pairs</a> |
| 34 | <dt><a href="#composition">Composition</a> |
| 35 | </dl> |
| 36 | Sometimes it convenient to create a temporary object just to support serialization |
| 37 | of some underlying data. This permits an archive class to define special |
| 38 | handling of this type. The library includes several such types for varying |
| 39 | purposes. |
| 40 | <p> |
| 41 | Wrappers need to be treated in a special way by some archives, and hence |
| 42 | the <A href="traits.html#wrappers"><code>is_wrapper</code></a> trait for |
| 43 | these wrapper classes is set to true. |
| 44 | |
| 45 | <h3><a name="binaryobjects">Binary Objects</a></h3> |
| 46 | A binary object is just a sequence of bytes stored as raw |
| 47 | binary data. This would most likely be used for a large amount |
| 48 | of "light weight" data such as a pixel map or embedded binary file. |
| 49 | The header file |
| 50 | <a href="../../../boost/serialization/binary_object.hpp" target="binary_object_hpp"> |
| 51 | binary_object.hpp |
| 52 | </a> |
| 53 | includes the constructors: |
| 54 | <pre><code> |
| 55 | boost::serialization::binary_object(void * t, size_t size); |
| 56 | boost::serialization::make_binary_object(void * t, size_t size); |
| 57 | </code></pre> |
| 58 | which will construct a temporary binary object that can be serialized just like any other object. |
| 59 | Its default serialization is to use archive class primitives |
| 60 | <code style="white-space: normal">save_binary</code> and <code>load_binary</code>. |
| 61 | Note that it doesn't allocated any storage or create any objects. |
| 62 | Its sole purpose is to pass the data size and address as a pair to the archive class. |
| 63 | |
| 64 | |
| 65 | <h3><a name="arrays">Arrays</a></h3> |
| 66 | An array is a contiguous sequence of homogeneous data types, such as a builtin |
| 67 | C-array, a <code>boost::array<T></code> or a <code>std::vector<T></code>. |
| 68 | The purpose of this wrapper is to support archive types (such as binary |
| 69 | archives) that provide optimized serialization for contiguous sequences of |
| 70 | objects of the same type. |
| 71 | |
| 72 | The header file |
| 73 | <a href="../../../boost/serialization/array.hpp" target="array_hpp"> |
| 74 | array.hpp |
| 75 | </a> |
| 76 | includes the function |
| 77 | <pre><code> |
| 78 | template <T> |
| 79 | boost::serialization::make_array(T* t, std::size_t size); |
| 80 | </code></pre> |
| 81 | which will construct a temporary <code>array</code> object |
| 82 | <pre><code> |
| 83 | template<class T> |
| 84 | class array |
| 85 | { |
| 86 | public: |
| 87 | typedef T value_type; |
| 88 | array(value_type* t, std::size_t s); |
| 89 | value_type* address() const; |
| 90 | std::size_t count() const; |
| 91 | }; |
| 92 | </code></pre> |
| 93 | that can be serialized just like any other object. |
| 94 | Its default serialization is to serialize each array element. |
| 95 | Note that it doesn't allocated any storage or create any objects. |
| 96 | Its sole purpose is to pass the data type, size and address to the archive class. |
| 97 | |
| 98 | Archive types that can provide optimized implementations for contiguous |
| 99 | arrays of homogeneous data types should overload the serialization of |
| 100 | <code>array</code>. |
| 101 | |
| 102 | |
| 103 | <h3><a name="strong_type"><code style="white-space: normal">BOOST_STRONG_TYPEDEF</code></h3> |
| 104 | Another example of a serialization wrapper is the |
| 105 | <a href="strong_typedef.html"><code style="white-space: normal">BOOST_STRONG_TYPEDEF</code></a> template. |
| 106 | The serialization libraries uses these to pass particular kinds of integers such |
| 107 | as object_id, version, etc. to an archive class. Given that these integers |
| 108 | are now distinguishable according to their type, XML archives can apply |
| 109 | special handling to these types. For example, a version number is rendered |
| 110 | as an XML attribute in the form "version=12". In the absence of any specific override, |
| 111 | these types are automatically converted to the underlying integer type so the |
| 112 | special overrides used for XML archives aren't needed for other archives. |
| 113 | |
| 114 | |
| 115 | |
| 116 | <h3><a name="collection_size_type">Collection Sizes</h3> |
| 117 | An example of a strong typedef is the <code>collection_size_type</code> in the |
| 118 | header file |
| 119 | <a href="../../../boost/serialization/collection_size_type.hpp" target="collection_size_type_hpp"> |
| 120 | collection_size_type.hpp |
| 121 | </a>. This type should be used for serializaing the size of a C++ collection, so |
| 122 | that the archive can pick the best integral representation for the serialization |
| 123 | of collection sizes. This is necessary since, although <code>std::size_t</code> |
| 124 | is guaranteed to be an integral type large enough to represent the size of |
| 125 | a collection on a specific platform, the archive might want to serialize |
| 126 | the size differently than this type. For example, the <code>collection_size_type</code> |
| 127 | might be serialized as a variable length integer in a portable binary archive. |
| 128 | |
| 129 | |
| 130 | |
| 131 | |
| 132 | |
| 133 | |
| 134 | <h3><a name="nvp">Name-Value Pairs</h3> |
| 135 | XML archives present a somewhat special case. XML format has a nested |
| 136 | structure that maps well to the "recursive class member visitor" pattern used |
| 137 | by the serialization system. However, XML differs from other formats |
| 138 | in that it requires a name for each class data member. Our goal is to |
| 139 | add this information to the class serialization specification while |
| 140 | still permiting the the serialization code to be used with any archive. |
| 141 | <p> |
| 142 | Our solution is to wrap class members to be serialized in a |
| 143 | <strong>name-value-pair</strong>. This structure is defined in |
| 144 | <a href="../../../boost/serialization/nvp.hpp" target="nvp_hpp">nvp.hpp</a>. |
| 145 | It is just a reference to the data member coupled with a pointer to |
| 146 | to a <code style="white-space: normal">const char *</code> which |
| 147 | corresponds to the XML name. It implements the default |
| 148 | serialization functions for a name-value pair. This default |
| 149 | action is to just ignore the item name and serialize the |
| 150 | data value in the normal manner. For archive classes that |
| 151 | don't make any special provision for name-value pairs, this |
| 152 | is the action which will be invoked when the name-value pair |
| 153 | is serialized. Hence, wrapping a data value into a name-value |
| 154 | pair will have no effect when used with archives which |
| 155 | make no special provision for this wrapper. |
| 156 | <p> |
| 157 | The xml archive classes contain code similar to: |
| 158 | <pre><code> |
| 159 | // special treatment for name-value pairs. |
| 160 | template<class T> |
| 161 | xml_oarchive & operator&(const boost::serialization::nvp<T> & t) |
| 162 | { |
| 163 | // write an xml start tag |
| 164 | start_tag(t.name()); |
| 165 | |
| 166 | // serialize the data as usual |
| 167 | *this & t.value(); |
| 168 | |
| 169 | // write an xml end tag |
| 170 | end_tag(t.name()); |
| 171 | } |
| 172 | </code></pre> |
| 173 | The most obvious and convient name to assign to as the XML data item name |
| 174 | is - surprise! - the name of the C++ class data member. So our serialization |
| 175 | code will look like: |
| 176 | <pre><code> |
| 177 | ar & make_nvp("my_variable", my_variable); |
| 178 | </code></pre> |
| 179 | To simplify typing and enhance readability a macro is defined so we can write: |
| 180 | <pre><code> |
| 181 | ar & BOOST_SERIALIZATION_NVP(my_variable); |
| 182 | </code></pre> |
| 183 | Similarly there exists a macro definition that permits us to write: |
| 184 | <pre><code> |
| 185 | BOOST_SERIALIZATION_BASE_OBJECT_NVP(my_base_class) |
| 186 | </code></pre> |
| 187 | |
| 188 | Note that these macros must be used in the namespace of the class, |
| 189 | and without qualifying the namespace in the argument. |
| 190 | |
| 191 | <p> |
| 192 | <a href="../example/demo_gps.hpp" target="demo_gps_hpp">demo_gps.hpp<a> |
| 193 | includes NVP wrappers or all data members. |
| 194 | <a href="../example/demo_xml.cpp" target="demo_xml_cpp">demo_xml.cpp<a> |
| 195 | saves and loads data to an XML archive. |
| 196 | <a href="../example/demo_save.xml" target="demo_save_xml">Here</a> |
| 197 | is example of the XML Archive corresponding to our tutorial example. |
| 198 | |
| 199 | <h3><a name="composition">Composition</h3> |
| 200 | Wrappers should be designed so that they can be composed as necessary. |
| 201 | For example, to pass binary data as a name value pair use: |
| 202 | <pre><code> |
| 203 | ar & make_nvp("named_binary_object", make_binary_object(address, size)); |
| 204 | </code></pre> |
| 205 | </html> |
| 206 | <hr> |
| 207 | <p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004. |
| 208 | Distributed under the Boost Software License, Version 1.0. (See |
| 209 | accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 210 | </i></p> |
| 211 | </body> |
| 212 | </html> |
| 213 | |