Riyyi
3 years ago
3 changed files with 179 additions and 0 deletions
@ -0,0 +1,140 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Riyyi |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <cstdint> // uint32_t |
||||||
|
#include <iterator> // prev |
||||||
|
#include <sstream> // ostringstream |
||||||
|
#include <string> |
||||||
|
|
||||||
|
#include "util/json/array.h" |
||||||
|
#include "util/json/lexer.h" |
||||||
|
#include "util/json/object.h" |
||||||
|
#include "util/json/stringify.h" |
||||||
|
|
||||||
|
namespace Json { |
||||||
|
|
||||||
|
Stringify::Stringify(const Value& value, const uint32_t indent, const char indentCharacter) |
||||||
|
: m_value(value) |
||||||
|
, m_indent(indent) |
||||||
|
, m_indentCharacter(indentCharacter) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
Stringify::~Stringify() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
std::string Stringify::dump() |
||||||
|
{ |
||||||
|
return dumpHelper(m_value); |
||||||
|
} |
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
std::string Stringify::dumpHelper(const Value& value, const uint32_t indentLevel) |
||||||
|
{ |
||||||
|
switch (value.type()) { |
||||||
|
case Value::Type::Null: |
||||||
|
return "null"; |
||||||
|
break; |
||||||
|
case Value::Type::Bool: |
||||||
|
return value.asBool() ? "true" : "false"; |
||||||
|
break; |
||||||
|
case Value::Type::Number: { |
||||||
|
std::ostringstream os; |
||||||
|
os << value.asDouble(); |
||||||
|
return os.str(); |
||||||
|
break; |
||||||
|
} |
||||||
|
case Value::Type::String: |
||||||
|
return "\"" + value.asString() + "\""; |
||||||
|
break; |
||||||
|
case Value::Type::Array: |
||||||
|
return dumpArray(value, indentLevel); |
||||||
|
break; |
||||||
|
case Value::Type::Object: |
||||||
|
return dumpObject(value, indentLevel); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
std::string Stringify::dumpArray(const Value& value, const uint32_t indentLevel) |
||||||
|
{ |
||||||
|
std::string result; |
||||||
|
|
||||||
|
// Append [
|
||||||
|
result += "["; |
||||||
|
if (m_indent > 0) { |
||||||
|
result += '\n'; |
||||||
|
} |
||||||
|
|
||||||
|
auto values = value.asArray().values(); |
||||||
|
for (auto it = values.begin(); it != values.end(); ++it) { |
||||||
|
result += std::string(m_indent * (indentLevel + 1), m_indentCharacter); |
||||||
|
result += dumpHelper(*it, indentLevel + 1); |
||||||
|
|
||||||
|
// Add comma, except after the last element
|
||||||
|
if (it != std::prev(values.end(), 1)) { |
||||||
|
result += ","; |
||||||
|
} |
||||||
|
if (m_indent > 0) { |
||||||
|
result += '\n'; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Append indentation
|
||||||
|
result += std::string(m_indent * indentLevel, m_indentCharacter); |
||||||
|
|
||||||
|
// Append ]
|
||||||
|
result += "]"; |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
std::string Stringify::dumpObject(const Value& value, const uint32_t indentLevel) |
||||||
|
{ |
||||||
|
std::string result; |
||||||
|
|
||||||
|
// Append {
|
||||||
|
result += "{"; |
||||||
|
if (m_indent > 0) { |
||||||
|
result += '\n'; |
||||||
|
} |
||||||
|
|
||||||
|
auto members = value.asObject().members(); |
||||||
|
for (auto it = members.begin(); it != members.end(); ++it) { |
||||||
|
result += std::string(m_indent * (indentLevel + 1), m_indentCharacter); |
||||||
|
result += "\"" + it->first + "\":"; |
||||||
|
if (m_indent > 0) { |
||||||
|
result += ' '; |
||||||
|
} |
||||||
|
result += dumpHelper(it->second, indentLevel + 1); |
||||||
|
|
||||||
|
// Add comma, except after the last element
|
||||||
|
if (it != std::prev(members.end(), 1)) { |
||||||
|
result += ","; |
||||||
|
} |
||||||
|
if (m_indent > 0) { |
||||||
|
result += '\n'; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Append indentation
|
||||||
|
result += std::string(m_indent * indentLevel, m_indentCharacter); |
||||||
|
|
||||||
|
// Append }
|
||||||
|
result += "}"; |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace Json
|
@ -0,0 +1,37 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Riyyi |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef JSON_STRINGIFY_H |
||||||
|
#define JSON_STRINGIFY_H |
||||||
|
|
||||||
|
#include <cstdint> // uint32_t |
||||||
|
#include <string> |
||||||
|
|
||||||
|
#include "util/json/value.h" |
||||||
|
|
||||||
|
namespace Json { |
||||||
|
|
||||||
|
class Stringify { |
||||||
|
public: |
||||||
|
Stringify(const Value& value, const uint32_t indent = 0, const char indentCharacter = ' '); |
||||||
|
virtual ~Stringify(); |
||||||
|
|
||||||
|
std::string dump(); |
||||||
|
|
||||||
|
private: |
||||||
|
std::string dumpHelper(const Value& value, const uint32_t indentLevel = 0); |
||||||
|
std::string dumpArray(const Value& value, const uint32_t indentLevel = 0); |
||||||
|
std::string dumpObject(const Value& value, const uint32_t indentLevel = 0); |
||||||
|
|
||||||
|
Value m_value; |
||||||
|
|
||||||
|
uint32_t m_indent { 0 }; |
||||||
|
char m_indentCharacter { ' ' }; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace Json
|
||||||
|
|
||||||
|
#endif // JSON_STRINGIFY_H
|
Loading…
Reference in new issue