#include "archiver.h" #include #include #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" #include "rapidjson/stringbuffer.h" using namespace rapidjson; struct JsonReaderStackItem { enum State { BeforeStart, //!< An object/array is in the stack but it is not yet called by StartObject()/StartArray(). Started, //!< An object/array is called by StartObject()/StartArray(). Closed //!< An array is closed after read all element, but before EndArray(). }; JsonReaderStackItem(const Value* value, State state) : value(value), state(state), index() {} const Value* value; State state; SizeType index; // For array iteration }; typedef std::stack JsonReaderStack; #define DOCUMENT reinterpret_cast(mDocument) #define STACK (reinterpret_cast(mStack)) #define TOP (STACK->top()) #define CURRENT (*TOP.value) JsonReader::JsonReader(const char* json) : mDocument(), mStack(), mError(false) { mDocument = new Document; DOCUMENT->Parse(json); if (DOCUMENT->HasParseError()) mError = true; else { mStack = new JsonReaderStack; STACK->push(JsonReaderStackItem(DOCUMENT, JsonReaderStackItem::BeforeStart)); } } JsonReader::~JsonReader() { delete DOCUMENT; delete STACK; } // Archive concept JsonReader& JsonReader::StartObject() { if (!mError) { if (CURRENT.IsObject() && TOP.state == JsonReaderStackItem::BeforeStart) TOP.state = JsonReaderStackItem::Started; else mError = true; } return *this; } JsonReader& JsonReader::EndObject() { if (!mError) { if (CURRENT.IsObject() && TOP.state == JsonReaderStackItem::Started) Next(); else mError = true; } return *this; } JsonReader& JsonReader::Member(const char* name) { if (!mError) { if (CURRENT.IsObject() && TOP.state == JsonReaderStackItem::Started) { Value::ConstMemberIterator memberItr = CURRENT.FindMember(name); if (memberItr != CURRENT.MemberEnd()) STACK->push(JsonReaderStackItem(&memberItr->value, JsonReaderStackItem::BeforeStart)); else mError = true; } else mError = true; } return *this; } bool JsonReader::HasMember(const char* name) const { if (!mError && CURRENT.IsObject() && TOP.state == JsonReaderStackItem::Started) return CURRENT.HasMember(name); return false; } JsonReader& JsonReader::StartArray(size_t* size) { if (!mError) { if (CURRENT.IsArray() && TOP.state == JsonReaderStackItem::BeforeStart) { TOP.state = JsonReaderStackItem::Started; if (size) *size = CURRENT.Size(); if (!CURRENT.Empty()) { const Value* value = &CURRENT[TOP.index]; STACK->push(JsonReaderStackItem(value, JsonReaderStackItem::BeforeStart)); } else TOP.state = JsonReaderStackItem::Closed; } else mError = true; } return *this; } JsonReader& JsonReader::EndArray() { if (!mError) { if (CURRENT.IsArray() && TOP.state == JsonReaderStackItem::Closed) Next(); else mError = true; } return *this; } JsonReader& JsonReader::operator&(bool& b) { if (!mError) { if (CURRENT.IsBool()) { b = CURRENT.GetBool(); Next(); } else mError = true; } return *this; } JsonReader& JsonReader::operator&(unsigned& u) { if (!mError) { if (CURRENT.IsUint()) { u = CURRENT.GetUint(); Next(); } else mError = true; } return *this; } JsonReader& JsonReader::operator&(int& i) { if (!mError) { if (CURRENT.IsInt()) { i = CURRENT.GetInt(); Next(); } else mError = true; } return *this; } JsonReader& JsonReader::operator&(double& d) { if (!mError) { if (CURRENT.IsNumber()) { d = CURRENT.GetDouble(); Next(); } else mError = true; } return *this; } JsonReader& JsonReader::operator&(std::string& s) { if (!mError) { if (CURRENT.IsString()) { s = CURRENT.GetString(); Next(); } else mError = true; } return *this; } JsonReader& JsonReader::SetNull() { // This function is for JsonWriter only. mError = true; return *this; } void JsonReader::Next() { if (!mError) { assert(!STACK->empty()); STACK->pop(); if (!STACK->empty() && CURRENT.IsArray()) { if (TOP.state == JsonReaderStackItem::Started) { // Otherwise means reading array item pass end if (TOP.index < CURRENT.Size() - 1) { const Value* value = &CURRENT[++TOP.index]; STACK->push(JsonReaderStackItem(value, JsonReaderStackItem::BeforeStart)); } else TOP.state = JsonReaderStackItem::Closed; } else mError = true; } } } #undef DOCUMENT #undef STACK #undef TOP #undef CURRENT //////////////////////////////////////////////////////////////////////////////// // JsonWriter #define WRITER reinterpret_cast*>(mWriter) #define STREAM reinterpret_cast(mStream) JsonWriter::JsonWriter() : mWriter(), mStream() { mStream = new StringBuffer; mWriter = new PrettyWriter(*STREAM); } JsonWriter::~JsonWriter() { delete WRITER; delete STREAM; } const char* JsonWriter::GetString() const { return STREAM->GetString(); } JsonWriter& JsonWriter::StartObject() { WRITER->StartObject(); return *this; } JsonWriter& JsonWriter::EndObject() { WRITER->EndObject(); return *this; } JsonWriter& JsonWriter::Member(const char* name) { WRITER->String(name, static_cast(strlen(name))); return *this; } bool JsonWriter::HasMember(const char*) const { // This function is for JsonReader only. assert(false); return false; } JsonWriter& JsonWriter::StartArray(size_t*) { WRITER->StartArray(); return *this; } JsonWriter& JsonWriter::EndArray() { WRITER->EndArray(); return *this; } JsonWriter& JsonWriter::operator&(bool& b) { WRITER->Bool(b); return *this; } JsonWriter& JsonWriter::operator&(unsigned& u) { WRITER->Uint(u); return *this; } JsonWriter& JsonWriter::operator&(int& i) { WRITER->Int(i); return *this; } JsonWriter& JsonWriter::operator&(double& d) { WRITER->Double(d); return *this; } JsonWriter& JsonWriter::operator&(std::string& s) { WRITER->String(s.c_str(), static_cast(s.size())); return *this; } JsonWriter& JsonWriter::SetNull() { WRITER->Null(); return *this; } #undef STREAM #undef WRITER