json_parser.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * Copyright (c) 2017-2019 Tencent Group. All rights reserved.
  3. * License-Identifier: Apache-2.0
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  6. * not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. /**
  19. * Edit by shockcao@tencent.com 2018/3/15
  20. */
  21. #include "json_parser.h"
  22. #include <stdarg.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include "lite-utils.h"
  27. #include "qcloud_iot_export_log.h"
  28. #define json_debug Log_d
  29. typedef struct JSON_NV {
  30. int nLen;
  31. int vLen;
  32. int vType;
  33. char *pN;
  34. char *pV;
  35. } JSON_NV;
  36. char *json_get_object(int type, char *str)
  37. {
  38. char *pos = 0;
  39. char ch = (type == JSOBJECT) ? '{' : '[';
  40. while (str != 0 && *str != 0) {
  41. if (*str == ' ') {
  42. str++;
  43. continue;
  44. }
  45. pos = (*str == ch) ? str : 0;
  46. break;
  47. }
  48. return pos;
  49. }
  50. char *json_get_next_object(int type, char *str, char **key, int *key_len, char **val, int *val_len, int *val_type)
  51. {
  52. char JsonMark[JSTYPEMAX][2] = {{'\"', '\"'}, {'{', '}'}, {'[', ']'}, {'0', ' '}};
  53. int iMarkDepth = 0, iValueType = JSNONE, iNameLen = 0, iValueLen = 0;
  54. char *p_cName = 0, *p_cValue = 0, *p_cPos = str;
  55. char lastchr = ' ';
  56. if (type == JSOBJECT) {
  57. /* Get Key */
  58. p_cPos = strchr(p_cPos, '"');
  59. if (!p_cPos) {
  60. return 0;
  61. }
  62. p_cName = ++p_cPos;
  63. p_cPos = strchr(p_cPos, '"');
  64. if (!p_cPos) {
  65. return 0;
  66. }
  67. iNameLen = p_cPos - p_cName;
  68. /* Get Value */
  69. p_cPos = strchr(p_cPos, ':');
  70. }
  71. while (p_cPos && *p_cPos) {
  72. if (*p_cPos == '"') {
  73. iValueType = JSSTRING;
  74. lastchr = *p_cPos;
  75. p_cValue = ++p_cPos;
  76. break;
  77. } else if (*p_cPos == '{') {
  78. iValueType = JSOBJECT;
  79. p_cValue = p_cPos++;
  80. break;
  81. } else if (*p_cPos == '[') {
  82. iValueType = JSARRAY;
  83. p_cValue = p_cPos++;
  84. break;
  85. } else if ((*p_cPos == '-') || (*p_cPos >= '0' && *p_cPos <= '9')) {
  86. iValueType = JSNUMBER;
  87. p_cValue = p_cPos++;
  88. break;
  89. } else if (*p_cPos == 't' || *p_cPos == 'T' || *p_cPos == 'f' || *p_cPos == 'F') {
  90. iValueType = JSBOOLEAN;
  91. p_cValue = p_cPos;
  92. break;
  93. } else if (*p_cPos == 'n' || *p_cPos == 'N') {
  94. iValueType = JSNULL;
  95. p_cValue = p_cPos;
  96. break;
  97. }
  98. p_cPos++;
  99. }
  100. while (p_cPos && *p_cPos && iValueType > JSNONE) {
  101. if (iValueType == JSBOOLEAN) {
  102. int len = strlen(p_cValue);
  103. if ((*p_cValue == 't' || *p_cValue == 'T') && len >= 4 &&
  104. (!strncmp(p_cValue, "true", 4) || !strncmp(p_cValue, "TRUE", 4))) {
  105. iValueLen = 4;
  106. // p_cPos = p_cValue + iValueLen;
  107. break;
  108. } else if ((*p_cValue == 'f' || *p_cValue == 'F') && len >= 5 &&
  109. (!strncmp(p_cValue, "false", 5) || !strncmp(p_cValue, "FALSE", 5))) {
  110. iValueLen = 5;
  111. // p_cPos = p_cValue + iValueLen;
  112. break;
  113. }
  114. } else if (iValueType == JSNULL) { // support null/NULL
  115. int nlen = strlen(p_cValue);
  116. if ((*p_cValue == 'n' || *p_cValue == 'N') && nlen >= 4 &&
  117. (!strncmp(p_cValue, "null", 4) || !strncmp(p_cValue, "NULL", 4))) {
  118. iValueLen = 4;
  119. // p_cPos = p_cValue + iValueLen;
  120. break;
  121. }
  122. } else if (iValueType == JSNUMBER) {
  123. // if (*p_cPos < '0' || *p_cPos > '9') {
  124. if ((*p_cPos < '0' || *p_cPos > '9') && (*p_cPos != '.')) { // support float
  125. iValueLen = p_cPos - p_cValue;
  126. break;
  127. }
  128. } else if (*p_cPos == JsonMark[iValueType][1]) {
  129. if (iMarkDepth == 0) {
  130. iValueLen = p_cPos - p_cValue + (iValueType == JSSTRING ? 0 : 1);
  131. p_cPos++;
  132. if ((iValueType == JSSTRING) && (lastchr == '\\')) {
  133. lastchr = *p_cPos;
  134. continue;
  135. } else {
  136. break;
  137. }
  138. } else {
  139. iMarkDepth--;
  140. }
  141. } else if (*p_cPos == JsonMark[iValueType][0]) {
  142. iMarkDepth++;
  143. }
  144. lastchr = *p_cPos;
  145. p_cPos++;
  146. }
  147. if (type == JSOBJECT) {
  148. *key = p_cName;
  149. *key_len = iNameLen;
  150. }
  151. *val = p_cValue;
  152. *val_len = iValueLen;
  153. *val_type = iValueType;
  154. if (iValueType == JSSTRING) {
  155. return p_cValue + iValueLen + 1;
  156. } else {
  157. return p_cValue + iValueLen;
  158. }
  159. }
  160. int json_parse_name_value(char *p_cJsonStr, int iStrLen, json_parse_cb pfnCB, void *p_CBData)
  161. {
  162. char *pos = 0, *key = 0, *val = 0;
  163. int klen = 0, vlen = 0, vtype = 0;
  164. char last_char = 0;
  165. int ret = JSON_RESULT_ERR;
  166. if (p_cJsonStr == NULL || iStrLen == 0 || pfnCB == NULL) {
  167. return ret;
  168. }
  169. if (iStrLen != strlen(p_cJsonStr)) {
  170. Log_w("Backup last_char since %d != %d", iStrLen, (int)strlen(p_cJsonStr));
  171. backup_json_str_last_char(p_cJsonStr, iStrLen, last_char);
  172. }
  173. json_object_for_each_kv(p_cJsonStr, pos, key, klen, val, vlen, vtype)
  174. {
  175. if (key && klen && val && vlen) {
  176. ret = JSON_RESULT_OK;
  177. if (JSON_PARSE_FINISH == pfnCB(key, klen, val, vlen, vtype, p_CBData)) {
  178. break;
  179. }
  180. }
  181. }
  182. if (iStrLen != strlen(p_cJsonStr)) {
  183. restore_json_str_last_char(p_cJsonStr, iStrLen, last_char);
  184. }
  185. return ret;
  186. }
  187. int json_get_value_by_name_cb(char *p_cName, int iNameLen, char *p_cValue, int iValueLen, int iValueType,
  188. void *p_CBData)
  189. {
  190. JSON_NV *p_stNameValue = (JSON_NV *)p_CBData;
  191. #if (JSON_DEBUG == 1)
  192. int i;
  193. if (p_cName) {
  194. json_debug("Name:");
  195. for (i = 0; i < iNameLen; i++) {
  196. json_debug("%c", *(p_cName + i));
  197. }
  198. }
  199. if (p_cValue) {
  200. json_debug("Value:");
  201. for (i = 0; i < iValueLen; i++) {
  202. json_debug("%c", *(p_cValue + i));
  203. }
  204. }
  205. #endif
  206. if ((iNameLen == p_stNameValue->nLen) && !strncmp(p_cName, p_stNameValue->pN, p_stNameValue->nLen)) {
  207. p_stNameValue->pV = p_cValue;
  208. p_stNameValue->vLen = iValueLen;
  209. p_stNameValue->vType = iValueType;
  210. return JSON_PARSE_FINISH;
  211. } else {
  212. return JSON_PARSE_OK;
  213. }
  214. }
  215. char *json_get_value_by_name(char *p_cJsonStr, int iStrLen, char *p_cName, int *p_iValueLen, int *p_iValueType)
  216. {
  217. JSON_NV stNV;
  218. memset(&stNV, 0, sizeof(stNV));
  219. stNV.pN = p_cName;
  220. stNV.nLen = strlen(p_cName);
  221. if (JSON_RESULT_OK == json_parse_name_value(p_cJsonStr, iStrLen, json_get_value_by_name_cb, (void *)&stNV)) {
  222. if (p_iValueLen) {
  223. *p_iValueLen = stNV.vLen;
  224. }
  225. if (p_iValueType) {
  226. *p_iValueType = stNV.vType;
  227. if (JSNULL == stNV.vType) {
  228. stNV.pV = NULL;
  229. }
  230. }
  231. }
  232. return stNV.pV;
  233. }