diff --git a/include/cereal/archives/json.hpp b/include/cereal/archives/json.hpp index 973de86e..fc3852e6 100644 --- a/include/cereal/archives/json.hpp +++ b/include/cereal/archives/json.hpp @@ -158,6 +158,8 @@ namespace cereal { if (itsNodeStack.top() == NodeType::InObject) itsWriter.EndObject(); + else if (itsNodeStack.top() == NodeType::InArray) + itsWriter.EndArray(); } //! Saves some binary data, encoded as a base64 string, with an optional name @@ -223,7 +225,7 @@ namespace cereal } //! Saves a bool to the current node - void saveValue(bool b) { itsWriter.Bool_(b); } + void saveValue(bool b) { itsWriter.Bool_(b); } //! Saves an int to the current node void saveValue(int i) { itsWriter.Int(i); } //! Saves a uint to the current node @@ -238,6 +240,8 @@ namespace cereal void saveValue(std::string const & s) { itsWriter.String(s.c_str(), static_cast( s.size() )); } //! Saves a const char * to the current node void saveValue(char const * s) { itsWriter.String(s); } + //! Saves a nullptr to the current node + void saveValue(std::nullptr_t) { itsWriter.Null_(); } private: // Some compilers/OS have difficulty disambiguating the above for various flavors of longs, so we provide @@ -416,7 +420,10 @@ namespace cereal itsReadStream(stream) { itsDocument.ParseStream<0>(itsReadStream); - itsIteratorStack.emplace_back(itsDocument.MemberBegin(), itsDocument.MemberEnd()); + if (itsDocument.IsArray()) + itsIteratorStack.emplace_back(itsDocument.Begin(), itsDocument.End()); + else + itsIteratorStack.emplace_back(itsDocument.MemberBegin(), itsDocument.MemberEnd()); } //! Loads some binary data, encoded as a base64 string @@ -607,9 +614,9 @@ namespace cereal } //! Loads a value from the current node - bool overload - void loadValue(bool & val) { search(); val = itsIteratorStack.back().value().GetBool_(); ++itsIteratorStack.back(); } + void loadValue(bool & val) { search(); val = itsIteratorStack.back().value().GetBool_(); ++itsIteratorStack.back(); } //! Loads a value from the current node - int64 overload - void loadValue(int64_t & val) { search(); val = itsIteratorStack.back().value().GetInt64(); ++itsIteratorStack.back(); } + void loadValue(int64_t & val) { search(); val = itsIteratorStack.back().value().GetInt64(); ++itsIteratorStack.back(); } //! Loads a value from the current node - uint64 overload void loadValue(uint64_t & val) { search(); val = itsIteratorStack.back().value().GetUint64(); ++itsIteratorStack.back(); } //! Loads a value from the current node - float overload @@ -618,6 +625,8 @@ namespace cereal void loadValue(double & val) { search(); val = itsIteratorStack.back().value().GetDouble(); ++itsIteratorStack.back(); } //! Loads a value from the current node - string overload void loadValue(std::string & val) { search(); val = itsIteratorStack.back().value().GetString(); ++itsIteratorStack.back(); } + //! Loads a nullptr from the current node + void loadValue(std::nullptr_t&) { search(); RAPIDJSON_ASSERT(itsIteratorStack.back().value().IsNull_()); ++itsIteratorStack.back(); } // Special cases to handle various flavors of long, which tend to conflict with // the int32_t or int64_t on various compiler/OS combinations. MSVC doesn't need any of this. @@ -642,7 +651,7 @@ namespace cereal template inline typename std::enable_if::value, void>::type loadLong(T & lu){ loadValue( reinterpret_cast( lu ) ); } - + public: //! Serialize a long if it would not be caught otherwise template inline @@ -685,7 +694,10 @@ namespace cereal //! Loads the size for a SizeTag void loadSize(size_type & size) { - size = (itsIteratorStack.rbegin() + 1)->value().Size(); + if (itsIteratorStack.size() == 1) + size = itsDocument.Size(); + else + size = (itsIteratorStack.rbegin() + 1)->value().Size(); } //! @} @@ -798,6 +810,30 @@ namespace cereal ar.finishNode(); } + // ###################################################################### + //! Prologue for arithmetic types for JSON archives + inline + void prologue( JSONOutputArchive & ar, std::nullptr_t const & ) + { + ar.writeName(); + } + + //! Prologue for arithmetic types for JSON archives + inline + void prologue( JSONInputArchive &, std::nullptr_t const & ) + { } + + // ###################################################################### + //! Epilogue for arithmetic types for JSON archives + inline + void epilogue( JSONOutputArchive &, std::nullptr_t const & ) + { } + + //! Epilogue for arithmetic types for JSON archives + inline + void epilogue( JSONInputArchive &, std::nullptr_t const & ) + { } + // ###################################################################### //! Prologue for arithmetic types for JSON archives template ::value> = traits::sfinae> inline @@ -864,6 +900,20 @@ namespace cereal ar( t.value ); } + //! Saving for nullptr to JSON + inline + void CEREAL_SAVE_FUNCTION_NAME(JSONOutputArchive & ar, std::nullptr_t const & t) + { + ar.saveValue( t ); + } + + //! Loading arithmetic from JSON + inline + void CEREAL_LOAD_FUNCTION_NAME(JSONInputArchive & ar, std::nullptr_t & t) + { + ar.loadValue( t ); + } + //! Saving for arithmetic to JSON template ::value> = traits::sfinae> inline void CEREAL_SAVE_FUNCTION_NAME(JSONOutputArchive & ar, T const & t)