Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/serialization/doc/archive_reference.html @ 33

Last change on this file since 33 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 21.1 KB
Line 
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 .
5Use, modification and distribution is subject to the Boost Software
6License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7http://www.boost.org/LICENSE_1_0.txt)
8-->
9<head>
10<meta http-equiv="Content-Type" content="text/html; 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 - More on Archives</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">Archive Class Reference</h2>
24    </td>
25  </tr>
26</table>
27<hr>
28<dl class="page-index">
29  <dt><a href="#implementation">Implementation</a>
30  <dt><a href="#usage">Usage</a>
31  <dt><a href="#testing">Testing</a>
32  <dt><a href="#polymorphic">Polymorphic Archives</a>
33</dl>
34<h3><a name="implementation">Implementation</a></h3>
35The <a href="archives.html"><strong>Archive</strong></a> concept specifies the functions that a
36class must implement to in order to be used to serialize
37<a href="serialization.html"><strong>Serializable</strong></a> types.
38The library implements a family of archives appropriate for different purposes. 
39This section describes how they have been implemented and how one can implement his own archive class.
40Our discussion will focus on archives used for loading as the hierarchy is exactly analogous
41for archives used for saving data.
42<p>
43Our archives have been factored in to a tree of classes in order to minimize
44repetition of code.  This is shown in the accompanying
45<a target="class_diagram" href="class_diagram.html">class diagram</a>.
46In order to diminish code repetition, input archives included with this library
47have all been derived from the following template:
48<pre><code>
49template&lt;class Archive&gt;
50detail::common_iarchive;
51</code></pre>
52<h4>Minimum Requirments</h4>
53An instance of the this template handles all the "bookkeeping" associated
54with serialization. In order to be a functional only the following additional
55functions <strong>must</strong> be defined:
56<dl>
57<dt><h4><code>void load(T &t);</code></h4></dt>
58<dd>
59This function must be implemented for all primitive data types.  This can be
60accomplished through the use of a member template or explict declarations
61for all prmititive types.
62</dd>
63
64<dt><h4><code>void load_binary(void *address, std::size_t size);</code></h4></dt>
65<dd>
66This function should <code style="white-space: normal">size</code> bytes from the archive, and
67copy them in to memory starting at address <code style="white-space: normal">address</code>.
68</dd>
69
70<dt><h4><code>friend class boost::archive::load_access;</code></h4></dt>
71<dd>
72In addition, such a class <strong>must</strong> provide a the following
73friend declaration grant access to the core serialization library to the functions
74of this class.
75</dd>
76
77</dl>
78
79So, the most trivial implementation of an input archive would look like this:
80
81<pre><code>
82<a href="../../../boost/archive/detail/common_iarchive.hpp" target="common_iarchive_hpp">
83#include &lt;boost/archive/detail/common_iarchive.hpp&gt;
84</a>
85
86/////////////////////////////////////////////////////////////////////////
87// class trivial_iarchive - read serialized objects from a input text stream
88class trivial_iarchive :
89    public boost::archive::detail::common_iarchive&lt;trivial_iarchive&gt;
90{
91    // permit serialization system priviledged access to permit
92    // implementation of inline templates for maximum speed.
93    friend class boost::archive::load_access;
94
95    // member template for loading primitive types.
96    // Override for any types/templates that special treatment
97    template&lt;class T&gt;
98    void load(T &amp; t);
99
100public:
101    //////////////////////////////////////////////////////////
102    // public interface used by programs that use the
103    // serialization library
104
105    // archives are expected to support this function
106    void load_binary(void *address, std::size_t count);
107};
108
109</code></pre>
110The simplest possible output archive class is exactly analogous to the above.
111In the following discussion, only input archives will be addressed.
112Output archives are exactly symmetrical to input archives.
113<p>
114Given a suitable definitions of <code style="white-space: normal">load</code>
115and <code style="white-space: normal">load_binary</code>,
116any program using serialization with a conforming C++ compiler should compile
117and run with this archive class.
118
119<h4>Optional Overrides</h4>
120
121The <code style="white-space: normal">detail::common_iarchive</code> class contains
122a number of functions that are used by various parts of the serialization library
123to help render the archive in a particular form.
124
125<dl>
126
127<dt><h4><code>void load_start()</code></h4></dt>
128<dd>
129<strong>Default</strong>:Does nothing.<br>
130<strong>Purpose</strong>:To inject/retrieve an object name into the archive.  Used
131by XML archive to inject "&lt;name " before data.
132</dd>
133<p>
134
135<dt><h4><code>void load_end()</code></h4></dt>
136<dd>
137<strong>Default</strong>:Does nothing.<br>
138<strong>Purpose</strong>:To inject/retrieve an object name into the archive. Used
139by XML archive to inject "&lt;/name&gt;" after data.
140<dd>
141</dd>
142<p>
143<dt><h4><code>void end_preamble()</code></h4></dt>
144<dd>
145<strong>Default</strong>:Does nothing.<br>
146<strong>Purpose</strong>:Called <strong>each time</strong> user data is saved.
147Its not called when archive book keeping data is saved.  This is used by XML archives
148to determine  when to inject a "&gt;" character at end of XML header. XML output archives
149keep their own internal flag indicating that data being written is header data. This
150internal flag is reset when an object start tag is written. When
151<code style="white-space: normal">void end_preamble()</code> is invoked and this internal flag is set
152a "&gt;" character is appended to the output and the internal flag is reset. The default
153implementation for <code style="white-space: normal">void end_preamble()</code> is a no-op there by permitting it
154to be optimised away for archive classes that don't use it.
155</dd>
156<p>
157<dt><h4><code>
158template&lt;class T&gt;
159void load_override(T & t, int);
160</code></h4></dt>
161<dd>
162<strong>Default</strong>:Invokes <code style="white-space: normal">archive::load(Archive & ar, t)</code><br>
163This is the main entry into the serialization library.<br>
164<strong>Purpose</strong>:This can be overridden in cases where the data is to be written
165to the archive in some special way.  For example, XML archives implement special handling for
166name-value pairs by overriding this function template for name-value pairs. 
167This replaces the default name-value pair handling, which is just to throw away the name,
168with one appropriate for XML which writes out the start of an XML tag with the correct object name.
169<p>
170The second argument must be part of the function signature even this it is not used.
171Its purpose is to be sure that code is portable to compilers which fail to correctly
172implement partial function template ordering.  For more information see
173<a href="implementation.html#functiontemplateordering">this</a>.
174</dd>
175
176</dl>
177
178<h4>Types used by the serialization library</h4>
179The serialization library injects bookkeeping data into the serialization archive.
180This data includes things like object ids, version numbers, class names etc.  Each
181of these objects is included in a wrapper so that the archive class can override the
182implementation of <code style="white-space: normal">void load_override(T & t, int);</code>.
183For example, in the XML archive, the override for this type renders an object_id equal to 23 as
184"object_id=_23".  The following table lists the types defined in the
185<code style="white-space: normal">boost::archive namespace</code>
186used internally by the serialization library:
187<p>
188<table border>
189<tr><th align=left>type</th><th align=left><code style="white-space: normal">default<br>serialed as</code></th>
190<tr><td><code style="white-space: normal">version_type</code></td><td><code style="white-space: normal">unsigned int</code></td>             
191<tr><td><code style="white-space: normal">object_id_type</code></td><td><code style="white-space: normal">unsigned int</code></td>   
192<tr><td><code style="white-space: normal">object_id_reference_type</code></td><td><code style="white-space: normal">unsigned int</code></td>   
193<tr><td><code style="white-space: normal">class_id_type</code></td><td><code style="white-space: normal">int</code></td>   
194<tr><td><code style="white-space: normal">class_id_optional_type</code></td><td><code style="white-space: normal">nothing</code></td>   
195<tr><td><code style="white-space: normal">class_id_reference_type</code></td><td><code style="white-space: normal">int</code></td>   
196<tr><td><code style="white-space: normal">tracking_type</code></td><td><code style="white-space: normal">bool</code></td>   
197<tr><td><code style="white-space: normal">classname_type</code></td><td><code style="white-space: normal">string</code></td>   
198</table>
199<p>
200All of these are associated with a default serialization defined in terms of primitive types
201so it isn't a requirement to define <code style="white-space: normal">load_override</code> 
202for these types.
203<p>
204These are defined in
205<a href="../../../boost/archive/basic_archive.hpp" target="basic_archive_hpp"><code style="white-space: normal">basic_archive.hpp</code></a>.
206All of these types have been assigned an
207<a target="detail" href="traits.html#level">implementation level</a> of
208<code style="white-space: normal">primitive</code> and are convertible to types such as int, unsigned int, etc.
209so that they have default implementations.  This is illustrated by
210<a href="../../../boost/archive/basic_text_iarchive.hpp" target="basic_text_iarchive_hpp"><code style="white-space: normal">basic_text_iarchive.hpp</code></a>.
211which relies upon the default.  However, in some cases, overrides will have to be
212explicitly provided for these types. For an example see
213<a href="../../../boost/archive/basic_xml_iarchive.hpp" target="basic_xml_iarchive_hpp"><code style="white-space: normal">basic_xml_iarchive.hpp</code></a>.
214<p>
215In real practice, we probably won't be quite done.
216One or more of the following issues may need to be addressed:
217<ul>
218    <li>Many compilers fail to implement correct partial ordering of
219    function templates.  The archives included with this library work around
220    this using argument overloading.  This technique is described in
221    <a target="detail" href="implementation.html#functiontemplateordering">
222    another section of this manual</a>
223    <li>Even if we are using a conforming compiler, we might want our new archive class
224    to be portable to non-conforming compilers.
225    <li>Our archive format might require extra information inserted into it.  For
226    example, XML archives need &lt;name ... &gt;...&lt;/name&gt; surrounding
227    all data objects.
228    <li>Addressing any of the above may generate more issues to be addressed.
229    <li>The archives included with library are all templates which use a
230    <code style="white-space: normal">stream</code> as a template parameter rather than simple classes.
231    Combined with the above, even more issues arise with non-conforming compilers.
232</ul>
233The attached <a target="class_diagram" href="class_diagram.html">class diagram</a>
234shows the relationships between classes used to implement the serialization library.
235<p>
236A close examination of the archives included with the library illustrate
237what it takes to make a portable archive that covers all data types.
238<h3><a name="usage">Usage</a></h3>
239The newly created archive will usually be stored in its own header module.  All
240that is necessary is to include the header and construct an instance of the new archive.
241EXCEPT for one special case.
242<ul>
243    <li>Instances of a derived class are serialized through a base class pointer.
244    <li>Such instances are not "registered" neither implicitly nor explicitly. That
245    is, the macro <code style="white-space: normal">BOOT_CLASS_EXPORT</code> is used to instantiate the serialization
246    code for the included archives.
247</ul>
248The problem here is that BOOT_CLASS_EXPORT only generates code for those archives
249included with the library - not those added subsequently.  To generate code for
250newly created archive classes, the following should be used.
251<pre><code>
252#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES trivial_oarchive
253#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES trivial_iarchive
254</code></pre>
255before <code style="white-space: normal">BOOST_CLASS_EXPORT</code> is invoked for any serializable class.
256Failure to do this will not inhibit the program from compiling, linking
257and executing properly - except in one case.  If an instance of a derived
258class is serialized through a pointer to its base class, the program
259will throw an
260<a href="exceptions.html#unregistered_class"><code style="white-space: normal">unregistered_class</code></a>
261exception.
262<p>
263Only one of the above statements is permitted, However, any number of new archive
264classes can be specified as list separated by commas.
265
266<h4><a name="testing">Testing</h4>
267Exhaustive testing of the library requires testing the different aspects of object
268serialization with each archive.  There are 36 different tests that can run with any archive.  There are
2695 "standard archives" included with the system. (3 in systems which don't support wide
270charactor i/o).
271<p>
272In addition, there are 22 other tests which aren't related to any particular archive
273class.
274<p>
275The default <code style="white-space: normal">bjam</code> testing setup will run all
276the above described tests.  This will result in as many as 39 archive tests * 5
277standard archives + 25 general tests = 220 tests. Note that a complete test of the
278library would include DLL vs static library, release vs debug so the actual total
279would be closer to 880 tests.
280<p>
281For each archive there is a header file in the test directory similar to the one below.
282The name of this archive is passed to the test program by setting the
283environmental variable <code style="white-space: normal">BOOST_ARCHIVE_TEST</code>
284to the name of the header.  Here is the header file
285<code style="white-space: normal">test_archive.hpp</code> . Test header files for
286other archives are similar.
287<pre><code>
288// text_archive test header
289// include output archive header
290#include &lt;boost/archive/text_oarchive.hpp&gt;
291// set name of test output archive
292typedef boost::archive::text_oarchive test_oarchive;
293// set name of test output stream
294typedef std::ofstream test_ostream;
295
296// repeat the above for input archive
297#include &lt;boost/archive/text_iarchive.hpp&gt;
298typedef boost::archive::text_iarchive test_iarchive;
299typedef std::ifstream test_istream;
300
301// define open mode for streams
302//   binary archives should use std::ios_base::binary
303#define TEST_STREAM_FLAGS (std::ios_base::openmode)0
304</code></pre>
305
306To test a new archive, for example, portable binary archives, make a
307header file <code style="white-space: normal">portable_binary_archive.hpp</code>
308and invoke <code style="white-space: normal">bjam</code> with
309<pre><code> 
310-sBOOST_ARCHIVE_LIST=portable_binary_archive.hpp
311</code></pre>
312This process in encapsulated in the shell script
313<code style="white-space: normal">run_archive_test</code> whose command line is
314<pre><code>
315run_archive_test &lt;test header file&gt; &lt;toolset&gt; [&lt;boost root&gt;] [&lt;target directory&gt;]
316</code></pre>
317<h3><a name="polymorphic">Polymorphic Archives</a></h3>
318
319<h4>Motivation</h4>
320
321All archives described so far are implemented as templates.  Code to save and load
322data to archives is regenerated for each combination of archive class and data type.
323Under these cirumstances, a good optimizing compiler that can expand
324<code>inline</code> functions to enough depth will generate fast code. 
325However:
326<ul>
327<li>Much inline code may be replicated.
328<li>If there are several archive classes, code will be regenerated for each archive class.
329<li>If serialization code is placed in a library, that library must be rebuilt
330each time a new archive class is created.
331<li>If serialization code is placed in a DLL,
332  <ul>
333  <li>The DLL will contain versions of code for each known archive type. 
334    This would result in loading of DLLs which contain
335    much code that is not used - basically defeating one of the main motivations
336    for choosing to use a DLL in the first place.
337  <li>If a new archive is created and an application shipped, all DLLs have to be
338    rebuilt, and reshipped along with the application which uses the new archive.  Thus
339    the other main motivation for using a DLL is defeated.
340  </ul>
341</ul>
342
343<h4>Implementation</h4>
344The solution is the the pair <code>polymorphic_oarchive</code>
345and <code>polymorphic_iarchive</code>.  They present a common interface of virtual
346functions - no templates - that is equivalent to the standard templated one.
347
348This is shown in the accompanying
349<a target="class_diagram" href="class_diagram.html">class diagram</a>
350<p>
351The accompanying demo program in files
352
353<a target=demo_polymorphic_cp href="../example/demo_polymorphic.cpp"><code style="white-space: normal">demo_polymorphic.cpp</code></a>,
354<a target=demo_polymorphic_A_hpp href="../example/demo_polymorphic_A.hpp"><code style="white-space: normal">demo_polymorphic_A.hpp</code></a>, and
355<a target=demo_polymorphic_A_cpp href="../example/demo_polymorphic_A.cpp"><code style="white-space: normal">demo_polymorphic_A</code></a>
356show how polymorphic archives are to be used. Note the following:
357<ul>
358  <li><a target=demo_polymorphic_A_hpp href="../example/demo_polymorphic_A.hpp"><code style="white-space: normal">demo_polymorphic_A.hpp</code></a> and
359<a target=demo_polymorphic_A_cpp href="../example/demo_polymorphic_A.cpp"><code style="white-space: normal">demo_polymorphic_A.cpp</code></a>
360contain no templates and no reference to any specific archive implementation.  That is, they will
361only have to be compiled once for all archive implementations.  The even applies to archives classes
362created in the future.
363  <li>The main program <a target=demo_polymorphic_cp href="../example/demo_polymorphic.cpp"><code style="white-space: normal">demo_polymorphic.cpp</code></a>
364specifies a specific archive implementation. 
365</ul>
366As can be seen in the
367<a target="class_diagram" href="class_diagram.html">class diagram</a>
368and the header files, this implementation is just a composition of the polymorphic
369interface and the standard template driven implementation.  This composition is
370accomplished by the templates
371<a target=polymorphic_iarchive_impl_hpp href="../../../boost/archive/detail/polymorphic_iarchive_impl.hpp"><code style="white-space: normal">polymorphic_iarchive_impl.hpp</code></a>
372and
373<a target=polymorphic_oarchive_impl_hpp href="../../../boost/archive/detail/polymorphic_oarchive_impl.hpp"><code style="white-space: normal">polymorphic_oarchive_impl.hpp</code></a>.
374As these contain no code specific to the particular implementation archive, they can be used to create
375a polymorphic archive implementation from any functioning templated archive implementation.
376<p>
377As a convenience, small header files have been included which contain
378<code style="white-space: normal">typedef</code> for polymorphic implementation for each corresponding
379templated one.  For example, the headers
380<a target=polymorphic_text_iarchive_hpp href="../../../boost/archive/polymorphic_text_iarchive.hpp"><code style="white-space: normal">polymorphic_text_iarchive.hpp</code></a>
381and
382<a target=polymorphic_text_oarchive_hpp href="../../../boost/archive/polymorphic_text_oarchive.hpp"><code style="white-space: normal">polymorphic_text_oarchive.hpp</code></a>.
383contain the <code style="white-space: normal">typedef</code> for the polymorphic implementation
384of the standard text archive classes 
385<a target=text_iarchive_hpp href="../../../boost/archive/text_iarchive.hpp"><code style="white-space: normal">text_iarchive.hpp</code></a>
386and
387<a target=text_oarchive_hpp href="../../../boost/archive/text_oarchive.hpp"><code style="white-space: normal">text_oarchive.hpp</code></a>
388respectively. All included polymorphic archives use the same naming scheme.
389<h4>Usage</h4>
390Polymorphic archives address the issues raised above regarding templated implementation.
391That is, there is no replicated code, and no recompilation for new archives.  This will
392result in smaller executables for program which use more than one type of archive, and
393smaller DLLS. There is a
394penalty for calling archive functions through a virtual function dispatch table and there
395is no possibility for a compiler to <code style="white-space: normal">inline</code> archive functions.  This will result
396in a detectable degradation in performance for saving and loading archives.
397<p>
398The main utility of polymorphic archives will be to permit the buiding of class DLLs that will
399include serialization code for all present and future archives with no redundant code.
400<hr>
401<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
402Distributed under the Boost Software License, Version 1.0. (See
403accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
404</i></p>
405</body>
406</html>
Note: See TracBrowser for help on using the repository browser.