summaryrefslogtreecommitdiffstats
path: root/library/cpp/json/writer/json_value.h
diff options
context:
space:
mode:
authorDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/json/writer/json_value.h
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/json/writer/json_value.h')
-rw-r--r--library/cpp/json/writer/json_value.h294
1 files changed, 294 insertions, 0 deletions
diff --git a/library/cpp/json/writer/json_value.h b/library/cpp/json/writer/json_value.h
new file mode 100644
index 00000000000..3f0f50bc4c8
--- /dev/null
+++ b/library/cpp/json/writer/json_value.h
@@ -0,0 +1,294 @@
+#pragma once
+
+#include <library/cpp/json/common/defs.h>
+
+#include <util/generic/string.h>
+#include <util/generic/hash.h>
+#include <util/generic/vector.h>
+#include <util/generic/deque.h>
+#include <util/generic/utility.h>
+#include <util/generic/yexception.h>
+
+namespace NJson {
+ enum EJsonValueType {
+ JSON_UNDEFINED /* "Undefined" */,
+ JSON_NULL /* "Null" */,
+ JSON_BOOLEAN /* "Boolean" */,
+ JSON_INTEGER /* "Integer" */,
+ JSON_DOUBLE /* "Double" */,
+ JSON_STRING /* "String" */,
+ JSON_MAP /* "Map" */,
+ JSON_ARRAY /* "Array" */,
+ JSON_UINTEGER /* "UInteger" */
+ };
+
+ class TJsonValue;
+
+ class IScanCallback {
+ public:
+ virtual ~IScanCallback() = default;
+
+ virtual bool Do(const TString& path, TJsonValue* parent, TJsonValue& value) = 0;
+ };
+
+ class TJsonValue {
+ void Clear() noexcept;
+
+ public:
+ typedef THashMap<TString, TJsonValue> TMapType;
+ typedef TDeque<TJsonValue> TArray;
+
+ TJsonValue() noexcept = default;
+ TJsonValue(EJsonValueType type);
+ TJsonValue(bool value) noexcept;
+ TJsonValue(int value) noexcept;
+ TJsonValue(unsigned int value) noexcept;
+ TJsonValue(long value) noexcept;
+ TJsonValue(unsigned long value) noexcept;
+ TJsonValue(long long value) noexcept;
+ TJsonValue(unsigned long long value) noexcept;
+ TJsonValue(double value) noexcept;
+ TJsonValue(TString value);
+ TJsonValue(const char* value);
+ template <class T>
+ TJsonValue(const T*) = delete;
+ TJsonValue(TStringBuf value);
+
+ TJsonValue(const std::string& s)
+ : TJsonValue(TStringBuf(s))
+ {
+ }
+
+ TJsonValue(const TJsonValue& vval);
+ TJsonValue(TJsonValue&& vval) noexcept;
+
+ TJsonValue& operator=(const TJsonValue& val);
+ TJsonValue& operator=(TJsonValue&& val) noexcept;
+
+ ~TJsonValue() {
+ Clear();
+ }
+
+ EJsonValueType GetType() const noexcept;
+ TJsonValue& SetType(EJsonValueType type);
+
+ TJsonValue& SetValue(const TJsonValue& value);
+ TJsonValue& SetValue(TJsonValue&& value);
+
+ // for Map
+ TJsonValue& InsertValue(const TString& key, const TJsonValue& value);
+ TJsonValue& InsertValue(TStringBuf key, const TJsonValue& value);
+ TJsonValue& InsertValue(const char* key, const TJsonValue& value);
+ TJsonValue& InsertValue(const TString& key, TJsonValue&& value);
+ TJsonValue& InsertValue(TStringBuf key, TJsonValue&& value);
+ TJsonValue& InsertValue(const char* key, TJsonValue&& value);
+
+ // for Array
+ TJsonValue& AppendValue(const TJsonValue& value);
+ TJsonValue& AppendValue(TJsonValue&& value);
+ TJsonValue& Back();
+ const TJsonValue& Back() const;
+
+ bool GetValueByPath(TStringBuf path, TJsonValue& result, char delimiter = '.') const;
+ bool SetValueByPath(TStringBuf path, const TJsonValue& value, char delimiter = '.');
+ bool SetValueByPath(TStringBuf path, TJsonValue&& value, char delimiter = '.');
+
+ // returns NULL on failure
+ const TJsonValue* GetValueByPath(TStringBuf path, char delimiter = '.') const noexcept;
+ TJsonValue* GetValueByPath(TStringBuf path, char delimiter = '.') noexcept;
+
+ void EraseValue(TStringBuf key);
+ void EraseValue(size_t index);
+
+ TJsonValue& operator[](size_t idx);
+ TJsonValue& operator[](const TStringBuf& key);
+ const TJsonValue& operator[](size_t idx) const noexcept;
+ const TJsonValue& operator[](const TStringBuf& key) const noexcept;
+
+ bool GetBoolean() const;
+ long long GetInteger() const;
+ unsigned long long GetUInteger() const;
+ double GetDouble() const;
+ const TString& GetString() const;
+ const TMapType& GetMap() const;
+ const TArray& GetArray() const;
+
+ //throwing TJsonException possible
+ bool GetBooleanSafe() const;
+ long long GetIntegerSafe() const;
+ unsigned long long GetUIntegerSafe() const;
+ double GetDoubleSafe() const;
+ const TString& GetStringSafe() const;
+ const TMapType& GetMapSafe() const;
+ TMapType& GetMapSafe();
+ const TArray& GetArraySafe() const;
+ TArray& GetArraySafe();
+
+ bool GetBooleanSafe(bool defaultValue) const;
+ long long GetIntegerSafe(long long defaultValue) const;
+ unsigned long long GetUIntegerSafe(unsigned long long defaultValue) const;
+ double GetDoubleSafe(double defaultValue) const;
+ TString GetStringSafe(const TString& defaultValue) const;
+
+ bool GetBooleanRobust() const noexcept;
+ long long GetIntegerRobust() const noexcept;
+ unsigned long long GetUIntegerRobust() const noexcept;
+ double GetDoubleRobust() const noexcept;
+ TString GetStringRobust() const;
+
+ // Exception-free accessors
+ bool GetBoolean(bool* value) const noexcept;
+ bool GetInteger(long long* value) const noexcept;
+ bool GetUInteger(unsigned long long* value) const noexcept;
+ bool GetDouble(double* value) const noexcept;
+ bool GetMapPointer(const TMapType** value) const noexcept;
+ bool GetArrayPointer(const TArray** value) const noexcept;
+
+ bool GetString(TString* value) const;
+ bool GetMap(TMapType* value) const;
+ bool GetArray(TArray* value) const;
+ bool GetValue(size_t index, TJsonValue* value) const;
+ bool GetValue(TStringBuf key, TJsonValue* value) const;
+ bool GetValuePointer(size_t index, const TJsonValue** value) const noexcept;
+ bool GetValuePointer(TStringBuf key, const TJsonValue** value) const noexcept;
+ bool GetValuePointer(TStringBuf key, TJsonValue** value) noexcept;
+
+ // Checking for defined non-null value
+ bool IsDefined() const noexcept {
+ return Type != JSON_UNDEFINED && Type != JSON_NULL;
+ }
+
+ bool IsNull() const noexcept;
+ bool IsBoolean() const noexcept;
+ bool IsDouble() const noexcept;
+ bool IsString() const noexcept;
+ bool IsMap() const noexcept;
+ bool IsArray() const noexcept;
+
+ /// @return true if JSON_INTEGER or (JSON_UINTEGER and Value <= Max<long long>)
+ bool IsInteger() const noexcept;
+
+ /// @return true if JSON_UINTEGER or (JSON_INTEGER and Value >= 0)
+ bool IsUInteger() const noexcept;
+
+ bool Has(const TStringBuf& key) const noexcept;
+ bool Has(size_t key) const noexcept;
+
+ void Scan(IScanCallback& callback);
+
+ /// Non-robust comparison.
+ bool operator==(const TJsonValue& rhs) const;
+
+ bool operator!=(const TJsonValue& rhs) const {
+ return !(*this == rhs);
+ }
+
+ void Swap(TJsonValue& rhs) noexcept;
+
+ // save using util/ysaveload.h serialization (not to JSON stream)
+ void Save(IOutputStream* s) const;
+
+ // load using util/ysaveload.h serialization (not as JSON stream)
+ void Load(IInputStream* s);
+
+ static const TJsonValue UNDEFINED;
+
+ private:
+ EJsonValueType Type = JSON_UNDEFINED;
+ union TValueUnion {
+ bool Boolean;
+ long long Integer;
+ unsigned long long UInteger;
+ double Double;
+ TString String;
+ TMapType* Map;
+ TArray* Array;
+
+ TValueUnion() noexcept {
+ Zero(*this);
+ }
+ ~TValueUnion() noexcept {
+ }
+ };
+ TValueUnion Value;
+ void DoScan(const TString& path, TJsonValue* parent, IScanCallback& callback);
+ void SwapWithUndefined(TJsonValue& output) noexcept;
+
+ /**
+ @throw yexception if Back shouldn't be called on the object.
+ */
+ void BackChecks() const;
+ };
+
+ inline bool GetBoolean(const TJsonValue& jv, size_t index, bool* value) noexcept {
+ return jv[index].GetBoolean(value);
+ }
+
+ inline bool GetInteger(const TJsonValue& jv, size_t index, long long* value) noexcept {
+ return jv[index].GetInteger(value);
+ }
+
+ inline bool GetUInteger(const TJsonValue& jv, size_t index, unsigned long long* value) noexcept {
+ return jv[index].GetUInteger(value);
+ }
+
+ inline bool GetDouble(const TJsonValue& jv, size_t index, double* value) noexcept {
+ return jv[index].GetDouble(value);
+ }
+
+ inline bool GetString(const TJsonValue& jv, size_t index, TString* value) {
+ return jv[index].GetString(value);
+ }
+
+ bool GetMapPointer(const TJsonValue& jv, size_t index, const TJsonValue::TMapType** value);
+ bool GetArrayPointer(const TJsonValue& jv, size_t index, const TJsonValue::TArray** value);
+
+ inline bool GetBoolean(const TJsonValue& jv, TStringBuf key, bool* value) noexcept {
+ return jv[key].GetBoolean(value);
+ }
+
+ inline bool GetInteger(const TJsonValue& jv, TStringBuf key, long long* value) noexcept {
+ return jv[key].GetInteger(value);
+ }
+
+ inline bool GetUInteger(const TJsonValue& jv, TStringBuf key, unsigned long long* value) noexcept {
+ return jv[key].GetUInteger(value);
+ }
+
+ inline bool GetDouble(const TJsonValue& jv, TStringBuf key, double* value) noexcept {
+ return jv[key].GetDouble(value);
+ }
+
+ inline bool GetString(const TJsonValue& jv, TStringBuf key, TString* value) {
+ return jv[key].GetString(value);
+ }
+
+ bool GetMapPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TMapType** value);
+ bool GetArrayPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TArray** value);
+
+ class TJsonMap: public TJsonValue {
+ public:
+ TJsonMap()
+ : TJsonValue(NJson::JSON_MAP)
+ {}
+
+ TJsonMap(const std::initializer_list<std::pair<TString, TJsonValue>>& list)
+ : TJsonValue(NJson::JSON_MAP)
+ {
+ GetMapSafe() = THashMap<TString, TJsonValue>(list);
+ }
+ };
+
+ class TJsonArray: public TJsonValue {
+ public:
+ TJsonArray()
+ : TJsonValue(NJson::JSON_ARRAY)
+ {}
+
+ TJsonArray(const std::initializer_list<TJsonValue>& list)
+ : TJsonValue(NJson::JSON_ARRAY)
+ {
+ GetArraySafe() = TJsonValue::TArray(list);
+ }
+ };
+}