json_value.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #pragma once
  2. #include <library/cpp/json/common/defs.h>
  3. #include <util/generic/string.h>
  4. #include <util/generic/hash.h>
  5. #include <util/generic/vector.h>
  6. #include <util/generic/deque.h>
  7. #include <util/generic/utility.h>
  8. #include <util/generic/yexception.h>
  9. namespace NJson {
  10. enum EJsonValueType {
  11. JSON_UNDEFINED /* "Undefined" */,
  12. JSON_NULL /* "Null" */,
  13. JSON_BOOLEAN /* "Boolean" */,
  14. JSON_INTEGER /* "Integer" */,
  15. JSON_DOUBLE /* "Double" */,
  16. JSON_STRING /* "String" */,
  17. JSON_MAP /* "Map" */,
  18. JSON_ARRAY /* "Array" */,
  19. JSON_UINTEGER /* "UInteger" */
  20. };
  21. class TJsonValue;
  22. class IScanCallback {
  23. public:
  24. virtual ~IScanCallback() = default;
  25. virtual bool Do(const TString& path, TJsonValue* parent, TJsonValue& value) = 0;
  26. };
  27. class TJsonValue {
  28. void Clear() noexcept;
  29. public:
  30. typedef THashMap<TString, TJsonValue> TMapType;
  31. typedef TDeque<TJsonValue> TArray;
  32. TJsonValue() noexcept = default;
  33. TJsonValue(EJsonValueType type);
  34. TJsonValue(bool value) noexcept;
  35. TJsonValue(int value) noexcept;
  36. TJsonValue(unsigned int value) noexcept;
  37. TJsonValue(long value) noexcept;
  38. TJsonValue(unsigned long value) noexcept;
  39. TJsonValue(long long value) noexcept;
  40. TJsonValue(unsigned long long value) noexcept;
  41. TJsonValue(double value) noexcept;
  42. TJsonValue(TString value);
  43. TJsonValue(const char* value);
  44. template <class T>
  45. TJsonValue(const T*) = delete;
  46. TJsonValue(TStringBuf value);
  47. TJsonValue(const std::string& s)
  48. : TJsonValue(TStringBuf(s))
  49. {
  50. }
  51. TJsonValue(const TJsonValue& vval);
  52. TJsonValue(TJsonValue&& vval) noexcept;
  53. TJsonValue& operator=(const TJsonValue& val);
  54. TJsonValue& operator=(TJsonValue&& val) noexcept;
  55. ~TJsonValue() {
  56. Clear();
  57. }
  58. EJsonValueType GetType() const noexcept;
  59. TJsonValue& SetType(EJsonValueType type);
  60. TJsonValue& SetValue(const TJsonValue& value);
  61. TJsonValue& SetValue(TJsonValue&& value);
  62. // for Map
  63. TJsonValue& InsertValue(const TString& key, const TJsonValue& value);
  64. TJsonValue& InsertValue(TStringBuf key, const TJsonValue& value);
  65. TJsonValue& InsertValue(const char* key, const TJsonValue& value);
  66. TJsonValue& InsertValue(const TString& key, TJsonValue&& value);
  67. TJsonValue& InsertValue(TStringBuf key, TJsonValue&& value);
  68. TJsonValue& InsertValue(const char* key, TJsonValue&& value);
  69. // for Array
  70. TJsonValue& AppendValue(const TJsonValue& value);
  71. TJsonValue& AppendValue(TJsonValue&& value);
  72. TJsonValue& Back();
  73. const TJsonValue& Back() const;
  74. bool GetValueByPath(TStringBuf path, TJsonValue& result, char delimiter = '.') const;
  75. bool SetValueByPath(TStringBuf path, const TJsonValue& value, char delimiter = '.');
  76. bool SetValueByPath(TStringBuf path, TJsonValue&& value, char delimiter = '.');
  77. // returns NULL on failure
  78. const TJsonValue* GetValueByPath(TStringBuf path, char delimiter = '.') const noexcept;
  79. TJsonValue* GetValueByPath(TStringBuf path, char delimiter = '.') noexcept;
  80. void EraseValue(TStringBuf key);
  81. void EraseValue(size_t index);
  82. TJsonValue& operator[](size_t idx);
  83. TJsonValue& operator[](const TStringBuf& key);
  84. const TJsonValue& operator[](size_t idx) const noexcept;
  85. const TJsonValue& operator[](const TStringBuf& key) const noexcept;
  86. bool GetBoolean() const;
  87. long long GetInteger() const;
  88. unsigned long long GetUInteger() const;
  89. double GetDouble() const;
  90. const TString& GetString() const;
  91. const TMapType& GetMap() const;
  92. const TArray& GetArray() const;
  93. //throwing TJsonException possible
  94. bool GetBooleanSafe() const;
  95. long long GetIntegerSafe() const;
  96. unsigned long long GetUIntegerSafe() const;
  97. double GetDoubleSafe() const;
  98. const TString& GetStringSafe() const;
  99. const TMapType& GetMapSafe() const;
  100. TMapType& GetMapSafe();
  101. const TArray& GetArraySafe() const;
  102. TArray& GetArraySafe();
  103. bool GetBooleanSafe(bool defaultValue) const;
  104. long long GetIntegerSafe(long long defaultValue) const;
  105. unsigned long long GetUIntegerSafe(unsigned long long defaultValue) const;
  106. double GetDoubleSafe(double defaultValue) const;
  107. TString GetStringSafe(const TString& defaultValue) const;
  108. bool GetBooleanRobust() const noexcept;
  109. long long GetIntegerRobust() const noexcept;
  110. unsigned long long GetUIntegerRobust() const noexcept;
  111. double GetDoubleRobust() const noexcept;
  112. TString GetStringRobust() const;
  113. // Exception-free accessors
  114. bool GetBoolean(bool* value) const noexcept;
  115. bool GetInteger(long long* value) const noexcept;
  116. bool GetUInteger(unsigned long long* value) const noexcept;
  117. bool GetDouble(double* value) const noexcept;
  118. bool GetMapPointer(const TMapType** value) const noexcept;
  119. bool GetArrayPointer(const TArray** value) const noexcept;
  120. bool GetString(TString* value) const;
  121. bool GetMap(TMapType* value) const;
  122. bool GetArray(TArray* value) const;
  123. bool GetValue(size_t index, TJsonValue* value) const;
  124. bool GetValue(TStringBuf key, TJsonValue* value) const;
  125. bool GetValuePointer(size_t index, const TJsonValue** value) const noexcept;
  126. bool GetValuePointer(TStringBuf key, const TJsonValue** value) const noexcept;
  127. bool GetValuePointer(TStringBuf key, TJsonValue** value) noexcept;
  128. // Checking for defined non-null value
  129. bool IsDefined() const noexcept {
  130. return Type != JSON_UNDEFINED && Type != JSON_NULL;
  131. }
  132. bool IsNull() const noexcept;
  133. bool IsBoolean() const noexcept;
  134. bool IsDouble() const noexcept;
  135. bool IsString() const noexcept;
  136. bool IsMap() const noexcept;
  137. bool IsArray() const noexcept;
  138. /// @return true if JSON_INTEGER or (JSON_UINTEGER and Value <= Max<long long>)
  139. bool IsInteger() const noexcept;
  140. /// @return true if JSON_UINTEGER or (JSON_INTEGER and Value >= 0)
  141. bool IsUInteger() const noexcept;
  142. bool Has(const TStringBuf& key) const noexcept;
  143. bool Has(size_t key) const noexcept;
  144. void Scan(IScanCallback& callback);
  145. /// Non-robust comparison.
  146. bool operator==(const TJsonValue& rhs) const;
  147. void Swap(TJsonValue& rhs) noexcept;
  148. // save using util/ysaveload.h serialization (not to JSON stream)
  149. void Save(IOutputStream* s) const;
  150. // load using util/ysaveload.h serialization (not as JSON stream)
  151. void Load(IInputStream* s);
  152. static const TJsonValue UNDEFINED;
  153. private:
  154. EJsonValueType Type = JSON_UNDEFINED;
  155. union TValueUnion {
  156. bool Boolean;
  157. long long Integer;
  158. unsigned long long UInteger;
  159. double Double;
  160. TString String;
  161. TMapType* Map;
  162. TArray* Array;
  163. TValueUnion() noexcept {
  164. Zero(*this);
  165. }
  166. ~TValueUnion() noexcept {
  167. }
  168. };
  169. TValueUnion Value;
  170. void DoScan(const TString& path, TJsonValue* parent, IScanCallback& callback);
  171. void SwapWithUndefined(TJsonValue& output) noexcept;
  172. /**
  173. @throw yexception if Back shouldn't be called on the object.
  174. */
  175. void BackChecks() const;
  176. };
  177. inline bool GetBoolean(const TJsonValue& jv, size_t index, bool* value) noexcept {
  178. return jv[index].GetBoolean(value);
  179. }
  180. inline bool GetInteger(const TJsonValue& jv, size_t index, long long* value) noexcept {
  181. return jv[index].GetInteger(value);
  182. }
  183. inline bool GetUInteger(const TJsonValue& jv, size_t index, unsigned long long* value) noexcept {
  184. return jv[index].GetUInteger(value);
  185. }
  186. inline bool GetDouble(const TJsonValue& jv, size_t index, double* value) noexcept {
  187. return jv[index].GetDouble(value);
  188. }
  189. inline bool GetString(const TJsonValue& jv, size_t index, TString* value) {
  190. return jv[index].GetString(value);
  191. }
  192. bool GetMapPointer(const TJsonValue& jv, size_t index, const TJsonValue::TMapType** value);
  193. bool GetArrayPointer(const TJsonValue& jv, size_t index, const TJsonValue::TArray** value);
  194. inline bool GetBoolean(const TJsonValue& jv, TStringBuf key, bool* value) noexcept {
  195. return jv[key].GetBoolean(value);
  196. }
  197. inline bool GetInteger(const TJsonValue& jv, TStringBuf key, long long* value) noexcept {
  198. return jv[key].GetInteger(value);
  199. }
  200. inline bool GetUInteger(const TJsonValue& jv, TStringBuf key, unsigned long long* value) noexcept {
  201. return jv[key].GetUInteger(value);
  202. }
  203. inline bool GetDouble(const TJsonValue& jv, TStringBuf key, double* value) noexcept {
  204. return jv[key].GetDouble(value);
  205. }
  206. inline bool GetString(const TJsonValue& jv, TStringBuf key, TString* value) {
  207. return jv[key].GetString(value);
  208. }
  209. bool GetMapPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TMapType** value);
  210. bool GetArrayPointer(const TJsonValue& jv, const TStringBuf key, const TJsonValue::TArray** value);
  211. class TJsonMap: public TJsonValue {
  212. public:
  213. TJsonMap()
  214. : TJsonValue(NJson::JSON_MAP)
  215. {}
  216. TJsonMap(const std::initializer_list<std::pair<TString, TJsonValue>>& list)
  217. : TJsonValue(NJson::JSON_MAP)
  218. {
  219. GetMapSafe() = THashMap<TString, TJsonValue>(list);
  220. }
  221. };
  222. class TJsonArray: public TJsonValue {
  223. public:
  224. TJsonArray()
  225. : TJsonValue(NJson::JSON_ARRAY)
  226. {}
  227. TJsonArray(const std::initializer_list<TJsonValue>& list)
  228. : TJsonValue(NJson::JSON_ARRAY)
  229. {
  230. GetArraySafe() = TJsonValue::TArray(list);
  231. }
  232. };
  233. }