Browse Source

Util: Add more ways of accessing and creating Json::Value objects

master
Riyyi 3 years ago
parent
commit
8bfae9b483
  1. 19
      src/util/json/array.h
  2. 12
      src/util/json/object.h
  3. 58
      src/util/json/value.cpp
  4. 14
      src/util/json/value.h

19
src/util/json/array.h

@ -7,6 +7,7 @@
#ifndef JSON_ARRAY_H #ifndef JSON_ARRAY_H
#define JSON_ARRAY_H #define JSON_ARRAY_H
#include <initializer_list>
#include <utility> // move #include <utility> // move
#include <vector> #include <vector>
@ -19,6 +20,10 @@ public:
Array() {} Array() {}
virtual ~Array() {} virtual ~Array() {}
Array(const std::initializer_list<Value>& values)
: m_values(values)
{}
Array(const Array& other) Array(const Array& other)
: m_values(other.m_values) : m_values(other.m_values)
{ {
@ -29,6 +34,19 @@ public:
m_values.emplace_back(std::move(value)); m_values.emplace_back(std::move(value));
} }
Value& at(size_t index)
{
if (index + 1 > m_values.size()) {
m_values.resize(index + 1);
}
return m_values.at(index);
}
Value& operator[](size_t index) { return at(index); }
const Value& at(size_t index) const { return m_values.at(index); }
const Value& operator[](size_t index) const { return m_values.at(index); }
size_t size() const { return m_values.size(); }
const std::vector<Value>& values() const { return m_values; } const std::vector<Value>& values() const { return m_values; }
private: private:
@ -37,5 +55,4 @@ private:
} // namespace Json } // namespace Json
#endif // JSON_ARRAY_H #endif // JSON_ARRAY_H

12
src/util/json/object.h

@ -30,6 +30,18 @@ public:
m_members.emplace(key, std::move(value)); m_members.emplace(key, std::move(value));
} }
Value& at(const std::string& key)
{
if (m_members.find(key) == m_members.end()) {
emplace(key, {});
}
return m_members.at(key);
}
Value& operator[](const std::string& key) { return at(key); }
const Value& at(const std::string& key) const { return m_members.at(key); }
const Value& operator[](const std::string& key) const { return m_members.at(key); }
const std::map<std::string, Value>& members() const { return m_members; } const std::map<std::string, Value>& members() const { return m_members; }
private: private:

58
src/util/json/value.cpp

@ -4,6 +4,7 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#include <algorithm> // all_of
#include <cassert> // assert #include <cassert> // assert
#include <cstdint> // uint32_t #include <cstdint> // uint32_t
#include <iostream> #include <iostream>
@ -38,6 +39,12 @@ Value::Value(bool value)
m_value.asBool = value; m_value.asBool = value;
} }
Value::Value(int value)
: m_type(Type::Number)
{
m_value.asDouble = value;
}
Value::Value(double value) Value::Value(double value)
: m_type(Type::Number) : m_type(Type::Number)
{ {
@ -68,7 +75,29 @@ Value::Value(const Object& value)
m_value.asObject = new Object(value); m_value.asObject = new Object(value);
} }
Value Value::operator[](size_t index) Value::Value(const std::initializer_list<Value>& values)
{
bool isObject = std::all_of(values.begin(), values.end(), [](const Value& value) {
return value.type() == Type::Array
&& value.m_value.asArray->size() == 2
&& value[0].m_type == Type::String;
});
if (!isObject) {
m_type = Type::Array;
m_value.asArray = new Array(values);
}
else {
m_type = Type::Object;
m_value.asObject = new Object;
for (auto& value : values) {
m_value.asObject->emplace(std::move(*value[0].m_value.asString),
std::move(value[1]));
}
}
}
// ------------------------------------------ // ------------------------------------------
Value Value::parse(const std::string& input) Value Value::parse(const std::string& input)
@ -87,15 +116,36 @@ std::string Value::dump(const uint32_t indent, const char indentCharacter) const
return stringify.dump(); return stringify.dump();
} }
// ------------------------------------------
Value& Value::operator[](size_t index)
{
assert(m_type == Type::Array);
return m_value.asArray->at(index);
}
Value& Value::operator[](const std::string& key)
{
// Implicit conversion to an object
if (m_type == Type::Null) {
m_type = Type::Object;
m_value.asObject = new Object;
}
assert(m_type == Type::Object);
return m_value.asObject->at(key);
}
const Value& Value::operator[](size_t index) const
{ {
assert(m_type == Type::Array); assert(m_type == Type::Array);
return m_value.asArray->values().at(index); return m_value.asArray->at(index);
} }
Value Value::operator[](const std::string& key) const Value& Value::operator[](const std::string& key) const
{ {
assert(m_type == Type::Object); assert(m_type == Type::Object);
return m_value.asObject->members().at(key); return m_value.asObject->at(key);
} }
// ------------------------------------------ // ------------------------------------------

14
src/util/json/value.h

@ -7,7 +7,9 @@
#ifndef JSON_VALUE_H #ifndef JSON_VALUE_H
#define JSON_VALUE_H #define JSON_VALUE_H
#include <cstddef> // nullptr_t
#include <cstdint> // uint32_t #include <cstdint> // uint32_t
#include <initializer_list>
#include <iostream> // istream, ostream #include <iostream> // istream, ostream
#include <string> #include <string>
@ -36,20 +38,28 @@ public:
Value& operator=(const Value& other); Value& operator=(const Value& other);
Value(bool value); Value(bool value);
Value(int value);
Value(double value); Value(double value);
Value(const char* value); Value(const char* value);
Value(const std::string& value); Value(const std::string& value);
Value(const Array& value); Value(const Array& value);
Value(const Object& value); Value(const Object& value);
Value(const std::initializer_list<Value>& values);
// ------------------------------------------ // ------------------------------------------
static Value parse(const std::string& input); static Value parse(const std::string& input);
std::string dump(const uint32_t indent = 0, const char indentCharacter = ' ') const; std::string dump(const uint32_t indent = 0, const char indentCharacter = ' ') const;
// ------------------------------------------
// Array index operator // Array index operator
Value operator[](size_t index); Value& operator[](size_t index);
Value operator[](const std::string& key); Value& operator[](const std::string& key);
const Value& operator[](size_t index) const;
const Value& operator[](const std::string& key) const;
// ------------------------------------------
Type type() const { return m_type; } Type type() const { return m_type; }

Loading…
Cancel
Save