_json.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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 = New_PikaDict();
  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. pikaDict_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 = New_pikaListFromVarArgs(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. pikaList_append(ret, val_nested);
  113. }
  114. val = arg_newObj(ret);
  115. break;
  116. }
  117. default: /* Should not reach here */
  118. val = NULL;
  119. }
  120. return val;
  121. }
  122. Arg* json_encode_cjson(cJSON* cjson) {
  123. if (cjson == NULL) {
  124. return NULL;
  125. }
  126. switch (cjson->type) {
  127. case pika_cJSON_Invalid: {
  128. return NULL;
  129. }
  130. case pika_cJSON_False: {
  131. return arg_newBool(pika_false);
  132. }
  133. case pika_cJSON_True: {
  134. return arg_newBool(pika_true);
  135. }
  136. case pika_cJSON_NULL: {
  137. return arg_newNull();
  138. }
  139. case pika_cJSON_Number: {
  140. pika_float num_f = cjson->valuedouble;
  141. int num_i = cjson->valueint;
  142. if (num_f == num_i) {
  143. return arg_newInt(num_i);
  144. } else {
  145. return arg_newFloat(num_f);
  146. }
  147. }
  148. case pika_cJSON_String: {
  149. return arg_newStr(cjson->valuestring);
  150. }
  151. case pika_cJSON_Array: {
  152. PikaObj* ret = New_pikaListFromVarArgs(NULL);
  153. for (int i = 0; i < pika_cJSON_GetArraySize(cjson); i++) {
  154. cJSON* item = pika_cJSON_GetArrayItem(cjson, i);
  155. Arg* nested_arg = json_encode_cjson(item);
  156. pikaList_append(ret, nested_arg);
  157. }
  158. return arg_newObj(ret);
  159. }
  160. case pika_cJSON_Object: {
  161. PikaObj* ret = New_pikaDictFromVarArgs(NULL);
  162. cJSON* child = cjson->child;
  163. for (int i = 0; i < pika_cJSON_GetArraySize(cjson); i++) {
  164. char* key = child->string;
  165. Arg* nested_arg = json_encode_cjson(child);
  166. pikaDict_set(ret, key, nested_arg);
  167. child = child->next;
  168. }
  169. return arg_newObj(ret);
  170. }
  171. case pika_cJSON_Raw: {
  172. return arg_newStr(cjson->valuestring);
  173. }
  174. default: {
  175. return NULL;
  176. }
  177. }
  178. }
  179. Arg* _json_loads(PikaObj* self, char* json_str) {
  180. #if USING_JSMN
  181. jsmn_parser parser;
  182. Arg* ret = NULL;
  183. jsmntok_t* tokens = NULL;
  184. int token_count = parse_json_jsmn(json_str, &parser, &tokens);
  185. if (token_count < 0) {
  186. ret = NULL;
  187. goto __exit;
  188. }
  189. ret = json_encode_jsmn(tokens, &(int){0}, json_str, token_count);
  190. __exit:
  191. if (NULL != tokens) {
  192. free(tokens);
  193. }
  194. return ret;
  195. #else
  196. cJSON* cjson = pika_cJSON_Parse(json_str);
  197. if (cjson == NULL) {
  198. obj_setSysOut(self, "JSONDecodeError: at \'%s\'",
  199. pika_cJSON_GetErrorPtr());
  200. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  201. return NULL;
  202. }
  203. Arg* ret = json_encode_cjson(cjson);
  204. pika_cJSON_Delete(cjson);
  205. return ret;
  206. #endif
  207. }
  208. typedef struct {
  209. cJSON* jsonArray;
  210. } JsonListContext;
  211. int32_t jsonListEachHandle(PikaObj* self,
  212. int itemIndex,
  213. Arg* itemEach,
  214. void* context) {
  215. JsonListContext* ctx = (JsonListContext*)context;
  216. pika_cJSON_AddItemToArray(ctx->jsonArray, _pika_cJSON_decode(itemEach));
  217. return 0;
  218. }
  219. typedef struct {
  220. cJSON* jsonObject;
  221. } JsonDictContext;
  222. int32_t jsonDictEachHandle(PikaObj* self,
  223. Arg* keyEach,
  224. Arg* valEach,
  225. void* context) {
  226. JsonDictContext* ctx = (JsonDictContext*)context;
  227. pika_cJSON_AddItemToObject(ctx->jsonObject, arg_getStr(keyEach),
  228. _pika_cJSON_decode(valEach));
  229. return 0;
  230. }
  231. cJSON* _pika_cJSON_decode(Arg* d) {
  232. ArgType type = arg_getType(d);
  233. switch (type) {
  234. case ARG_TYPE_NONE:
  235. return pika_cJSON_CreateNull();
  236. case ARG_TYPE_INT:
  237. return pika_cJSON_CreateNumber(arg_getInt(d));
  238. case ARG_TYPE_FLOAT:
  239. return pika_cJSON_CreateNumber(arg_getFloat(d));
  240. case ARG_TYPE_BOOL:
  241. return arg_getBool(d) ? pika_cJSON_CreateTrue()
  242. : pika_cJSON_CreateFalse();
  243. case ARG_TYPE_STRING:
  244. return pika_cJSON_CreateString(arg_getStr(d));
  245. default:
  246. if (arg_isList(d)) {
  247. JsonListContext context;
  248. context.jsonArray = pika_cJSON_CreateArray();
  249. pikaList_forEach(arg_getObj(d), jsonListEachHandle, &context);
  250. return context.jsonArray;
  251. }
  252. if (arg_isDict(d)) {
  253. JsonDictContext context;
  254. context.jsonObject = pika_cJSON_CreateObject();
  255. pikaDict_forEach(arg_getObj(d), jsonDictEachHandle, &context);
  256. return context.jsonObject;
  257. }
  258. return pika_cJSON_CreateNull();
  259. }
  260. }
  261. char* _json_dumps(PikaObj* self, Arg* d) {
  262. cJSON* json = _pika_cJSON_decode(d);
  263. char* ret = pika_cJSON_Print(json);
  264. char* cached = obj_cacheStr(self, ret);
  265. pika_cJSON_Delete(json);
  266. pika_platform_free(ret);
  267. return cached;
  268. }