Skip to content

Commit e158eec

Browse files
committed
added cereal serialization library into code base
1 parent 8d5d29c commit e158eec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+15730
-4
lines changed

cereal/access.hpp

Lines changed: 427 additions & 0 deletions
Large diffs are not rendered by default.

cereal/archives/adapters.hpp

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*! \file adapters.hpp
2+
\brief Archive adapters that provide additional functionality
3+
on top of an existing archive */
4+
/*
5+
Copyright (c) 2014, Randolph Voorhies, Shane Grant
6+
All rights reserved.
7+
8+
Redistribution and use in source and binary forms, with or without
9+
modification, are permitted provided that the following conditions are met:
10+
* Redistributions of source code must retain the above copyright
11+
notice, this list of conditions and the following disclaimer.
12+
* Redistributions in binary form must reproduce the above copyright
13+
notice, this list of conditions and the following disclaimer in the
14+
documentation and/or other materials provided with the distribution.
15+
* Neither the name of cereal nor the
16+
names of its contributors may be used to endorse or promote products
17+
derived from this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
23+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*/
30+
#ifndef CEREAL_ARCHIVES_ADAPTERS_HPP_
31+
#define CEREAL_ARCHIVES_ADAPTERS_HPP_
32+
33+
#include <cereal/details/helpers.hpp>
34+
#include <utility>
35+
36+
namespace cereal
37+
{
38+
#ifdef CEREAL_FUTURE_EXPERIMENTAL
39+
40+
// Forward declaration for friend access
41+
template <class U, class A> U & get_user_data( A & );
42+
43+
//! Wraps an archive and gives access to user data
44+
/*! This adapter is useful if you require access to
45+
either raw pointers or references within your
46+
serialization functions.
47+
48+
While cereal does not directly support serialization
49+
raw pointers or references, it is sometimes the case
50+
that you may want to supply something such as a raw
51+
pointer or global reference to some constructor.
52+
In this situation this adapter would likely be used
53+
with the construct class to allow for non-default
54+
constructors.
55+
56+
@note This feature is experimental and may be altered or removed in a future release. See issue #46.
57+
58+
@code{.cpp}
59+
struct MyUserData
60+
{
61+
int * myRawPointer;
62+
std::reference_wrapper<MyOtherType> myReference;
63+
};
64+
65+
struct MyClass
66+
{
67+
// Note the raw pointer parameter
68+
MyClass( int xx, int * rawP );
69+
70+
int x;
71+
72+
template <class Archive>
73+
void serialize( Archive & ar )
74+
{ ar( x ); }
75+
76+
template <class Archive>
77+
static void load_and_construct( Archive & ar, cereal::construct<MyClass> & construct )
78+
{
79+
int xx;
80+
ar( xx );
81+
// note the need to use get_user_data to retrieve user data from the archive
82+
construct( xx, cereal::get_user_data<MyUserData>( ar ).myRawPointer );
83+
}
84+
};
85+
86+
int main()
87+
{
88+
{
89+
MyUserData md;
90+
md.myRawPointer = &something;
91+
md.myReference = someInstanceOfType;
92+
93+
std::ifstream is( "data.xml" );
94+
cereal::UserDataAdapter<MyUserData, cereal::XMLInputArchive> ar( md, is );
95+
96+
std::unique_ptr<MyClass> sc;
97+
ar( sc ); // use as normal
98+
}
99+
100+
return 0;
101+
}
102+
@endcode
103+
104+
@relates get_user_data
105+
106+
@tparam UserData The type to give the archive access to
107+
@tparam Archive The archive to wrap */
108+
template <class UserData, class Archive>
109+
class UserDataAdapter : public Archive
110+
{
111+
public:
112+
//! Construct the archive with some user data struct
113+
/*! This will forward all arguments (other than the user
114+
data) to the wrapped archive type. The UserDataAdapter
115+
can then be used identically to the wrapped archive type
116+
117+
@tparam Args The arguments to pass to the constructor of
118+
the archive. */
119+
template <class ... Args>
120+
UserDataAdapter( UserData & ud, Args && ... args ) :
121+
Archive( std::forward<Args>( args )... ),
122+
userdata( ud )
123+
{ }
124+
125+
private:
126+
//! Overload the rtti function to enable dynamic_cast
127+
void rtti() {}
128+
friend UserData & get_user_data<UserData>( Archive & ar );
129+
UserData & userdata; //!< The actual user data
130+
};
131+
132+
//! Retrieves user data from an archive wrapped by UserDataAdapter
133+
/*! This will attempt to retrieve the user data associated with
134+
some archive wrapped by UserDataAdapter. If this is used on
135+
an archive that is not wrapped, a run-time exception will occur.
136+
137+
@note This feature is experimental and may be altered or removed in a future release. See issue #46.
138+
139+
@note The correct use of this function cannot be enforced at compile
140+
time.
141+
142+
@relates UserDataAdapter
143+
@tparam UserData The data struct contained in the archive
144+
@tparam Archive The archive, which should be wrapped by UserDataAdapter
145+
@param ar The archive
146+
@throws Exception if the archive this is used upon is not wrapped with
147+
UserDataAdapter. */
148+
template <class UserData, class Archive>
149+
UserData & get_user_data( Archive & ar )
150+
{
151+
try
152+
{
153+
return dynamic_cast<UserDataAdapter<UserData, Archive> &>( ar ).userdata;
154+
}
155+
catch( std::bad_cast const & )
156+
{
157+
throw ::cereal::Exception("Attempting to get user data from archive not wrapped in UserDataAdapter");
158+
}
159+
}
160+
#endif // CEREAL_FUTURE_EXPERIMENTAL
161+
} // namespace cereal
162+
163+
#endif // CEREAL_ARCHIVES_ADAPTERS_HPP_

