1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2006 Marcin Kalicinski
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see www.boost.org
9 // ----------------------------------------------------------------------------
10 #ifndef BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED
11 #define BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED
12 
13 #include <boost/property_tree/ptree.hpp>
14 
15 #include <boost/serialization/nvp.hpp>
16 #include <boost/serialization/collections_save_imp.hpp>
17 #include <boost/serialization/detail/stack_constructor.hpp>
18 #include <boost/serialization/split_free.hpp>
19 #include <boost/serialization/utility.hpp>
20 
21 namespace boost { namespace property_tree
22 {
23 
24     ///////////////////////////////////////////////////////////////////////////
25     // boost::serialization support
26 
27     /**
28      * Serialize the property tree to the given archive.
29      * @note In addition to serializing to regular archives, this supports
30      *       serializing to archives requiring name-value pairs, e.g. XML
31      *       archives.  However, the output format in the XML archive is not
32      *       guaranteed to be the same as that when using the Boost.PropertyTree
33      *       library's @c boost::property_tree::xml_parser::write_xml.
34      * @param ar The archive to which to save the serialized property tree.
35      *           This archive should conform to the concept laid out by the
36      *           Boost.Serialization library.
37      * @param t The property tree to serialize.
38      * @param file_version file_version for the archive.
39      * @post @c ar will contain the serialized form of @c t.
40      */
41     template<class Archive, class K, class D, class C>
save(Archive & ar,const basic_ptree<K,D,C> & t,const unsigned int file_version)42     inline void save(Archive &ar,
43                      const basic_ptree<K, D, C> &t,
44                      const unsigned int file_version)
45     {
46         using namespace boost::serialization;
47         stl::save_collection<Archive, basic_ptree<K, D, C> >(ar, t);
48         ar << make_nvp("data", t.data());
49     }
50 
51     namespace detail
52     {
53         template <class Archive, class K, class D, class C>
load_children(Archive & ar,basic_ptree<K,D,C> & t)54         inline void load_children(Archive &ar,
55                                   basic_ptree<K, D, C> &t)
56         {
57             namespace bsl = boost::serialization;
58             namespace bsa = boost::archive;
59 
60             typedef basic_ptree<K, D, C> tree;
61             typedef typename tree::value_type value_type;
62 
63             bsl::collection_size_type count;
64             ar >> BOOST_SERIALIZATION_NVP(count);
65             bsl::item_version_type item_version(0);
66             const bsa::library_version_type library_version(
67                 ar.get_library_version()
68             );
69             if(bsa::library_version_type(3) < library_version){
70                 ar >> BOOST_SERIALIZATION_NVP(item_version);
71             }
72             // Can't use the serialization helper, it expects resize() to exist
73             // for default-constructible elements.
74             // This is a copy/paste of the fallback version.
75             t.clear();
76             while(count-- > 0){
77                 bsl::detail::stack_construct<Archive, value_type>
78                     u(ar, item_version);
79                 ar >> bsl::make_nvp("item", u.reference());
80                 t.push_back(u.reference());
81                 ar.reset_object_address(& t.back() , & u.reference());
82             }
83         }
84     }
85 
86     /**
87      * De-serialize the property tree to the given archive.
88      * @note In addition to de-serializing from regular archives, this supports
89      *       loading from archives requiring name-value pairs, e.g. XML
90      *       archives. The format should be that used by
91      *       boost::property_tree::save.
92      * @param ar The archive from which to load the serialized property tree.
93      *           This archive should conform to the concept laid out by the
94      *           Boost.Serialization library.
95      * @param t The property tree to de-serialize.
96      * @param file_version file_version for the archive.
97      * @post @c t will contain the de-serialized data from @c ar.
98      */
99     template<class Archive, class K, class D, class C>
load(Archive & ar,basic_ptree<K,D,C> & t,const unsigned int file_version)100     inline void load(Archive &ar,
101                      basic_ptree<K, D, C> &t,
102                      const unsigned int file_version)
103     {
104         namespace bsl = boost::serialization;
105 
106         detail::load_children(ar, t);
107         ar >> bsl::make_nvp("data", t.data());
108     }
109 
110     /**
111      * Load or store the property tree using the given archive.
112      * @param ar The archive from which to load or save the serialized property
113      *           tree. The type of this archive will determine whether saving or
114      *           loading is performed.
115      * @param t The property tree to load or save.
116      * @param file_version file_version for the archive.
117      */
118     template<class Archive, class K, class D, class C>
serialize(Archive & ar,basic_ptree<K,D,C> & t,const unsigned int file_version)119     inline void serialize(Archive &ar,
120                           basic_ptree<K, D, C> &t,
121                           const unsigned int file_version)
122     {
123         using namespace boost::serialization;
124         split_free(ar, t, file_version);
125     }
126 
127 } }
128 
129 #endif
130