mirror of
https://github.com/USCiLab/cereal.git
synced 2025-10-18 01:45:52 +02:00
Basic single level JSON reading works
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include <cereal/external/rapidjson/prettywriter.h>
|
||||
#include <cereal/external/rapidjson/genericstream.h>
|
||||
#include <cereal/external/rapidjson/reader.h>
|
||||
#include <cereal/external/rapidjson/document.h>
|
||||
#include <cereal/external/base64.hpp>
|
||||
|
||||
#include <sstream>
|
||||
@@ -74,16 +75,16 @@ namespace cereal
|
||||
itsWriter.EndObject();
|
||||
}
|
||||
|
||||
void saveValue(bool b) { itsWriter.Bool(b); }
|
||||
void saveValue(int i) { itsWriter.Int(i); }
|
||||
void saveValue(unsigned u) { itsWriter.Uint(u); }
|
||||
void saveValue(int64_t i64) { itsWriter.Int64(i64); }
|
||||
void saveValue(uint64_t u64) { itsWriter.Uint64(u64); }
|
||||
void saveValue(double d) { itsWriter.Double(d); }
|
||||
void saveValue(std::string const & s) { rawString(s); }
|
||||
void saveValue(char const * s) { itsWriter.String(s); }
|
||||
void saveNull() { itsWriter.Null(); }
|
||||
void saveValue(bool b) { itsWriter.Bool(b); }
|
||||
void saveValue(int i) { itsWriter.Int(i); }
|
||||
void saveValue(unsigned u) { itsWriter.Uint(u); }
|
||||
void saveValue(int64_t i64) { itsWriter.Int64(i64); }
|
||||
void saveValue(uint64_t u64) { itsWriter.Uint64(u64); }
|
||||
void saveValue(double d) { itsWriter.Double(d); }
|
||||
void saveValue(std::string const & s) { itsWriter.String(s.c_str(), s.size()); }
|
||||
void saveValue(char const * s) { itsWriter.String(s); }
|
||||
|
||||
//! Write the name of the upcoming node
|
||||
void writeName()
|
||||
{
|
||||
if(itsNextName == nullptr)
|
||||
@@ -98,11 +99,6 @@ namespace cereal
|
||||
}
|
||||
}
|
||||
|
||||
void rawString(std::string const & s)
|
||||
{
|
||||
itsWriter.String(s.c_str(), s.size());
|
||||
}
|
||||
|
||||
//! Creates a new node that is a child of the node at the top of the stack
|
||||
/*! Nodes will be given a name that has either been pre-set by a name value pair,
|
||||
or generated based upon a counter unique to the parent node.
|
||||
@@ -163,47 +159,107 @@ namespace cereal
|
||||
\ingroup Archives */
|
||||
class JSONInputArchive : public InputArchive<JSONInputArchive>
|
||||
{
|
||||
//typedef rapidjson::GenericWriteStream WriteStream;
|
||||
//typedef rapidjson::PrettyWriter<WriteStream> JSONWriter;
|
||||
typedef rapidjson::GenericReadStream ReadStream;
|
||||
typedef rapidjson::GenericValue<rapidjson::UTF8<>> JSONValue;
|
||||
typedef JSONValue::ConstMemberIterator JSONIterator;
|
||||
|
||||
public:
|
||||
//! Construct, outputting to the provided stream
|
||||
/*! @param stream The stream to output to. Can be a stringstream, a file stream, or
|
||||
even cout! */
|
||||
JSONInputArchive(std::istream & ) :
|
||||
InputArchive<JSONInputArchive>(this)
|
||||
JSONInputArchive(std::istream & is) :
|
||||
InputArchive<JSONInputArchive>(this),
|
||||
itsReadStream(is)
|
||||
{
|
||||
itsDocument.ParseStream<0>(itsReadStream);
|
||||
itsValueStack.push(itsDocument.MemberBegin());
|
||||
}
|
||||
|
||||
void setNextName(char const * name)
|
||||
{
|
||||
itsNextName = name;
|
||||
}
|
||||
|
||||
void startNode()
|
||||
{
|
||||
itsValueStack.push(itsValueStack.top()->value.MemberBegin());
|
||||
}
|
||||
|
||||
void finishNode()
|
||||
{
|
||||
itsValueStack.pop();
|
||||
++itsValueStack.top();
|
||||
}
|
||||
|
||||
void loadValue(bool & val) { val = itsValueStack.top()->value.GetBool(); ++itsValueStack.top(); }
|
||||
void loadValue(int & val) { val = itsValueStack.top()->value.GetInt(); ++itsValueStack.top(); }
|
||||
void loadValue(unsigned & val) { val = itsValueStack.top()->value.GetUint(); ++itsValueStack.top(); }
|
||||
void loadValue(int64_t & val) { val = itsValueStack.top()->value.GetInt64(); ++itsValueStack.top(); }
|
||||
void loadValue(uint64_t & val) { val = itsValueStack.top()->value.GetUint64(); ++itsValueStack.top(); }
|
||||
void loadValue(double & val) { val = itsValueStack.top()->value.GetDouble(); ++itsValueStack.top(); }
|
||||
void loadValue(std::string & val) { val = itsValueStack.top()->value.GetString(); ++itsValueStack.top(); }
|
||||
|
||||
private:
|
||||
char const * itsNextName;
|
||||
ReadStream itsReadStream; //!< Rapidjson write stream
|
||||
std::stack<JSONIterator> itsValueStack; //!< Stack of values
|
||||
rapidjson::Document itsDocument; //!< Rapidjson document
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
// JSONArchive prologue and epilogue functions
|
||||
// ######################################################################
|
||||
|
||||
// ######################################################################
|
||||
//! Prologue for NVPs for JSON archives
|
||||
/*! NVPs do not start or finish nodes - they just set up the names */
|
||||
template <class T>
|
||||
void prologue( JSONOutputArchive &, NameValuePair<T> const & )
|
||||
{ }
|
||||
|
||||
//! Prologue for NVPs for JSON archives
|
||||
template <class T>
|
||||
void prologue( JSONInputArchive &, NameValuePair<T> const & )
|
||||
{ }
|
||||
|
||||
// ######################################################################
|
||||
//! Epilogue for NVPs for JSON archives
|
||||
/*! NVPs do not start or finish nodes - they just set up the names */
|
||||
template <class T>
|
||||
void epilogue( JSONOutputArchive &, NameValuePair<T> const & )
|
||||
{ }
|
||||
|
||||
//! Epilogue for NVPs for JSON archives
|
||||
/*! NVPs do not start or finish nodes - they just set up the names */
|
||||
template <class T>
|
||||
void epilogue( JSONInputArchive &, NameValuePair<T> const & )
|
||||
{ }
|
||||
|
||||
// ######################################################################
|
||||
//! Prologue for SizeTags for JSON archives
|
||||
/*! SizeTags are strictly ignored for JSON */
|
||||
template <class T>
|
||||
void prologue( JSONOutputArchive &, SizeTag<T> const & )
|
||||
{ }
|
||||
|
||||
//! Prologue for SizeTags for JSON archives
|
||||
template <class T>
|
||||
void prologue( JSONInputArchive &, SizeTag<T> const & )
|
||||
{ }
|
||||
|
||||
// ######################################################################
|
||||
//! Epilogue for SizeTags for JSON archives
|
||||
/*! SizeTags are strictly ignored for JSON */
|
||||
template <class T>
|
||||
void epilogue( JSONOutputArchive &, SizeTag<T> const & )
|
||||
{ }
|
||||
|
||||
//! Epilogue for SizeTags for JSON archives
|
||||
template <class T>
|
||||
void epilogue( JSONInputArchive &, SizeTag<T> const & )
|
||||
{ }
|
||||
|
||||
// ######################################################################
|
||||
//! Prologue for all other types for JSON archives
|
||||
/*! Starts a new node, named either automatically or by some NVP,
|
||||
that may be given data by the type about to be archived */
|
||||
@@ -214,6 +270,15 @@ namespace cereal
|
||||
ar.startNode();
|
||||
}
|
||||
|
||||
//! Prologue for all other types for JSON archives
|
||||
template <class T>
|
||||
typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
|
||||
prologue( JSONInputArchive & ar, T const & data )
|
||||
{
|
||||
ar.startNode();
|
||||
}
|
||||
|
||||
// ######################################################################
|
||||
//! Epilogue for all other types other for JSON archives
|
||||
/*! Finishes the node created in the prologue */
|
||||
template <class T>
|
||||
@@ -223,6 +288,16 @@ namespace cereal
|
||||
ar.finishNode();
|
||||
}
|
||||
|
||||
//! Epilogue for all other types other for JSON archives
|
||||
template <class T>
|
||||
typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
|
||||
epilogue( JSONInputArchive & ar, T const & data )
|
||||
{
|
||||
ar.finishNode();
|
||||
}
|
||||
|
||||
// ######################################################################
|
||||
//! Prologue for arithmetic types for JSON archives
|
||||
template <class T>
|
||||
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
prologue( JSONOutputArchive & ar, T const & data )
|
||||
@@ -230,23 +305,52 @@ namespace cereal
|
||||
ar.writeName();
|
||||
}
|
||||
|
||||
//! Prologue for arithmetic types for JSON archives
|
||||
template <class T>
|
||||
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
epilogue( JSONOutputArchive & ar, T const & data )
|
||||
prologue( JSONInputArchive & ar, T const & data )
|
||||
{
|
||||
}
|
||||
|
||||
// ######################################################################
|
||||
//! Epilogue for arithmetic types for JSON archives
|
||||
template <class T>
|
||||
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
epilogue( JSONOutputArchive & ar, T const & data )
|
||||
{ }
|
||||
|
||||
//! Epilogue for arithmetic types for JSON archives
|
||||
template <class T>
|
||||
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
epilogue( JSONInputArchive & ar, T const & data )
|
||||
{ }
|
||||
|
||||
// ######################################################################
|
||||
//! Prologue for strings for JSON archives
|
||||
template<class CharT, class Traits, class Alloc> inline
|
||||
void prologue(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
|
||||
{
|
||||
ar.writeName();
|
||||
}
|
||||
|
||||
//! Prologue for strings for JSON archives
|
||||
template<class CharT, class Traits, class Alloc> inline
|
||||
void epilogue(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
|
||||
void prologue(JSONInputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ######################################################################
|
||||
//! Epilogue for strings for JSON archives
|
||||
template<class CharT, class Traits, class Alloc> inline
|
||||
void epilogue(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
|
||||
{ }
|
||||
|
||||
//! Epilogue for strings for JSON archives
|
||||
template<class CharT, class Traits, class Alloc> inline
|
||||
void epilogue(JSONInputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
|
||||
{ }
|
||||
|
||||
// ######################################################################
|
||||
// Common JSONArchive serialization functions
|
||||
// ######################################################################
|
||||
@@ -274,6 +378,14 @@ namespace cereal
|
||||
ar.saveValue( t );
|
||||
}
|
||||
|
||||
//! Loading arithmetic from JSON
|
||||
template<class T> inline
|
||||
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
load(JSONInputArchive & ar, T & t)
|
||||
{
|
||||
ar.loadValue( t );
|
||||
}
|
||||
|
||||
//! saving string to JSON
|
||||
template<class CharT, class Traits, class Alloc> inline
|
||||
void save(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
|
||||
|
||||
164
sandbox_json.cpp
164
sandbox_json.cpp
@@ -37,6 +37,8 @@
|
||||
#include <cereal/types/array.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
|
||||
#include <cereal/external/rapidjson/filestream.h>
|
||||
|
||||
#include <cxxabi.h>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
@@ -44,48 +46,6 @@
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
|
||||
class Base
|
||||
{
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template <class Archive>
|
||||
void serialize( Archive & ar )
|
||||
{
|
||||
std::cout << "Base serialize" << std::endl;
|
||||
ar( x );
|
||||
}
|
||||
|
||||
int x;
|
||||
};
|
||||
|
||||
class Derived : public Base
|
||||
{
|
||||
public:
|
||||
template <class Archive>
|
||||
void save( Archive & ar ) const
|
||||
{
|
||||
ar( cereal::virtual_base_class<Base>(this) );
|
||||
std::cout << "Derived save" << std::endl;
|
||||
ar( y );
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void load( Archive & ar )
|
||||
{
|
||||
ar( cereal::virtual_base_class<Base>(this) );
|
||||
std::cout << "Derived load" << std::endl;
|
||||
ar( y );
|
||||
}
|
||||
|
||||
int y;
|
||||
};
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
template <class Archive> struct specialize<Archive, Derived, cereal::specialization::member_load_save> {};
|
||||
//template <class Archive> struct specialize<Archive, Derived, cereal::specialization::non_member_load_save> {};
|
||||
}
|
||||
|
||||
// ###################################
|
||||
struct Test1
|
||||
{
|
||||
@@ -209,52 +169,6 @@ struct Everything
|
||||
}
|
||||
};
|
||||
|
||||
struct EmptyStruct
|
||||
{
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar)
|
||||
{
|
||||
std::cout << "Side effects!" << std::endl;
|
||||
};
|
||||
};
|
||||
|
||||
struct NonEmptyStruct
|
||||
{
|
||||
int x, y, z;
|
||||
};
|
||||
|
||||
struct NoDefaultCtor
|
||||
{
|
||||
NoDefaultCtor() = delete;
|
||||
NoDefaultCtor(int x) : y(x)
|
||||
{ }
|
||||
|
||||
int y;
|
||||
|
||||
template <class Archive>
|
||||
void serialize( Archive & archive )
|
||||
{
|
||||
}
|
||||
|
||||
//template <class Archive>
|
||||
//static NoDefaultCtor * load_and_allocate( Archive & ar )
|
||||
//{
|
||||
// return new NoDefaultCtor(5);
|
||||
//}
|
||||
};
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
template <>
|
||||
struct LoadAndAllocate<NoDefaultCtor>
|
||||
{
|
||||
template <class Archive>
|
||||
static NoDefaultCtor * load_and_allocate( Archive & ar )
|
||||
{
|
||||
return new NoDefaultCtor(5);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct SubFixture
|
||||
{
|
||||
@@ -302,53 +216,57 @@ struct Fixture
|
||||
}
|
||||
};
|
||||
|
||||
void foo(int t)
|
||||
{
|
||||
std::cout << "int" << std::endl;
|
||||
}
|
||||
|
||||
void foo(unsigned int t)
|
||||
{
|
||||
std::cout << "unsigned int" << std::endl;
|
||||
}
|
||||
|
||||
// ######################################################################
|
||||
int main()
|
||||
{
|
||||
std::cout << std::boolalpha << std::endl;
|
||||
|
||||
{
|
||||
cereal::JSONOutputArchive oar( std::cout );
|
||||
std::ofstream os("file.json");
|
||||
cereal::JSONOutputArchive oar( os );
|
||||
|
||||
Fixture fixture;
|
||||
oar( CEREAL_NVP(fixture) );
|
||||
|
||||
std::vector<double> vecD = {1.23, 4.56, 7,89};
|
||||
oar( CEREAL_NVP(vecD) );
|
||||
|
||||
bool b = true;
|
||||
oar( cereal::make_nvp("coolean boolean", b) );
|
||||
|
||||
std::shared_ptr<std::string> sPtr = std::make_shared<std::string>("i'm a shared pointer");
|
||||
oar( CEREAL_NVP(sPtr) );
|
||||
|
||||
int xxx[] = {-1, 95, 3};
|
||||
oar.saveBinaryValue( xxx, sizeof(int)*3, "xxxbinary" );
|
||||
oar.saveBinaryValue( xxx, sizeof(int)*3 );
|
||||
int x = 10;
|
||||
double y = 99;
|
||||
oar(CEREAL_NVP(x));
|
||||
oar(CEREAL_NVP(y));
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
{
|
||||
cereal::JSONInputArchive iar( std::cin );
|
||||
|
||||
Fixture fixture; fixture.change();
|
||||
//iar( fixture );
|
||||
|
||||
std::vector<double> vecD;
|
||||
//iar( vecD );
|
||||
std::ifstream is("file.json");
|
||||
std::string str((std::istreambuf_iterator<char>(is)), std::istreambuf_iterator<char>());
|
||||
std::cout << "---------------------" << std::endl << str << std::endl << "---------------------" << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
std::ifstream is("file.json");
|
||||
cereal::JSONInputArchive iar( is );
|
||||
|
||||
int x;
|
||||
double y;
|
||||
iar(CEREAL_NVP(x));
|
||||
iar(CEREAL_NVP(y));
|
||||
|
||||
std::cout << x << " " << y << std::endl;
|
||||
}
|
||||
|
||||
//{
|
||||
// std::ifstream is("file.json");
|
||||
// rapidjson::GenericReadStream itsReadStream(is);
|
||||
// rapidjson::Document itsDocument;
|
||||
// itsDocument.ParseStream<0>(itsReadStream);
|
||||
//
|
||||
// //FILE * f = std::fopen("file.json", "r");
|
||||
// //rapidjson::FileStream filestream(f);
|
||||
// //rapidjson::Document itsDocument;
|
||||
// //itsDocument.ParseStream<0>(filestream);
|
||||
|
||||
// std::cout << itsDocument.IsObject() << std::endl;
|
||||
// std::cout << itsDocument.HasMember("x") << std::endl;
|
||||
|
||||
// auto it = itsDocument.MemberBegin();
|
||||
// std::cout << it->name.GetString() << std::endl;
|
||||
// it->value.GetInt();
|
||||
//}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user