cereal
A C++11 library for serialization
 All Classes Files Functions Variables Typedefs Enumerations Groups
json.hpp
Go to the documentation of this file.
1 
3 /*
4  Copyright (c) 2013, 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 <COPYRIGHT HOLDER> 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_JSON_HPP_
30 #define CEREAL_ARCHIVES_JSON_HPP_
31 
32 #include <cereal/cereal.hpp>
33 #include <cereal/details/util.hpp>
34 
35 #include <cereal/external/rapidjson/prettywriter.h>
36 #include <cereal/external/rapidjson/genericstream.h>
37 #include <cereal/external/base64.hpp>
38 
39 #include <sstream>
40 #include <stack>
41 #include <vector>
42 #include <string>
43 
44 #include <iostream>
45 
46 namespace cereal
47 {
48  // ######################################################################
50 
52  class JSONOutputArchive : public OutputArchive<JSONOutputArchive>
53  {
54  typedef rapidjson::GenericWriteStream WriteStream;
55  typedef rapidjson::PrettyWriter<WriteStream> JSONWriter;
56 
57  public:
59 
61  JSONOutputArchive(std::ostream & stream) :
63  itsWriteStream(stream),
64  itsWriter(itsWriteStream)
65  {
66  itsNameCounter.push(0);
67  itsWriter.StartObject();
68  }
69 
72  {
73  itsWriter.EndObject();
74  }
75 
76  void saveValue(bool b) { itsWriter.Bool(b); }
77  void saveValue(int i) { itsWriter.Int(i); }
78  void saveValue(unsigned u) { itsWriter.Uint(u); }
79  void saveValue(int64_t i64) { itsWriter.Int64(i64); }
80  void saveValue(uint64_t u64) { itsWriter.Uint64(u64); }
81  void saveValue(double d) { itsWriter.Double(d); }
82  void saveValue(std::string const & s) { rawString(s); }
83  void saveValue(char const * s) { itsWriter.String(s); }
84  void saveNull() { itsWriter.Null(); }
85 
86  void writeName()
87  {
88  if(itsNextName == nullptr)
89  {
90  std::string name = "value" + std::to_string( itsNameCounter.top()++ ) + "\0";
91  saveValue(name);
92  }
93  else
94  {
95  saveValue(itsNextName);
96  itsNextName = nullptr;
97  }
98  }
99 
100  void rawString(std::string const & s)
101  {
102  itsWriter.String(s.c_str(), s.size());
103  }
104 
106 
110  void startNode()
111  {
112  writeName();
113 
114  itsWriter.StartObject();
115 
116  itsNameCounter.push(0);
117  }
118 
120  void finishNode()
121  {
122  itsWriter.EndObject();
123 
124  itsNameCounter.pop();
125  }
126 
128  void setNextName( const char * name )
129  {
130  itsNextName = name;
131  }
132 
134 
136  void saveBinaryValue( const void * data, size_t size, const char * name = nullptr )
137  {
138  };
139 
140  void setOutputType(bool outputType)
141  {
142  itsOutputType = outputType;
143  }
144 
145  protected:
146 
147  private:
148  WriteStream itsWriteStream;
149  JSONWriter itsWriter;
150  std::ostringstream itsOS;
151  bool itsOutputType;
152  char const * itsNextName;
153  std::stack<uint32_t> itsNameCounter;
154  }; // JSONOutputArchive
155 
156 
157 
158  // ######################################################################
160 
163  {
164  };
165 
166  // ######################################################################
167  // JSONArchive prologue and epilogue functions
168 
170 
171  template <class T>
172  void prologue( JSONOutputArchive &, NameValuePair<T> const & )
173  { }
174 
176 
177  template <class T>
178  void epilogue( JSONOutputArchive &, NameValuePair<T> const & )
179  { }
180 
182 
183  template <class T>
184  void prologue( JSONOutputArchive &, SizeTag<T> const & )
185  { }
186 
188 
189  template <class T>
190  void epilogue( JSONOutputArchive &, SizeTag<T> const & )
191  { }
192 
194 
196  template <class T>
197  typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
198  prologue( JSONOutputArchive & ar, T const & data )
199  {
200  ar.startNode();
201  }
202 
204 
205  template <class T>
206  typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
207  epilogue( JSONOutputArchive & ar, T const & data )
208  {
209  ar.finishNode();
210  }
211 
212  template <class T>
213  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
214  prologue( JSONOutputArchive & ar, T const & data )
215  {
216  ar.writeName();
217  }
218 
219  template <class T>
220  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
221  epilogue( JSONOutputArchive & ar, T const & data )
222  {
223  }
224 
225  template<class CharT, class Traits, class Alloc> inline
226  void prologue(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
227  {
228  ar.writeName();
229  }
230 
231  template<class CharT, class Traits, class Alloc> inline
232  void epilogue(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
233  {
234  }
235 
236  // ######################################################################
237  // Common JSONArchive serialization functions
238 
240  template <class Archive, class T> inline
241  CEREAL_ARCHIVE_RESTRICT(JSONInputArchive, JSONOutputArchive)
242  serialize( Archive & ar, NameValuePair<T> & t )
243  {
244  ar.setNextName( t.name );
245  ar( t.value );
246  }
247 
249  template <class Archive, class T> inline
250  CEREAL_ARCHIVE_RESTRICT(JSONInputArchive, JSONOutputArchive)
251  serialize( Archive & ar, SizeTag<T> & )
252  { }
253 
255  template<class T> inline
256  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
257  save(JSONOutputArchive & ar, T const & t)
258  {
259  ar.saveValue( t );
260  }
261 
263  template<class CharT, class Traits, class Alloc> inline
264  void save(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
265  {
266  ar.saveValue( str );
267  }
268 
269 } // namespace cereal
270 
271 // register archives for polymorphic support
272 CEREAL_REGISTER_ARCHIVE(cereal::JSONOutputArchive);
273 
274 #endif // CEREAL_ARCHIVES_JSON_HPP_
275