json_parser.c 7.1 KB

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