Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

1097 linhas
31 KiB

  1. // This file is part of Jiffy released under the MIT license.
  2. // See the LICENSE file for more information.
  3. #include <assert.h>
  4. #include <errno.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "erl_nif.h"
  9. #include "jiffy.h"
  10. #define U(c) ((unsigned char) (c))
  11. #define ERROR(i, msg) make_error(st, env, msg)
  12. #define STACK_SIZE_INC 64
  13. #define NUM_BUF_LEN 32
  14. #if WINDOWS || WIN32
  15. #define snprintf _snprintf
  16. #endif
  17. enum {
  18. st_value=0,
  19. st_object,
  20. st_array,
  21. st_key,
  22. st_colon,
  23. st_comma,
  24. st_done,
  25. st_invalid
  26. } JsonState;
  27. enum {
  28. nst_init=0,
  29. nst_sign,
  30. nst_mantissa,
  31. nst_frac0,
  32. nst_frac1,
  33. nst_frac,
  34. nst_esign,
  35. nst_edigit
  36. } JsonNumState;
  37. typedef struct {
  38. ErlNifEnv* env;
  39. jiffy_st* atoms;
  40. ERL_NIF_TERM arg;
  41. ErlNifBinary bin;
  42. size_t bytes_per_red;
  43. int is_partial;
  44. int return_maps;
  45. int return_trailer;
  46. int attempt_atom;
  47. ERL_NIF_TERM null_term;
  48. char* p;
  49. unsigned char* u;
  50. int i;
  51. int len;
  52. char* st_data;
  53. int st_size;
  54. int st_top;
  55. } Decoder;
  56. Decoder*
  57. dec_new(ErlNifEnv* env)
  58. {
  59. jiffy_st* st = (jiffy_st*) enif_priv_data(env);
  60. Decoder* d = enif_alloc_resource(st->res_dec, sizeof(Decoder));
  61. int i;
  62. if(d == NULL) {
  63. return NULL;
  64. }
  65. d->atoms = st;
  66. d->bytes_per_red = DEFAULT_BYTES_PER_REDUCTION;
  67. d->is_partial = 0;
  68. d->return_maps = 0;
  69. d->return_trailer = 0;
  70. d->attempt_atom = 0;
  71. d->null_term = d->atoms->atom_null;
  72. d->p = NULL;
  73. d->u = NULL;
  74. d->len = -1;
  75. d->i = -1;
  76. d->st_data = (char*) enif_alloc(STACK_SIZE_INC * sizeof(char));
  77. d->st_size = STACK_SIZE_INC;
  78. d->st_top = 0;
  79. for(i = 0; i < d->st_size; i++) {
  80. d->st_data[i] = st_invalid;
  81. }
  82. d->st_data[0] = st_value;
  83. d->st_top++;
  84. return d;
  85. }
  86. void
  87. dec_init(Decoder* d, ErlNifEnv* env, ERL_NIF_TERM arg, ErlNifBinary* bin)
  88. {
  89. d->env = env;
  90. d->arg = arg;
  91. d->p = (char*) bin->data;
  92. d->u = bin->data;
  93. d->len = bin->size;
  94. // I'd like to be more forceful on this check so that when
  95. // we run a second iteration of the decoder we are sure
  96. // that we're using the same binary. Unfortunately, I don't
  97. // think there's a value to base this assertion on.
  98. if(d->i < 0) {
  99. d->i = 0;
  100. } else {
  101. assert(d->i <= d->len && "mismatched binary lengths");
  102. }
  103. }
  104. void
  105. dec_destroy(ErlNifEnv* env, void* obj)
  106. {
  107. Decoder* d = (Decoder*) obj;
  108. if(d->st_data != NULL) {
  109. enif_free(d->st_data);
  110. }
  111. }
  112. ERL_NIF_TERM
  113. dec_error(Decoder* d, const char* atom)
  114. {
  115. ERL_NIF_TERM pos = enif_make_int(d->env, d->i+1);
  116. ERL_NIF_TERM msg = make_atom(d->env, atom);
  117. ERL_NIF_TERM ret = enif_make_tuple2(d->env, pos, msg);
  118. return enif_make_tuple2(d->env, d->atoms->atom_error, ret);
  119. }
  120. char
  121. dec_curr(Decoder* d)
  122. {
  123. return d->st_data[d->st_top-1];
  124. }
  125. int
  126. dec_top(Decoder* d)
  127. {
  128. return d->st_top;
  129. }
  130. void
  131. dec_push(Decoder* d, char val)
  132. {
  133. char* tmp;
  134. int new_sz;
  135. int i;
  136. if(d->st_top >= d->st_size) {
  137. new_sz = d->st_size + STACK_SIZE_INC;
  138. tmp = (char*) enif_alloc(new_sz * sizeof(char));
  139. memcpy(tmp, d->st_data, d->st_size * sizeof(char));
  140. enif_free(d->st_data);
  141. d->st_data = tmp;
  142. d->st_size = new_sz;
  143. for(i = d->st_top; i < d->st_size; i++) {
  144. d->st_data[i] = st_invalid;
  145. }
  146. }
  147. d->st_data[d->st_top++] = val;
  148. }
  149. void
  150. dec_pop(Decoder* d, char val)
  151. {
  152. assert(d->st_data[d->st_top-1] == val && "popped invalid state.");
  153. d->st_data[d->st_top-1] = st_invalid;
  154. d->st_top--;
  155. }
  156. int
  157. dec_string(Decoder* d, ERL_NIF_TERM* value)
  158. {
  159. int has_escape = 0;
  160. int num_escapes = 0;
  161. int st;
  162. int ulen;
  163. int ui;
  164. int hi;
  165. int lo;
  166. char* chrbuf;
  167. int chrpos;
  168. if(d->p[d->i] != '\"') {
  169. return 0;
  170. }
  171. d->i++;
  172. st = d->i;
  173. while(d->i < d->len) {
  174. if(d->u[d->i] < 0x20) {
  175. return 0;
  176. } else if(d->p[d->i] == '\"') {
  177. d->i++;
  178. goto parse;
  179. } else if(d->p[d->i] == '\\') {
  180. if(d->i+1 >= d->len) {
  181. return 0;
  182. }
  183. has_escape = 1;
  184. num_escapes += 1;
  185. d->i++;
  186. switch(d->p[d->i]) {
  187. case '\"':
  188. case '\\':
  189. case '/':
  190. case 'b':
  191. case 'f':
  192. case 'n':
  193. case 'r':
  194. case 't':
  195. d->i++;
  196. break;
  197. case 'u':
  198. hi = 0;
  199. lo = 0;
  200. d->i++;
  201. if(d->i + 4 >= d->len) {
  202. return 0;
  203. }
  204. hi = int_from_hex(&(d->u[d->i]));
  205. if(hi < 0) {
  206. return 0;
  207. }
  208. d->i += 4;
  209. if(hi >= 0xD800 && hi < 0xDC00) {
  210. if(d->i + 6 >= d->len) {
  211. return 0;
  212. }
  213. if(d->p[d->i++] != '\\') {
  214. return 0;
  215. } else if(d->p[d->i++] != 'u') {
  216. return 0;
  217. }
  218. lo = int_from_hex(&(d->u[d->i]));
  219. if(lo < 0) {
  220. return 0;
  221. }
  222. hi = unicode_from_pair(hi, lo);
  223. if(hi < 0) {
  224. return 0;
  225. }
  226. }
  227. hi = utf8_len(hi);
  228. if(hi < 0) {
  229. return 0;
  230. }
  231. if(lo == 0) {
  232. num_escapes += 5 - hi;
  233. } else {
  234. num_escapes += 11 - hi;
  235. }
  236. break;
  237. default:
  238. return 0;
  239. }
  240. } else if(d->u[d->i] < 0x80) {
  241. d->i++;
  242. } else {
  243. ulen = utf8_validate(&(d->u[d->i]), d->len - d->i);
  244. if(ulen < 0) {
  245. return 0;
  246. }
  247. d->i += ulen;
  248. }
  249. }
  250. // The goto above ensures that we only
  251. // hit this when a string is not terminated
  252. // correctly.
  253. return 0;
  254. parse:
  255. if(!has_escape) {
  256. *value = enif_make_sub_binary(d->env, d->arg, st, (d->i - st - 1));
  257. return 1;
  258. }
  259. hi = 0;
  260. lo = 0;
  261. ulen = (d->i - 1) - st - num_escapes;
  262. chrbuf = (char*) enif_make_new_binary(d->env, ulen, value);
  263. chrpos = 0;
  264. ui = st;
  265. while(ui < d->i - 1) {
  266. if(d->p[ui] != '\\') {
  267. chrbuf[chrpos++] = d->p[ui++];
  268. continue;
  269. }
  270. ui++;
  271. switch(d->p[ui]) {
  272. case '\"':
  273. case '\\':
  274. case '/':
  275. chrbuf[chrpos++] = d->p[ui];
  276. ui++;
  277. break;
  278. case 'b':
  279. chrbuf[chrpos++] = '\b';
  280. ui++;
  281. break;
  282. case 'f':
  283. chrbuf[chrpos++] = '\f';
  284. ui++;
  285. break;
  286. case 'n':
  287. chrbuf[chrpos++] = '\n';
  288. ui++;
  289. break;
  290. case 'r':
  291. chrbuf[chrpos++] = '\r';
  292. ui++;
  293. break;
  294. case 't':
  295. chrbuf[chrpos++] = '\t';
  296. ui++;
  297. break;
  298. case 'u':
  299. ui++;
  300. hi = int_from_hex(&(d->u[ui]));
  301. if(hi < 0) {
  302. return 0;
  303. }
  304. if(hi >= 0xD800 && hi < 0xDC00) {
  305. lo = int_from_hex(&(d->u[ui+6]));
  306. if(lo < 0) {
  307. return 0;
  308. }
  309. hi = unicode_from_pair(hi, lo);
  310. ui += 10;
  311. } else {
  312. ui += 4;
  313. }
  314. hi = unicode_to_utf8(hi, (unsigned char*) chrbuf+chrpos);
  315. if(hi < 0) {
  316. return 0;
  317. }
  318. chrpos += hi;
  319. break;
  320. default:
  321. return 0;
  322. }
  323. }
  324. return 1;
  325. }
  326. int
  327. dec_number(Decoder* d, ERL_NIF_TERM* value)
  328. {
  329. ERL_NIF_TERM num_type = d->atoms->atom_error;
  330. char state = nst_init;
  331. char nbuf[NUM_BUF_LEN];
  332. int st = d->i;
  333. int has_frac = 0;
  334. int has_exp = 0;
  335. double dval;
  336. long lval;
  337. while(d->i < d->len) {
  338. switch(state) {
  339. case nst_init:
  340. switch(d->p[d->i]) {
  341. case '-':
  342. state = nst_sign;
  343. d->i++;
  344. break;
  345. case '0':
  346. state = nst_frac0;
  347. d->i++;
  348. break;
  349. case '1':
  350. case '2':
  351. case '3':
  352. case '4':
  353. case '5':
  354. case '6':
  355. case '7':
  356. case '8':
  357. case '9':
  358. state = nst_mantissa;
  359. d->i++;
  360. break;
  361. default:
  362. return 0;
  363. }
  364. break;
  365. case nst_sign:
  366. switch(d->p[d->i]) {
  367. case '0':
  368. state = nst_frac0;
  369. d->i++;
  370. break;
  371. case '1':
  372. case '2':
  373. case '3':
  374. case '4':
  375. case '5':
  376. case '6':
  377. case '7':
  378. case '8':
  379. case '9':
  380. state = nst_mantissa;
  381. d->i++;
  382. break;
  383. default:
  384. return 0;
  385. }
  386. break;
  387. case nst_mantissa:
  388. switch(d->p[d->i]) {
  389. case '.':
  390. state = nst_frac1;
  391. d->i++;
  392. break;
  393. case 'e':
  394. case 'E':
  395. state = nst_esign;
  396. d->i++;
  397. break;
  398. case '0':
  399. case '1':
  400. case '2':
  401. case '3':
  402. case '4':
  403. case '5':
  404. case '6':
  405. case '7':
  406. case '8':
  407. case '9':
  408. d->i++;
  409. break;
  410. default:
  411. goto parse;
  412. }
  413. break;
  414. case nst_frac0:
  415. switch(d->p[d->i]) {
  416. case '.':
  417. state = nst_frac1;
  418. d->i++;
  419. break;
  420. case 'e':
  421. case 'E':
  422. state = nst_esign;
  423. d->i++;
  424. break;
  425. default:
  426. goto parse;
  427. }
  428. break;
  429. case nst_frac1:
  430. has_frac = 1;
  431. switch(d->p[d->i]) {
  432. case '0':
  433. case '1':
  434. case '2':
  435. case '3':
  436. case '4':
  437. case '5':
  438. case '6':
  439. case '7':
  440. case '8':
  441. case '9':
  442. state = nst_frac;
  443. d->i++;
  444. break;
  445. default:
  446. goto parse;
  447. }
  448. break;
  449. case nst_frac:
  450. switch(d->p[d->i]) {
  451. case 'e':
  452. case 'E':
  453. state = nst_esign;
  454. d->i++;
  455. break;
  456. case '0':
  457. case '1':
  458. case '2':
  459. case '3':
  460. case '4':
  461. case '5':
  462. case '6':
  463. case '7':
  464. case '8':
  465. case '9':
  466. d->i++;
  467. break;
  468. default:
  469. goto parse;
  470. }
  471. break;
  472. case nst_esign:
  473. has_exp = 1;
  474. switch(d->p[d->i]) {
  475. case '-':
  476. case '+':
  477. case '0':
  478. case '1':
  479. case '2':
  480. case '3':
  481. case '4':
  482. case '5':
  483. case '6':
  484. case '7':
  485. case '8':
  486. case '9':
  487. state = nst_edigit;
  488. d->i++;
  489. break;
  490. default:
  491. return 0;
  492. }
  493. break;
  494. case nst_edigit:
  495. switch(d->p[d->i]) {
  496. case '0':
  497. case '1':
  498. case '2':
  499. case '3':
  500. case '4':
  501. case '5':
  502. case '6':
  503. case '7':
  504. case '8':
  505. case '9':
  506. d->i++;
  507. break;
  508. default:
  509. goto parse;
  510. }
  511. break;
  512. default:
  513. return 0;
  514. }
  515. }
  516. parse:
  517. switch(state) {
  518. case nst_init:
  519. case nst_sign:
  520. case nst_frac1:
  521. case nst_esign:
  522. return 0;
  523. default:
  524. break;
  525. }
  526. errno = 0;
  527. if(d->i - st < NUM_BUF_LEN) {
  528. memset(nbuf, 0, NUM_BUF_LEN);
  529. memcpy(nbuf, &(d->p[st]), d->i - st);
  530. if(has_frac || has_exp) {
  531. dval = strtod(nbuf, NULL);
  532. if(errno != ERANGE) {
  533. *value = enif_make_double(d->env, dval);
  534. return 1;
  535. }
  536. } else {
  537. lval = strtol(nbuf, NULL, 10);
  538. if(errno != ERANGE) {
  539. *value = enif_make_int64(d->env, lval);
  540. return 1;
  541. }
  542. }
  543. }
  544. if(!has_frac && !has_exp) {
  545. num_type = d->atoms->atom_bignum;
  546. } else if(!has_frac && has_exp) {
  547. num_type = d->atoms->atom_bignum_e;
  548. } else {
  549. num_type = d->atoms->atom_bigdbl;
  550. }
  551. d->is_partial = 1;
  552. *value = enif_make_sub_binary(d->env, d->arg, st, d->i - st);
  553. *value = enif_make_tuple2(d->env, num_type, *value);
  554. return 1;
  555. }
  556. ERL_NIF_TERM
  557. make_empty_object(ErlNifEnv* env, int ret_map)
  558. {
  559. #if MAP_TYPE_PRESENT
  560. if(ret_map) {
  561. return enif_make_new_map(env);
  562. }
  563. #endif
  564. return enif_make_tuple1(env, enif_make_list(env, 0));
  565. }
  566. ERL_NIF_TERM
  567. key_attempt_atom(ErlNifEnv* env, ERL_NIF_TERM key) {
  568. ERL_NIF_TERM keyatom;
  569. ErlNifBinary keybin;
  570. // maximum atom length is 255 bytes
  571. char keybuf[256];
  572. if(enif_inspect_binary(env, key, &keybin) && keybin.size < sizeof(keybuf)) {
  573. memcpy(keybuf, keybin.data, keybin.size);
  574. keybuf[keybin.size] = 0;
  575. if(enif_make_existing_atom(env, keybuf, &keyatom, ERL_NIF_LATIN1)) {
  576. return keyatom;
  577. }
  578. }
  579. return key;
  580. }
  581. int
  582. make_object(ErlNifEnv* env, ERL_NIF_TERM pairs, ERL_NIF_TERM* out, int ret_map, int attempt_atom)
  583. {
  584. ERL_NIF_TERM ret;
  585. ERL_NIF_TERM key;
  586. ERL_NIF_TERM val;
  587. #if MAP_TYPE_PRESENT
  588. if(ret_map) {
  589. ret = enif_make_new_map(env);
  590. while(enif_get_list_cell(env, pairs, &val, &pairs)) {
  591. if(!enif_get_list_cell(env, pairs, &key, &pairs)) {
  592. assert(0 == 1 && "Unbalanced object pairs.");
  593. }
  594. if(attempt_atom) {
  595. key = key_attempt_atom(env, key);
  596. }
  597. if(!enif_make_map_put(env, ret, key, val, &ret)) {
  598. return 0;
  599. }
  600. }
  601. *out = ret;
  602. return 1;
  603. }
  604. #endif
  605. ret = enif_make_list(env, 0);
  606. while(enif_get_list_cell(env, pairs, &val, &pairs)) {
  607. if(!enif_get_list_cell(env, pairs, &key, &pairs)) {
  608. assert(0 == 1 && "Unbalanced object pairs.");
  609. }
  610. if(attempt_atom) {
  611. key = key_attempt_atom(env, key);
  612. }
  613. val = enif_make_tuple2(env, key, val);
  614. ret = enif_make_list_cell(env, val, ret);
  615. }
  616. *out = enif_make_tuple1(env, ret);
  617. return 1;
  618. }
  619. ERL_NIF_TERM
  620. make_array(ErlNifEnv* env, ERL_NIF_TERM list)
  621. {
  622. ERL_NIF_TERM ret = enif_make_list(env, 0);
  623. ERL_NIF_TERM item;
  624. while(enif_get_list_cell(env, list, &item, &list)) {
  625. ret = enif_make_list_cell(env, item, ret);
  626. }
  627. return ret;
  628. }
  629. ERL_NIF_TERM
  630. decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  631. {
  632. Decoder* d;
  633. jiffy_st* st = (jiffy_st*) enif_priv_data(env);
  634. ERL_NIF_TERM tmp_argv[5];
  635. ERL_NIF_TERM opts;
  636. ERL_NIF_TERM val;
  637. if(argc != 2) {
  638. return enif_make_badarg(env);
  639. }
  640. d = dec_new(env);
  641. if(d == NULL) {
  642. return make_error(st, env, "internal_error");
  643. }
  644. tmp_argv[0] = argv[0];
  645. tmp_argv[1] = enif_make_resource(env, d);
  646. tmp_argv[2] = st->atom_error;
  647. tmp_argv[3] = enif_make_list(env, 0);
  648. tmp_argv[4] = enif_make_list(env, 0);
  649. enif_release_resource(d);
  650. opts = argv[1];
  651. if(!enif_is_list(env, opts)) {
  652. return enif_make_badarg(env);
  653. }
  654. while(enif_get_list_cell(env, opts, &val, &opts)) {
  655. if(get_bytes_per_iter(env, val, &(d->bytes_per_red))) {
  656. continue;
  657. } else if(get_bytes_per_red(env, val, &(d->bytes_per_red))) {
  658. continue;
  659. } else if(enif_compare(val, d->atoms->atom_return_maps) == 0) {
  660. #if MAP_TYPE_PRESENT
  661. d->return_maps = 1;
  662. #else
  663. return enif_make_badarg(env);
  664. #endif
  665. } else if(enif_compare(val, d->atoms->atom_return_trailer) == 0) {
  666. d->return_trailer = 1;
  667. } else if(enif_compare(val, d->atoms->atom_use_nil) == 0) {
  668. d->null_term = d->atoms->atom_nil;
  669. } else if(get_null_term(env, val, &(d->null_term))) {
  670. continue;
  671. } else if(enif_compare(val, d->atoms->atom_attempt_atom) == 0) {
  672. d->attempt_atom = 1;
  673. } else {
  674. return enif_make_badarg(env);
  675. }
  676. }
  677. return decode_iter(env, 5, tmp_argv);
  678. }
  679. ERL_NIF_TERM
  680. decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  681. {
  682. Decoder* d;
  683. jiffy_st* st = (jiffy_st*) enif_priv_data(env);
  684. ErlNifBinary bin;
  685. ERL_NIF_TERM objs;
  686. ERL_NIF_TERM curr;
  687. ERL_NIF_TERM val = argv[2];
  688. ERL_NIF_TERM trailer;
  689. ERL_NIF_TERM ret;
  690. size_t bytes_read = 0;
  691. if(argc != 5) {
  692. return enif_make_badarg(env);
  693. } else if(!enif_inspect_binary(env, argv[0], &bin)) {
  694. return enif_make_badarg(env);
  695. } else if(!enif_get_resource(env, argv[1], st->res_dec, (void**) &d)) {
  696. return enif_make_badarg(env);
  697. } else if(!enif_is_list(env, argv[3])) {
  698. return enif_make_badarg(env);
  699. } else if(!enif_is_list(env, argv[4])) {
  700. return enif_make_badarg(env);
  701. }
  702. dec_init(d, env, argv[0], &bin);
  703. objs = argv[3];
  704. curr = argv[4];
  705. while(d->i < bin.size) {
  706. if(should_yield(env, &bytes_read, d->bytes_per_red)) {
  707. return enif_make_tuple5(
  708. env,
  709. st->atom_iter,
  710. argv[1],
  711. val,
  712. objs,
  713. curr
  714. );
  715. }
  716. bytes_read += 1;
  717. switch(dec_curr(d)) {
  718. case st_value:
  719. switch(d->p[d->i]) {
  720. case ' ':
  721. case '\n':
  722. case '\r':
  723. case '\t':
  724. d->i++;
  725. break;
  726. case 'n':
  727. if(d->i + 3 >= d->len) {
  728. ret = dec_error(d, "invalid_literal");
  729. goto done;
  730. }
  731. if(memcmp(&(d->p[d->i]), "null", 4) != 0) {
  732. ret = dec_error(d, "invalid_literal");
  733. goto done;
  734. }
  735. val = d->null_term;
  736. dec_pop(d, st_value);
  737. d->i += 4;
  738. break;
  739. case 't':
  740. if(d->i + 3 >= d->len) {
  741. ret = dec_error(d, "invalid_literal");
  742. goto done;
  743. }
  744. if(memcmp(&(d->p[d->i]), "true", 4) != 0) {
  745. ret = dec_error(d, "invalid_literal");
  746. goto done;
  747. }
  748. val = d->atoms->atom_true;
  749. dec_pop(d, st_value);
  750. d->i += 4;
  751. break;
  752. case 'f':
  753. if(d->i + 4 >= bin.size) {
  754. ret = dec_error(d, "invalid_literal");
  755. goto done;
  756. }
  757. if(memcmp(&(d->p[d->i]), "false", 5) != 0) {
  758. ret = dec_error(d, "invalid_literal");
  759. goto done;
  760. }
  761. val = d->atoms->atom_false;
  762. dec_pop(d, st_value);
  763. d->i += 5;
  764. break;
  765. case '\"':
  766. if(!dec_string(d, &val)) {
  767. ret = dec_error(d, "invalid_string");
  768. goto done;
  769. }
  770. dec_pop(d, st_value);
  771. break;
  772. case '-':
  773. case '0':
  774. case '1':
  775. case '2':
  776. case '3':
  777. case '4':
  778. case '5':
  779. case '6':
  780. case '7':
  781. case '8':
  782. case '9':
  783. if(!dec_number(d, &val)) {
  784. ret = dec_error(d, "invalid_number");
  785. goto done;
  786. }
  787. dec_pop(d, st_value);
  788. break;
  789. case '{':
  790. dec_push(d, st_object);
  791. dec_push(d, st_key);
  792. objs = enif_make_list_cell(env, curr, objs);
  793. curr = enif_make_list(env, 0);
  794. d->i++;
  795. break;
  796. case '[':
  797. dec_push(d, st_array);
  798. dec_push(d, st_value);
  799. objs = enif_make_list_cell(env, curr, objs);
  800. curr = enif_make_list(env, 0);
  801. d->i++;
  802. break;
  803. case ']':
  804. if(!enif_is_empty_list(env, curr)) {
  805. ret = dec_error(d, "invalid_json");
  806. goto done;
  807. }
  808. dec_pop(d, st_value);
  809. if(dec_curr(d) != st_array) {
  810. ret = dec_error(d, "invalid_json");
  811. goto done;
  812. }
  813. dec_pop(d, st_array);
  814. dec_pop(d, st_value);
  815. val = curr; // curr is []
  816. if(!enif_get_list_cell(env, objs, &curr, &objs)) {
  817. ret = dec_error(d, "internal_error");
  818. goto done;
  819. }
  820. d->i++;
  821. break;
  822. default:
  823. ret = dec_error(d, "invalid_json");
  824. goto done;
  825. }
  826. if(dec_top(d) == 0) {
  827. dec_push(d, st_done);
  828. } else if(dec_curr(d) != st_value && dec_curr(d) != st_key) {
  829. dec_push(d, st_comma);
  830. curr = enif_make_list_cell(env, val, curr);
  831. }
  832. break;
  833. case st_key:
  834. switch(d->p[d->i]) {
  835. case ' ':
  836. case '\n':
  837. case '\r':
  838. case '\t':
  839. d->i++;
  840. break;
  841. case '\"':
  842. if(!dec_string(d, &val)) {
  843. ret = dec_error(d, "invalid_string");
  844. goto done;
  845. }
  846. dec_pop(d, st_key);
  847. dec_push(d, st_colon);
  848. curr = enif_make_list_cell(env, val, curr);
  849. break;
  850. case '}':
  851. if(!enif_is_empty_list(env, curr)) {
  852. ret = dec_error(d, "invalid_json");
  853. goto done;
  854. }
  855. dec_pop(d, st_key);
  856. dec_pop(d, st_object);
  857. dec_pop(d, st_value);
  858. val = make_empty_object(env, d->return_maps);
  859. if(!enif_get_list_cell(env, objs, &curr, &objs)) {
  860. ret = dec_error(d, "internal_error");
  861. goto done;
  862. }
  863. if(dec_top(d) == 0) {
  864. dec_push(d, st_done);
  865. } else {
  866. dec_push(d, st_comma);
  867. curr = enif_make_list_cell(env, val, curr);
  868. }
  869. d->i++;
  870. break;
  871. default:
  872. ret = dec_error(d, "invalid_json");
  873. goto done;
  874. }
  875. break;
  876. case st_colon:
  877. switch(d->p[d->i]) {
  878. case ' ':
  879. case '\n':
  880. case '\r':
  881. case '\t':
  882. d->i++;
  883. break;
  884. case ':':
  885. dec_pop(d, st_colon);
  886. dec_push(d, st_value);
  887. d->i++;
  888. break;
  889. default:
  890. ret = dec_error(d, "invalid_json");
  891. goto done;
  892. }
  893. break;
  894. case st_comma:
  895. switch(d->p[d->i]) {
  896. case ' ':
  897. case '\n':
  898. case '\r':
  899. case '\t':
  900. d->i++;
  901. break;
  902. case ',':
  903. dec_pop(d, st_comma);
  904. switch(dec_curr(d)) {
  905. case st_object:
  906. dec_push(d, st_key);
  907. break;
  908. case st_array:
  909. dec_push(d, st_value);
  910. break;
  911. default:
  912. ret = dec_error(d, "internal_error");
  913. goto done;
  914. }
  915. d->i++;
  916. break;
  917. case '}':
  918. dec_pop(d, st_comma);
  919. if(dec_curr(d) != st_object) {
  920. ret = dec_error(d, "invalid_json");
  921. goto done;
  922. }
  923. dec_pop(d, st_object);
  924. dec_pop(d, st_value);
  925. if(!make_object(env, curr, &val, d->return_maps, d->attempt_atom)) {
  926. ret = dec_error(d, "internal_object_error");
  927. goto done;
  928. }
  929. if(!enif_get_list_cell(env, objs, &curr, &objs)) {
  930. ret = dec_error(d, "internal_error");
  931. goto done;
  932. }
  933. if(dec_top(d) > 0) {
  934. dec_push(d, st_comma);
  935. curr = enif_make_list_cell(env, val, curr);
  936. } else {
  937. dec_push(d, st_done);
  938. }
  939. d->i++;
  940. break;
  941. case ']':
  942. dec_pop(d, st_comma);
  943. if(dec_curr(d) != st_array) {
  944. ret = dec_error(d, "invalid_json");
  945. goto done;
  946. }
  947. dec_pop(d, st_array);
  948. dec_pop(d, st_value);
  949. val = make_array(env, curr);
  950. if(!enif_get_list_cell(env, objs, &curr, &objs)) {
  951. ret = dec_error(d, "internal_error");
  952. goto done;
  953. }
  954. if(dec_top(d) > 0) {
  955. dec_push(d, st_comma);
  956. curr = enif_make_list_cell(env, val, curr);
  957. } else {
  958. dec_push(d, st_done);
  959. }
  960. d->i++;
  961. break;
  962. default:
  963. ret = dec_error(d, "invalid_json");
  964. goto done;
  965. }
  966. break;
  967. case st_done:
  968. switch(d->p[d->i]) {
  969. case ' ':
  970. case '\n':
  971. case '\r':
  972. case '\t':
  973. d->i++;
  974. break;
  975. default:
  976. goto decode_done;
  977. }
  978. break;
  979. default:
  980. ret = dec_error(d, "invalid_internal_state");
  981. goto done;
  982. }
  983. }
  984. decode_done:
  985. if(d->i < bin.size && d->return_trailer) {
  986. trailer = enif_make_sub_binary(env, argv[0], d->i, bin.size - d->i);
  987. val = enif_make_tuple3(env, d->atoms->atom_has_trailer, val, trailer);
  988. } else if(d->i < bin.size) {
  989. ret = dec_error(d, "invalid_trailing_data");
  990. goto done;
  991. }
  992. if(dec_curr(d) != st_done) {
  993. ret = dec_error(d, "truncated_json");
  994. } else if(d->is_partial) {
  995. ret = enif_make_tuple2(env, d->atoms->atom_partial, val);
  996. } else {
  997. ret = val;
  998. }
  999. done:
  1000. return ret;
  1001. }