json.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. #pragma once
  2. #include <vector>
  3. #include <string>
  4. #include <iostream>
  5. #include <sstream>
  6. #include <map>
  7. #include "base/define.h"
  8. #include "base/conversion.h"
  9. /* project version */
  10. #define CJSON_VERSION_MAJOR 1
  11. #define CJSON_VERSION_MINOR 7
  12. #define CJSON_VERSION_PATCH 15
  13. #include <stddef.h>
  14. /* cJSON Types: */
  15. #define cJSON_Invalid (0)
  16. #define cJSON_False (1 << 0)
  17. #define cJSON_True (1 << 1)
  18. #define cJSON_NULL (1 << 2)
  19. #define cJSON_Number (1 << 3)
  20. #define cJSON_String (1 << 4)
  21. #define cJSON_Array (1 << 5)
  22. #define cJSON_Object (1 << 6)
  23. #define cJSON_Raw (1 << 7) /* raw json */
  24. #define cJSON_IsReference 256
  25. #define cJSON_StringIsConst 512
  26. /* The cJSON structure: */
  27. typedef struct cJSON
  28. {
  29. /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
  30. struct cJSON* next;
  31. struct cJSON* prev;
  32. /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
  33. struct cJSON* child;
  34. /* The type of the item, as above. */
  35. int type;
  36. /* The item's string, if type==cJSON_String and type == cJSON_Raw */
  37. char* valuestring;
  38. /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
  39. int valueint;
  40. /* The item's number, if type==cJSON_Number */
  41. double valuedouble;
  42. /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
  43. char* string;
  44. } cJSON;
  45. typedef struct cJSON_Hooks
  46. {
  47. /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
  48. void* (*malloc_fn)(size_t sz);
  49. void (*free_fn)(void* ptr);
  50. } cJSON_Hooks;
  51. typedef int cJSON_bool;
  52. #define CJSON_NESTING_LIMIT 1000
  53. /* Supply malloc, realloc and free functions to cJSON */
  54. void cJSON_InitHooks(cJSON_Hooks* hooks);
  55. /* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
  56. /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
  57. cJSON* cJSON_Parse(const char* value);
  58. cJSON* cJSON_ParseWithLength(const char* value, size_t buffer_length);
  59. /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
  60. /* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
  61. cJSON* cJSON_ParseWithOpts(const char* value, const char** return_parse_end, cJSON_bool require_null_terminated);
  62. cJSON* cJSON_ParseWithLengthOpts(const char* value, size_t buffer_length, const char** return_parse_end, cJSON_bool require_null_terminated);
  63. /* Render a cJSON entity to text for transfer/storage. */
  64. char* cJSON_Print(const cJSON* item);
  65. /* Render a cJSON entity to text for transfer/storage without any formatting. */
  66. char* cJSON_PrintUnformatted(const cJSON* item);
  67. /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
  68. char* cJSON_PrintBuffered(const cJSON* item, int prebuffer, cJSON_bool fmt);
  69. /* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
  70. /* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
  71. cJSON_bool cJSON_PrintPreallocated(cJSON* item, char* buffer, const int length, const cJSON_bool format);
  72. /* Delete a cJSON entity and all subentities. */
  73. void cJSON_Delete(cJSON* item);
  74. /* Returns the number of items in an array (or object). */
  75. int cJSON_GetArraySize(const cJSON* array);
  76. /* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
  77. cJSON* cJSON_GetArrayItem(const cJSON* array, int index);
  78. /* Get item "string" from object. Case insensitive. */
  79. cJSON* cJSON_GetObjectItem(const cJSON* const object, const char* const string);
  80. cJSON* cJSON_GetObjectItemCaseSensitive(const cJSON* const object, const char* const string);
  81. cJSON_bool cJSON_HasObjectItem(const cJSON* object, const char* string);
  82. /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
  83. const char* cJSON_GetErrorPtr(void);
  84. /* Check item type and return its value */
  85. char* cJSON_GetStringValue(const cJSON* const item);
  86. double cJSON_GetNumberValue(const cJSON* const item);
  87. /* These functions check the type of an item */
  88. cJSON_bool cJSON_IsInvalid(const cJSON* const item);
  89. cJSON_bool cJSON_IsFalse(const cJSON* const item);
  90. cJSON_bool cJSON_IsTrue(const cJSON* const item);
  91. cJSON_bool cJSON_IsBool(const cJSON* const item);
  92. cJSON_bool cJSON_IsNull(const cJSON* const item);
  93. cJSON_bool cJSON_IsNumber(const cJSON* const item);
  94. cJSON_bool cJSON_IsString(const cJSON* const item);
  95. cJSON_bool cJSON_IsArray(const cJSON* const item);
  96. cJSON_bool cJSON_IsObject(const cJSON* const item);
  97. cJSON_bool cJSON_IsRaw(const cJSON* const item);
  98. /* These calls create a cJSON item of the appropriate type. */
  99. cJSON* cJSON_CreateNull(void);
  100. cJSON* cJSON_CreateTrue(void);
  101. cJSON* cJSON_CreateFalse(void);
  102. cJSON* cJSON_CreateBool(cJSON_bool boolean);
  103. cJSON* cJSON_CreateNumber(double num);
  104. cJSON* cJSON_CreateString(const char* string);
  105. /* raw json */
  106. cJSON* cJSON_CreateRaw(const char* raw);
  107. cJSON* cJSON_CreateArray(void);
  108. cJSON* cJSON_CreateObject(void);
  109. /* Create a string where valuestring references a string so
  110. * it will not be freed by cJSON_Delete */
  111. cJSON* cJSON_CreateStringReference(const char* string);
  112. /* Create an object/array that only references it's elements so
  113. * they will not be freed by cJSON_Delete */
  114. cJSON* cJSON_CreateObjectReference(const cJSON* child);
  115. cJSON* cJSON_CreateArrayReference(const cJSON* child);
  116. /* These utilities create an Array of count items.
  117. * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
  118. cJSON* cJSON_CreateIntArray(const int* numbers, int count);
  119. cJSON* cJSON_CreateFloatArray(const float* numbers, int count);
  120. cJSON* cJSON_CreateDoubleArray(const double* numbers, int count);
  121. cJSON* cJSON_CreateStringArray(const char* const* strings, int count);
  122. /* Append item to the specified array/object. */
  123. cJSON_bool cJSON_AddItemToArray(cJSON* array, cJSON* item);
  124. cJSON_bool cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item);
  125. /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
  126. * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
  127. * writing to `item->string` */
  128. cJSON_bool cJSON_AddItemToObjectCS(cJSON* object, const char* string, cJSON* item);
  129. /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
  130. cJSON_bool cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item);
  131. cJSON_bool cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item);
  132. /* Remove/Detach items from Arrays/Objects. */
  133. cJSON* cJSON_DetachItemViaPointer(cJSON* parent, cJSON* const item);
  134. cJSON* cJSON_DetachItemFromArray(cJSON* array, int which);
  135. void cJSON_DeleteItemFromArray(cJSON* array, int which);
  136. cJSON* cJSON_DetachItemFromObject(cJSON* object, const char* string);
  137. cJSON* cJSON_DetachItemFromObjectCaseSensitive(cJSON* object, const char* string);
  138. void cJSON_DeleteItemFromObject(cJSON* object, const char* string);
  139. void cJSON_DeleteItemFromObjectCaseSensitive(cJSON* object, const char* string);
  140. /* Update array items. */
  141. cJSON_bool cJSON_InsertItemInArray(cJSON* array, int which, cJSON* newitem); /* Shifts pre-existing items to the right. */
  142. cJSON_bool cJSON_ReplaceItemViaPointer(cJSON* const parent, cJSON* const item, cJSON* replacement);
  143. cJSON_bool cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem);
  144. cJSON_bool cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem);
  145. cJSON_bool cJSON_ReplaceItemInObjectCaseSensitive(cJSON* object, const char* string, cJSON* newitem);
  146. /* Duplicate a cJSON item */
  147. cJSON* cJSON_Duplicate(const cJSON* item, cJSON_bool recurse);
  148. /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
  149. * need to be released. With recurse!=0, it will duplicate any children connected to the item.
  150. * The item->next and ->prev pointers are always zero on return from Duplicate. */
  151. /* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
  152. * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
  153. cJSON_bool cJSON_Compare(const cJSON* const a, const cJSON* const b, const cJSON_bool case_sensitive);
  154. /* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
  155. * The input pointer json cannot point to a read-only address area, such as a string constant,
  156. * but should point to a readable and writable address area. */
  157. void cJSON_Minify(char* json);
  158. /* Helper functions for creating and adding items to an object at the same time.
  159. * They return the added item or NULL on failure. */
  160. cJSON* cJSON_AddNullToObject_(cJSON* const object, const char* const name);
  161. cJSON* cJSON_AddTrueToObject_(cJSON* const object, const char* const name);
  162. cJSON* cJSON_AddFalseToObject_(cJSON* const object, const char* const name);
  163. cJSON* cJSON_AddBoolToObject(cJSON* const object, const char* const name, const cJSON_bool boolean);
  164. cJSON* cJSON_AddNumberToObject_(cJSON* const object, const char* const name, const double number);
  165. cJSON* cJSON_AddStringToObject_(cJSON* const object, const char* const name, const char* const string);
  166. cJSON* cJSON_AddRawToObject(cJSON* const object, const char* const name, const char* const raw);
  167. cJSON* cJSON_AddObjectToObject(cJSON* const object, const char* const name);
  168. cJSON* cJSON_AddArrayToObject(cJSON* const object, const char* const name);
  169. #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
  170. double cJSON_SetNumberHelper(cJSON* object, double number);
  171. #define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
  172. char* cJSON_SetValuestring(cJSON* object, const char* valuestring);
  173. #define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
  174. void* cJSON_malloc(size_t size);
  175. void cJSON_free(void* object);
  176. namespace ylib
  177. {
  178. class json
  179. {
  180. public:
  181. enum type
  182. {
  183. null,
  184. obj,
  185. empty,
  186. array,
  187. boolean,
  188. number,
  189. string
  190. };
  191. public:
  192. json();
  193. json(const ylib::json& value);
  194. json(cJSON* json,const std::string& name);
  195. json(const std::vector<uint32>& value);
  196. json(const std::vector<int32>& value);
  197. json(const std::vector<uint64>& value);
  198. json(const std::vector<int64>& value);
  199. json(const std::vector<const char*>& value);
  200. json(const std::vector<std::string>& value);
  201. json(const std::vector<bool>& value);
  202. json(const std::vector<double>& value);
  203. json(const std::vector<float>& value);
  204. json(const std::vector<ylib::json>& value);
  205. //json(const std::initializer_list<ylib::json>& value);
  206. //json(std::map<const char*, ylib::json> value);
  207. json(const uint32& value);
  208. json(const int32& value);
  209. json(const uint64& value);
  210. json(const int64& value);
  211. json(const std::string& value);
  212. json(const bool& value);
  213. json(const double& value);
  214. json(const float& value);
  215. json(const char* value);
  216. ~json() ;
  217. bool parse(const std::string& value);
  218. void path(const std::string& path);
  219. void safe(bool safe);
  220. bool safe();
  221. static ylib::json from(const std::string& value);
  222. uint32 size() const;
  223. void resize(uint32 size);
  224. bool is_empty() const;
  225. bool is_null() const;
  226. bool is_obj() const;
  227. bool is_array() const;
  228. bool is_bool() const;
  229. bool is_number() const;
  230. bool is_string() const;
  231. bool exist(const std::string& name) const;
  232. void erase(const std::string& key);
  233. void erase(uint32 index);
  234. std::vector<std::string> keys() const;
  235. const std::string& to_string(bool format = false) const;
  236. ylib::json& operator[](const std::string name);
  237. const ylib::json& operator[](const std::string name) const;
  238. ylib::json& operator[](const size_t idx);
  239. const ylib::json& operator[](const size_t idx) const;
  240. //
  241. void operator=(const std::vector<uint32>& value);
  242. void operator=(const std::vector<int32>& value);
  243. void operator=(const std::vector<uint64>& value);
  244. void operator=(const std::vector<int64>& value);
  245. void operator=(const std::vector<const char*>& value);
  246. void operator=(const std::vector<std::string>& value);
  247. void operator=(const std::vector<bool>& value);
  248. void operator=(const std::vector<double>& value);
  249. void operator=(const std::vector<float>& value);
  250. void operator=(const std::vector<ylib::json>& value);
  251. #ifndef MSVC_2010
  252. void operator=(std::initializer_list<ylib::json> value);
  253. #endif
  254. void operator=(std::map<const char*, ylib::json> value);
  255. void operator=(uint32 value);
  256. void operator=(int32 value);
  257. void operator=(uint64 value);
  258. void operator=(int64 value);
  259. void operator=(std::string value);
  260. void operator=(const bool value);
  261. void operator=(double value);
  262. void operator=(float value);
  263. void operator=(const char* value);
  264. void operator=(ylib::json::type value);
  265. void operator=(const ylib::json& value);
  266. void push_back(uint32 value);
  267. void push_back(int32 value);
  268. void push_back(uint64 value);
  269. void push_back(int64 value);
  270. void push_back(std::string value);
  271. void push_back(const bool value);
  272. void push_back(double value);
  273. void push_back(float value);
  274. void push_back(const char* value);
  275. void push_back(const ylib::json& value);
  276. void clear();
  277. template<typename T_TO>
  278. T_TO to(bool check = false) const
  279. {
  280. if (check)
  281. {
  282. if (is_empty())
  283. {
  284. //trw_str("JSON is empty !!! Name:"+m_name);
  285. }
  286. }
  287. #define RETURN_T(PARAM) return *((T_TO*)&PARAM)
  288. #define CASE_T(TYPE) std::is_same<TYPE,T_TO>::value
  289. if (CASE_T(std::vector<std::string>))
  290. {
  291. std::vector<std::string> result;
  292. if (is_array() == false)
  293. RETURN_T(result);
  294. for (uint32 i = 0;i < size();i++)
  295. result.push_back(this->operator[](i).to<std::string>());
  296. RETURN_T(result);
  297. }
  298. else if (CASE_T(std::vector<ylib::json>))
  299. {
  300. std::vector<ylib::json> result;
  301. if (is_array() == false)
  302. RETURN_T(result);
  303. for (uint32 i = 0;i < size();i++)
  304. result.push_back(this->operator[](i));
  305. RETURN_T(result);
  306. }
  307. else if (CASE_T(std::vector<int>) || CASE_T(std::vector<unsigned int>) || CASE_T(std::vector<long>))
  308. {
  309. std::vector<uint32> result;
  310. if (is_array() == false)
  311. RETURN_T(result);
  312. for (uint32 i = 0;i < size();i++)
  313. result.push_back(this->operator[](i).to<int>());
  314. RETURN_T(result);
  315. }
  316. else if (CASE_T(std::vector<double>))
  317. {
  318. std::vector<double> result;
  319. if (is_array() == false)
  320. RETURN_T(result);
  321. for (uint32 i = 0;i < size();i++)
  322. result.push_back(this->operator[](i).to<double>());
  323. RETURN_T(result);
  324. }
  325. else if (CASE_T(std::vector<long long>) || CASE_T(std::vector<unsigned long long>))
  326. {
  327. std::vector<unsigned long long> result;
  328. if (is_array() == false)
  329. RETURN_T(result);
  330. for (uint32 i = 0;i < size();i++)
  331. result.push_back(this->operator[](i).to<unsigned long long>());
  332. RETURN_T(result);
  333. }
  334. else if (CASE_T(std::vector<float>))
  335. {
  336. std::vector<float> result;
  337. if (is_array() == false)
  338. RETURN_T(result);
  339. for (uint32 i = 0;i < size();i++)
  340. result.push_back(this->operator[](i).to<float>());
  341. RETURN_T(result);
  342. }
  343. else if (CASE_T(int) || CASE_T(unsigned int) || CASE_T(long))
  344. {
  345. static int result = 0;
  346. if (m_number)
  347. result = (int)this->m_value_double;
  348. else
  349. result = ylib::stoi(m_value_string);
  350. RETURN_T(result);
  351. }
  352. else if (CASE_T(short) || CASE_T(unsigned short))
  353. {
  354. static short result = 0;
  355. if (m_number)
  356. result = (short)this->m_value_double;
  357. else
  358. result = (short)ylib::stoi(m_value_string);
  359. RETURN_T(result);
  360. }
  361. else if (CASE_T(std::string))
  362. {
  363. RETURN_T(this->m_value_string);
  364. }
  365. else if (CASE_T(double))
  366. {
  367. RETURN_T(this->m_value_double);
  368. }
  369. else if (CASE_T(long long) || CASE_T(unsigned long long))
  370. {
  371. static uint64 result = 0;
  372. if (m_number)
  373. result = (int)this->m_value_double;
  374. else
  375. {
  376. result = ylib::stoull(m_value_string);
  377. }
  378. RETURN_T(result);
  379. }
  380. else if (CASE_T(float))
  381. {
  382. static float result = (float)this->m_value_double;
  383. RETURN_T(result);
  384. }
  385. else if (CASE_T(bool))
  386. {
  387. RETURN_T(this->m_value_bool);
  388. }
  389. else
  390. {
  391. throw ylib::exception("not exception");
  392. }
  393. return T_TO();
  394. }
  395. private:
  396. void init(cJSON* item);
  397. void erase();
  398. cJSON* arrangement() const;
  399. bool is_newobj();
  400. void clear_type();
  401. bool __parse(const char* value,uint32 length);
  402. private:
  403. std::map<std::string, json*> m_objs;
  404. std::vector<json*> m_arrs;
  405. std::string m_name;
  406. std::string m_value_string;
  407. bool m_safe = false;
  408. double m_value_double = 0.0f;
  409. bool m_value_bool = false;
  410. bool m_empty = false;
  411. bool m_bool = false;
  412. bool m_array = false;
  413. bool m_obj = false;
  414. bool m_string = false;
  415. bool m_number = false;
  416. bool m_null = false;
  417. std::string m_jsonstring;
  418. };
  419. }