cereal/archives/binary.hpp

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*! \file binary.hpp
2+
\brief Binary input and output archives */
3+
/*
4+
Copyright (c) 2014, Randolph Voorhies, Shane Grant
5+
All rights reserved.
6+
7+
Redistribution and use in source and binary forms, with or without
8+
modification, are permitted provided that the following conditions are met:
9+
* Redistributions of source code must retain the above copyright
10+
notice, this list of conditions and the following disclaimer.
11+
* Redistributions in binary form must reproduce the above copyright
12+
notice, this list of conditions and the following disclaimer in the
13+
documentation and/or other materials provided with the distribution.
14+
* Neither the name of cereal nor the
15+
names of its contributors may be used to endorse or promote products
16+
derived from this software without specific prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
22+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*/
29+
#ifndef CEREAL_ARCHIVES_BINARY_HPP_
30+
#define CEREAL_ARCHIVES_BINARY_HPP_
31+
32+
#include <cereal/cereal.hpp>
33+
#include <sstream>
34+
35+
namespace cereal
36+
{
37+
// ######################################################################
38+
//! An output archive designed to save data in a compact binary representation
39+
/*! This archive outputs data to a stream in an extremely compact binary
40+
representation with as little extra metadata as possible.
41+
42+
This archive does nothing to ensure that the endianness of the saved
43+
and loaded data is the same. If you need to have portability over
44+
architectures with different endianness, use PortableBinaryOutputArchive.
45+
46+
When using a binary archive and a file stream, you must use the
47+
std::ios::binary format flag to avoid having your data altered
48+
inadvertently.
49+
50+
\ingroup Archives */
51+
class BinaryOutputArchive : public OutputArchive<BinaryOutputArchive, AllowEmptyClassElision>
52+
{
53+
public:
54+
//! Construct, outputting to the provided stream
55+
/*! @param stream The stream to output to. Can be a stringstream, a file stream, or
56+
even cout! */
57+
BinaryOutputArchive(std::ostream & stream) :
58+
OutputArchive<BinaryOutputArchive, AllowEmptyClassElision>(this),
59+
itsStream(stream)
60+
{ }
61+
62+
//! Writes size bytes of data to the output stream
63+
void saveBinary( const void * data, std::size_t size )
64+
{
65+
auto const writtenSize = static_cast<std::size_t>( itsStream.rdbuf()->sputn( reinterpret_cast<const char*>( data ), size ) );
66+
67+
if(writtenSize != size)
68+
throw Exception("Failed to write " + std::to_string(size) + " bytes to output stream! Wrote " + std::to_string(writtenSize));
69+
}
70+
71+
private:
72+
std::ostream & itsStream;
73+
};
74+
75+
// ######################################################################
76+
//! An input archive designed to load data saved using BinaryOutputArchive
77+
/* This archive does nothing to ensure that the endianness of the saved
78+
and loaded data is the same. If you need to have portability over
79+
architectures with different endianness, use PortableBinaryOutputArchive.
80+
81+
When using a binary archive and a file stream, you must use the
82+
std::ios::binary format flag to avoid having your data altered
83+
inadvertently.
84+
85+
\ingroup Archives */
86+
class BinaryInputArchive : public InputArchive<BinaryInputArchive, AllowEmptyClassElision>
87+
{
88+
public:
89+
//! Construct, loading from the provided stream
90+
BinaryInputArchive(std::istream & stream) :
91+
InputArchive<BinaryInputArchive, AllowEmptyClassElision>(this),
92+
itsStream(stream)
93+
{ }
94+
95+
//! Reads size bytes of data from the input stream
96+
void loadBinary( void * const data, std::size_t size )
97+
{
98+
auto const readSize = static_cast<std::size_t>( itsStream.rdbuf()->sgetn( reinterpret_cast<char*>( data ), size ) );
99+
100+
if(readSize != size)
101+
throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize));
102+
}
103+
104+
private:
105+
std::istream & itsStream;
106+
};
107+
108+
// ######################################################################
109+
// Common BinaryArchive serialization functions
110+
111+
//! Saving for POD types to binary
112+
template<class T> inline
113+
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
114+
CEREAL_SAVE_FUNCTION_NAME(BinaryOutputArchive & ar, T const & t)
115+
{
116+
ar.saveBinary(std::addressof(t), sizeof(t));
117+
}
118+
119+
//! Loading for POD types from binary
120+
template<class T> inline
121+
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
122+
CEREAL_LOAD_FUNCTION_NAME(BinaryInputArchive & ar, T & t)
123+
{
124+
ar.loadBinary(std::addressof(t), sizeof(t));
125+
}
126+
127+
//! Serializing NVP types to binary
128+
template <class Archive, class T> inline
129+
CEREAL_ARCHIVE_RESTRICT(BinaryInputArchive, BinaryOutputArchive)
130+
CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar, NameValuePair<T> & t )
131+
{
132+
ar( t.value );
133+
}
134+
135+
//! Serializing SizeTags to binary
136+
template <class Archive, class T> inline
137+
CEREAL_ARCHIVE_RESTRICT(BinaryInputArchive, BinaryOutputArchive)
138+
CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar, SizeTag<T> & t )
139+
{
140+
ar( t.size );
141+
}
142+
143+
//! Saving binary data
144+
template <class T> inline
145+
void CEREAL_SAVE_FUNCTION_NAME(BinaryOutputArchive & ar, BinaryData<T> const & bd)
146+
{
147+
ar.saveBinary( bd.data, static_cast<std::size_t>( bd.size ) );
148+
}
149+
150+
//! Loading binary data
151+
template <class T> inline
152+
void CEREAL_LOAD_FUNCTION_NAME(BinaryInputArchive & ar, BinaryData<T> & bd)
153+
{
154+
ar.loadBinary(bd.data, static_cast<std::size_t>(bd.size));
155+
}
156+
} // namespace cereal
157+
158+
// register archives for polymorphic support
159+
CEREAL_REGISTER_ARCHIVE(cereal::BinaryOutputArchive)
160+
CEREAL_REGISTER_ARCHIVE(cereal::BinaryInputArchive)
161+
162+
// tie input and output archives together
163+
CEREAL_SETUP_ARCHIVE_TRAITS(cereal::BinaryInputArchive, cereal::BinaryOutputArchive)
164+
165+
#endif // CEREAL_ARCHIVES_BINARY_HPP_

0 commit comments

Comments
 (0)