Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.69 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5. #include <stdint.h>
  6.  
  7. #define JSON_THINGS_SIZE 256
  8. #define JSON_STRINGS_SIZE 1024
  9. #define JSON_COMPOUNDS_SIZE 256
  10.  
  11. typedef enum {
  12. JSON_UNPARSED,
  13. JSON_NULL,
  14. JSON_BOOL,
  15. JSON_NUMBER,
  16. JSON_STRING,
  17. JSON_ARRAY,
  18. JSON_OBJECT
  19. } json_thing_type_t;
  20.  
  21. typedef struct json_compound_t {
  22. const char *key;
  23. struct json_thing_t *thing;
  24. struct json_compound_t *next;
  25. } json_compound_t;
  26.  
  27. typedef struct json_thing_t {
  28. json_thing_type_t type;
  29.  
  30. union {
  31. const char *string;
  32. int32_t integer;
  33. bool boolean;
  34. json_compound_t *compound;
  35. } val;
  36. } json_thing_t;
  37.  
  38. typedef struct {
  39. void *mem_things;
  40. void *mem_strings;
  41. void *mem_compounds;
  42.  
  43. json_thing_t *things;
  44. uint16_t things_rem;
  45. uint16_t things_total;
  46.  
  47. char *strings;
  48. uint16_t strings_rem;
  49. uint16_t strings_total;
  50.  
  51. json_compound_t *compounds;
  52. uint16_t compounds_rem;
  53. uint16_t compounds_total;
  54. } json_t;
  55.  
  56. json_t *json_init(void)
  57. {
  58. void *mem = malloc(sizeof(json_t)
  59. + sizeof(json_thing_t) * JSON_THINGS_SIZE);
  60. if (mem == NULL) {
  61. fprintf(stderr, "%d\n", __LINE__); return NULL;
  62. }
  63.  
  64. void *mem2 = malloc(JSON_STRINGS_SIZE);
  65. if (mem2 == NULL) {
  66. free(mem);
  67. fprintf(stderr, "%d\n", __LINE__); return NULL;
  68.  
  69. }
  70.  
  71. void *mem3 = malloc(sizeof(json_compound_t) * JSON_COMPOUNDS_SIZE);
  72. if (mem3 == NULL) {
  73. free(mem);
  74. free(mem2);
  75. fprintf(stderr, "%d\n", __LINE__); return NULL;
  76.  
  77. }
  78.  
  79. json_t *json = (json_t*)mem;
  80.  
  81. json->mem_things = mem;
  82. json->mem_strings = mem2;
  83. json->mem_compounds = mem3;
  84.  
  85. json->things = (json_thing_t*)((char*)mem + sizeof(json_t));
  86. json->things_rem = JSON_THINGS_SIZE;
  87. json->things_total = JSON_THINGS_SIZE;
  88.  
  89. json->strings = mem2;
  90. json->strings_rem = JSON_STRINGS_SIZE;
  91. json->strings_total = JSON_STRINGS_SIZE;
  92.  
  93. json->compounds = mem3;
  94. json->compounds_rem = JSON_COMPOUNDS_SIZE;
  95. json->compounds_total = JSON_COMPOUNDS_SIZE;
  96.  
  97. return json;
  98. }
  99.  
  100. json_thing_t *json_allocate_thing(json_t *json)
  101. {
  102. if (json->things_rem == 0) {
  103. // TODO: reallocate.
  104. fprintf(stderr, "%d\n", __LINE__); return NULL;
  105. }
  106.  
  107. json_thing_t *thing = json->things;
  108. json->things += 1;
  109. json->things_rem -= 1;
  110.  
  111. return thing;
  112. }
  113.  
  114. const char *json_allocate_string(json_t *json, const char *str, size_t len)
  115. {
  116. if (json->strings_rem < len + 1) {
  117. // TODO: reallocate.
  118. fprintf(stderr, "%d\n", __LINE__); return NULL;
  119. }
  120.  
  121. char *ret = json->strings;
  122. strncpy(ret, str, len);
  123. ret[len] = '\0';
  124.  
  125. json->strings += (len + 1);
  126. json->strings_rem -= (len + 1);
  127.  
  128. return ret;
  129. }
  130.  
  131. json_compound_t *json_allocate_compound(json_t *json)
  132. {
  133. if (json->compounds_rem == 0) {
  134. // TODO: reallocate.
  135. fprintf(stderr, "%d\n", __LINE__); return NULL;
  136.  
  137. }
  138.  
  139. json_compound_t *compound = json->compounds;
  140. json->compounds += 1;
  141. json->compounds_rem -= 1;
  142.  
  143. compound->key = NULL;
  144. compound->thing = NULL;
  145. compound->next = NULL;
  146.  
  147. return compound;
  148. }
  149.  
  150. json_thing_t *json_get_singleton(json_t *json, const char **json_str,
  151. int8_t type)
  152. {
  153. json_thing_t *thing = json_allocate_thing(json);
  154. if (thing == NULL) {
  155. fprintf(stderr, "%d\n", __LINE__); return NULL;
  156.  
  157. }
  158.  
  159. switch (type) {
  160. case 0:
  161. thing->type = JSON_NULL;
  162. (*json_str) += 4;
  163. break;
  164.  
  165. case 1:
  166. thing->type = JSON_BOOL;
  167. thing->val.boolean = true;
  168. (*json_str) += 4;
  169. break;
  170.  
  171. case -1:
  172. thing->type = JSON_BOOL;
  173. thing->val.boolean = false;
  174. (*json_str) += 5;
  175. break;
  176. }
  177.  
  178. return thing;
  179. }
  180.  
  181. json_thing_t *json_get_unparsed(json_t *json, const char **json_str,
  182. const char *stop_chars)
  183. {
  184. json_thing_t *thing = json_allocate_thing(json);
  185. if (thing == NULL) {
  186. fprintf(stderr, "%d\n", __LINE__);
  187. return NULL;
  188. }
  189.  
  190. size_t sclen = strlen(stop_chars);
  191.  
  192. if (sclen) {
  193. while (**json_str != '\0') {
  194. for (uint8_t i = 0; i < sclen; ++i) {
  195. if (**json_str == stop_chars[i]) {
  196. goto END;
  197. }
  198. }
  199.  
  200. (*json_str)++;
  201. }
  202. }
  203.  
  204. END:
  205. thing->type = JSON_UNPARSED;
  206.  
  207. return thing;
  208. }
  209.  
  210. json_thing_t *json_get_string(json_t *json, const char **json_str)
  211. {
  212. json_thing_t *thing = json_allocate_thing(json);
  213. if (thing == NULL) {
  214. fprintf(stderr, "%d\n", __LINE__); return NULL;
  215. }
  216.  
  217. thing->type = JSON_STRING;
  218. thing->val.string = json->strings;
  219.  
  220. (*json_str)++;
  221.  
  222. bool escape = false;
  223. for (; **json_str != '\0'; (*json_str)++) {
  224. if (escape) {
  225. switch (**json_str) {
  226. case '\\':
  227. *(json->strings) = '\\';
  228. break;
  229.  
  230. case 't':
  231. *(json->strings) = '\t';
  232. break;
  233.  
  234. case 'r':
  235. *(json->strings) = '\r';
  236. break;
  237.  
  238. case 'n':
  239. *(json->strings) = '\n';
  240. break;
  241.  
  242. case '"':
  243. *(json->strings) = '"';
  244. break;
  245.  
  246. default:
  247. *(json->strings) = **json_str;
  248. break;
  249. }
  250.  
  251. json->strings += 1;
  252. json->strings_rem -= 1;
  253. escape = false;
  254. } else {
  255. switch (**json_str) {
  256. case '\\':
  257. escape = true;
  258. break;
  259.  
  260. case '"':
  261. (*json_str)++;
  262. goto END;
  263.  
  264. default:
  265. *(json->strings) = **json_str;
  266.  
  267. json->strings += 1;
  268. json->strings_rem -= 1;
  269. break;
  270. }
  271. }
  272.  
  273. if (json->strings_rem < 2) {
  274. // TODO: reallocate.
  275. fprintf(stderr, "%d\n", __LINE__);
  276. return NULL;
  277. }
  278. }
  279.  
  280. END:
  281. *(json->strings) = '\0';
  282. json->strings += 1;
  283. json->strings_rem -= 1;
  284.  
  285. return thing;
  286. }
  287.  
  288. json_thing_t *json_parse(json_t *json, const char **json_str,
  289. const char *stop_chars);
  290.  
  291. json_thing_t *json_get_object(json_t *json, const char **json_str)
  292. {
  293. json_thing_t *obj_head = json_allocate_thing(json);
  294. if (obj_head == NULL) {
  295. fprintf(stderr, "%d\n", __LINE__); return NULL;
  296. }
  297.  
  298. obj_head->type = JSON_OBJECT;
  299. obj_head->val.compound = NULL;
  300.  
  301. (*json_str)++;
  302.  
  303. json_compound_t *last_compound = NULL;
  304. json_compound_t *compound = NULL;
  305.  
  306. bool is_key = true;
  307.  
  308. while (**json_str != '\0') {
  309. if (is_key) {
  310. if (compound == NULL) {
  311. compound = json_allocate_compound(json);
  312. if (compound == NULL) {
  313. fprintf(stderr, "%d\n", __LINE__);
  314. return NULL;
  315. }
  316.  
  317. compound->key = json->strings;
  318. compound->thing = NULL;
  319. compound->next = NULL;
  320. }
  321.  
  322. switch (**json_str) {
  323. case '}':
  324. (*json_str)++;
  325. goto END;
  326.  
  327. case ':':
  328. // TODO: detect out of memory.
  329. *(json->strings) = '\0';
  330. json->strings += 1;
  331. json->strings_rem -= 1;
  332.  
  333. is_key = false;
  334. (*json_str)++;
  335. break;
  336.  
  337. case ' ':
  338. case ',':
  339. (*json_str)++;
  340. continue;
  341.  
  342. default:
  343. *(json->strings) = **json_str;
  344.  
  345. // TODO: detect out of memory.
  346. json->strings += 1;
  347. json->strings_rem -= 1;
  348.  
  349. (*json_str)++;
  350. continue;
  351. }
  352. }
  353.  
  354. json_thing_t *thing = json_parse(json, json_str, ",}");
  355. if (thing == NULL) {
  356. fprintf(stderr, "%d\n", __LINE__);
  357. return NULL;
  358. }
  359.  
  360. compound->thing = thing;
  361.  
  362. if (last_compound != NULL) {
  363. last_compound->next = compound;
  364. } else {
  365. obj_head->val.compound = compound;
  366. }
  367.  
  368. last_compound = compound;
  369. compound = NULL;
  370. is_key = true;
  371. }
  372.  
  373. END:
  374. return obj_head;
  375. }
  376.  
  377. json_thing_t *json_get_array(json_t *json, const char **json_str)
  378. {
  379. json_thing_t *array_head = json_allocate_thing(json);
  380. if (array_head == NULL) {
  381. fprintf(stderr, "%d\n", __LINE__); return NULL;
  382. }
  383.  
  384. array_head->type = JSON_ARRAY;
  385. array_head->val.compound = NULL;
  386.  
  387. (*json_str)++;
  388.  
  389. json_compound_t *last_compound = NULL;
  390.  
  391. while (**json_str != '\0') {
  392. switch (**json_str) {
  393. json_thing_t *thing;
  394. json_compound_t *compound;
  395.  
  396. case ']':
  397. (*json_str)++;
  398. goto END;
  399.  
  400. case ' ':
  401. case ',':
  402. (*json_str)++;
  403. break;
  404.  
  405. default:
  406. thing = json_parse(json, json_str, ",]");
  407. if (thing == NULL) {
  408. fprintf(stderr, "%d\n", __LINE__); return NULL;
  409. }
  410.  
  411. compound = json_allocate_compound(json);
  412. if (compound == NULL) {
  413. fprintf(stderr, "%d\n", __LINE__); return NULL;
  414. }
  415.  
  416. compound->thing = thing;
  417.  
  418. if (last_compound != NULL) {
  419. last_compound->next = compound;
  420. } else {
  421. array_head->val.compound = compound;
  422. }
  423.  
  424. last_compound = compound;
  425.  
  426. break;
  427. }
  428. }
  429.  
  430. END:
  431. return array_head;
  432. }
  433.  
  434. json_thing_t *json_get_number(json_t *json, const char **json_str)
  435. {
  436. json_thing_t *thing = json_allocate_thing(json);
  437. if (thing == NULL) {
  438. fprintf(stderr, "%d\n", __LINE__); return NULL;
  439. }
  440.  
  441. thing->type = JSON_NUMBER;
  442. thing->val.integer = 0;
  443.  
  444. int8_t sign = 1;
  445. if (**json_str == '-') {
  446. sign = -1;
  447. (*json_str)++;
  448. } else if (**json_str == '+') {
  449. (*json_str)++;
  450. }
  451.  
  452. for (; **json_str != '\0'; (*json_str)++) {
  453. if (**json_str >= '0' && **json_str <= '9') {
  454. thing->val.integer *= 10;
  455. thing->val.integer += (**json_str - '0');
  456. } else {
  457. (*json_str)++;
  458. break;
  459. }
  460. }
  461.  
  462. thing->val.integer *= sign;
  463.  
  464. return thing;
  465. }
  466.  
  467. json_thing_t *json_parse(json_t *json, const char **json_str,
  468. const char *stop_chars)
  469. {
  470. while (**json_str != '\0') {
  471. switch (**json_str) {
  472. case '{':
  473. return json_get_object(json, json_str);
  474.  
  475. case '[':
  476. return json_get_array(json, json_str);
  477.  
  478. case '"':
  479. return json_get_string(json, json_str);
  480.  
  481. case '+':
  482. case '-':
  483. case '0':
  484. case '1':
  485. case '2':
  486. case '3':
  487. case '4':
  488. case '5':
  489. case '6':
  490. case '7':
  491. case '8':
  492. case '9':
  493. return json_get_number(json, json_str);
  494.  
  495. case 'n':
  496. case 't':
  497. case 'f':
  498. if (strncmp(*json_str, "null", 4) == 0) {
  499. return json_get_singleton(json, json_str, 0);
  500. } else if (strncmp(*json_str, "true", 4) == 0) {
  501. return json_get_singleton(json, json_str, 1);
  502. } else if (strncmp(*json_str, "false", 5) == 0) {
  503. return json_get_singleton(json, json_str, -1);
  504. } else {
  505. return json_get_unparsed(json, json_str, stop_chars);
  506. }
  507.  
  508. case ' ':
  509. case '\t':
  510. case '\r':
  511. case '\n':
  512. (*json_str)++;
  513. break;
  514.  
  515. default:
  516. (*json_str)++;
  517. return json_get_unparsed(json, json_str, stop_chars);
  518. }
  519. }
  520.  
  521. fprintf(stderr, "%d\n", __LINE__); return NULL;
  522. }
  523.  
  524. void json_print_thing(const json_thing_t *thing) {
  525. switch (thing->type) {
  526. case JSON_UNPARSED:
  527. printf("<*UNPARSED*>");
  528. break;
  529.  
  530. case JSON_NULL:
  531. printf("null");
  532. break;
  533.  
  534. case JSON_BOOL:
  535. printf("%s", thing->val.boolean ? "true" : "false");
  536. break;
  537.  
  538. case JSON_NUMBER:
  539. printf("%d", thing->val.integer);
  540. break;
  541.  
  542. case JSON_STRING:
  543. putchar('"');
  544. for (const char *c = thing->val.string; *c != '\0'; ++c) {
  545. switch (*c) {
  546. case '\\':
  547. putchar('\\');
  548. putchar('\\');
  549. break;
  550.  
  551. case '\t':
  552. putchar('\\');
  553. putchar('t');
  554. break;
  555.  
  556. case '\r':
  557. putchar('\\');
  558. putchar('r');
  559. break;
  560.  
  561. case '\n':
  562. putchar('\\');
  563. putchar('n');
  564. break;
  565.  
  566. case '"':
  567. putchar('\\');
  568. putchar('"');
  569. break;
  570.  
  571. default:
  572. putchar(*c);
  573. }
  574. }
  575. putchar('"');
  576. break;
  577.  
  578. case JSON_ARRAY:
  579. putchar('[');
  580.  
  581. for (const json_compound_t *compound = thing->val.compound;
  582. compound != NULL; compound = compound->next)
  583. {
  584. json_print_thing(compound->thing);
  585. if (compound->next != NULL) {
  586. putchar(',');
  587. putchar(' ');
  588. }
  589. }
  590.  
  591. putchar(']');
  592. break;
  593.  
  594. case JSON_OBJECT:
  595. putchar('{');
  596.  
  597. for (const json_compound_t *compound = thing->val.compound;
  598. compound != NULL; compound = compound->next)
  599. {
  600. printf("\"%s\": ", compound->key);
  601. json_print_thing(compound->thing);
  602. if (compound->next != NULL) {
  603. putchar(',');
  604. putchar(' ');
  605. }
  606. }
  607.  
  608. putchar('}');
  609. break;
  610. }
  611. }
  612.  
  613. void json_print_stats(const json_t *json)
  614. {
  615. size_t size_things = json->things_total - json->things_rem;
  616. size_t size_compounds = json->compounds_total - json->compounds_rem;
  617. size_t size_things_b = size_things * sizeof(json_thing_t);
  618. size_t size_strings_b = json->strings_total - json->strings_rem;
  619. size_t size_compounds_b = size_compounds * sizeof(json_compound_t);
  620.  
  621. printf("%zu things (%zu bytes), %zu bytes of strings, "
  622. "%zu compounds (%zu bytes).\n%zu bytes in total.\n",
  623. size_things, size_things_b, size_strings_b, size_compounds,
  624. size_compounds_b,
  625. size_things_b + size_strings_b + size_compounds_b);
  626. }
  627.  
  628. int main(int argc, char *argv[]) {
  629. if (argc < 2) {
  630. puts("Write some json.");
  631. return 1;
  632. }
  633.  
  634. const char *json_str = argv[1];
  635. json_t *json = json_init();
  636. json_thing_t *thing = json_parse(json, &json_str, "");
  637.  
  638. if (thing != NULL) {
  639. json_print_thing(thing);
  640. putchar('\n');
  641. }
  642.  
  643. json_print_stats(json);
  644. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement