_json.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. #include "_json.h"
  2. #include "_pika_cJSON.h"
  3. #include "jsmn.h"
  4. #if !PIKASCRIPT_VERSION_REQUIRE_MINIMUN(1, 12, 4)
  5. #error "pikapython version must be greater than 1.13.0"
  6. #endif
  7. cJSON* _pika_cJSON_decode(Arg* d);
  8. #define USING_JSMN 0
  9. int parse_json_jsmn(const char* json_string,
  10. jsmn_parser* parser,
  11. jsmntok_t** tokens) {
  12. jsmn_init(parser);
  13. int token_count =
  14. jsmn_parse(parser, json_string, strlen(json_string), NULL, 0);
  15. if (token_count < 0) {
  16. // JSMN_ERROR_INVAL or JSMN_ERROR_PART
  17. pika_platform_printf("Failed to parse JSON: %d\n", token_count);
  18. return -1;
  19. }
  20. *tokens = pika_platform_malloc(sizeof(jsmntok_t) * token_count);
  21. if (*tokens == NULL) {
  22. pika_platform_printf("Failed to allocate memory: %d\n", token_count);
  23. return -1;
  24. }
  25. jsmn_init(parser);
  26. int result = jsmn_parse(parser, json_string, strlen(json_string), *tokens,
  27. token_count);
  28. if (result < 0) {
  29. pika_platform_printf("Failed to parse JSON: %d\n", result);
  30. pika_platform_free(*tokens);
  31. *tokens = NULL;
  32. return -1;
  33. }
  34. return result;
  35. }
  36. Arg* json_encode_jsmn(jsmntok_t* t,
  37. int* index,
  38. char* json_str,
  39. int token_count) {
  40. Arg* val;
  41. pika_assert(*index >= 0);
  42. pika_assert(*index < token_count);
  43. jsmntype_t type = t[*index].type;
  44. switch (type) {
  45. case JSMN_PRIMITIVE: {
  46. char buff[PIKA_NAME_BUFF_SIZE] = {0};
  47. pika_assert(t[*index].end - t[*index].start < PIKA_NAME_BUFF_SIZE);
  48. pika_platform_memcpy(buff, json_str + t[*index].start,
  49. t[*index].end - t[*index].start);
  50. if (strEqu(buff, "true")) {
  51. val = arg_newBool(1);
  52. } else if (strEqu(buff, "false")) {
  53. val = arg_newBool(0);
  54. } else if (strEqu(buff, "null")) {
  55. val = arg_newNull();
  56. } else {
  57. /* float */
  58. if (strIsContain(buff, '.') ||
  59. (strIsContain(buff, 'e') || strIsContain(buff, 'E'))) {
  60. val = arg_newFloat(strtod(buff, NULL));
  61. } else {
  62. /* int */
  63. val = arg_newInt(fast_atoi(buff));
  64. }
  65. }
  66. break;
  67. }
  68. case JSMN_STRING: {
  69. val = arg_newStrN(json_str + t[*index].start,
  70. t[*index].end - t[*index].start);
  71. char* raw = arg_getStr(val);
  72. if (strIsContain(arg_getStr(val), '\\')) {
  73. Args buffs = {0};
  74. size_t i = 0;
  75. char* transfered_str = strsTransfer(&buffs, raw, &i);
  76. Arg* val_transfered = arg_newStr(transfered_str);
  77. arg_deinit(val);
  78. val = val_transfered;
  79. strsDeinit(&buffs);
  80. }
  81. break;
  82. }
  83. case JSMN_OBJECT: {
  84. PikaObj* ret = objDict_new(NULL);
  85. int num_keys = t[*index].size;
  86. for (int i = 0; i < num_keys; i++) {
  87. (*index)++;
  88. jsmntok_t* key_tok = &t[*index];
  89. char* value = json_str + key_tok->start;
  90. int size = key_tok->end - key_tok->start;
  91. pika_assert(key_tok->type == JSMN_STRING);
  92. char key[PIKA_NAME_BUFF_SIZE] = {0};
  93. pika_assert(size < PIKA_NAME_BUFF_SIZE);
  94. pika_platform_memcpy(key, value, size);
  95. (*index)++;
  96. Arg* val_nested =
  97. json_encode_jsmn(t, index, json_str, token_count);
  98. objDict_set(ret, key, val_nested);
  99. arg_deinit(val_nested);
  100. }
  101. val = arg_newObj(ret);
  102. break;
  103. }
  104. case JSMN_ARRAY: {
  105. PikaObj* ret = objList_new(NULL);
  106. jsmntok_t* key_tok = &t[*index];
  107. int num_elements = key_tok->size;
  108. for (int i = 0; i < num_elements; i++) {
  109. (*index)++;
  110. Arg* val_nested =
  111. json_encode_jsmn(t, index, json_str, token_count);
  112. objList_append(ret, val_nested);
  113. arg_deinit(val_nested);
  114. }
  115. val = arg_newObj(ret);
  116. break;
  117. }
  118. default: /* Should not reach here */
  119. val = NULL;
  120. }
  121. return val;
  122. }
  123. Arg* json_encode_cjson(cJSON* cjson) {
  124. if (cjson == NULL) {
  125. return NULL;
  126. }
  127. switch (cjson->type) {
  128. case pika_cJSON_Invalid: {
  129. return NULL;
  130. }
  131. case pika_cJSON_False: {
  132. return arg_newBool(pika_false);
  133. }
  134. case pika_cJSON_True: {
  135. return arg_newBool(pika_true);
  136. }
  137. case pika_cJSON_NULL: {
  138. return arg_newNull();
  139. }
  140. case pika_cJSON_Number: {
  141. pika_float num_f = cjson->valuedouble;
  142. int num_i = cjson->valueint;
  143. if (num_f == num_i) {
  144. return arg_newInt(num_i);
  145. } else {
  146. return arg_newFloat(num_f);
  147. }
  148. }
  149. case pika_cJSON_String: {
  150. return arg_newStr(cjson->valuestring);
  151. }
  152. case pika_cJSON_Array: {
  153. PikaObj* ret = objList_new(NULL);
  154. for (int i = 0; i < pika_cJSON_GetArraySize(cjson); i++) {
  155. cJSON* item = pika_cJSON_GetArrayItem(cjson, i);
  156. Arg* nested_arg = json_encode_cjson(item);
  157. objList_append(ret, nested_arg);
  158. arg_deinit(nested_arg);
  159. }
  160. return arg_newObj(ret);
  161. }
  162. case pika_cJSON_Object: {
  163. PikaObj* ret = objDict_new(NULL);
  164. cJSON* child = cjson->child;
  165. for (int i = 0; i < pika_cJSON_GetArraySize(cjson); i++) {
  166. char* key = child->string;
  167. Arg* nested_arg = json_encode_cjson(child);
  168. objDict_set(ret, key, nested_arg);
  169. arg_deinit(nested_arg);
  170. child = child->next;
  171. }
  172. return arg_newObj(ret);
  173. }
  174. case pika_cJSON_Raw: {
  175. return arg_newStr(cjson->valuestring);
  176. }
  177. default: {
  178. return NULL;
  179. }
  180. }
  181. }
  182. Arg* _json_loads(PikaObj* self, char* json_str) {
  183. #if USING_JSMN
  184. jsmn_parser parser;
  185. Arg* ret = NULL;
  186. jsmntok_t* tokens = NULL;
  187. int token_count = parse_json_jsmn(json_str, &parser, &tokens);
  188. if (token_count < 0) {
  189. ret = NULL;
  190. goto __exit;
  191. }
  192. ret = json_encode_jsmn(tokens, &(int){0}, json_str, token_count);
  193. __exit:
  194. if (NULL != tokens) {
  195. free(tokens);
  196. }
  197. return ret;
  198. #else
  199. cJSON* cjson = pika_cJSON_Parse(json_str);
  200. if (cjson == NULL) {
  201. pika_platform_printf("JSONDecodeError: at \'%s\'\r\n",
  202. pika_cJSON_GetErrorPtr());
  203. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  204. return NULL;
  205. }
  206. Arg* ret = json_encode_cjson(cjson);
  207. pika_cJSON_Delete(cjson);
  208. return ret;
  209. #endif
  210. }
  211. typedef struct {
  212. cJSON* jsonArray;
  213. } JsonListContext;
  214. int32_t jsonListEachHandle(PikaObj* self,
  215. int itemIndex,
  216. Arg* itemEach,
  217. void* context) {
  218. JsonListContext* ctx = (JsonListContext*)context;
  219. pika_cJSON_AddItemToArray(ctx->jsonArray, _pika_cJSON_decode(itemEach));
  220. return 0;
  221. }
  222. typedef struct {
  223. cJSON* jsonObject;
  224. } JsonDictContext;
  225. int32_t jsonDictEachHandle(PikaObj* self,
  226. Arg* keyEach,
  227. Arg* valEach,
  228. void* context) {
  229. JsonDictContext* ctx = (JsonDictContext*)context;
  230. pika_cJSON_AddItemToObject(ctx->jsonObject, arg_getStr(keyEach),
  231. _pika_cJSON_decode(valEach));
  232. return 0;
  233. }
  234. cJSON* _pika_cJSON_decode(Arg* d) {
  235. ArgType type = arg_getType(d);
  236. switch (type) {
  237. case ARG_TYPE_NONE:
  238. return pika_cJSON_CreateNull();
  239. case ARG_TYPE_INT:
  240. return pika_cJSON_CreateNumber(arg_getInt(d));
  241. case ARG_TYPE_FLOAT:
  242. return pika_cJSON_CreateNumber(arg_getFloat(d));
  243. case ARG_TYPE_BOOL:
  244. return arg_getBool(d) ? pika_cJSON_CreateTrue()
  245. : pika_cJSON_CreateFalse();
  246. case ARG_TYPE_STRING:
  247. return pika_cJSON_CreateString(arg_getStr(d));
  248. default:
  249. if (arg_isList(d)) {
  250. JsonListContext context;
  251. context.jsonArray = pika_cJSON_CreateArray();
  252. objList_forEach(arg_getObj(d), jsonListEachHandle, &context);
  253. return context.jsonArray;
  254. }
  255. if (arg_isDict(d)) {
  256. JsonDictContext context;
  257. context.jsonObject = pika_cJSON_CreateObject();
  258. objDict_forEach(arg_getObj(d), jsonDictEachHandle, &context);
  259. return context.jsonObject;
  260. }
  261. return pika_cJSON_CreateNull();
  262. }
  263. }
  264. char* _json_dumps(PikaObj* self, Arg* d) {
  265. cJSON* json = _pika_cJSON_decode(d);
  266. char* ret = pika_cJSON_Print(json);
  267. char* cached = obj_cacheStr(self, ret);
  268. pika_cJSON_Delete(json);
  269. pika_platform_free(ret);
  270. return cached;
  271. }