Skip to content

Commit

Permalink
Merge f2a28ee into 87d4e07
Browse files Browse the repository at this point in the history
  • Loading branch information
miloyip committed Dec 13, 2017
2 parents 87d4e07 + f2a28ee commit 9435a31
Show file tree
Hide file tree
Showing 4 changed files with 714 additions and 0 deletions.
2 changes: 2 additions & 0 deletions example/CMakeLists.txt
Expand Up @@ -32,6 +32,8 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif()

add_executable(archivertest archiver/archiver.cpp archiver/archivertest.cpp)

foreach (example ${EXAMPLES})
add_executable(${example} ${example}/${example}.cpp)
endforeach()
Expand Down
292 changes: 292 additions & 0 deletions example/archiver/archiver.cpp
@@ -0,0 +1,292 @@
#include "archiver.h"
#include <cassert>
#include <stack>
#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<JsonReaderStackItem> JsonReaderStack;

#define DOCUMENT reinterpret_cast<Document*>(mDocument)
#define STACK (reinterpret_cast<JsonReaderStack*>(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<PrettyWriter<StringBuffer>*>(mWriter)
#define STREAM reinterpret_cast<StringBuffer*>(mStream)

JsonWriter::JsonWriter() : mWriter(), mStream() {
mStream = new StringBuffer;
mWriter = new PrettyWriter<StringBuffer>(*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<SizeType>(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<SizeType>(s.size()));
return *this;
}

JsonWriter& JsonWriter::SetNull() {
WRITER->Null();
return *this;
}

#undef STREAM
#undef WRITER

0 comments on commit 9435a31

Please sign in to comment.