json.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <ctype.h>
  4. #include <math.h>
  5. #include <toaru/hashmap.h>
  6. #include <toaru/list.h>
  7. #include <toaru/json.h>
  8. typedef struct JSON_Value Value;
  9. /* Internal usage */
  10. struct JSON_Context {
  11. const char * string;
  12. int c;
  13. const char * error;
  14. };
  15. void json_free(Value * v) {
  16. if (v->type == JSON_TYPE_STRING) {
  17. free(v->string);
  18. }
  19. if (v->type == JSON_TYPE_OBJECT) {
  20. hashmap_free(v->object);
  21. free(v->object);
  22. }
  23. if (v->type == JSON_TYPE_ARRAY) {
  24. foreach(node, v->array) {
  25. json_free(node->value);
  26. }
  27. list_free(v->array);
  28. free(v->array);
  29. }
  30. free(v);
  31. }
  32. static Value * value(struct JSON_Context * ctx);
  33. static int peek(struct JSON_Context * ctx) {
  34. return ctx->string[ctx->c];
  35. }
  36. static void advance(struct JSON_Context * ctx) {
  37. ctx->c++;
  38. }
  39. static void whitespace(struct JSON_Context * ctx) {
  40. while (1) {
  41. int ch = peek(ctx);
  42. if (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t') {
  43. advance(ctx);
  44. } else {
  45. break;
  46. }
  47. }
  48. }
  49. static Value * string(struct JSON_Context * ctx) {
  50. if (peek(ctx) != '"') return NULL;
  51. advance(ctx);
  52. int size = 4;
  53. char * tmp = malloc(4);
  54. tmp[0] = 0;
  55. int used = 0;
  56. #define add(c) do { \
  57. if (used + 1 == size) { \
  58. size *= 2; \
  59. tmp = realloc(tmp, size); \
  60. } \
  61. tmp[used] = c; \
  62. tmp[used+1] = 0; \
  63. used++; \
  64. } while (0)
  65. while (1) {
  66. int ch = peek(ctx);
  67. if (ch == 0) goto string_error;
  68. if (ch == '"') {
  69. break;
  70. } else if (ch == '\\') {
  71. advance(ctx);
  72. ch = peek(ctx);
  73. if (ch == '"') add('"');
  74. else if (ch == '\\') add('\\');
  75. else if (ch == '/') add('/');
  76. else if (ch == 'b') add('\b');
  77. else if (ch == 'f') add('\f');
  78. else if (ch == 'n') add('\n');
  79. else if (ch == 'r') add('\r');
  80. else if (ch == 't') add('\t');
  81. else if (ch == 'u') {
  82. /* Parse hex */
  83. advance(ctx);
  84. char hex_digits[5];
  85. if (!isxdigit(peek(ctx))) goto string_error;
  86. hex_digits[0] = peek(ctx); advance(ctx);
  87. if (!isxdigit(peek(ctx))) goto string_error;
  88. hex_digits[1] = peek(ctx); advance(ctx);
  89. if (!isxdigit(peek(ctx))) goto string_error;
  90. hex_digits[2] = peek(ctx); advance(ctx);
  91. if (!isxdigit(peek(ctx))) goto string_error;
  92. hex_digits[3] = peek(ctx); /* will be advanced later */
  93. hex_digits[4] = 0;
  94. uint32_t val = strtoul(hex_digits, NULL, 16);
  95. if (val < 0x0080) {
  96. add(val);
  97. } else if (val < 0x0800) {
  98. add(0xC0 | (val >> 6));
  99. add(0x80 | (val & 0x3F));
  100. } else {
  101. add(0xE0 | (val >> 12));
  102. add(0x80 | ((val >> 6) & 0x3F));
  103. add(0x80 | (val & 0x3F));
  104. }
  105. } else {
  106. goto string_error;
  107. }
  108. advance(ctx);
  109. } else {
  110. add(ch);
  111. advance(ctx);
  112. }
  113. }
  114. if (peek(ctx) != '"') {
  115. ctx->error = "Unexpected EOF?";
  116. goto string_error;
  117. }
  118. advance(ctx);
  119. Value * out = malloc(sizeof(Value));
  120. out->type = JSON_TYPE_STRING;
  121. out->string = strdup(tmp);
  122. free(tmp);
  123. return out;
  124. string_error:
  125. free(tmp);
  126. return NULL;
  127. }
  128. static Value * object(struct JSON_Context * ctx) {
  129. if (peek(ctx) != '{') {
  130. ctx->error = "Expected { (internal error)";
  131. return NULL;
  132. }
  133. advance(ctx);
  134. Value * out;
  135. hashmap_t * output = hashmap_create(10);
  136. output->hash_val_free = (void (*)(void *))json_free;
  137. whitespace(ctx);
  138. if (peek(ctx) == '}') {
  139. advance(ctx);
  140. goto _object_done;
  141. }
  142. while (1) {
  143. whitespace(ctx);
  144. Value * s = string(ctx);
  145. if (!s) {
  146. ctx->error = "Expected string";
  147. break;
  148. }
  149. whitespace(ctx);
  150. if (peek(ctx) != ':') {
  151. ctx->error = "Expected :";
  152. break;
  153. }
  154. advance(ctx);
  155. Value * v = value(ctx);
  156. hashmap_set(output, s->string, v);
  157. json_free(s);
  158. if (peek(ctx) == '}') {
  159. advance(ctx);
  160. goto _object_done;
  161. }
  162. if (peek(ctx) != ',') {
  163. ctx->error = "Expected , or {";
  164. break;
  165. }
  166. advance(ctx);
  167. }
  168. hashmap_free(output);
  169. return NULL;
  170. _object_done:
  171. out = malloc(sizeof(Value));
  172. out->type = JSON_TYPE_OBJECT;
  173. out->object = output;
  174. return out;
  175. }
  176. static Value * boolean(struct JSON_Context * ctx) {
  177. int value = -1;
  178. if (peek(ctx) == 't') {
  179. advance(ctx);
  180. if (peek(ctx) != 'r') { ctx->error = "Invalid literal while parsing bool"; return NULL; }
  181. advance(ctx);
  182. if (peek(ctx) != 'u') { ctx->error = "Invalid literal while parsing bool"; return NULL; }
  183. advance(ctx);
  184. if (peek(ctx) != 'e') { ctx->error = "Invalid literal while parsing bool"; return NULL; }
  185. advance(ctx);
  186. value = 1;
  187. } else if (peek(ctx) == 'f') {
  188. advance(ctx);
  189. if (peek(ctx) != 'a') { ctx->error = "Invalid literal while parsing bool"; return NULL; }
  190. advance(ctx);
  191. if (peek(ctx) != 'l') { ctx->error = "Invalid literal while parsing bool"; return NULL; }
  192. advance(ctx);
  193. if (peek(ctx) != 's') { ctx->error = "Invalid literal while parsing bool"; return NULL; }
  194. advance(ctx);
  195. if (peek(ctx) != 'e') { ctx->error = "Invalid literal while parsing bool"; return NULL; }
  196. advance(ctx);
  197. value = 0;
  198. } else { ctx->error = "Invalid literal while parsing bool"; return NULL; }
  199. Value * out = malloc(sizeof(Value));
  200. out->type = JSON_TYPE_BOOL;
  201. out->boolean = value;
  202. return out;
  203. }
  204. static Value * null(struct JSON_Context * ctx) {
  205. if (peek(ctx) != 'n') { ctx->error = "Invalid literal while parsing null"; return NULL; }
  206. advance(ctx);
  207. if (peek(ctx) != 'u') { ctx->error = "Invalid literal while parsing null"; return NULL; }
  208. advance(ctx);
  209. if (peek(ctx) != 'l') { ctx->error = "Invalid literal while parsing null"; return NULL; }
  210. advance(ctx);
  211. if (peek(ctx) != 'l') { ctx->error = "Invalid literal while parsing null"; return NULL; }
  212. advance(ctx);
  213. Value * out = malloc(sizeof(Value));
  214. out->type = JSON_TYPE_NULL;
  215. return out;
  216. }
  217. static Value * number(struct JSON_Context * ctx) {
  218. double value = 0;
  219. int sign = 1;
  220. if (peek(ctx) == '-') {
  221. /* Negative */
  222. sign = -1;
  223. advance(ctx);
  224. }
  225. if (peek(ctx) == '0') {
  226. advance(ctx);
  227. } else if (isdigit(peek(ctx))) {
  228. /* Read any digit */
  229. value = peek(ctx) - '0';
  230. advance(ctx);
  231. while (isdigit(peek(ctx))) {
  232. value *= 10;
  233. value += peek(ctx) - '0';
  234. advance(ctx);
  235. }
  236. } else {
  237. ctx->error = "Expected digit";
  238. return NULL;
  239. }
  240. if (peek(ctx) == '.') {
  241. /* Read fractional part */
  242. advance(ctx);
  243. double multiplier = 0.1;
  244. /* read at least one digit */
  245. if (!isdigit(peek(ctx))) {
  246. ctx->error = "Expected digit";
  247. return NULL;
  248. }
  249. while (isdigit(peek(ctx))) {
  250. value += multiplier * (peek(ctx) - '0');
  251. multiplier *= 0.1;
  252. advance(ctx);
  253. }
  254. }
  255. if (peek(ctx) == 'e' || peek(ctx) == 'E') {
  256. /* Read exponent */
  257. int exp_sign = 1;
  258. advance(ctx);
  259. if (peek(ctx) == '+') advance(ctx);
  260. else if (peek(ctx) == '-') {
  261. exp_sign = -1;
  262. advance(ctx);
  263. }
  264. /* read digits */
  265. if (!isdigit(peek(ctx))) {
  266. ctx->error = "Expected digit";
  267. return NULL;
  268. }
  269. double exp = peek(ctx) - '0';
  270. advance(ctx);
  271. while (isdigit(peek(ctx))) {
  272. exp *= 10;
  273. exp += peek(ctx) - '0';
  274. advance(ctx);
  275. }
  276. value = value * pow(10.0,exp * exp_sign);
  277. }
  278. Value * out = malloc(sizeof(Value));
  279. out->type = JSON_TYPE_NUMBER;
  280. out->number = value * sign;
  281. return out;
  282. }
  283. static Value * array(struct JSON_Context * ctx) {
  284. if (peek(ctx) != '[') return NULL;
  285. advance(ctx);
  286. whitespace(ctx);
  287. list_t * output = list_create();
  288. Value * out;
  289. if (peek(ctx) == ']') {
  290. advance(ctx);
  291. goto _array_done;
  292. }
  293. while (1) {
  294. Value * next = value(ctx);
  295. if (!next) break;
  296. list_insert(output, next);
  297. if (peek(ctx) == ']') {
  298. advance(ctx);
  299. goto _array_done;
  300. }
  301. if (peek(ctx) != ',') {
  302. ctx->error = "Expected ,";
  303. break;
  304. }
  305. advance(ctx);
  306. }
  307. /* uh oh */
  308. foreach(node, output) {
  309. json_free(node->value);
  310. }
  311. list_free(output);
  312. free(output);
  313. return NULL;
  314. _array_done:
  315. out = malloc(sizeof(Value));
  316. out->type = JSON_TYPE_ARRAY;
  317. out->array = output;
  318. return out;
  319. }
  320. #define WHITE(c) { \
  321. Value * out = c; \
  322. whitespace(ctx); \
  323. return out; \
  324. }
  325. static Value * value(struct JSON_Context * ctx) {
  326. whitespace(ctx);
  327. if (peek(ctx) == '"') WHITE(string(ctx))
  328. else if (peek(ctx) == '{') WHITE(object(ctx))
  329. else if (peek(ctx) == '[') WHITE(array(ctx))
  330. else if (peek(ctx) == '-' || isdigit(peek(ctx))) WHITE(number(ctx))
  331. else if (peek(ctx) == 't') WHITE(boolean(ctx))
  332. else if (peek(ctx) == 'f') WHITE(boolean(ctx))
  333. else if (peek(ctx) == 'n') WHITE(null(ctx))
  334. ctx->error = "Unexpected value";
  335. return NULL;
  336. }
  337. Value * json_parse(const char * str) {
  338. struct JSON_Context ctx;
  339. ctx.string = str;
  340. ctx.c = 0;
  341. ctx.error = NULL;
  342. Value * out = value(&ctx);
  343. #if 0
  344. if (!out) {
  345. fprintf(stderr, "JSON parse error at %d (%c)\n", ctx.c, ctx.string[ctx.c]);
  346. fprintf(stderr, "%s\n", ctx.error);
  347. fprintf(stderr, "%s\n", ctx.string);
  348. for (int i = 0; i < ctx.c; ++i) { fprintf(stderr, " "); }
  349. fprintf(stderr, "^\n");
  350. }
  351. #endif
  352. return out;
  353. }
  354. Value * json_parse_file(const char * filename) {
  355. FILE * f = fopen(filename, "r");
  356. if (!f) return NULL;
  357. fseek(f, 0, SEEK_END);
  358. size_t size = ftell(f);
  359. fseek(f, 0, SEEK_SET);
  360. char * tmp = malloc(size + 1);
  361. fread(tmp, size, 1, f);
  362. tmp[size] = 0;
  363. fclose(f);
  364. Value * out = json_parse(tmp);
  365. free(tmp);
  366. return out;
  367. }