Browse Source

Util: Add a JSON stringifier

master
Riyyi 2 years ago
parent
commit
aad95de5fd
  1. 140
      src/util/json/stringify.cpp
  2. 37
      src/util/json/stringify.h
  3. 2
      src/util/json/value.h

140
src/util/json/stringify.cpp

@ -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

37
src/util/json/stringify.h

@ -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

2
src/util/json/value.h

@ -44,6 +44,8 @@ public:
Value operator[](size_t index);
Value operator[](const std::string& key);
Type type() const { return m_type; }
bool asBool() const { return m_value.asBool; }
double asDouble() const { return m_value.asDouble; }
const std::string& asString() const { return *m_value.asString; }

Loading…
Cancel
Save