frozen.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // Copyright (c) 2004-2013 Sergey Lyubka <[email protected]>
  2. // Copyright (c) 2013 Cesanta Software Limited
  3. // All rights reserved
  4. //
  5. // This library is dual-licensed: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License version 2 as
  7. // published by the Free Software Foundation. For the terms of this
  8. // license, see <http://www.gnu.org/licenses/>.
  9. //
  10. // You are free to use this library under the terms of the GNU General
  11. // Public License, but WITHOUT ANY WARRANTY; without even the implied
  12. // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. // See the GNU General Public License for more details.
  14. //
  15. // Alternatively, you can license this library under a commercial
  16. // license, as set out in <http://cesanta.com/products.html>.
  17. #include <stdio.h>
  18. #include "frozen.h"
  19. struct frozen {
  20. const char *end;
  21. const char *cur;
  22. struct json_token *tokens;
  23. int max_tokens;
  24. int num_tokens;
  25. };
  26. static int parse_object(struct frozen *f);
  27. static int parse_value(struct frozen *f);
  28. #define EXPECT(cond, err_code) do { if (!(cond)) return (err_code); } while (0)
  29. #define TRY(expr) do { int n = expr; if (n < 0) return n; } while (0)
  30. #define END_OF_STRING (-1)
  31. static int left(const struct frozen *f) {
  32. return f->end - f->cur;
  33. }
  34. static int is_space(int ch) {
  35. return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';
  36. }
  37. static void skip_whitespaces(struct frozen *f) {
  38. while (f->cur < f->end && is_space(*f->cur)) f->cur++;
  39. }
  40. static int cur(struct frozen *f) {
  41. skip_whitespaces(f);
  42. return f->cur >= f->end ? END_OF_STRING : * (unsigned char *) f->cur;
  43. }
  44. static int test_and_skip(struct frozen *f, int expected) {
  45. int ch = cur(f);
  46. if (ch == expected) { f->cur++; return 0; }
  47. return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID;
  48. }
  49. static int is_alpha(int ch) {
  50. return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
  51. }
  52. static int is_digit(int ch) {
  53. return ch >= '0' && ch <= '9';
  54. }
  55. static int is_hex_digit(int ch) {
  56. return is_digit(ch) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
  57. }
  58. static int get_escape_len(const char *s, int len) {
  59. switch (*s) {
  60. case 'u':
  61. return len < 6 ? JSON_STRING_INCOMPLETE :
  62. is_hex_digit(s[1]) && is_hex_digit(s[2]) &&
  63. is_hex_digit(s[3]) && is_hex_digit(s[4]) ? 5 : JSON_STRING_INVALID;
  64. case '"': case '\\': case '/': case 'b':
  65. case 'f': case 'n': case 'r': case 't':
  66. return len < 2 ? JSON_STRING_INCOMPLETE : 1;
  67. default:
  68. return JSON_STRING_INVALID;
  69. }
  70. }
  71. static int capture_ptr(struct frozen *f, const char *ptr, int type) {
  72. if (f->tokens == 0 || f->max_tokens == 0) return 0;
  73. if (f->num_tokens >= f->max_tokens) return JSON_TOKEN_ARRAY_TOO_SMALL;
  74. f->tokens[f->num_tokens].ptr = ptr;
  75. f->tokens[f->num_tokens].type = type;
  76. f->num_tokens++;
  77. return 0;
  78. }
  79. static int capture_len(struct frozen *f, int token_index, const char *ptr) {
  80. if (f->tokens == 0 || f->max_tokens == 0) return 0;
  81. EXPECT(token_index >= 0 && token_index < f->max_tokens, JSON_STRING_INVALID);
  82. f->tokens[token_index].len = ptr - f->tokens[token_index].ptr;
  83. f->tokens[token_index].num_desc = (f->num_tokens - 1) - token_index;
  84. return 0;
  85. }
  86. // identifier = letter { letter | digit | '_' }
  87. static int parse_identifier(struct frozen *f) {
  88. EXPECT(is_alpha(cur(f)), JSON_STRING_INVALID);
  89. TRY(capture_ptr(f, f->cur, JSON_TYPE_STRING));
  90. while (f->cur < f->end &&
  91. (*f->cur == '_' || is_alpha(*f->cur) || is_digit(*f->cur))) {
  92. f->cur++;
  93. }
  94. capture_len(f, f->num_tokens - 1, f->cur);
  95. return 0;
  96. }
  97. static int get_utf8_char_len(unsigned char ch) {
  98. if ((ch & 0x80) == 0) return 1;
  99. switch (ch & 0xf0) {
  100. case 0xf0: return 4;
  101. case 0xe0: return 3;
  102. default: return 2;
  103. }
  104. }
  105. // string = '"' { quoted_printable_chars } '"'
  106. static int parse_string(struct frozen *f) {
  107. int n, ch = 0, len = 0;
  108. TRY(test_and_skip(f, '"'));
  109. TRY(capture_ptr(f, f->cur, JSON_TYPE_STRING));
  110. for (; f->cur < f->end; f->cur += len) {
  111. ch = * (unsigned char *) f->cur;
  112. len = get_utf8_char_len(ch);
  113. //printf("[%c] [%d]\n", ch, len);
  114. EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); // No control chars
  115. EXPECT(len < left(f), JSON_STRING_INCOMPLETE);
  116. if (ch == '\\') {
  117. EXPECT((n = get_escape_len(f->cur + 1, left(f))) > 0, n);
  118. len += n;
  119. } else if (ch == '"') {
  120. capture_len(f, f->num_tokens - 1, f->cur);
  121. f->cur++;
  122. break;
  123. };
  124. }
  125. return ch == '"' ? 0 : JSON_STRING_INCOMPLETE;
  126. }
  127. // number = [ '-' ] digit+ [ '.' digit+ ] [ ['e'|'E'] ['+'|'-'] digit+ ]
  128. static int parse_number(struct frozen *f) {
  129. int ch = cur(f);
  130. TRY(capture_ptr(f, f->cur, JSON_TYPE_NUMBER));
  131. if (ch == '-') f->cur++;
  132. EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
  133. EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
  134. while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
  135. if (f->cur < f->end && f->cur[0] == '.') {
  136. f->cur++;
  137. EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
  138. EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
  139. while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
  140. }
  141. if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) {
  142. f->cur++;
  143. EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
  144. if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++;
  145. EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
  146. EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
  147. while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
  148. }
  149. capture_len(f, f->num_tokens - 1, f->cur);
  150. return 0;
  151. }
  152. // array = '[' [ value { ',' value } ] ']'
  153. static int parse_array(struct frozen *f) {
  154. int ind;
  155. TRY(test_and_skip(f, '['));
  156. TRY(capture_ptr(f, f->cur - 1, JSON_TYPE_ARRAY));
  157. ind = f->num_tokens - 1;
  158. while (cur(f) != ']') {
  159. TRY(parse_value(f));
  160. if (cur(f) == ',') f->cur++;
  161. }
  162. TRY(test_and_skip(f, ']'));
  163. capture_len(f, ind, f->cur);
  164. return 0;
  165. }
  166. static int compare(const char *s, const char *str, int len) {
  167. int i = 0;
  168. while (i < len && s[i] == str[i]) i++;
  169. return i == len ? 1 : 0;
  170. }
  171. // value = 'null' | 'true' | 'false' | number | string | array | object
  172. static int parse_value(struct frozen *f) {
  173. int ch = cur(f);
  174. if (ch == '"') {
  175. TRY(parse_string(f));
  176. } else if (ch == '{') {
  177. TRY(parse_object(f));
  178. } else if (ch == '[') {
  179. TRY(parse_array(f));
  180. } else if (ch == 'n' && left(f) > 4 && compare(f->cur, "null", 4)) {
  181. TRY(capture_ptr(f, f->cur, JSON_TYPE_NULL));
  182. f->cur += 4;
  183. capture_len(f, f->num_tokens - 1, f->cur);
  184. } else if (ch == 't' && left(f) > 4 && compare(f->cur, "true", 4)) {
  185. TRY(capture_ptr(f, f->cur, JSON_TYPE_TRUE));
  186. f->cur += 4;
  187. capture_len(f, f->num_tokens - 1, f->cur);
  188. } else if (ch == 'f' && left(f) > 5 && compare(f->cur, "false", 5)) {
  189. TRY(capture_ptr(f, f->cur, JSON_TYPE_FALSE));
  190. f->cur += 5;
  191. capture_len(f, f->num_tokens - 1, f->cur);
  192. } else if (is_digit(ch) ||
  193. (ch == '-' && f->cur + 1 < f->end && is_digit(f->cur[1]))) {
  194. TRY(parse_number(f));
  195. } else {
  196. return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID;
  197. }
  198. return 0;
  199. }
  200. // key = identifier | string
  201. static int parse_key(struct frozen *f) {
  202. int ch = cur(f);
  203. #if 0
  204. printf("%s 1 [%.*s]\n", __func__, (int) (f->end - f->cur), f->cur);
  205. #endif
  206. if (is_alpha(ch)) {
  207. TRY(parse_identifier(f));
  208. } else if (ch == '"') {
  209. TRY(parse_string(f));
  210. } else {
  211. return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID;
  212. }
  213. return 0;
  214. }
  215. // pair = key ':' value
  216. static int parse_pair(struct frozen *f) {
  217. TRY(parse_key(f));
  218. TRY(test_and_skip(f, ':'));
  219. TRY(parse_value(f));
  220. return 0;
  221. }
  222. // object = '{' pair { ',' pair } '}'
  223. static int parse_object(struct frozen *f) {
  224. int ind;
  225. TRY(test_and_skip(f, '{'));
  226. TRY(capture_ptr(f, f->cur - 1, JSON_TYPE_OBJECT));
  227. ind = f->num_tokens - 1;
  228. while (cur(f) != '}') {
  229. TRY(parse_pair(f));
  230. if (cur(f) == ',') f->cur++;
  231. }
  232. TRY(test_and_skip(f, '}'));
  233. capture_len(f, ind, f->cur);
  234. return 0;
  235. }
  236. // json = object
  237. int parse_json(const char *s, int s_len, struct json_token *arr, int arr_len) {
  238. struct frozen frozen = { s + s_len, s, arr, arr_len, 0 };
  239. if (s == 0 || s_len < 0) return JSON_STRING_INVALID;
  240. if (s_len == 0) return JSON_STRING_INCOMPLETE;
  241. TRY(parse_object(&frozen));
  242. TRY(capture_ptr(&frozen, frozen.cur, JSON_TYPE_EOF));
  243. capture_len(&frozen, frozen.num_tokens, frozen.cur);
  244. return frozen.cur - s;
  245. }
  246. static int path_part_len(const char *p) {
  247. int i = 0;
  248. while (p[i] != '\0' && p[i] != '[' && p[i] != '.') i++;
  249. return i;
  250. }
  251. const struct json_token *find_json_token(const struct json_token *toks,
  252. const char *path) {
  253. if (path == 0 || path[0] == '\0') return 0;
  254. for (;;) {
  255. int i, ind2 = 0, ind = -1, skip = 2, n = path_part_len(path);
  256. if (path[0] == '\0') return 0;
  257. if (path[0] == '[') {
  258. if (toks->type != JSON_TYPE_ARRAY || !is_digit(path[1])) return 0;
  259. for (ind = 0, n = 1; path[n] != ']' && path[n] != '\0'; n++) {
  260. if (!is_digit(path[n])) return 0;
  261. ind *= 10;
  262. ind += path[n] - '0';
  263. }
  264. if (path[n++] != ']') return 0;
  265. skip = 1; // In objects, we skip 2 elems while iterating, in arrays 1.
  266. } else if (toks->type != JSON_TYPE_OBJECT) return 0;
  267. toks++;
  268. for (i = 0; i < toks[-1].num_desc; i += skip, ind2++) {
  269. // ind == -1 indicated that we're iterating an array, not object
  270. if (ind == -1 && toks[i].type != JSON_TYPE_STRING) return 0;
  271. if (ind2 == ind ||
  272. (ind == -1 && toks[i].len == n && compare(path, toks[i].ptr, n))) {
  273. i += skip - 1;
  274. break;
  275. };
  276. if (toks[i + 1].type == JSON_TYPE_ARRAY ||
  277. toks[i + 1].type == JSON_TYPE_OBJECT) {
  278. i += toks[i + 1].num_desc;
  279. }
  280. }
  281. if (i == toks[-1].num_desc) return 0;
  282. path += n;
  283. if (path[0] == '.') path++;
  284. if (path[0] == '\0') return &toks[i];
  285. toks += i;
  286. }
  287. return 0;
  288. }
  289. int json_emit_int(char *buf, int buf_len, long int value) {
  290. return buf_len <= 0 ? 0 : snprintf(buf, buf_len, "%ld", value);
  291. }
  292. int json_emit_double(char *buf, int buf_len, double value) {
  293. return buf_len <= 0 ? 0 : snprintf(buf, buf_len, "%g", value);
  294. }
  295. int json_emit_quoted_str(char *buf, int buf_len, const char *str) {
  296. int i = 0, j = 0, ch;
  297. #define EMIT(x) do { if (j < buf_len) buf[j++] = x; } while (0)
  298. EMIT('"');
  299. while ((ch = str[i++]) != '\0' && j < buf_len) {
  300. switch (ch) {
  301. case '"': EMIT('\\'); EMIT('"'); break;
  302. case '\\': EMIT('\\'); EMIT('\\'); break;
  303. case '\b': EMIT('\\'); EMIT('b'); break;
  304. case '\f': EMIT('\\'); EMIT('f'); break;
  305. case '\n': EMIT('\\'); EMIT('n'); break;
  306. case '\r': EMIT('\\'); EMIT('r'); break;
  307. case '\t': EMIT('\\'); EMIT('t'); break;
  308. default: EMIT(ch);
  309. }
  310. }
  311. EMIT('"');
  312. EMIT(0);
  313. return j == 0 ? 0 : j - 1;
  314. }
  315. int json_emit_raw_str(char *buf, int buf_len, const char *str) {
  316. return buf_len <= 0 ? 0 : snprintf(buf, buf_len, "%s", str);
  317. }