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 | <head> |
| 4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| 5 | <link rel="stylesheet" type="text/css" href="../../../boost.css"> |
| 6 | <link rel="stylesheet" type="text/css" href="style.css"> |
| 7 | <title>Serialization - Archives</title> |
| 8 | </head> |
| 9 | <body link="#0000ff" vlink="#800080"> |
| 10 | <table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header"> |
| 11 | <tr> |
| 12 | <td valign="top" width="300"> |
| 13 | <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3> |
| 14 | </td> |
| 15 | <td valign="top"> |
| 16 | <h1 align="center">Serialization</h1> |
| 17 | <h2 align="center">Archive Concepts</h2> |
| 18 | </td> |
| 19 | </tr> |
| 20 | </table> |
| 21 | <hr> |
| 22 | <dl class="page-index"> |
| 23 | <dt><a href="#saving_interface">Saving Archive Concept</a> |
| 24 | <dt><a href="#loading_interface">Loading Archive Concept</a> |
| 25 | <dt><a href="#archive_models">Models</a> |
| 26 | <dt><a href="#exceptions">Exceptions</a> |
| 27 | <dt><a href="#charactersets">Character Sets</a> |
| 28 | </dl> |
| 29 | <h4>Notation</h4> |
| 30 | In the following descriptions |
| 31 | <ul> |
| 32 | <li><code>SA</code> is an type modeling the <a href="#saving_interface">Saving Archive Concept</a>. |
| 33 | <li><code>sa</code> is an instance of type SA. |
| 34 | <li><code>LA</code> is an type modeling the <a href="#loading_interface">Loading Archive Concept</a>. |
| 35 | <li><code>la</code> is an instance of type LA. |
| 36 | <li><code>T</code> is an <a href="serialization.html"><strong>Serializable</strong></a> Type. |
| 37 | <li><code>x</code> is an instance of type T Type. |
| 38 | <li><code>u,v</code> is a pointer to a an instance of type T. |
| 39 | <li><code>count</code> is an instance of a type that can be converted to <code>std::size_t</code>. |
| 40 | </ul> |
| 41 | <h4><a name="saving_interface">Saving Archive Concept</a></h4> |
| 42 | <h4>Associated Types</h4> |
| 43 | Intuitively, a type modeling this concept will generate a sequence of bytes |
| 44 | corresponding to an arbitrary set of C++ data structures. Each type modeling the |
| 45 | Saving Archive concept (SA) may be associated with another type modeling the |
| 46 | <a href="#loading_interface">Loading Archive Concept</a>(LA). |
| 47 | This associated type will perform the inverse operation. |
| 48 | That is, given a sequence of bytes generated by SA, it will generate a set of |
| 49 | C++ data structures that is equivalent to the original. |
| 50 | The notion of equivalence is defined by the implementations of the pair of archives and the |
| 51 | way the data are rendered <a href="serialization.html">serializable</a>. |
| 52 | <p> |
| 53 | <h4>Valid Expressions</h4> |
| 54 | <dl> |
| 55 | <dt><h4><code> |
| 56 | SA::is_saving |
| 57 | </code></h4></dt> |
| 58 | <dd> |
| 59 | Returns the Boost MPL Integral Constant type boost::mpl::bool_<true> |
| 60 | </dd> |
| 61 | <dt><h4><code> |
| 62 | SA::is_loading |
| 63 | </code></h4></dt> |
| 64 | <dd> |
| 65 | Returns the Boost MPL Integral Constant type boost::mpl::bool_<false> |
| 66 | </dd> |
| 67 | <dt><h4><code> |
| 68 | sa << x |
| 69 | <br> |
| 70 | sa & x |
| 71 | </code></h4></dt> |
| 72 | <dd> |
| 73 | These expressions must perform exactly the same function. They append the |
| 74 | value of <code style="white-space: normal">x</code> along with other information to <code>sa</code>. |
| 75 | This other information is defined by the implementation of the archive. |
| 76 | Typically this information is that which is required by a corresponding |
| 77 | Loading Archive type to properly restore the value of <code>x</code>. |
| 78 | <p> |
| 79 | Returns a reference to <code>sa</code>. |
| 80 | </dd> |
| 81 | <dt><h4><code> |
| 82 | sa.save_binary(u, count) |
| 83 | </code></h4></dt> |
| 84 | <dd> |
| 85 | Appends to the archive <code style="white-space: normal">size_t(count)</code> bytes found at |
| 86 | <code style="white-space: normal">u</code>. |
| 87 | </dd> |
| 88 | <dt><h4><code> |
| 89 | sa.register_type<T>() |
| 90 | <br> |
| 91 | sa.register_type(u) |
| 92 | </code></h4></dt> |
| 93 | <dd> |
| 94 | Appends information about class T to the archive. This information is used to |
| 95 | construct the correct class when a derived pointer is loaded by a corresponding |
| 96 | Loading Archive type. |
| 97 | Invocation of this member function is referred to as "class registration". |
| 98 | This is explained in detail in |
| 99 | <a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>. |
| 100 | The second syntax is included to permit this function to be called on non-conforming |
| 101 | compilers when <code style="white-space: normal">sa</code> is a template argument. |
| 102 | For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a> |
| 103 | </dd> |
| 104 | <dt><h4><code> |
| 105 | sa.get_library_version() |
| 106 | </code></h4></dt> |
| 107 | <dd> |
| 108 | Returns an unsigned integer containing the current version number of the serialization |
| 109 | library. This number will be incremented each time the library is altered in such a |
| 110 | way that serialization could be altered for some type. For example, suppose the type |
| 111 | used for a count of collection members is changed. The code that loads collections |
| 112 | might be conditioned on the library version to make sure that libraries created by |
| 113 | previous versions of the library can still be read. |
| 114 | </dd> |
| 115 | <dt><h4><code> |
| 116 | sa.get_helper<Helper>(void * const helper_instance_id = 0) |
| 117 | </code></h4></dt> |
| 118 | <dd> |
| 119 | See <code>la.get_helper<Helper>(void * const helper_instance_id = 0)</code> |
| 120 | below. |
| 121 | </dd> |
| 122 | |
| 123 | </dl> |
| 124 | |
| 125 | <h4><a name="loading_interface">Loading Archive Concept</a></h4> |
| 126 | <h4>Associated Types</h4> |
| 127 | Each model of this concept presumes the |
| 128 | existence of a corresponding type modeling the |
| 129 | <a href="#saving_interface">Saving Archive Concept</a>. |
| 130 | The purpose of an instance of this concept is to convert a sequence of bytes |
| 131 | generated by this corresponding type to a set of C++ data structures |
| 132 | equivalent to the original. |
| 133 | <h4>Valid Expressions</h4> |
| 134 | <dl> |
| 135 | <dt><h4><code> |
| 136 | LA::is_saving |
| 137 | </code></h4></dt> |
| 138 | <dd> |
| 139 | Returns the Boost MPL Integral Constant type boost::mpl::bool_<false> |
| 140 | </dd> |
| 141 | <dt><h4><code> |
| 142 | LA::is_loading |
| 143 | </code></h4></dt> |
| 144 | <dd> |
| 145 | Returns the Boost MPL Integral Constant type boost::mpl::bool_<true> |
| 146 | </dd> |
| 147 | <dt><h4><code> |
| 148 | la >> x |
| 149 | <br> |
| 150 | la & x |
| 151 | </code></h4></dt> |
| 152 | <dd> |
| 153 | These expressions must perform exactly the same function. |
| 154 | Sets <code>x</code> to a value retrieved from <code>la</code>. |
| 155 | <p> |
| 156 | Returns a reference to <code>la</code>. |
| 157 | </dd> |
| 158 | <dt><h4><code> |
| 159 | la.load_binary(u, count) |
| 160 | </code></h4></dt> |
| 161 | <dd> |
| 162 | Retrieves from <code style="white-space: normal">la</code> <code style="white-space: normal">size_t(count)</code> bytes and stores |
| 163 | them in memory starting at <code style="white-space: normal">u</code>. |
| 164 | </dd> |
| 165 | <dt> |
| 166 | <dt><h4><code> |
| 167 | la.register_type<T>() |
| 168 | <br> |
| 169 | la.register_type(u) |
| 170 | </code></h4></dt> |
| 171 | <dd> |
| 172 | Retrieves information about class T from the archive. This information is used to |
| 173 | construct the correct class when loading a pointer to a derived class not |
| 174 | otherwise referred to in the program by name. |
| 175 | Invocation of this member function is referred to as "class registration". |
| 176 | This is explained in detail in |
| 177 | <a href="special.html#derivedpointers">Special Considerations - Derived Pointers</a>. |
| 178 | The second syntax is included to permit this function to be called on non-conforming |
| 179 | compilers when <code style="white-space: normal">la</code> is a template argument. |
| 180 | For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a> |
| 181 | </dd> |
| 182 | <dt><h4><code> |
| 183 | la.get_library_version() |
| 184 | </code></h4></dt> |
| 185 | <dd> |
| 186 | Returns an unsigned integer containing the version number of the serialization |
| 187 | library that created the archive. This number will be incremented each time the |
| 188 | library is altered in such a way that serialization could be altered for some type. |
| 189 | For example, suppose the type used for a count of collection members is changed. |
| 190 | The code that loads collections might be conditioned on the library version to make |
| 191 | sure that libraries created by previous versions of the library can still be read. |
| 192 | </dd> |
| 193 | <dt><h4><code> |
| 194 | la.get_helper<Helper>(void * const helper_instance_id) |
| 195 | </code></h4></dt> |
| 196 | <dd> |
| 197 | Some otherwise unserializable types can be made serializable by inclusion of |
| 198 | a helper object. The iconic example of this is shared_ptr which needs this |
| 199 | helper object to keep track of previously loaded shared_ptr instances so they |
| 200 | can be "matched up" with subsequently loaded ones. |
| 201 | The first time <code style="white-space: normal">la.get_helper<Helper>(void * const helper_instance_id)</code> |
| 202 | is invoked for a given helper_instance_id, <code style="white-space: normal">Helper</code>, a default-constructed |
| 203 | <code style="white-space: normal">Helper</code> object is created, attached to |
| 204 | <code style="white-space: normal">la</code> and a reference to it is returned. Subsequent |
| 205 | invocations of <code style="white-space: normal">la.get_helper<Helper>(void * const helper_instance_id)</code> with the same id value return |
| 206 | a reference to the formerly constructed object. All objects created in this manner are |
| 207 | destroyed upon <code style="white-space: normal">la</code> destruction time. The purpose |
| 208 | of helper objects is discussed in |
| 209 | <a href="special.html#helpersupport">Special Considerations - Helper Support</a>. |
| 210 | </dd> |
| 211 | <dt><h4><code> |
| 212 | la.reset_object_address(v, u) |
| 213 | </code></h4></dt> |
| 214 | <dd> |
| 215 | Communicates to the archive that the object originally at address u has been |
| 216 | moved to address v. |
| 217 | <p> |
| 218 | When an object is loaded to a temporary variable and later moved to another location, |
| 219 | this function must be called in order communicate this fact. This permits the |
| 220 | archive to properly implement object tracking. Object tracking is required in order |
| 221 | to correctly implement serialization of pointers to instances of derived classes. |
| 222 | </dd> |
| 223 | <dt><h4><code> |
| 224 | la.delete_created_pointers() |
| 225 | </code></h4></dt> |
| 226 | <dd> |
| 227 | Deletes all objects created by the loading of pointers. This can be used to |
| 228 | avoid memory leaks that might otherwise occur if pointers are being loaded |
| 229 | and the archive load encounters an exception. |
| 230 | </dd> |
| 231 | </dl> |
| 232 | |
| 233 | There are archives based on text, binary and XML file |
| 234 | formats but all have the above interface. Given that all archives present |
| 235 | the same public interface, specifcation of serialization is exactly the same |
| 236 | for all archives. Archive classes have other members not mentioned here. |
| 237 | However they are related to the internal functioning of the library and |
| 238 | are not meant to be called by users of an archive. Implementation of new |
| 239 | archives is discussed in |
| 240 | <a href="archive_reference.html#implementation">New Archives - Implementation</a>. |
| 241 | |
| 242 | <p> |
| 243 | The existence of the <code style="white-space: normal"><<</code> |
| 244 | and <code style="white-space: normal">>></code> suggests |
| 245 | a relationship between archives and C++ i/o streams. <strong>Archives are not |
| 246 | C++ i/o streams</strong>. All the archives included with this system take a stream |
| 247 | as an argument in the constructor and that stream is used for output or input. |
| 248 | However, this is not a requirement of the serialization functions or the |
| 249 | archive interface. It just turns out that the archives written so far have |
| 250 | found it useful to base their implementation on streams. |
| 251 | |
| 252 | <h3><a name="archive_models">Archive Models</a></h3> |
| 253 | This library includes various implementations of the Archive concept. |
| 254 | |
| 255 | An archive is defined by two complementary classes. One is for saving data while |
| 256 | the other is for loading it. |
| 257 | |
| 258 | This library includes a number of archive implementations that are "ready to go" for the |
| 259 | most common requirements. These classes implement the archive concept for differing data formats. |
| 260 | They can be used "as is" or as a basis for developing one's own particular type of archive. |
| 261 | An archive is defined by two complementary classes. One is for saving data while the other is for loading it. |
| 262 | |
| 263 | To invoke serialization using one of |
| 264 | these archives, one or more of the following header files must be |
| 265 | included in the code module containing the serialization code. |
| 266 | <pre><code> |
| 267 | // a portable text archive</a> |
| 268 | <a href="../../../boost/archive/text_oarchive.hpp" target="text_oarchive_cpp">boost::archive::text_oarchive</a> // saving |
| 269 | <a href="../../../boost/archive/text_iarchive.hpp" target="text_iarchive_cpp">boost::archive::text_iarchive</a> // loading |
| 270 | |
| 271 | // a portable text archive using a wide character stream</a> |
| 272 | <a href="../../../boost/archive/text_woarchive.hpp">boost::archive::text_woarchive</a> // saving |
| 273 | <a href="../../../boost/archive/text_wiarchive.hpp">boost::archive::text_wiarchive</a> // loading |
| 274 | |
| 275 | // a portable XML archive</a> |
| 276 | <a href="../../../boost/archive/xml_oarchive.hpp" target="xml_oarchive_cpp">boost::archive::xml_oarchive</a> // saving |
| 277 | <a href="../../../boost/archive/xml_iarchive.hpp" target="xml_iarchive_cpp">boost::archive::xml_iarchive</a> // loading |
| 278 | |
| 279 | // a portable XML archive which uses wide characters - use for utf-8 output</a> |
| 280 | <a href="../../../boost/archive/xml_woarchive.hpp" target="xml_woarchive_cpp">boost::archive::xml_woarchive</a> // saving |
| 281 | <a href="../../../boost/archive/xml_wiarchive.hpp" target="xml_wiarchive_cpp">boost::archive::xml_wiarchive</a> // loading |
| 282 | |
| 283 | // a non-portable native binary archive</a> |
| 284 | <a href="../../../boost/archive/binary_oarchive.hpp" target="binary_oarchive_cpp">boost::archive::binary_oarchive</a> // saving |
| 285 | <a href="../../../boost/archive/binary_iarchive.hpp" target="binary_iarchive_cpp">boost::archive::binary_iarchive</a> // loading |
| 286 | |
| 287 | <!-- |
| 288 | // a non-portable native binary archive which use wide character streams |
| 289 | <a href="../../../boost/archive/binary_woarchive.hpp">boost::archive::binary_woarchive</a> // saving |
| 290 | <a href="../../../boost/archive/binary_wiarchive.hpp">boost::archive::binary_wiarchive</a> // loading |
| 291 | --> |
| 292 | |
| 293 | </code></pre> |
| 294 | |
| 295 | All of these archives implement the same interface. Hence, it should suffice to describe only one |
| 296 | of them in detail. For this purpose we will use the text archive. |
| 297 | |
| 298 | |
| 299 | <pre><code> |
| 300 | namespace boost { |
| 301 | namespace archive { |
| 302 | |
| 303 | enum archive_flags { |
| 304 | no_header = 1, // suppress archive header info |
| 305 | no_codecvt = 2, // suppress alteration of codecvt facet |
| 306 | no_xml_tag_checking = 4 // suppress checking of xml tags - igored on saving |
| 307 | }; |
| 308 | |
| 309 | } // archive |
| 310 | } // boost |
| 311 | </code></pre> |
| 312 | |
| 313 | <pre><code> |
| 314 | namespace boost { |
| 315 | namespace archive { |
| 316 | |
| 317 | class text_oarchive : ... |
| 318 | { |
| 319 | ... |
| 320 | public: |
| 321 | ... // implementation of the <strong>Saving Archive</strong> concept |
| 322 | text_oarchive(std::ostream & os, unsigned int flags = 0); |
| 323 | ~text_oarchive(); |
| 324 | }; |
| 325 | |
| 326 | } // archive |
| 327 | } // boost |
| 328 | </code></pre> |
| 329 | |
| 330 | <dl> |
| 331 | |
| 332 | <dt><h4><code> |
| 333 | text_oarchive(std::ostream & os, unsigned int flags = 0); |
| 334 | </code></h4></dt> |
| 335 | <dd> |
| 336 | Constructs an archive given an open <code style="white-space: normal">stream</code> as |
| 337 | an argument and optional flags. For most applications there will be no need to use flags. |
| 338 | Flags are defined by <code style="white-space: normal">enum archive_flags</code> enumerator. |
| 339 | Multiple flags can be combined with the <code style="white-space: normal">|</code> operator. |
| 340 | |
| 341 | By default, archives prepend |
| 342 | output with initial data which helps identify them as archives produced by this system. |
| 343 | This permits a more graceful handling of the case where an attempt is made to load an archive |
| 344 | from an invalid file format. In addition to this, each type of archive might have |
| 345 | its own information. For example, native binary archives include information about |
| 346 | sizes of native types and endianess to gracefully handle the case where it has been |
| 347 | erroneously assumed that such an archive is portable across platforms. In some cases, |
| 348 | where this extra overhead might be considered objectionable, it can be suppressed with the |
| 349 | <code style="white-space: normal">no_header</code> flag. |
| 350 | <p> |
| 351 | In some cases, an archive may alter (and later restore) |
| 352 | the codecvt facet of the stream locale. To suppress this action, |
| 353 | include the <code style="white-space: normal">no_codecvt</code> flag. |
| 354 | <p> |
| 355 | XML archives contain nested tags signifying the start and end of data fields. |
| 356 | These tags are normally checked for agreement with the object name when |
| 357 | data is loaded. If a mismatch occurs an exception is thrown. It's possible |
| 358 | that this may not be desired behavior. To suppress this checking of XML |
| 359 | tags, use <code style="white-space: normal">no_xml_tag_checking</code> flag. |
| 360 | </dd> |
| 361 | |
| 362 | <dt><h4><code> |
| 363 | ~text_oarchive(); |
| 364 | </code></h4></dt> |
| 365 | <dd> |
| 366 | Destructor for an archive. This should be called before the stream is |
| 367 | closed. It restores any altered stream facets to their state before the |
| 368 | archive was opened. |
| 369 | </dd> |
| 370 | |
| 371 | </dl> |
| 372 | |
| 373 | <pre><code> |
| 374 | namespace boost { |
| 375 | namespace archive { |
| 376 | |
| 377 | class text_iarchive : ... |
| 378 | { |
| 379 | ... |
| 380 | public: |
| 381 | ... // implementation of the <strong>Loading Archive</strong> concept |
| 382 | text_iarchive(std::istream & is, unsigned int flags = 0); |
| 383 | ~text_iarchive(); |
| 384 | }; |
| 385 | |
| 386 | } //namespace archive |
| 387 | ) //namespace boost |
| 388 | |
| 389 | </code></pre> |
| 390 | |
| 391 | <dl> |
| 392 | |
| 393 | <dt><h4><code> |
| 394 | text_iarchive(std::istream & is, unsigned int flags = 0); |
| 395 | </code></h4></dt> |
| 396 | <dd> |
| 397 | Contructs an archive given an open <code style="white-space: normal">stream</code> as |
| 398 | an argument and optional flags. If flags are used, they should be the same |
| 399 | as those used when the archive was created. Function and usage of flags is described |
| 400 | above. |
| 401 | </dd> |
| 402 | |
| 403 | <dt><h4><code> |
| 404 | ~text_iarchive(); |
| 405 | </code></h4></dt> |
| 406 | <dd> |
| 407 | Destructor for an archive. This should be called before the stream is |
| 408 | closed. It restores any altered stream facets to their state before the |
| 409 | the archive was opened. |
| 410 | </dd> |
| 411 | </dl> |
| 412 | <p> |
| 413 | The <code style="white-space: normal">binary_oarchive</code> and |
| 414 | <code style="white-space: normal">binary_iarchive</code> classes are |
| 415 | implemented in terms of the more basic |
| 416 | <code style="white-space: normal">std::streambuf</code>. So, in addition |
| 417 | to the common class interface described above, they include the following |
| 418 | constructors: |
| 419 | <dl> |
| 420 | <dt><h4><code> |
| 421 | binary_oarchive(std::streambuf & bsb, unsigned int flags = 0); |
| 422 | </code></h4></dt> |
| 423 | and |
| 424 | <dt><h4><code> |
| 425 | binary_iarchive(std::streambuf & bsb, unsigned int flags = 0); |
| 426 | </code></h4></dt> |
| 427 | </dl> |
| 428 | |
| 429 | <h3><a name="exceptions">Exceptions</h3> |
| 430 | All of the archive classes included may throw exceptions. The list of exceptions that might |
| 431 | be thrown can be found in section <a target="detail" href="exceptions.html">Archive Exceptions</a> |
| 432 | of this documentation. |
| 433 | |
| 434 | <h3><a name="charactersets">Character Sets</h3> |
| 435 | This library includes two archive classes for XML. The wide character |
| 436 | version (<code style="white-space: normal">xml_w?archive</code>) renders its output as UTF-8 which can |
| 437 | handle any wide character without loss of information. |
| 438 | <code style="white-space: normal">std::string</code> data is converted from multi-byte format to wide |
| 439 | character format using the current <code style="white-space: normal"> |
| 440 | locale</code>. Hence this version should give a fair rendering of all |
| 441 | C++ data for all cases. This could result in some unexpected behavior. |
| 442 | Suppose an <code style="white-space: normal">std::string</code> |
| 443 | is created with the <code style="white-space: normal">locale</code> character |
| 444 | set to hebrew characters. On output this is converted to wide characters. |
| 445 | On input however, there could be a problem if the <code style="white-space: normal">locale</code> is |
| 446 | not set the same as when the archive is created. |
| 447 | <p> |
| 448 | The normal character version (<code style="white-space: normal">xml_?archive</code>) renders |
| 449 | <code style="white-space: normal">std::string</code> output without any conversion. Though this may work |
| 450 | fine for serialization, it may create difficulties if the XML archive is used |
| 451 | for some other purpose. |
| 452 | <hr> |
| 453 | <p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004. |
| 454 | Distributed under the Boost Software License, Version 1.0. (See |
| 455 | accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 456 | </i></p> |
| 457 | </body> |
| 458 | </html> |