v1.4.4
This commit is contained in:
commit
9c94d113d3
10260 changed files with 1237388 additions and 0 deletions
168
source/core/StarJsonBuilder.cpp
Normal file
168
source/core/StarJsonBuilder.cpp
Normal file
|
@ -0,0 +1,168 @@
|
|||
#include "StarJsonBuilder.hpp"
|
||||
#include "StarLexicalCast.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
void JsonBuilderStream::beginObject() {
|
||||
pushSentry();
|
||||
}
|
||||
|
||||
void JsonBuilderStream::objectKey(char32_t const* s, size_t len) {
|
||||
push(Json(s, len));
|
||||
}
|
||||
|
||||
void JsonBuilderStream::endObject() {
|
||||
JsonObject object;
|
||||
while (true) {
|
||||
if (isSentry()) {
|
||||
set(Json(move(object)));
|
||||
return;
|
||||
} else {
|
||||
Json v = pop();
|
||||
String k = pop().toString();
|
||||
if (!object.insert(k, move(v)).second)
|
||||
throw JsonParsingException(strf("Json object contains a duplicate entry for key '%s'", k));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JsonBuilderStream::beginArray() {
|
||||
pushSentry();
|
||||
}
|
||||
|
||||
void JsonBuilderStream::endArray() {
|
||||
JsonArray array;
|
||||
while (true) {
|
||||
if (isSentry()) {
|
||||
array.reverse();
|
||||
set(Json(move(array)));
|
||||
return;
|
||||
} else {
|
||||
array.append(pop());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JsonBuilderStream::putString(char32_t const* s, size_t len) {
|
||||
push(Json(s, len));
|
||||
}
|
||||
|
||||
void JsonBuilderStream::putDouble(char32_t const* s, size_t len) {
|
||||
push(Json(lexicalCast<double>(String(s, len))));
|
||||
}
|
||||
|
||||
void JsonBuilderStream::putInteger(char32_t const* s, size_t len) {
|
||||
push(Json(lexicalCast<long long>(String(s, len))));
|
||||
}
|
||||
|
||||
void JsonBuilderStream::putBoolean(bool b) {
|
||||
push(Json(b));
|
||||
}
|
||||
|
||||
void JsonBuilderStream::putNull() {
|
||||
push(Json());
|
||||
}
|
||||
|
||||
void JsonBuilderStream::putWhitespace(char32_t const*, size_t) {}
|
||||
|
||||
void JsonBuilderStream::putColon() {}
|
||||
|
||||
void JsonBuilderStream::putComma() {}
|
||||
|
||||
size_t JsonBuilderStream::stackSize() {
|
||||
return m_stack.size();
|
||||
}
|
||||
|
||||
Json JsonBuilderStream::takeTop() {
|
||||
if (m_stack.size())
|
||||
return m_stack.takeLast().take();
|
||||
else
|
||||
return Json();
|
||||
}
|
||||
|
||||
void JsonBuilderStream::push(Json v) {
|
||||
m_stack.append(move(v));
|
||||
}
|
||||
|
||||
Json JsonBuilderStream::pop() {
|
||||
return m_stack.takeLast().take();
|
||||
}
|
||||
|
||||
void JsonBuilderStream::set(Json v) {
|
||||
m_stack.last() = move(v);
|
||||
}
|
||||
|
||||
void JsonBuilderStream::pushSentry() {
|
||||
m_stack.append({});
|
||||
}
|
||||
|
||||
bool JsonBuilderStream::isSentry() {
|
||||
return !m_stack.empty() && !m_stack.last();
|
||||
}
|
||||
|
||||
void JsonStreamer<Json>::toJsonStream(Json const& val, JsonStream& stream, bool sort) {
|
||||
Json::Type type = val.type();
|
||||
if (type == Json::Type::Null) {
|
||||
stream.putNull();
|
||||
} else if (type == Json::Type::Float) {
|
||||
auto d = String(toString(val.toDouble())).wideString();
|
||||
stream.putDouble(d.c_str(), d.length());
|
||||
} else if (type == Json::Type::Bool) {
|
||||
stream.putBoolean(val.toBool());
|
||||
} else if (type == Json::Type::Int) {
|
||||
auto i = String(toString(val.toInt())).wideString();
|
||||
stream.putInteger(i.c_str(), i.length());
|
||||
} else if (type == Json::Type::String) {
|
||||
auto ws = val.toString().wideString();
|
||||
stream.putString(ws.c_str(), ws.length());
|
||||
} else if (type == Json::Type::Array) {
|
||||
stream.beginArray();
|
||||
bool first = true;
|
||||
for (auto const& elem : val.iterateArray()) {
|
||||
if (!first)
|
||||
stream.putComma();
|
||||
first = false;
|
||||
toJsonStream(elem, stream, sort);
|
||||
}
|
||||
stream.endArray();
|
||||
} else if (type == Json::Type::Object) {
|
||||
stream.beginObject();
|
||||
List<String::Char> chars;
|
||||
if (sort) {
|
||||
auto objectPtr = val.objectPtr();
|
||||
List<JsonObject::const_iterator> iterators;
|
||||
iterators.reserve(objectPtr->size());
|
||||
for (auto i = objectPtr->begin(); i != objectPtr->end(); ++i)
|
||||
iterators.append(i);
|
||||
iterators.sort([](JsonObject::const_iterator a, JsonObject::const_iterator b) {
|
||||
return a->first < b->first;
|
||||
});
|
||||
bool first = true;
|
||||
for (auto const& i : iterators) {
|
||||
if (!first)
|
||||
stream.putComma();
|
||||
first = false;
|
||||
chars.clear();
|
||||
for (auto const& c : i->first)
|
||||
chars.push_back(c);
|
||||
stream.objectKey(chars.ptr(), chars.size());
|
||||
stream.putColon();
|
||||
toJsonStream(i->second, stream, sort);
|
||||
}
|
||||
} else {
|
||||
bool first = true;
|
||||
for (auto const& pair : val.iterateObject()) {
|
||||
if (!first)
|
||||
stream.putComma();
|
||||
first = false;
|
||||
auto ws = pair.first.wideString();
|
||||
stream.objectKey(ws.c_str(), ws.length());
|
||||
stream.putColon();
|
||||
toJsonStream(pair.second, stream, sort);
|
||||
}
|
||||
}
|
||||
stream.endObject();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue