mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 09:09:29 +01:00
json: Allow formatting read json back to writer.
This commit is contained in:
1 parent
fb876e78c0
commit
03cc4eab01
2 files changed
+152
-2
No files matched your search
@@ -1,5 +1,6 @@
|
||||
#include <iomanip>
|
||||
#include <cstring>
|
||||
#include "ext/vjson/json.h"
|
||||
#include "json/json_writer.h"
|
||||
|
||||
JsonWriter::JsonWriter(int flags) {
|
||||
@@ -15,6 +16,16 @@ void JsonWriter::begin() {
|
||||
stack_.push_back(StackEntry(DICT));
|
||||
}
|
||||
|
||||
void JsonWriter::beginArray() {
|
||||
str_ << "[";
|
||||
stack_.push_back(StackEntry(ARRAY));
|
||||
}
|
||||
|
||||
void JsonWriter::beginRaw() {
|
||||
// For the uncommon case of writing a value directly, to avoid duplicated code.
|
||||
stack_.push_back(StackEntry(RAW));
|
||||
}
|
||||
|
||||
void JsonWriter::end() {
|
||||
pop();
|
||||
if (pretty_)
|
||||
@@ -41,6 +52,8 @@ const char *JsonWriter::indent() const {
|
||||
}
|
||||
|
||||
const char *JsonWriter::arrayIndent() const {
|
||||
if (!pretty_)
|
||||
return "";
|
||||
int amount = (int)stack_.size() + 1;
|
||||
amount *= 2; // 2-space indent.
|
||||
return stack_.back().first ? indent(amount) : "";
|
||||
@@ -128,6 +141,19 @@ void JsonWriter::writeString(const char *name, const char *value) {
|
||||
stack_.back().first = false;
|
||||
}
|
||||
|
||||
void JsonWriter::writeRaw(const char *value) {
|
||||
str_ << arrayComma() << arrayIndent() << value;
|
||||
stack_.back().first = false;
|
||||
}
|
||||
|
||||
void JsonWriter::writeRaw(const char *name, const char *value) {
|
||||
str_ << comma() << indent() << "\"";
|
||||
writeEscapedString(name);
|
||||
str_ << (pretty_ ? "\": " : "\":");
|
||||
str_ << value;
|
||||
stack_.back().first = false;
|
||||
}
|
||||
|
||||
void JsonWriter::pop() {
|
||||
BlockType type = stack_.back().type;
|
||||
stack_.pop_back();
|
||||
@@ -140,6 +166,8 @@ void JsonWriter::pop() {
|
||||
case DICT:
|
||||
str_ << "}";
|
||||
break;
|
||||
case RAW:
|
||||
break;
|
||||
}
|
||||
if (stack_.size() > 0)
|
||||
stack_.back().first = false;
|
||||
@@ -181,3 +209,109 @@ void JsonWriter::writeEscapedString(const char *str) {
|
||||
str_ << str;
|
||||
}
|
||||
}
|
||||
|
||||
static void json_stringify_object(JsonWriter &writer, const json_value *value);
|
||||
static void json_stringify_array(JsonWriter &writer, const json_value *value);
|
||||
|
||||
std::string json_stringify(const json_value *value) {
|
||||
JsonWriter writer;
|
||||
|
||||
// Handle direct values too, not just objects.
|
||||
switch (value->type) {
|
||||
case JSON_NULL:
|
||||
case JSON_STRING:
|
||||
case JSON_INT:
|
||||
case JSON_FLOAT:
|
||||
case JSON_BOOL:
|
||||
writer.beginRaw();
|
||||
// It's the same as a one entry array without brackets, so reuse.
|
||||
json_stringify_array(writer, value);
|
||||
break;
|
||||
|
||||
case JSON_OBJECT:
|
||||
writer.begin();
|
||||
for (const json_value *it = value->first_child; it; it = it->next_sibling) {
|
||||
json_stringify_object(writer, it);
|
||||
}
|
||||
break;
|
||||
case JSON_ARRAY:
|
||||
writer.beginArray();
|
||||
for (const json_value *it = value->first_child; it; it = it->next_sibling) {
|
||||
json_stringify_array(writer, it);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
writer.end();
|
||||
return writer.str();
|
||||
}
|
||||
|
||||
static void json_stringify_object(JsonWriter &writer, const json_value *value) {
|
||||
switch (value->type) {
|
||||
case JSON_NULL:
|
||||
writer.writeRaw(value->name, "null");
|
||||
break;
|
||||
case JSON_STRING:
|
||||
writer.writeString(value->name, value->string_value);
|
||||
break;
|
||||
case JSON_INT:
|
||||
writer.writeInt(value->name, value->int_value);
|
||||
break;
|
||||
case JSON_FLOAT:
|
||||
writer.writeFloat(value->name, value->float_value);
|
||||
break;
|
||||
case JSON_BOOL:
|
||||
writer.writeBool(value->name, value->int_value != 0);
|
||||
break;
|
||||
|
||||
case JSON_OBJECT:
|
||||
writer.pushDict(value->name);
|
||||
for (const json_value *it = value->first_child; it; it = it->next_sibling) {
|
||||
json_stringify_object(writer, it);
|
||||
}
|
||||
writer.pop();
|
||||
break;
|
||||
case JSON_ARRAY:
|
||||
writer.pushArray(value->name);
|
||||
for (const json_value *it = value->first_child; it; it = it->next_sibling) {
|
||||
json_stringify_array(writer, it);
|
||||
}
|
||||
writer.pop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void json_stringify_array(JsonWriter &writer, const json_value *value) {
|
||||
switch (value->type) {
|
||||
case JSON_NULL:
|
||||
writer.writeRaw("null");
|
||||
break;
|
||||
case JSON_STRING:
|
||||
writer.writeString(value->string_value);
|
||||
break;
|
||||
case JSON_INT:
|
||||
writer.writeInt(value->int_value);
|
||||
break;
|
||||
case JSON_FLOAT:
|
||||
writer.writeFloat(value->float_value);
|
||||
break;
|
||||
case JSON_BOOL:
|
||||
writer.writeBool(value->int_value != 0);
|
||||
break;
|
||||
|
||||
case JSON_OBJECT:
|
||||
writer.begin();
|
||||
for (const json_value *it = value->first_child; it; it = it->next_sibling) {
|
||||
json_stringify_object(writer, it);
|
||||
}
|
||||
writer.pop();
|
||||
break;
|
||||
case JSON_ARRAY:
|
||||
writer.beginArray();
|
||||
for (const json_value *it = value->first_child; it; it = it->next_sibling) {
|
||||
json_stringify_array(writer, it);
|
||||
}
|
||||
writer.pop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,7 @@
|
||||
//
|
||||
// Does not deal with encodings in any way.
|
||||
//
|
||||
// Zero dependencies apart from stdlib.
|
||||
// See json_writer_test.cpp for usage.
|
||||
// Zero dependencies apart from stdlib (if you remove the vhjson usage.)
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -19,6 +18,8 @@ public:
|
||||
JsonWriter(int flags = NORMAL);
|
||||
~JsonWriter();
|
||||
void begin();
|
||||
void beginArray();
|
||||
void beginRaw();
|
||||
void end();
|
||||
void pushDict(const char *name);
|
||||
void pushArray(const char *name);
|
||||
@@ -40,6 +41,17 @@ public:
|
||||
void writeString(const std::string &name, const std::string &value) {
|
||||
writeString(name.c_str(), value.c_str());
|
||||
}
|
||||
void writeRaw(const char *value);
|
||||
void writeRaw(const char *name, const char *value);
|
||||
void writeRaw(const std::string &value) {
|
||||
writeRaw(value.c_str());
|
||||
}
|
||||
void writeRaw(const char *name, const std::string &value) {
|
||||
writeRaw(name, value.c_str());
|
||||
}
|
||||
void writeRaw(const std::string &name, const std::string &value) {
|
||||
writeRaw(name.c_str(), value.c_str());
|
||||
}
|
||||
|
||||
std::string str() const {
|
||||
return str_.str();
|
||||
@@ -61,6 +73,7 @@ private:
|
||||
enum BlockType {
|
||||
ARRAY,
|
||||
DICT,
|
||||
RAW,
|
||||
};
|
||||
struct StackEntry {
|
||||
StackEntry(BlockType t) : type(t), first(true) {}
|
||||
@@ -71,3 +84,6 @@ private:
|
||||
std::ostringstream str_;
|
||||
bool pretty_;
|
||||
};
|
||||
|
||||
struct json_value;
|
||||
std::string json_stringify(const json_value *json);
|
||||
Reference in new issue
Block a user