NDDEM
json.hpp
Go to the documentation of this file.
1 
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 the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 namespace cereal
36 {
38 
40  { RapidJSONException( const char * what_ ) : Exception( what_ ) {} };
41 }
42 
43 // Inform rapidjson that assert will throw
44 #ifndef CEREAL_RAPIDJSON_ASSERT_THROWS
45 #define CEREAL_RAPIDJSON_ASSERT_THROWS
46 #endif // CEREAL_RAPIDJSON_ASSERT_THROWS
47 
48 // Override rapidjson assertions to throw exceptions by default
49 #ifndef CEREAL_RAPIDJSON_ASSERT
50 #define CEREAL_RAPIDJSON_ASSERT(x) if(!(x)){ \
51  throw ::cereal::RapidJSONException("rapidjson internal assertion failure: " #x); }
52 #endif // RAPIDJSON_ASSERT
53 
54 // Enable support for parsing of nan, inf, -inf
55 #ifndef CEREAL_RAPIDJSON_WRITE_DEFAULT_FLAGS
56 #define CEREAL_RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNanAndInfFlag
57 #endif
58 
59 // Enable support for parsing of nan, inf, -inf
60 #ifndef CEREAL_RAPIDJSON_PARSE_DEFAULT_FLAGS
61 #define CEREAL_RAPIDJSON_PARSE_DEFAULT_FLAGS kParseFullPrecisionFlag | kParseNanAndInfFlag
62 #endif
63 
69 
70 #include <limits>
71 #include <sstream>
72 #include <stack>
73 #include <vector>
74 #include <string>
75 
76 namespace cereal
77 {
78  // ######################################################################
80 
106  class JSONOutputArchive : public OutputArchive<JSONOutputArchive>, public traits::TextArchive
107  {
109 
111  using JSONWriter = CEREAL_RAPIDJSON_NAMESPACE::PrettyWriter<WriteStream>;
112 
113  public:
117 
119  class Options
120  {
121  public:
123  static Options Default(){ return Options(); }
124 
126  static Options NoIndent(){ return Options( JSONWriter::kDefaultMaxDecimalPlaces, IndentChar::space, 0 ); }
127 
129  enum class IndentChar : char
130  {
131  space = ' ',
132  tab = '\t',
133  newline = '\n',
134  carriage_return = '\r'
135  };
136 
138 
142  explicit Options( int precision = JSONWriter::kDefaultMaxDecimalPlaces,
143  IndentChar indentChar = IndentChar::space,
144  unsigned int indentLength = 4 ) :
145  itsPrecision( precision ),
146  itsIndentChar( static_cast<char>(indentChar) ),
147  itsIndentLength( indentLength ) { }
148 
149  private:
150  friend class JSONOutputArchive;
153  unsigned int itsIndentLength;
154  };
155 
157 
160  JSONOutputArchive(std::ostream & stream, Options const & options = Options::Default() ) :
162  itsWriteStream(stream),
164  itsNextName(nullptr)
165  {
166  itsWriter.SetMaxDecimalPlaces( options.itsPrecision );
167  itsWriter.SetIndent( options.itsIndentChar, options.itsIndentLength );
168  itsNameCounter.push(0);
170  }
171 
174  {
175  if (itsNodeStack.top() == NodeType::InObject)
176  itsWriter.EndObject();
177  else if (itsNodeStack.top() == NodeType::InArray)
178  itsWriter.EndArray();
179  }
180 
182 
184  void saveBinaryValue( const void * data, size_t size, const char * name = nullptr )
185  {
186  setNextName( name );
187  writeName();
188 
189  auto base64string = base64::encode( reinterpret_cast<const unsigned char *>( data ), size );
190  saveValue( base64string );
191  }
192 
194 
198 
200 
204  void startNode()
205  {
206  writeName();
208  itsNameCounter.push(0);
209  }
210 
212  void finishNode()
213  {
214  // if we ended up serializing an empty object or array, writeName
215  // will never have been called - so start and then immediately end
216  // the object/array.
217  //
218  // We'll also end any object/arrays we happen to be in
219  switch(itsNodeStack.top())
220  {
222  itsWriter.StartArray();
223  // fall through
224  case NodeType::InArray:
225  itsWriter.EndArray();
226  break;
228  itsWriter.StartObject();
229  // fall through
230  case NodeType::InObject:
231  itsWriter.EndObject();
232  break;
233  }
234 
235  itsNodeStack.pop();
236  itsNameCounter.pop();
237  }
238 
240  void setNextName( const char * name )
241  {
242  itsNextName = name;
243  }
244 
246  void saveValue(bool b) { itsWriter.Bool(b); }
248  void saveValue(int i) { itsWriter.Int(i); }
250  void saveValue(unsigned u) { itsWriter.Uint(u); }
252  void saveValue(int64_t i64) { itsWriter.Int64(i64); }
254  void saveValue(uint64_t u64) { itsWriter.Uint64(u64); }
256  void saveValue(double d) { itsWriter.Double(d); }
258  void saveValue(std::string const & s) { itsWriter.String(s.c_str(), static_cast<CEREAL_RAPIDJSON_NAMESPACE::SizeType>( s.size() )); }
260  void saveValue(char const * s) { itsWriter.String(s); }
262  void saveValue(std::nullptr_t) { itsWriter.Null(); }
263 
264  template <class T> inline
266  saveValue(T val) { itsWriter.Int64(val); }
267  template <class T> inline
269  saveValue(T val) { itsWriter.Uint64(val); }
270 
271  private:
272  // Some compilers/OS have difficulty disambiguating the above for various flavors of longs, so we provide
273  // special overloads to handle these cases.
274 
276  template <class T, traits::EnableIf<sizeof(T) == sizeof(std::int32_t),
278  void saveLong(T l){ saveValue( static_cast<std::int32_t>( l ) ); }
279 
281  template <class T, traits::EnableIf<sizeof(T) != sizeof(std::int32_t),
283  void saveLong(T l){ saveValue( static_cast<std::int64_t>( l ) ); }
284 
286  template <class T, traits::EnableIf<sizeof(T) == sizeof(std::int32_t),
288  void saveLong(T lu){ saveValue( static_cast<std::uint32_t>( lu ) ); }
289 
291  template <class T, traits::EnableIf<sizeof(T) != sizeof(std::int32_t),
293  void saveLong(T lu){ saveValue( static_cast<std::uint64_t>( lu ) ); }
294 
295  public:
296 #if defined(_MSC_VER) && _MSC_VER < 1916
298  void saveValue( unsigned long lu ){ saveLong( lu ); };
299 #else // _MSC_VER
301  template <class T, traits::EnableIf<std::is_same<T, long>::value,
304  void saveValue( T t ){ saveLong( t ); }
305 
310  void saveValue( T t ){ saveLong( t ); }
311 #endif // _MSC_VER
312 
314 
322  (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae> inline
323  void saveValue(T const & t)
324  {
325  std::stringstream ss; ss.precision( std::numeric_limits<long double>::max_digits10 );
326  ss << t;
327  saveValue( ss.str() );
328  }
329 
331 
343  void writeName()
344  {
345  NodeType const & nodeType = itsNodeStack.top();
346 
347  // Start up either an object or an array, depending on state
348  if(nodeType == NodeType::StartArray)
349  {
350  itsWriter.StartArray();
352  }
353  else if(nodeType == NodeType::StartObject)
354  {
356  itsWriter.StartObject();
357  }
358 
359  // Array types do not output names
360  if(nodeType == NodeType::InArray) return;
361 
362  if(itsNextName == nullptr)
363  {
364  std::string name = "value" + std::to_string( itsNameCounter.top()++ ) + "\0";
365  saveValue(name);
366  }
367  else
368  {
370  itsNextName = nullptr;
371  }
372  }
373 
375  void makeArray()
376  {
378  }
379 
381 
382  private:
385  char const * itsNextName;
386  std::stack<uint32_t> itsNameCounter;
387  std::stack<NodeType> itsNodeStack;
388  }; // JSONOutputArchive
389 
390  // ######################################################################
392 
428  class JSONInputArchive : public InputArchive<JSONInputArchive>, public traits::TextArchive
429  {
430  private:
432  typedef CEREAL_RAPIDJSON_NAMESPACE::GenericValue<CEREAL_RAPIDJSON_NAMESPACE::UTF8<>> JSONValue;
433  typedef JSONValue::ConstMemberIterator MemberIterator;
434  typedef JSONValue::ConstValueIterator ValueIterator;
435  typedef CEREAL_RAPIDJSON_NAMESPACE::Document::GenericValue GenericValue;
436 
437  public:
441 
443 
444  JSONInputArchive(std::istream & stream) :
446  itsNextName( nullptr ),
447  itsReadStream(stream)
448  {
449  itsDocument.ParseStream<>(itsReadStream);
450  if (itsDocument.IsArray())
451  itsIteratorStack.emplace_back(itsDocument.Begin(), itsDocument.End());
452  else
453  itsIteratorStack.emplace_back(itsDocument.MemberBegin(), itsDocument.MemberEnd());
454  }
455 
457 
459 
464  void loadBinaryValue( void * data, size_t size, const char * name = nullptr )
465  {
466  itsNextName = name;
467 
468  std::string encoded;
469  loadValue( encoded );
470  auto decoded = base64::decode( encoded );
471 
472  if( size != decoded.size() )
473  throw Exception("Decoded binary data size does not match specified size");
474 
475  std::memcpy( data, decoded.data(), decoded.size() );
476  itsNextName = nullptr;
477  }
478 
479  private:
481 
485 
487 
489  class Iterator
490  {
491  public:
493 
495  itsMemberItBegin(begin), itsMemberItEnd(end), itsIndex(0), itsSize(std::distance(begin, end)), itsType(Member)
496  {
497  if( itsSize == 0 )
498  itsType = Null_;
499  }
500 
502  itsValueItBegin(begin), itsIndex(0), itsSize(std::distance(begin, end)), itsType(Value)
503  {
504  if( itsSize == 0 )
505  itsType = Null_;
506  }
507 
510  {
511  ++itsIndex;
512  return *this;
513  }
514 
516  GenericValue const & value()
517  {
518  if( itsIndex >= itsSize )
519  throw cereal::Exception("No more objects in input");
520 
521  switch(itsType)
522  {
523  case Value : return itsValueItBegin[itsIndex];
524  case Member: return itsMemberItBegin[itsIndex].value;
525  default: throw cereal::Exception("JSONInputArchive internal error: null or empty iterator to object or array!");
526  }
527  }
528 
530  const char * name() const
531  {
533  return itsMemberItBegin[itsIndex].name.GetString();
534  else
535  return nullptr;
536  }
537 
539 
540  inline void search( const char * searchName )
541  {
542  const auto len = std::strlen( searchName );
543  size_t index = 0;
544  for( auto it = itsMemberItBegin; it != itsMemberItEnd; ++it, ++index )
545  {
546  const auto currentName = it->name.GetString();
547  if( ( std::strncmp( searchName, currentName, len ) == 0 ) &&
548  ( std::strlen( currentName ) == len ) )
549  {
550  itsIndex = index;
551  return;
552  }
553  }
554 
555  throw Exception("JSON Parsing failed - provided NVP (" + std::string(searchName) + ") not found");
556  }
557 
558  private:
561  size_t itsIndex, itsSize;
563  };
564 
566 
574  inline void search()
575  {
576  // store pointer to itsNextName locally and reset to nullptr in case search() throws
577  auto localNextName = itsNextName;
578  itsNextName = nullptr;
579 
580  // The name an NVP provided with setNextName()
581  if( localNextName )
582  {
583  // The actual name of the current node
584  auto const actualName = itsIteratorStack.back().name();
585 
586  // Do a search if we don't see a name coming up, or if the names don't match
587  if( !actualName || std::strcmp( localNextName, actualName ) != 0 )
588  itsIteratorStack.back().search( localNextName );
589  }
590  }
591 
592  public:
594 
603  void startNode()
604  {
605  search();
606 
607  if(itsIteratorStack.back().value().IsArray())
608  itsIteratorStack.emplace_back(itsIteratorStack.back().value().Begin(), itsIteratorStack.back().value().End());
609  else
610  itsIteratorStack.emplace_back(itsIteratorStack.back().value().MemberBegin(), itsIteratorStack.back().value().MemberEnd());
611  }
612 
614  void finishNode()
615  {
616  itsIteratorStack.pop_back();
617  ++itsIteratorStack.back();
618  }
619 
621 
622  const char * getNodeName() const
623  {
624  return itsIteratorStack.back().name();
625  }
626 
628  void setNextName( const char * name )
629  {
630  itsNextName = name;
631  }
632 
635  sizeof(T) < sizeof(int64_t)> = traits::sfinae> inline
636  void loadValue(T & val)
637  {
638  search();
639 
640  val = static_cast<T>( itsIteratorStack.back().value().GetInt() );
641  ++itsIteratorStack.back();
642  }
643 
646  sizeof(T) < sizeof(uint64_t),
648  void loadValue(T & val)
649  {
650  search();
651 
652  val = static_cast<T>( itsIteratorStack.back().value().GetUint() );
653  ++itsIteratorStack.back();
654  }
655 
657  void loadValue(bool & val) { search(); val = itsIteratorStack.back().value().GetBool(); ++itsIteratorStack.back(); }
659  void loadValue(int64_t & val) { search(); val = itsIteratorStack.back().value().GetInt64(); ++itsIteratorStack.back(); }
661  void loadValue(uint64_t & val) { search(); val = itsIteratorStack.back().value().GetUint64(); ++itsIteratorStack.back(); }
663  void loadValue(float & val) { search(); val = static_cast<float>(itsIteratorStack.back().value().GetDouble()); ++itsIteratorStack.back(); }
665  void loadValue(double & val) { search(); val = itsIteratorStack.back().value().GetDouble(); ++itsIteratorStack.back(); }
667  void loadValue(std::string & val) { search(); val = itsIteratorStack.back().value().GetString(); ++itsIteratorStack.back(); }
669  void loadValue(std::nullptr_t&) { search(); CEREAL_RAPIDJSON_ASSERT(itsIteratorStack.back().value().IsNull()); ++itsIteratorStack.back(); }
670 
671  template <class T> inline
673  loadValue(T & val) { search(); val = itsIteratorStack.back().value().GetInt64(); ++itsIteratorStack.back(); }
674  template <class T> inline
676  loadValue(T & val) { search(); val = itsIteratorStack.back().value().GetUint64(); ++itsIteratorStack.back(); }
677  // Special cases to handle various flavors of long, which tend to conflict with
678  // the int32_t or int64_t on various compiler/OS combinations. MSVC doesn't need any of this.
679  #ifndef _MSC_VER
680  private:
682  template <class T> inline
683  typename std::enable_if<sizeof(T) == sizeof(std::int32_t) && std::is_signed<T>::value, void>::type
684  loadLong(T & l){ loadValue( reinterpret_cast<std::int32_t&>( l ) ); }
685 
687  template <class T> inline
688  typename std::enable_if<sizeof(T) == sizeof(std::int64_t) && std::is_signed<T>::value, void>::type
689  loadLong(T & l){ loadValue( reinterpret_cast<std::int64_t&>( l ) ); }
690 
692  template <class T> inline
693  typename std::enable_if<sizeof(T) == sizeof(std::uint32_t) && !std::is_signed<T>::value, void>::type
694  loadLong(T & lu){ loadValue( reinterpret_cast<std::uint32_t&>( lu ) ); }
695 
697  template <class T> inline
698  typename std::enable_if<sizeof(T) == sizeof(std::uint64_t) && !std::is_signed<T>::value, void>::type
699  loadLong(T & lu){ loadValue( reinterpret_cast<std::uint64_t&>( lu ) ); }
700 
701  public:
703  template <class T> inline
705  sizeof(T) >= sizeof(std::int64_t) &&
707  loadValue( T & t ){ loadLong(t); }
708 
710  template <class T> inline
712  sizeof(T) >= sizeof(std::uint64_t) &&
714  loadValue( T & t ){ loadLong(t); }
715  #endif // _MSC_VER
716 
717  private:
719  void stringToNumber( std::string const & str, long long & val ) { val = std::stoll( str ); }
721  void stringToNumber( std::string const & str, unsigned long long & val ) { val = std::stoull( str ); }
723  void stringToNumber( std::string const & str, long double & val ) { val = std::stold( str ); }
724 
725  public:
734  (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae>
735  inline void loadValue(T & val)
736  {
737  std::string encoded;
738  loadValue( encoded );
739  stringToNumber( encoded, val );
740  }
741 
743  void loadSize(size_type & size)
744  {
745  if (itsIteratorStack.size() == 1)
746  size = itsDocument.Size();
747  else
748  size = (itsIteratorStack.rbegin() + 1)->value().Size();
749  }
750 
752 
753  private:
754  const char * itsNextName;
756  std::vector<Iterator> itsIteratorStack;
758  };
759 
760  // ######################################################################
761  // JSONArchive prologue and epilogue functions
762  // ######################################################################
763 
764  // ######################################################################
766 
767  template <class T> inline
769  { }
770 
772  template <class T> inline
774  { }
775 
776  // ######################################################################
778 
779  template <class T> inline
781  { }
782 
784 
785  template <class T> inline
787  { }
788 
789  // ######################################################################
791 
792  template <class T> inline
794  { }
795 
797  template <class T> inline
799  { }
800 
801  // ######################################################################
803 
804  template <class T> inline
806  { }
807 
809 
810  template <class T> inline
812  { }
813 
814  // ######################################################################
816 
818  template <class T> inline
819  void prologue( JSONOutputArchive & ar, SizeTag<T> const & )
820  {
821  ar.makeArray();
822  }
823 
825  template <class T> inline
827  { }
828 
829  // ######################################################################
831 
832  template <class T> inline
834  { }
835 
837  template <class T> inline
839  { }
840 
841  // ######################################################################
843 
850  inline void prologue( JSONOutputArchive & ar, T const & )
851  {
852  ar.startNode();
853  }
854 
859  inline void prologue( JSONInputArchive & ar, T const & )
860  {
861  ar.startNode();
862  }
863 
864  // ######################################################################
866 
872  inline void epilogue( JSONOutputArchive & ar, T const & )
873  {
874  ar.finishNode();
875  }
876 
881  inline void epilogue( JSONInputArchive & ar, T const & )
882  {
883  ar.finishNode();
884  }
885 
886  // ######################################################################
888  inline
889  void prologue( JSONOutputArchive & ar, std::nullptr_t const & )
890  {
891  ar.writeName();
892  }
893 
895  inline
896  void prologue( JSONInputArchive &, std::nullptr_t const & )
897  { }
898 
899  // ######################################################################
901  inline
902  void epilogue( JSONOutputArchive &, std::nullptr_t const & )
903  { }
904 
906  inline
907  void epilogue( JSONInputArchive &, std::nullptr_t const & )
908  { }
909 
910  // ######################################################################
913  void prologue( JSONOutputArchive & ar, T const & )
914  {
915  ar.writeName();
916  }
917 
920  void prologue( JSONInputArchive &, T const & )
921  { }
922 
923  // ######################################################################
926  void epilogue( JSONOutputArchive &, T const & )
927  { }
928 
931  void epilogue( JSONInputArchive &, T const & )
932  { }
933 
934  // ######################################################################
936  template<class CharT, class Traits, class Alloc> inline
937  void prologue(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const &)
938  {
939  ar.writeName();
940  }
941 
943  template<class CharT, class Traits, class Alloc> inline
944  void prologue(JSONInputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
945  { }
946 
947  // ######################################################################
949  template<class CharT, class Traits, class Alloc> inline
950  void epilogue(JSONOutputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
951  { }
952 
954  template<class CharT, class Traits, class Alloc> inline
955  void epilogue(JSONInputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
956  { }
957 
958  // ######################################################################
959  // Common JSONArchive serialization functions
960  // ######################################################################
962  template <class T> inline
964  {
965  ar.setNextName( t.name );
966  ar( t.value );
967  }
968 
969  template <class T> inline
971  {
972  ar.setNextName( t.name );
973  ar( t.value );
974  }
975 
977  inline
978  void CEREAL_SAVE_FUNCTION_NAME(JSONOutputArchive & ar, std::nullptr_t const & t)
979  {
980  ar.saveValue( t );
981  }
982 
984  inline
985  void CEREAL_LOAD_FUNCTION_NAME(JSONInputArchive & ar, std::nullptr_t & t)
986  {
987  ar.loadValue( t );
988  }
989 
993  {
994  ar.saveValue( t );
995  }
996 
1000  {
1001  ar.loadValue( t );
1002  }
1003 
1005  template<class CharT, class Traits, class Alloc> inline
1006  void CEREAL_SAVE_FUNCTION_NAME(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
1007  {
1008  ar.saveValue( str );
1009  }
1010 
1012  template<class CharT, class Traits, class Alloc> inline
1013  void CEREAL_LOAD_FUNCTION_NAME(JSONInputArchive & ar, std::basic_string<CharT, Traits, Alloc> & str)
1014  {
1015  ar.loadValue( str );
1016  }
1017 
1018  // ######################################################################
1020  template <class T> inline
1022  {
1023  // nothing to do here, we don't explicitly save the size
1024  }
1025 
1027  template <class T> inline
1029  {
1030  ar.loadSize( st.size );
1031  }
1032 } // namespace cereal
1033 
1034 // register archives for polymorphic support
1037 
1038 // tie input and output archives together
1040 
1041 #endif // CEREAL_ARCHIVES_JSON_HPP_
#define CEREAL_RAPIDJSON_ASSERT(x)
Definition: json.hpp:50
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:25318
Main cereal functionality.
#define CEREAL_REGISTER_ARCHIVE(Archive)
Registers a specific Archive type with cereal.
Definition: cereal.hpp:195
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:585
A wrapper around data that should be serialized after all non-deferred data.
Definition: helpers.hpp:233
The base input archive class.
Definition: cereal.hpp:711
An internal iterator that handles both array and object types.
Definition: json.hpp:490
size_t itsSize
The current index of this iterator.
Definition: json.hpp:561
void search(const char *searchName)
Adjust our position such that we are at the node with the given name.
Definition: json.hpp:540
MemberIterator itsMemberItBegin
Definition: json.hpp:559
MemberIterator itsMemberItEnd
The member iterator (object)
Definition: json.hpp:559
size_t itsIndex
Definition: json.hpp:561
Type
Definition: json.hpp:562
@ Value
Definition: json.hpp:562
@ Null_
Definition: json.hpp:562
@ Member
Definition: json.hpp:562
GenericValue const & value()
Get the value of the current node.
Definition: json.hpp:516
Iterator(MemberIterator begin, MemberIterator end)
Definition: json.hpp:494
enum cereal::JSONInputArchive::Iterator::Type itsType
Whether this holds values (array) or members (objects) or nothing.
const char * name() const
Get the name of the current node, or nullptr if it has no name.
Definition: json.hpp:530
Iterator & operator++()
Advance to the next node.
Definition: json.hpp:509
Iterator()
Definition: json.hpp:492
ValueIterator itsValueItBegin
The value iterator (array)
Definition: json.hpp:560
Iterator(ValueIterator begin, ValueIterator end)
Definition: json.hpp:501
An input archive designed to load data from JSON.
Definition: json.hpp:429
CEREAL_RAPIDJSON_NAMESPACE::Document itsDocument
Rapidjson document.
Definition: json.hpp:757
CEREAL_RAPIDJSON_NAMESPACE::Document::GenericValue GenericValue
Definition: json.hpp:435
void search()
Searches for the expectedName node if it doesn't match the actualName.
Definition: json.hpp:574
~JSONInputArchive() CEREAL_NOEXCEPT=default
JSONInputArchive(std::istream &stream)
Construct, reading from the provided stream.
Definition: json.hpp:444
void stringToNumber(std::string const &str, long double &val)
Convert a string to a long double.
Definition: json.hpp:723
CEREAL_RAPIDJSON_NAMESPACE::GenericValue< CEREAL_RAPIDJSON_NAMESPACE::UTF8<> > JSONValue
Definition: json.hpp:432
::type loadValue(T &t)
Loads a value from the current node - small signed overload.
Definition: json.hpp:714
void loadBinaryValue(void *data, size_t size, const char *name=nullptr)
Loads some binary data, encoded as a base64 string.
Definition: json.hpp:464
void loadSize(size_type &size)
Loads the size for a SizeTag.
Definition: json.hpp:743
JSONValue::ConstMemberIterator MemberIterator
Definition: json.hpp:433
const char * getNodeName() const
Retrieves the current node name.
Definition: json.hpp:622
void stringToNumber(std::string const &str, unsigned long long &val)
Convert a string to an unsigned long long.
Definition: json.hpp:721
JSONValue::ConstValueIterator ValueIterator
Definition: json.hpp:434
void startNode()
Starts a new node, going into its proper iterator.
Definition: json.hpp:603
void loadValue(T &val)
Loads a value from the current node - long double and long long overloads.
Definition: json.hpp:735
void finishNode()
Finishes the most recently started node.
Definition: json.hpp:614
CEREAL_RAPIDJSON_NAMESPACE::IStreamWrapper ReadStream
Definition: json.hpp:431
const char * itsNextName
Next name set by NVP.
Definition: json.hpp:754
void stringToNumber(std::string const &str, long long &val)
Convert a string to a long long.
Definition: json.hpp:719
ReadStream itsReadStream
Rapidjson write stream.
Definition: json.hpp:755
std::vector< Iterator > itsIteratorStack
'Stack' of rapidJSON iterators
Definition: json.hpp:756
void setNextName(const char *name)
Sets the name for the next node created with startNode.
Definition: json.hpp:628
A class containing various advanced options for the JSON archive.
Definition: json.hpp:120
static Options NoIndent()
Default options with no indentation.
Definition: json.hpp:126
Options(int precision=JSONWriter::kDefaultMaxDecimalPlaces, IndentChar indentChar=IndentChar::space, unsigned int indentLength=4)
Specify specific options for the JSONOutputArchive.
Definition: json.hpp:142
unsigned int itsIndentLength
Definition: json.hpp:153
char itsIndentChar
Definition: json.hpp:152
static Options Default()
Default options.
Definition: json.hpp:123
int itsPrecision
Definition: json.hpp:151
IndentChar
The character to use for indenting.
Definition: json.hpp:130
An output archive designed to save data to JSON.
Definition: json.hpp:107
void saveBinaryValue(const void *data, size_t size, const char *name=nullptr)
Saves some binary data, encoded as a base64 string, with an optional name.
Definition: json.hpp:184
std::enable_if<!std::is_same< T, uint64_t >::value &&std::is_same< T, unsigned long long >::value, void >::type saveValue(T val)
Definition: json.hpp:269
void saveValue(bool b)
Saves a bool to the current node.
Definition: json.hpp:246
void finishNode()
Designates the most recently added node as finished.
Definition: json.hpp:212
CEREAL_RAPIDJSON_NAMESPACE::OStreamWrapper WriteStream
Definition: json.hpp:110
void setNextName(const char *name)
Sets the name for the next node created with startNode.
Definition: json.hpp:240
CEREAL_RAPIDJSON_NAMESPACE::PrettyWriter< WriteStream > JSONWriter
Definition: json.hpp:111
std::stack< NodeType > itsNodeStack
Definition: json.hpp:387
void writeName()
Write the name of the upcoming node and prepare object/array state.
Definition: json.hpp:343
void makeArray()
Designates that the current node should be output as an array, not an object.
Definition: json.hpp:375
std::stack< uint32_t > itsNameCounter
Counter for creating unique names for unnamed nodes.
Definition: json.hpp:386
void saveValue(int64_t i64)
Saves an int64 to the current node.
Definition: json.hpp:252
void saveValue(T t)
Serialize a long if it would not be caught otherwise.
Definition: json.hpp:304
void saveValue(int i)
Saves an int to the current node.
Definition: json.hpp:248
~JSONOutputArchive() CEREAL_NOEXCEPT
Destructor, flushes the JSON.
Definition: json.hpp:173
void saveValue(std::nullptr_t)
Saves a nullptr to the current node.
Definition: json.hpp:262
JSONOutputArchive(std::ostream &stream, Options const &options=Options::Default())
Construct, outputting to the provided stream.
Definition: json.hpp:160
NodeType
Definition: json.hpp:108
WriteStream itsWriteStream
Rapidjson write stream.
Definition: json.hpp:383
void saveValue(double d)
Saves a double to the current node.
Definition: json.hpp:256
void saveValue(unsigned u)
Saves a uint to the current node.
Definition: json.hpp:250
char const * itsNextName
The next name.
Definition: json.hpp:385
void saveValue(T const &t)
Save exotic arithmetic as strings to current node.
Definition: json.hpp:323
void startNode()
Starts a new node in the JSON output.
Definition: json.hpp:204
void saveValue(char const *s)
Saves a const char * to the current node.
Definition: json.hpp:260
std::enable_if<!std::is_same< T, int64_t >::value &&std::is_same< T, long long >::value, void >::type saveValue(T val)
Definition: json.hpp:266
void saveLong(T lu)
32 bit unsigned long saving to current node
Definition: json.hpp:288
void saveValue(std::string const &s)
Saves a string to the current node.
Definition: json.hpp:258
void saveLong(T l)
32 bit signed long saving to current node
Definition: json.hpp:278
JSONWriter itsWriter
Rapidjson writer.
Definition: json.hpp:384
void saveValue(uint64_t u64)
Saves a uint64 to the current node.
Definition: json.hpp:254
For holding name value pairs.
Definition: helpers.hpp:140
char const * name
Definition: helpers.hpp:167
Type value
Definition: helpers.hpp:168
The base output archive class.
Definition: cereal.hpp:319
A wrapper around size metadata.
Definition: helpers.hpp:313
Type size
Definition: helpers.hpp:326
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2513
uint d
BasicIStreamWrapper< std::istream > IStreamWrapper
Definition: istreamwrapper.h:119
#define CEREAL_NOEXCEPT
Defines the CEREAL_NOEXCEPT macro to use instead of noexcept.
Definition: macros.hpp:130
std::string decode(std::string const &encoded_string)
Definition: base64.hpp:89
std::string encode(unsigned char const *bytes_to_encode, size_t in_len)
Definition: base64.hpp:48
type
The type the bitset is encoded with.
Definition: bitset.hpp:44
in certain simple scenarios. They should probably not be used if maximizing performance is the main o...
Definition: access.hpp:42
void epilogue(JSONOutputArchive &, NameValuePair< T > const &)
Epilogue for NVPs for JSON archives.
Definition: json.hpp:780
std::enable_if< std::is_arithmetic< T >::value, void >::type CEREAL_LOAD_FUNCTION_NAME(BinaryInputArchive &ar, T &t)
Loading for POD types from binary.
Definition: binary.hpp:126
std::enable_if< std::is_arithmetic< T >::value, void >::type CEREAL_SAVE_FUNCTION_NAME(BinaryOutputArchive &ar, T const &t)
Saving for POD types to binary.
Definition: binary.hpp:118
CEREAL_SIZE_TYPE size_type
The size type used by cereal.
Definition: helpers.hpp:61
void prologue(JSONOutputArchive &, NameValuePair< T > const &)
Prologue for NVPs for JSON archives.
Definition: json.hpp:768
Definition: json.hpp:5678
BasicOStreamWrapper< std::ostream > OStreamWrapper
Definition: ostreamwrapper.h:72
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1282
CEREAL_RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:384
signed __int64 int64_t
Definition: stdint.h:135
unsigned int uint32_t
Definition: stdint.h:126
signed int int32_t
Definition: stdint.h:123
unsigned __int64 uint64_t
Definition: stdint.h:136
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:49
Exception(const std::string &what_)
Definition: helpers.hpp:50
An exception thrown when rapidjson fails an internal assertion.
Definition: json.hpp:40
RapidJSONException(const char *what_)
Definition: json.hpp:40
Type traits only struct used to mark an archive as human readable (text based)
Definition: traits.hpp:1321
#define CEREAL_SETUP_ARCHIVE_TRAITS(InputArchive, OutputArchive)
Sets up traits that relate an input archive to an output archive.
Definition: traits.hpp:169
typename detail::EnableIfHelper< Conditions... >::type EnableIf
Provides a way to enable a function if conditions are met.
Definition: traits.hpp:116
static const detail::sfinae sfinae
Used as the default value for EnableIf and DisableIf template parameters.
Definition: traits.hpp:88
Internal misc utilities.
#define const
Definition: zconf.h:233