1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 #include "linkkit/infra/infra_config.h"
5 
6 #ifdef INFRA_JSON_PARSER
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdarg.h>
12 
13 #include "linkkit/infra/infra_types.h"
14 #include "linkkit/infra/infra_json_parser.h"
15 #include "linkkit/wrappers/wrappers.h"
16 
17 #ifdef INFRA_LOG
18 #include "linkkit/infra/infra_log.h"
19 #define jparser_debug(...) log_debug("jparser", __VA_ARGS__)
20 #else
21 #define jparser_debug(...)       \
22     do {                         \
23         HAL_Printf(__VA_ARGS__); \
24         HAL_Printf("\r\n");      \
25     } while (0)
26 #endif
27 
28 #ifdef INFRA_MEM_STATS
29 #include "linkkit/infra/infra_mem_stats.h"
30 #define jparser_malloc(size) LITE_malloc(size, MEM_MAGIC, "jparser")
31 #define jparser_free(ptr)    LITE_free(ptr)
32 #else
33 #define jparser_malloc(size) HAL_Malloc(size)
34 #define jparser_free(ptr)      \
35     {                          \
36         HAL_Free((void *)ptr); \
37         ptr = NULL;            \
38     }
39 #endif
40 
json_get_object(int type,char * str,char * str_end)41 char *json_get_object(int type, char *str, char *str_end)
42 {
43     char *pos = NULL;
44     char ch = (type == JOBJECT) ? '{' : '[';
45 
46     if (!str || !str_end) {
47         return NULL;
48     }
49 
50     while (str != NULL && *str != 0 && str < str_end) {
51         if (*str == ' ') {
52             str++;
53             continue;
54         }
55         pos = (*str == ch) ? str : NULL;
56         break;
57     }
58     return pos;
59 }
60 
json_get_next_object(int type,char * str,char * str_end,char ** key,int * key_len,char ** val,int * val_len,int * val_type)61 char *json_get_next_object(int type, char *str, char *str_end, char **key,
62                            int *key_len, char **val, int *val_len,
63                            int *val_type)
64 {
65     char JsonMark[JTYPEMAX][2] = {
66         { '\"', '\"' }, { '{', '}' }, { '[', ']' }, { '0', ' ' }
67     };
68     int iMarkDepth = 0, iValueType = JNONE, iNameLen = 0, iValueLen = 0,
69         iStringDepth = 0;
70     char *p_cName = 0, *p_cValue = 0, *p_cPos = str;
71 
72     if (type == JOBJECT) {
73         /* Get Key */
74         p_cPos = strchr(p_cPos, '\"');
75         if (!p_cPos) {
76             goto do_exit;
77         }
78         p_cName = ++p_cPos;
79         p_cPos = strchr(p_cPos, '\"');
80         if (!p_cPos) {
81             goto do_exit;
82         }
83         iNameLen = p_cPos - p_cName;
84 
85         /* Get Value */
86         p_cPos = strchr(p_cPos, ':');
87     }
88     while (p_cPos && *p_cPos && p_cPos < str_end) {
89         if (*p_cPos == '\"') {
90             iValueType = JSTRING;
91             p_cValue = ++p_cPos;
92             break;
93         } else if (*p_cPos == '{') {
94             iValueType = JOBJECT;
95             p_cValue = p_cPos++;
96             break;
97         } else if (*p_cPos == '[') {
98             iValueType = JARRAY;
99             p_cValue = p_cPos++;
100             break;
101         } else if ((*p_cPos == '-') || (*p_cPos >= '0' && *p_cPos <= '9')) {
102             iValueType = JNUMBER;
103             p_cValue = p_cPos++;
104             break;
105         } else if (*p_cPos == 't' || *p_cPos == 'T' || *p_cPos == 'f' ||
106                    *p_cPos == 'F') {
107             iValueType = JBOOLEAN;
108             p_cValue = p_cPos;
109             break;
110         }
111         p_cPos++;
112     }
113 
114     while (p_cPos && *p_cPos && p_cPos < str_end && iValueType > JNONE) {
115         if (iValueType == JBOOLEAN) {
116             int len = strlen(p_cValue);
117 
118             if ((*p_cValue == 't' || *p_cValue == 'T') && len >= 4 &&
119                 (!strncmp(p_cValue, "true", 4) ||
120                  !strncmp(p_cValue, "TRUE", 4))) {
121                 iValueLen = 4;
122                 p_cPos = p_cValue + iValueLen;
123                 break;
124             } else if ((*p_cValue == 'f' || *p_cValue == 'F') && len >= 5 &&
125                        (!strncmp(p_cValue, "false", 5) ||
126                         !strncmp(p_cValue, "FALSE", 5))) {
127                 iValueLen = 5;
128                 p_cPos = p_cValue + iValueLen;
129                 break;
130             }
131         } else if (iValueType == JNUMBER) {
132             if ((*p_cPos < '0' || *p_cPos > '9') && (*p_cPos != '.') &&
133                 (*p_cPos != '+') && (*p_cPos != '-') && ((*p_cPos != 'e')) &&
134                 (*p_cPos != 'E')) {
135                 iValueLen = p_cPos - p_cValue;
136                 break;
137             }
138         } else if (iValueType == JSTRING) {
139             if (*p_cPos == '\"') {
140                 iValueLen = p_cPos - p_cValue;
141                 break;
142             }
143         } else if (*p_cPos == JsonMark[iValueType][1]) {
144             if (iStringDepth == 0) {
145                 if (iMarkDepth == 0) {
146                     iValueLen = p_cPos - p_cValue + 1;
147                     p_cPos++;
148                     break;
149                 } else {
150                     iMarkDepth--;
151                 }
152             }
153         } else if (*p_cPos == JsonMark[iValueType][0]) {
154             if (iStringDepth == 0) {
155                 iMarkDepth++;
156             }
157         } else if (*p_cPos == '\"') {
158             if (iStringDepth) {
159                 iStringDepth = 0;
160             } else {
161                 iStringDepth = 1;
162             }
163         }
164         p_cPos++;
165     }
166 
167     if (type == JOBJECT) {
168         if ((p_cName + iNameLen) > str_end) {
169             goto do_exit;
170         }
171         *key = p_cName;
172         *key_len = iNameLen;
173     }
174     if ((p_cValue + iValueLen) > str_end) {
175         goto do_exit;
176     }
177 
178     *val = p_cValue;
179     *val_len = iValueLen;
180     *val_type = iValueType;
181     if (iValueType == JSTRING) {
182         return p_cValue + iValueLen + 1;
183     } else {
184         return p_cValue + iValueLen;
185     }
186 
187 do_exit:
188     *val = NULL;
189     *val_len = 0;
190     *key = NULL;
191     *key_len = 0;
192     return NULL;
193 }
194 
json_parse_name_value(char * p_cJsonStr,int iStrLen,json_parse_cb pfnCB,void * p_CBData)195 int json_parse_name_value(char *p_cJsonStr, int iStrLen, json_parse_cb pfnCB,
196                           void *p_CBData)
197 {
198     char *pos = 0, *key = 0, *val = 0;
199     int klen = 0, vlen = 0, vtype = 0;
200     int ret = JSON_RESULT_ERR;
201 
202     if (p_cJsonStr == NULL || iStrLen == 0 || pfnCB == NULL) {
203         return ret;
204     }
205 
206     json_object_for_each_kv(p_cJsonStr, iStrLen, pos, key, klen, val, vlen,
207                             vtype)
208     {
209         if (key && klen && val && vlen) {
210             ret = JSON_RESULT_OK;
211             if (JSON_PARSE_FINISH ==
212                 pfnCB(key, klen, val, vlen, vtype, p_CBData)) {
213                 break;
214             }
215         }
216     }
217 
218     return ret;
219 }
220 
json_get_value_by_name_cb(char * p_cName,int iNameLen,char * p_cValue,int iValueLen,int iValueType,void * p_CBData)221 int json_get_value_by_name_cb(char *p_cName, int iNameLen, char *p_cValue,
222                               int iValueLen, int iValueType, void *p_CBData)
223 {
224     JSON_NV *p_stNameValue = (JSON_NV *)p_CBData;
225 
226 #ifdef JSON_DEBUG
227     int i;
228 
229     if (p_cName) {
230         jparser_debug("Name:");
231         for (i = 0; i < iNameLen; i++) {
232             jparser_debug("%c", *(p_cName + i));
233         }
234     }
235 
236     if (p_cValue) {
237         jparser_debug("Value:");
238         for (i = 0; i < iValueLen; i++) {
239             jparser_debug("%c", *(p_cValue + i));
240         }
241     }
242 #endif
243 
244     if ((iNameLen == p_stNameValue->nLen) &&
245         !strncmp(p_cName, p_stNameValue->pN, p_stNameValue->nLen)) {
246         p_stNameValue->pV = p_cValue;
247         p_stNameValue->vLen = iValueLen;
248         p_stNameValue->vType = iValueType;
249         return JSON_PARSE_FINISH;
250     } else {
251         return JSON_PARSE_OK;
252     }
253 }
254 
json_get_value_by_name(char * p_cJsonStr,int iStrLen,char * p_cName,int * p_iValueLen,int * p_iValueType)255 char *json_get_value_by_name(char *p_cJsonStr, int iStrLen, char *p_cName,
256                              int *p_iValueLen, int *p_iValueType)
257 {
258     JSON_NV stNV;
259 
260     memset(&stNV, 0, sizeof(stNV));
261     stNV.pN = p_cName;
262     stNV.nLen = strlen(p_cName);
263     if (JSON_RESULT_OK == json_parse_name_value(p_cJsonStr, iStrLen,
264                                                 json_get_value_by_name_cb,
265                                                 (void *)&stNV)) {
266         if (p_iValueLen) {
267             *p_iValueLen = stNV.vLen;
268         }
269         if (p_iValueType) {
270             *p_iValueType = stNV.vType;
271         }
272     }
273     return stNV.pV;
274 }
275 
json_get_value_by_name_len(char * p_cJsonStr,int iStrLen,char * p_cName,int p_cNameLen,int * p_iValueLen,int * p_iValueType)276 char *json_get_value_by_name_len(char *p_cJsonStr, int iStrLen, char *p_cName,
277                                  int p_cNameLen, int *p_iValueLen,
278                                  int *p_iValueType)
279 {
280     JSON_NV stNV;
281 
282     memset(&stNV, 0, sizeof(stNV));
283     stNV.pN = p_cName;
284     stNV.nLen = p_cNameLen;
285     if (JSON_RESULT_OK == json_parse_name_value(p_cJsonStr, iStrLen,
286                                                 json_get_value_by_name_cb,
287                                                 (void *)&stNV)) {
288         if (p_iValueLen) {
289             *p_iValueLen = stNV.vLen;
290         }
291         if (p_iValueType) {
292             *p_iValueType = stNV.vType;
293         }
294     }
295     return stNV.pV;
296 }
297 
LITE_json_value_of(char * key,char * src,...)298 char *LITE_json_value_of(char *key, char *src, ...)
299 {
300     char *value = NULL;
301     char *ret = NULL;
302     char *delim = NULL;
303     char *key_iter;
304     char *key_next;
305     char *src_iter;
306 
307     int key_len;
308     int value_len = -1;
309     int src_iter_len;
310 
311     if (NULL == key || NULL == src) {
312         return NULL;
313     }
314 
315 #if WITH_MEM_STATS_PER_MODULE
316     {
317         char *module_name = NULL;
318         int magic = 0;
319         va_list ap;
320         va_start(ap, src);
321         magic = va_arg(ap, int);
322         if (MEM_MAGIC == magic) {
323             module_name = va_arg(ap, char *);
324         }
325         va_end(ap);
326     }
327 #endif
328 
329     src_iter = src;
330     src_iter_len = strlen(src_iter);
331     key_iter = key;
332 
333     do {
334         delim = strchr(key_iter, '.');
335         if (delim != NULL) {
336             key_len = delim - key_iter;
337             key_next = key_iter;
338 
339             value = json_get_value_by_name_len(src_iter, src_iter_len, key_next,
340                                                key_len, &value_len, 0);
341             if (value == NULL) {
342                 return NULL;
343             }
344 
345             src_iter = value;
346             src_iter_len = value_len;
347             key_iter = delim + 1;
348         }
349     } while (delim);
350 
351     key_len = strlen(key_iter);
352     key_next = key_iter;
353     value = json_get_value_by_name_len(src_iter, src_iter_len, key_next,
354                                        key_len, &value_len, 0);
355     if (NULL == value) {
356         return NULL;
357     }
358 
359     ret = jparser_malloc((value_len + 1) * sizeof(char));
360 
361     if (NULL == ret) {
362         return NULL;
363     }
364 
365     HAL_Snprintf(ret, value_len + 1, "%s", value);
366     return ret;
367 }
368 
369 #if WITH_JSON_KEYS_OF
_LITE_json_keys_of(char * src,int src_len,char * prefix,...)370 static list_head_t *_LITE_json_keys_of(char *src, int src_len, char *prefix,
371                                        ...)
372 {
373     static LIST_HEAD(keylist);
374     char *module_name = NULL;
375     char *iter_pre = NULL;
376     char *pos = 0, *key = 0, *val = 0;
377     int klen = 0, vlen = 0, vtype = 0;
378     int magic = 0;
379     unsigned int mlen = 0;
380 
381 #if WITH_MEM_STATS_PER_MODULE
382     va_list ap;
383     va_start(ap, prefix);
384     magic = va_arg(ap, int);
385     if (MEM_MAGIC == magic) {
386         module_name = va_arg(ap, char *);
387     }
388     va_end(ap);
389 #endif
390 
391     if (!strcmp("", prefix)) {
392         INIT_LIST_HEAD(&keylist);
393     }
394 
395     json_object_for_each_kv(src, src_len, pos, key, klen, val, vlen, vtype)
396     {
397         if (key && klen && val && vlen) {
398             json_key_t *entry = NULL;
399 
400             entry = jparser_malloc(sizeof(json_key_t), magic, module_name);
401             if (NULL == entry) {
402                 utils_err("jparser_malloc failed!");
403                 return NULL;
404             }
405             memset(entry, 0, sizeof(json_key_t));
406 
407             mlen = strlen(prefix) + klen + 1;
408             if (module_name) {
409                 entry->key = LITE_format_nstring(
410                     mlen, "%s%.*s", magic, module_name, prefix, klen, key);
411             } else {
412                 entry->key =
413                     LITE_format_nstring(mlen, "%s%.*s", prefix, klen, key);
414             }
415             if (NULL == entry->key) {
416                 jparser_free(entry);
417                 return NULL;
418             }
419 
420             list_add_tail(&entry->list, &keylist);
421 
422             if (JOBJECT == vtype) {
423                 mlen = strlen(prefix) + klen + 2;
424                 if (module_name) {
425                     iter_pre = LITE_format_nstring(
426                         mlen, "%s%.*s.", magic, module_name, prefix, klen, key);
427                 } else {
428                     iter_pre =
429                         LITE_format_nstring(mlen, "%s%.*s.", prefix, klen, key);
430                 }
431                 if (NULL == iter_pre) {
432                     return NULL;
433                 }
434 
435                 _LITE_json_keys_of(val, vlen, iter_pre, magic, module_name);
436                 jparser_free(iter_pre);
437             }
438         }
439     }
440 
441     if (!strcmp("", prefix)) {
442         json_key_t *entry = NULL;
443 
444         entry = jparser_malloc(sizeof(json_key_t), magic, module_name);
445         if (NULL == entry) {
446             utils_err("jparser_malloc failed!");
447             return NULL;
448         }
449         memset(entry, 0, sizeof(json_key_t));
450         list_add_tail(&entry->list, &keylist);
451 
452         return &keylist;
453     }
454 
455     return NULL;
456 }
457 
LITE_json_keys_of(char * src,char * prefix,...)458 list_head_t *LITE_json_keys_of(char *src, char *prefix, ...)
459 {
460     char *module_name = NULL;
461     int magic = 0;
462 
463     if (!src || !prefix) {
464         return NULL;
465     }
466 
467 #if WITH_MEM_STATS_PER_MODULE
468 
469     va_list ap;
470     va_start(ap, prefix);
471     magic = va_arg(ap, int);
472     if (MEM_MAGIC == magic) {
473         module_name = va_arg(ap, char *);
474     }
475     va_end(ap);
476 #endif
477 
478     return _LITE_json_keys_of(src, strlen(src), prefix, magic, module_name);
479 }
480 
481 #if WITH_JSON_TOKEN_EXT
_LITE_json_keys_of_ext(int type,char * src,int src_len,char * prefix,...)482 static list_head_t *_LITE_json_keys_of_ext(int type, char *src, int src_len,
483                                            char *prefix, ...)
484 {
485     static LIST_HEAD(keylist);
486     char *module_name = NULL;
487     char *iter_pre = NULL;
488     char *pos = 0, *key = 0, *val = 0;
489     int klen = 0, vlen = 0, vtype = 0;
490     int magic = 0;
491     unsigned int count = 1;
492     unsigned int mlen = 0;
493 
494     if (src == NULL || prefix == NULL) {
495         return NULL;
496     }
497 
498 #if WITH_MEM_STATS_PER_MODULE
499     va_list ap;
500     va_start(ap, prefix);
501     magic = va_arg(ap, int);
502     if (MEM_MAGIC == magic) {
503         module_name = va_arg(ap, char *);
504     }
505     va_end(ap);
506 #endif
507 
508     if (!strcmp("", prefix)) {
509         INIT_LIST_HEAD(&keylist);
510     }
511 
512     if (JOBJECT == type) {
513         json_object_for_each_kv(src, src_len, pos, key, klen, val, vlen, vtype)
514         {
515             if (key && klen && val && vlen) {
516                 json_key_t *entry = NULL;
517 
518                 entry = jparser_malloc(sizeof(json_key_t), magic, module_name);
519 
520                 if (NULL == entry) {
521                     utils_err("jparser_malloc failed!");
522                     return NULL;
523                 }
524                 memset(entry, 0, sizeof(json_key_t));
525 
526                 mlen = strlen(prefix) + klen + 1;
527                 if (module_name) {
528                     entry->key = LITE_format_nstring(
529                         mlen, "%s%.*s", magic, module_name, prefix, klen, key);
530                 } else {
531                     entry->key =
532                         LITE_format_nstring(mlen, "%s%.*s", prefix, klen, key);
533                 }
534 
535                 if (NULL == entry->key) {
536                     jparser_free(entry);
537                     return NULL;
538                 }
539 
540                 list_add_tail(&entry->list, &keylist);
541 
542                 if (JOBJECT == vtype) {
543                     mlen = strlen(prefix) + klen + 2;
544                     if (module_name) {
545                         iter_pre =
546                             LITE_format_nstring(mlen, "%s%.*s.", magic,
547                                                 module_name, prefix, klen, key);
548                     } else {
549                         iter_pre = LITE_format_nstring(mlen, "%s%.*s.", prefix,
550                                                        klen, key);
551                     }
552                     if (NULL == iter_pre) {
553                         return NULL;
554                     }
555 
556                     _LITE_json_keys_of_ext(vtype, val, vlen, iter_pre, magic,
557                                            module_name);
558                     jparser_free(iter_pre);
559                 } else if (JARRAY == vtype) {
560                     mlen = strlen(prefix) + klen + 1;
561                     if (module_name) {
562                         iter_pre =
563                             LITE_format_nstring(mlen, "%s%.*s", magic,
564                                                 module_name, prefix, klen, key);
565                     } else {
566                         iter_pre = LITE_format_nstring(mlen, "%s%.*s", prefix,
567                                                        klen, key);
568                     }
569                     if (NULL == iter_pre) {
570                         return NULL;
571                     }
572 
573                     _LITE_json_keys_of_ext(vtype, val, vlen, iter_pre, magic,
574                                            module_name);
575                     jparser_free(iter_pre);
576                 }
577             }
578         }
579     } else if (JARRAY == type) {
580         json_array_for_each_entry(src, src_len, pos, val, vlen, vtype)
581         {
582             if (val && vlen) {
583                 json_key_t *entry = NULL;
584                 unsigned int tmp = 0;
585                 unsigned int arridxlen = 0;
586                 entry = jparser_malloc(sizeof(json_key_t), magic, module_name);
587                 if (NULL == entry) {
588                     utils_err("jparser_malloc failed!");
589                     return NULL;
590                 }
591                 memset(entry, 0, sizeof(json_key_t));
592 
593                 tmp = count;
594                 do {
595                     tmp /= 10;
596                     ++arridxlen;
597                 } while (tmp);
598                 mlen = strlen("%s[%d]") + strlen(prefix) + arridxlen;
599                 if (module_name) {
600                     entry->key = LITE_format_nstring(
601                         mlen, "%s[%d]", magic, module_name, prefix, count);
602                 } else {
603                     entry->key =
604                         LITE_format_nstring(mlen, "%s[%d]", prefix, count);
605                 }
606                 if (NULL == entry->key) {
607                     jparser_free(entry);
608                     return NULL;
609                 }
610 
611                 list_add_tail(&entry->list, &keylist);
612 
613                 if (JOBJECT == vtype) {
614                     mlen = strlen("%s[%d].") + strlen(prefix) + arridxlen;
615                     if (module_name) {
616                         iter_pre = LITE_format_nstring(
617                             mlen, "%s[%d].", magic, module_name, prefix, count);
618                     } else {
619                         iter_pre =
620                             LITE_format_nstring(mlen, "%s[%d].", prefix, count);
621                     }
622                     if (NULL == iter_pre) {
623                         return NULL;
624                     }
625 
626                     _LITE_json_keys_of_ext(vtype, val, vlen, iter_pre, magic,
627                                            module_name);
628                     jparser_free(iter_pre);
629                 } else if (JARRAY == vtype) {
630                     mlen = strlen("%s[%d]") + strlen(prefix) + arridxlen;
631                     if (module_name) {
632                         iter_pre = LITE_format_nstring(
633                             mlen, "%s[%d]", magic, module_name, prefix, count);
634                     } else {
635                         iter_pre =
636                             LITE_format_nstring(mlen, "%s[%d]", prefix, count);
637                     }
638                     if (NULL == iter_pre) {
639                         return NULL;
640                     }
641 
642                     _LITE_json_keys_of_ext(vtype, val, vlen, iter_pre, magic,
643                                            module_name);
644                     jparser_free(iter_pre);
645                 }
646                 ++count;
647             }
648         }
649     }
650 
651     if (!strcmp("", prefix)) {
652         json_key_t *entry = NULL;
653 
654         entry = jparser_malloc(sizeof(json_key_t), magic, module_name);
655         if (NULL == entry) {
656             utils_err("jparser_malloc failed!");
657             return NULL;
658         }
659         memset(entry, 0, sizeof(json_key_t));
660         list_add_tail(&entry->list, &keylist);
661 
662         return &keylist;
663     }
664 
665     return NULL;
666 }
667 
contain_arr(const char * src,int src_len,const char ** arr_pre)668 int contain_arr(const char *src, int src_len, const char **arr_pre)
669 {
670     int i = 0;
671     int ret = -1;
672     int deep = 0;
673     const char *pre = NULL;
674 
675     if (NULL == src || NULL == arr_pre || src_len <= 0) {
676         return -1;
677     }
678 
679     *arr_pre = NULL;
680     for (i = 0; i < src_len; ++i) {
681         switch (src[i]) {
682         case '[':
683             {
684                 if (deep != 0) {
685                     return ret;
686                 }
687                 ++deep;
688                 if (!pre) {
689                     pre = &src[i];
690                 }
691             }
692             break;
693         case ']':
694             {
695                 if (deep != 1) {
696                     return ret;
697                 }
698                 --deep;
699                 if ('[' == src[i - 1]) {
700                     return ret;
701                 }
702             }
703             break;
704         default:
705             {
706                 if ((pre != NULL) && (0 == deep)) {
707                     return ret;
708                 }
709             }
710             break;
711         }
712     }
713     if ((NULL != pre) && (pre < src + src_len) && (pre >= src)) {
714         *arr_pre = pre;
715         ret = 0;
716     }
717     return ret;
718 }
719 
_json_value_by_arrname(char * src,int src_len,const char * key,int key_len,int * val_len)720 static char *_json_value_by_arrname(char *src, int src_len, const char *key,
721                                     int key_len, int *val_len)
722 {
723     char *pos = src;
724     char *entry = NULL;
725     const char *p = NULL;
726     const char *arr_pre = key;
727     const char *arr_suf = NULL;
728     int vtype;
729     int loop;
730     int loop_tmp = 0;
731     do {
732         loop = 0;
733 
734         arr_pre = strchr(arr_pre, '[');
735         if (arr_pre && (arr_pre < key + key_len)) {
736             arr_suf = strchr(arr_pre, ']');
737         }
738         if (arr_pre && arr_suf && (arr_suf < key + key_len)) {
739             loop_tmp = 0;
740             for (p = arr_pre + 1; p < arr_suf; ++p) {
741                 if (*p > '9' || *p < '0') {
742                     return NULL;
743                 }
744                 loop_tmp *= 10;
745                 loop_tmp += *p - '0';
746             }
747 
748             pos = json_get_object(JARRAY, pos, src + src_len);
749             if (pos != 0 && *pos != 0) {
750                 if (*pos == '[' && *(pos + 1) == ']') {
751                     return NULL;
752                 }
753             }
754 
755             json_array_for_each_entry(src, src_len, pos, entry, *val_len, vtype)
756             {
757                 if (entry && *val_len) {
758                     if (++loop >= loop_tmp) {
759                         break;
760                     }
761                 }
762             }
763 
764             if (loop != loop_tmp) {
765                 return NULL;
766             }
767             src = entry;
768             arr_pre = arr_suf + 1;
769         }
770     } while (arr_pre && arr_suf && (arr_pre < key + key_len));
771     return entry;
772 }
773 
LITE_json_keys_release(list_head_t * keylist)774 void LITE_json_keys_release(list_head_t *keylist)
775 {
776     json_key_t *pos, *tmp;
777 
778     if (NULL == keylist) {
779         return;
780     }
781 
782     list_for_each_entry_safe(pos, tmp, keylist, list, json_key_t)
783     {
784         if (pos->key) {
785             jparser_free(pos->key);
786         }
787         list_del(&pos->list);
788         jparser_free(pos);
789     }
790 }
791 
LITE_json_keys_of_ext(char * src,char * prefix,...)792 list_head_t *LITE_json_keys_of_ext(char *src, char *prefix, ...)
793 {
794     char *module_name = NULL;
795     int magic = 0;
796 
797 #if WITH_MEM_STATS_PER_MODULE
798 
799     va_list ap;
800     va_start(ap, prefix);
801     magic = va_arg(ap, int);
802     if (MEM_MAGIC == magic) {
803         module_name = va_arg(ap, char *);
804     }
805     va_end(ap);
806 #endif
807 
808     if (!src || !prefix) {
809         return NULL;
810     }
811 
812     return _LITE_json_keys_of_ext(JOBJECT, src, strlen(src), prefix, magic,
813                                   module_name);
814 }
815 
_LITE_json_value_of_ext(char * key,char * src,int src_len,int * val_len)816 static char *_LITE_json_value_of_ext(char *key, char *src, int src_len,
817                                      int *val_len)
818 {
819     char *value = NULL;
820     char *delim = NULL;
821     char *key_iter;
822     char *key_next;
823     char *src_iter;
824     const char *arr_pre = NULL;
825 
826     int value_len;
827     int key_len;
828     int obj_key_len = 0;
829     int key_type;
830     int src_iter_len;
831 
832     src_iter = src;
833     src_iter_len = src_len;
834     key_iter = key;
835     value_len = src_iter_len;
836     do {
837         delim = strchr(key_iter, '.');
838         if (delim != NULL) {
839             key_len = delim - key_iter;
840             key_type = JOBJECT;
841             key_next = key_iter;
842             if (0 == contain_arr(key_next, key_len, &arr_pre)) {
843                 key_type = JARRAY;
844                 obj_key_len = arr_pre - key_iter;
845                 if (obj_key_len) {
846                     value = json_get_value_by_name_len(src_iter, src_iter_len,
847                                                        key_next, obj_key_len,
848                                                        &value_len, 0);
849                 } else {
850                     value = src_iter;
851                 }
852             } else {
853                 value = json_get_value_by_name_len(
854                     src_iter, src_iter_len, key_next, key_len, &value_len, 0);
855             }
856 
857             if (NULL == value) {
858                 return NULL;
859             }
860 
861             if (key_type == JARRAY) {
862                 value = _json_value_by_arrname(
863                                  value, value_len, arr_pre,
864                                  key_len - obj_key_len, &value_len);
865                 if (value == NULL) {
866                     return NULL;
867                 }
868             }
869             src_iter = value;
870             src_iter_len = value_len;
871             key_iter = delim + 1;
872         }
873     } while (delim);
874 
875     key_len = strlen(key_iter);
876     key_next = key_iter;
877     key_type = JOBJECT;
878     if (0 == contain_arr(key_next, key_len, &arr_pre)) {
879         key_type = JARRAY;
880         obj_key_len = arr_pre - key_iter;
881         if (obj_key_len) {
882             value = json_get_value_by_name_len(src_iter, src_iter_len, key_next,
883                                                obj_key_len, &value_len, 0);
884         } else {
885             value = src_iter;
886         }
887     } else {
888         value = json_get_value_by_name_len(src_iter, src_iter_len, key_next,
889                                            key_len, &value_len, 0);
890     }
891 
892     if (NULL == value) {
893         return NULL;
894     }
895     if (key_type == JARRAY) {
896         value = _json_value_by_arrname(value, value_len, arr_pre,
897                                        key_len - obj_key_len,
898                                        &value_len);
899         if (value == NULL) {
900             return NULL;
901         }
902     }
903     *val_len = value_len;
904     return value;
905 }
906 
907 #endif /* #if WITH_JSON_TOKEN_EXT */
908 #endif /* #if WITH_JSON_KEYS_OF */
909 #endif
910