diff options
author | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /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.h | 294 |
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); + } + }; +} |