iodine 0.4.14 → 0.4.15

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of iodine might be problematic. Click here for more details.

Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +61 -33
  3. data/README.md +7 -5
  4. data/ext/iodine/base64.c +12 -0
  5. data/ext/iodine/defer.c +211 -108
  6. data/ext/iodine/defer.h +7 -0
  7. data/ext/iodine/facil.c +5 -1
  8. data/ext/iodine/facil.h +1 -1
  9. data/ext/iodine/fio2resp.c +19 -30
  10. data/ext/iodine/fio2resp.h +2 -1
  11. data/ext/iodine/fio_cli_helper.c +2 -2
  12. data/ext/iodine/fiobj.h +11 -624
  13. data/ext/iodine/fiobj_ary.c +65 -26
  14. data/ext/iodine/fiobj_ary.h +106 -0
  15. data/ext/iodine/fiobj_hash.c +175 -115
  16. data/ext/iodine/fiobj_hash.h +128 -0
  17. data/ext/iodine/fiobj_internal.c +189 -0
  18. data/ext/iodine/{fiobj_types.h → fiobj_internal.h} +126 -136
  19. data/ext/iodine/fiobj_json.c +161 -207
  20. data/ext/iodine/fiobj_json.h +43 -0
  21. data/ext/iodine/fiobj_numbers.c +53 -35
  22. data/ext/iodine/fiobj_numbers.h +49 -0
  23. data/ext/iodine/fiobj_primitives.c +103 -70
  24. data/ext/iodine/fiobj_primitives.h +55 -0
  25. data/ext/iodine/fiobj_str.c +171 -59
  26. data/ext/iodine/fiobj_str.h +113 -0
  27. data/ext/iodine/fiobj_sym.c +46 -124
  28. data/ext/iodine/fiobj_sym.h +60 -0
  29. data/ext/iodine/fiobject.c +589 -0
  30. data/ext/iodine/fiobject.h +276 -0
  31. data/ext/iodine/pubsub.h +1 -1
  32. data/ext/iodine/resp.c +2 -2
  33. data/ext/iodine/siphash.c +11 -0
  34. data/ext/iodine/spnlock.inc +7 -5
  35. data/ext/iodine/websocket_parser.h +44 -7
  36. data/lib/iodine/version.rb +1 -1
  37. metadata +13 -8
  38. data/ext/iodine/fiobj_alloc.c +0 -81
  39. data/ext/iodine/fiobj_generic.c +0 -260
  40. data/ext/iodine/fiobj_io.c +0 -58
  41. data/ext/iodine/fiobj_misc.c +0 -213
  42. data/ext/iodine/fiobj_tests.c +0 -474
@@ -1,12 +1,14 @@
1
1
  /*
2
- Copyright: Boaz segev, 2017
2
+ Copyright: Boaz Segev, 2017
3
3
  License: MIT
4
-
5
- Feel free to copy, use and enjoy according to the license provided.
6
4
  */
7
- #include "fiobj_types.h"
5
+ #include "fiobj_json.h"
6
+
8
7
  // #include "fio2resp.h"
9
8
  #include <ctype.h>
9
+ #include <math.h>
10
+ #include <stdlib.h>
11
+ #include <string.h>
10
12
 
11
13
  /* *****************************************************************************
12
14
  JSON API
@@ -82,81 +84,88 @@ static inline int utf8_from_u32(uint8_t *dest, uint32_t u) {
82
84
  return 4;
83
85
  }
84
86
 
85
- /** Writes a JSON friendly version of the src String, requires the */
86
- static void write_safe_str(fiobj_s *dest, fiobj_s *str) {
87
+ /** Writes a JSON friendly version of the src String */
88
+ static void write_safe_str(fiobj_s *dest, const fiobj_s *str) {
87
89
  fio_cstr_s s = fiobj_obj2cstr(str);
88
- const uint8_t *src = (const uint8_t *)s.data;
90
+ fio_cstr_s t = fiobj_obj2cstr(dest);
91
+ const uint8_t *restrict src = (const uint8_t *)s.data;
89
92
  size_t len = s.len;
90
- uint64_t end = obj2str(dest)->len;
93
+ uint64_t end = t.len;
91
94
  /* make sure we have some room */
92
95
  size_t added = 0;
93
- if (obj2str(dest)->capa <= end + s.len + 64)
94
- fiobj_str_capa_assert(dest, (((obj2str(dest)->capa >> 12) + 1) << 12) - 1);
96
+ size_t capa = fiobj_str_capa(dest);
97
+ if (capa <= end + s.len + 64) {
98
+ capa = (((capa >> 12) + 1) << 12) - 1;
99
+ fiobj_str_capa_assert(dest, capa);
100
+ fio_cstr_s tmp = fiobj_obj2cstr(dest);
101
+ t = tmp;
102
+ }
95
103
  while (len) {
104
+ char *restrict writer = (char *)t.data;
96
105
  while (len &&
97
106
  (src[0] > 32 && src[0] != '"' && src[0] != '\\' && src[0] != '/')) {
98
107
  len--;
99
- obj2str(dest)->str[end++] = *(src++);
108
+ writer[end++] = *(src++);
100
109
  }
101
110
  if (!len)
102
111
  break;
103
112
  switch (src[0]) {
104
113
  case '\b':
105
- obj2str(dest)->str[end++] = '\\';
106
- obj2str(dest)->str[end++] = 'b';
114
+ writer[end++] = '\\';
115
+ writer[end++] = 'b';
107
116
  added++;
108
117
  break; /* from switch */
109
118
  case '\f':
110
- obj2str(dest)->str[end++] = '\\';
111
- obj2str(dest)->str[end++] = 'f';
119
+ writer[end++] = '\\';
120
+ writer[end++] = 'f';
112
121
  added++;
113
122
  break; /* from switch */
114
123
  case '\n':
115
- obj2str(dest)->str[end++] = '\\';
116
- obj2str(dest)->str[end++] = 'n';
124
+ writer[end++] = '\\';
125
+ writer[end++] = 'n';
117
126
  added++;
118
127
  break; /* from switch */
119
128
  case '\r':
120
- obj2str(dest)->str[end++] = '\\';
121
- obj2str(dest)->str[end++] = 'r';
129
+ writer[end++] = '\\';
130
+ writer[end++] = 'r';
122
131
  added++;
123
132
  break; /* from switch */
124
133
  case '\t':
125
- obj2str(dest)->str[end++] = '\\';
126
- obj2str(dest)->str[end++] = 't';
134
+ writer[end++] = '\\';
135
+ writer[end++] = 't';
127
136
  added++;
128
137
  break; /* from switch */
129
138
  case '"':
130
139
  case '\\':
131
140
  case '/':
132
- obj2str(dest)->str[end++] = '\\';
133
- obj2str(dest)->str[end++] = src[0];
141
+ writer[end++] = '\\';
142
+ writer[end++] = src[0];
134
143
  added++;
135
144
  break; /* from switch */
136
145
  default:
137
146
  if (src[0] <= 31) {
138
147
  /* MUST escape all control values less than 32 */
139
- obj2str(dest)->str[end++] = '\\';
140
- obj2str(dest)->str[end++] = 'u';
141
- obj2str(dest)->str[end++] = '0';
142
- obj2str(dest)->str[end++] = '0';
143
- obj2str(dest)->str[end++] = hex_chars[src[0] >> 4];
144
- obj2str(dest)->str[end++] = hex_chars[src[0] & 15];
148
+ writer[end++] = '\\';
149
+ writer[end++] = 'u';
150
+ writer[end++] = '0';
151
+ writer[end++] = '0';
152
+ writer[end++] = hex_chars[src[0] >> 4];
153
+ writer[end++] = hex_chars[src[0] & 15];
145
154
  added += 4;
146
155
  } else
147
- obj2str(dest)->str[end++] = src[0];
156
+ writer[end++] = src[0];
148
157
  break; /* from switch */
149
158
  }
150
159
  src++;
151
160
  len--;
152
- if (added >= 48 && obj2str(dest)->capa <= end + len + 64) {
153
- fiobj_str_capa_assert(dest,
154
- (((obj2str(dest)->capa >> 12) + 1) << 12) - 1);
161
+ if (added >= 48 && capa <= end + len + 64) {
162
+ capa = (((capa >> 12) + 1) << 12) - 1;
163
+ fiobj_str_capa_assert(dest, capa);
164
+ t = fiobj_obj2cstr(dest);
155
165
  added = 0;
156
166
  }
157
167
  }
158
- obj2str(dest)->len = end;
159
- obj2str(dest)->str[end] = 0;
168
+ fiobj_str_resize(dest, end);
160
169
  }
161
170
 
162
171
  /* *****************************************************************************
@@ -179,7 +188,7 @@ static int fiobj_str_new_json_task(fiobj_s *obj, void *d_) {
179
188
  /* headroom */
180
189
  fiobj_str_capa_assert(
181
190
  data->buffer,
182
- ((((obj2str(data->buffer)->len + 63) >> 12) + 1) << 12) - 1);
191
+ ((((fiobj_obj2cstr(data->buffer).len + 63) >> 12) + 1) << 12) - 1);
183
192
  pretty_re_rooted:
184
193
  /* pretty? */
185
194
  if (data->pretty) {
@@ -193,36 +202,32 @@ re_rooted:
193
202
  fiobj_str_write(data->buffer, "null", 4);
194
203
  goto review_nesting;
195
204
  }
196
- switch (obj->type) {
197
- case FIOBJ_T_HASH:
205
+ if (obj->type == FIOBJ_T_HASH) {
198
206
  fiobj_str_write(data->buffer, "{", 1);
199
207
  fiobj_ary_push(data->parent, obj);
200
208
  fiobj_ary_push(data->waiting, data->count);
201
209
  data->count = fiobj_num_new(fiobj_hash_count(obj));
202
- break;
203
- case FIOBJ_T_ARRAY:
210
+ } else if (obj->type == FIOBJ_T_ARRAY) {
204
211
  fiobj_str_write(data->buffer, "[", 1);
205
212
  /* push current state to stacks and update state */
206
213
  fiobj_ary_push(data->parent, obj);
207
214
  fiobj_ary_push(data->waiting, data->count);
208
215
  data->count = fiobj_num_new(fiobj_ary_count(obj));
209
- break;
210
- case FIOBJ_T_SYMBOL:
211
- case FIOBJ_T_STRING: {
216
+ } else if (obj->type == FIOBJ_T_SYMBOL || FIOBJ_IS_STRING(obj)) {
212
217
  fiobj_str_capa_assert(
213
218
  data->buffer,
214
- ((((obj2str(data->buffer)->len + 63 + obj2str(obj)->len) >> 12) + 1)
219
+ ((((fiobj_obj2cstr(data->buffer).len + 63 + fiobj_obj2cstr(obj).len) >>
220
+ 12) +
221
+ 1)
215
222
  << 12) -
216
223
  1);
217
224
  fiobj_str_write(data->buffer, "\"", 1);
218
225
  write_safe_str(data->buffer, obj);
219
226
  fiobj_str_write(data->buffer, "\"", 1);
220
- break;
221
- }
222
- case FIOBJ_T_COUPLET: {
227
+ } else if (obj->type == FIOBJ_T_COUPLET) {
223
228
  fiobj_str_capa_assert(data->buffer,
224
- ((((obj2str(data->buffer)->len + 31 +
225
- obj2sym(fiobj_couplet2key(obj))->len) >>
229
+ ((((fiobj_obj2cstr(data->buffer).len + 31 +
230
+ fiobj_obj2cstr(fiobj_couplet2key(obj)).len) >>
226
231
  12) +
227
232
  1)
228
233
  << 12) -
@@ -235,54 +240,15 @@ re_rooted:
235
240
  (obj->type == FIOBJ_T_ARRAY || obj->type == FIOBJ_T_HASH))
236
241
  goto pretty_re_rooted;
237
242
  goto re_rooted;
238
- break;
239
- }
240
- case FIOBJ_T_NUMBER:
241
- obj2str(data->buffer)->len +=
242
- fio_ltoa(obj2str(data->buffer)->str + obj2str(data->buffer)->len,
243
- obj2num(obj)->i, 10);
244
- break;
245
- case FIOBJ_T_FLOAT:
246
- if (isnan(obj2float(obj)->f))
247
- fiobj_str_write(data->buffer, "\"NaN\"", 5);
248
- else if (isinf(obj2float(obj)->f)) {
249
- if (obj2float(obj)->f > 0)
250
- fiobj_str_write(data->buffer, "\"Infinity\"", 10);
251
- else
252
- fiobj_str_write(data->buffer, "\"-Infinity\"", 11);
253
- } else {
254
- char *start = obj2str(data->buffer)->str + obj2str(data->buffer)->len;
255
- fiobj_str_write2(data->buffer, "%g", obj2float(obj)->f);
256
- uint8_t need_zero = 1;
257
- while (*start) {
258
- if (*start == ',') // locale issues?
259
- *start = '.';
260
- if (*start == '.' || *start == 'e') {
261
- need_zero = 0;
262
- break;
263
- }
264
- start++;
265
- }
266
- if (need_zero)
267
- fiobj_str_write(data->buffer, ".0", 2);
268
- }
269
- break;
270
- // case FIOBJ_T_FLOAT:
271
- // obj2str(data->buffer)->len +=
272
- // fio_ftoa(obj2str(data->buffer)->str + obj2str(data->buffer)->len,
273
- // obj2float(obj)->f, 10);
274
- // break;
275
- case FIOBJ_T_TRUE:
243
+ } else if (obj->type == FIOBJ_T_NUMBER || obj->type == FIOBJ_T_FLOAT) {
244
+ fio_cstr_s i2s = fiobj_obj2cstr(obj);
245
+ fiobj_str_write(data->buffer, i2s.data, i2s.len);
246
+ } else if (obj->type == FIOBJ_T_NULL) {
247
+ fiobj_str_write(data->buffer, "null", 4);
248
+ } else if (fiobj_is_true(obj)) {
276
249
  fiobj_str_write(data->buffer, "true", 4);
277
- break;
278
- case FIOBJ_T_FALSE:
250
+ } else
279
251
  fiobj_str_write(data->buffer, "false", 5);
280
- break;
281
- case FIOBJ_T_IO:
282
- case FIOBJ_T_NULL:
283
- fiobj_str_write(data->buffer, "null", 4);
284
- break;
285
- }
286
252
 
287
253
  review_nesting:
288
254
  /* print clousure to String */
@@ -423,14 +389,14 @@ JSON UTF-8 safe string deconstruction
423
389
  *
424
390
  * Also deals with the non-standard oct ("\77") and hex ("\xFF") notations
425
391
  */
426
- static void safestr2local(fiobj_s *str) {
392
+ static uintptr_t safestr2local(fiobj_s *str) {
427
393
  if (str->type != FIOBJ_T_STRING && str->type != FIOBJ_T_SYMBOL) {
428
394
  fprintf(stderr,
429
395
  "CRITICAL ERROR: unexpected function call `safestr2local`\n");
430
396
  exit(-1);
431
397
  }
432
398
  fio_cstr_s s = fiobj_obj2cstr(str);
433
- uint8_t had_changed = 0;
399
+ // uint8_t had_changed = 0;
434
400
  uint8_t *end = (uint8_t *)s.bytes + s.len;
435
401
  uint8_t *reader = (uint8_t *)s.bytes;
436
402
  uint8_t *writer = (uint8_t *)s.bytes;
@@ -441,7 +407,7 @@ static void safestr2local(fiobj_s *str) {
441
407
  if (reader[0] != '\\')
442
408
  break;
443
409
 
444
- had_changed = 1;
410
+ // had_changed = 1;
445
411
  switch (reader[1]) {
446
412
  case 'b':
447
413
  *(writer++) = '\b';
@@ -528,15 +494,8 @@ static void safestr2local(fiobj_s *str) {
528
494
  reader += 2;
529
495
  }
530
496
  }
531
- if (str->type == FIOBJ_T_STRING) {
532
- obj2str(str)->len = (uintptr_t)writer - (uintptr_t)obj2str(str)->str;
533
- obj2str(str)->str[obj2str(str)->len] = 0;
534
- } else {
535
- obj2sym(str)->len = (uintptr_t)writer - (uintptr_t)obj2sym(str)->str;
536
- obj2sym(str)->str[obj2sym(str)->len] = 0;
537
- if (had_changed)
538
- obj2sym(str)->hash = fiobj_sym_hash(obj2sym(str)->str, obj2sym(str)->len);
539
- }
497
+ // if(had_changed)
498
+ return ((uintptr_t)writer - (uintptr_t)s.bytes);
540
499
  }
541
500
 
542
501
  /* *****************************************************************************
@@ -556,6 +515,7 @@ size_t fiobj_json2obj(fiobj_s **pobj, const void *data, size_t len) {
556
515
  return 0;
557
516
  }
558
517
  fiobj_s *nesting = fiobj_ary_new2(JSON_MAX_DEPTH + 2);
518
+ int64_t num;
559
519
  const uint8_t *start;
560
520
  fiobj_s *obj;
561
521
  const uint8_t *end = (uint8_t *)data;
@@ -573,6 +533,57 @@ size_t fiobj_json2obj(fiobj_s **pobj, const void *data, size_t len) {
573
533
 
574
534
  /* test object type. tests are ordered by precedence, if one fails, the
575
535
  * other is performed. */
536
+ if (start[0] == '"') {
537
+ /* object is a string (require qoutes) */
538
+ start++;
539
+ end++;
540
+ uint8_t dirty = 0;
541
+ while (move_to_quote(&end, stop)) {
542
+ end += 2;
543
+ dirty = 1;
544
+ }
545
+ if (end >= stop) {
546
+ goto error;
547
+ }
548
+
549
+ if (fiobj_ary_index(nesting, -1) &&
550
+ fiobj_ary_index(nesting, -1)->type == FIOBJ_T_HASH) {
551
+ obj = fiobj_sym_new((char *)start, end - start);
552
+ if (dirty)
553
+ fiobj_sym_reinitialize(obj, (size_t)safestr2local(obj));
554
+ } else {
555
+ obj = fiobj_str_new((char *)start, end - start);
556
+ if (dirty)
557
+ fiobj_str_resize(obj, (size_t)safestr2local(obj));
558
+ }
559
+ end++;
560
+
561
+ goto has_obj;
562
+ }
563
+ if (end[0] >= 'a' && end[0] <= 'z') {
564
+ if (end + 3 < stop && end[0] == 't' && end[1] == 'r' && end[2] == 'u' &&
565
+ end[3] == 'e') {
566
+ /* true */
567
+ end += 4;
568
+ obj = fiobj_true();
569
+ goto has_obj;
570
+ }
571
+ if (end + 4 < stop && end[0] == 'f' && end[1] == 'a' && end[2] == 'l' &&
572
+ end[3] == 's' && end[4] == 'e') {
573
+ /* false */
574
+ end += 5;
575
+ obj = fiobj_false();
576
+ goto has_obj;
577
+ }
578
+ if (end + 3 < stop && end[0] == 'n' && end[1] == 'u' && end[2] == 'l' &&
579
+ end[3] == 'l') {
580
+ /* null */
581
+ end += 4;
582
+ obj = fiobj_null();
583
+ goto has_obj;
584
+ }
585
+ goto error;
586
+ }
576
587
  if (end[0] == '{') {
577
588
  /* start an object (hash) */
578
589
  fiobj_ary_push(nesting, fiobj_hash_new());
@@ -613,25 +624,47 @@ size_t fiobj_json2obj(fiobj_s **pobj, const void *data, size_t len) {
613
624
  }
614
625
  goto has_obj;
615
626
  }
616
- if (end + 3 < stop && end[0] == 't' && end[1] == 'r' && end[2] == 'u' &&
617
- end[3] == 'e') {
618
- /* true */
619
- end += 4;
620
- obj = fiobj_true();
627
+
628
+ if (end[0] == '-') {
629
+ if (end[0] == '-' && end[1] == 'N' && end[2] == 'a' && end[3] == 'N') {
630
+ move_to_end(&end, stop);
631
+ double fl = nan("");
632
+ fl = copysign(fl, (double)-1);
633
+ obj = fiobj_float_new(fl);
634
+ goto has_obj;
635
+ }
636
+ if (end[0] == '-' && end[1] == 'I' && end[2] == 'n' && end[3] == 'f') {
637
+ move_to_end(&end, stop);
638
+ double fl = INFINITY;
639
+ fl = copysign(fl, (double)-1);
640
+ obj = fiobj_float_new(fl);
641
+ goto has_obj;
642
+ }
643
+ goto test_for_number;
644
+ }
645
+ if (end[0] >= '0' && end[0] <= '9') {
646
+ test_for_number: /* test for a number OR float */
647
+ num = fio_atol((char **)&end);
648
+ if (end == start || *end == '.' || *end == 'e' || *end == 'E') {
649
+ end = start;
650
+ double fnum = fio_atof((char **)&end);
651
+ if (end == start)
652
+ goto error;
653
+ obj = fiobj_float_new(fnum);
654
+ goto has_obj;
655
+ }
656
+ obj = fiobj_num_new(num);
621
657
  goto has_obj;
622
658
  }
623
- if (end + 4 < stop && end[0] == 'f' && end[1] == 'a' && end[2] == 'l' &&
624
- end[3] == 's' && end[4] == 'e') {
625
- /* false */
626
- end += 5;
627
- obj = fiobj_false();
659
+
660
+ if (end[0] == 'N' && end[1] == 'a' && end[2] == 'N') {
661
+ move_to_end(&end, stop);
662
+ obj = fiobj_float_new(nan(""));
628
663
  goto has_obj;
629
664
  }
630
- if (end + 3 < stop && end[0] == 'n' && end[1] == 'u' && end[2] == 'l' &&
631
- end[3] == 'l') {
632
- /* null */
633
- end += 4;
634
- obj = fiobj_null();
665
+ if (end[0] == 'I' && end[1] == 'n' && end[2] == 'f') {
666
+ move_to_end(&end, stop);
667
+ obj = fiobj_float_new(INFINITY);
635
668
  goto has_obj;
636
669
  }
637
670
  if (end[0] == '/') {
@@ -655,103 +688,24 @@ size_t fiobj_json2obj(fiobj_s **pobj, const void *data, size_t len) {
655
688
  move_to_eol(&end, stop);
656
689
  continue;
657
690
  }
658
- if (start[0] == '"') {
659
- /* object is a string (require qoutes) */
660
- start++;
661
- end++;
662
- uint8_t dirty = 0;
663
- while (move_to_quote(&end, stop)) {
664
- end += 2;
665
- dirty = 1;
666
- }
667
- if (end >= stop) {
668
- goto error;
669
- }
670
- if (fiobj_ary_entry(nesting, -1) &&
671
- fiobj_ary_entry(nesting, -1)->type == FIOBJ_T_HASH) {
672
- obj = fiobj_sym_new((char *)start, end - start);
673
- } else {
674
- obj = fiobj_str_new((char *)start, end - start);
675
- }
676
- if (dirty)
677
- safestr2local(obj);
678
- end++;
679
-
680
- goto has_obj;
681
- }
682
- if (end[0] == '-' || (end[0] >= '0' && end[0] <= '9')) {
683
- /* test for a number OR float */
684
- int64_t num = fio_atol((char **)&end);
685
- if (end == start || *end == '.' || *end == 'e' || *end == 'E') {
686
- end = start;
687
- double fnum = fio_atof((char **)&end);
688
- if (end == start)
689
- goto error;
690
- obj = fiobj_float_new(fnum);
691
- goto has_obj;
692
- }
693
- obj = fiobj_num_new(num);
694
- goto has_obj;
695
- // uint8_t decimal = 0;
696
- // while (end < stop && JSON_SEPERATOR[*end] == 0 && *end != ']' &&
697
- // *end != '}') {
698
- // if (*end == '.' || *end == 'e' || *end == 'E')
699
- // decimal = 1;
700
- // end++;
701
- // }
702
- // /* test against forbidden leading zeros... but allow hex and binary
703
- // */ if (end - start > 1 && start[0] == '0' &&
704
- // !(start[1] == '.' || start[1] == 'x' || start[1] == 'b')) {
705
- // goto error;
706
- // }
707
- // /* it's a number */
708
- // if (decimal) {
709
- // obj = fiobj_float_new(fio_atof((char *)start));
710
- // } else {
711
- // obj = fiobj_num_new(fio_atol((char *)start));
712
- // }
713
- // goto has_obj;
714
- }
715
- if (end[0] == 'N' && end[1] == 'a' && end[2] == 'N') {
716
- obj = fiobj_float_new(nan(""));
717
- goto has_obj;
718
- }
719
- if (end[0] == '-' && end[1] == 'I' && end[2] == 'n' && end[3] == 'f') {
720
- obj = fiobj_float_new(nan(""));
721
- obj2float(obj)->f = copysign(obj2float(obj)->f, (double)-1);
722
- goto has_obj;
723
- }
724
- if (end[0] == 'I' && end[1] == 'n' && end[2] == 'f') {
725
- move_to_end(&end, stop);
726
- obj = fiobj_float_new(INFINITY);
727
- goto has_obj;
728
- }
729
- if (end[0] == '-' && end[1] == 'I' && end[2] == 'n' && end[3] == 'f') {
730
- move_to_end(&end, stop);
731
- obj = fiobj_float_new(INFINITY);
732
- obj2float(obj)->f = copysign(obj2float(obj)->f, (double)-1);
733
- goto has_obj;
734
- }
735
691
  goto error;
736
692
 
737
693
  has_obj:
738
694
 
739
695
  if (fiobj_ary_count(nesting) == 0)
740
696
  goto finish_with_obj;
741
- if (fiobj_ary_entry(nesting, -1)->type == FIOBJ_T_ARRAY) {
742
- fiobj_ary_push(fiobj_ary_entry(nesting, -1), obj);
697
+ if (fiobj_ary_index(nesting, -1)->type == FIOBJ_T_ARRAY) {
698
+ fiobj_ary_push(fiobj_ary_index(nesting, -1), obj);
743
699
  continue;
744
700
  }
745
- if (fiobj_ary_entry(nesting, -1)->type == FIOBJ_T_HASH) {
746
- fio_cstr_s s = fiobj_obj2cstr(obj);
747
- fiobj_ary_push(nesting, fiobj_sym_new(s.buffer, s.len));
748
- fiobj_free(obj);
701
+ if (fiobj_ary_index(nesting, -1)->type == FIOBJ_T_HASH) {
702
+ fiobj_ary_push(nesting, obj);
749
703
  continue;
750
704
  }
751
705
  fiobj_s *sym = fiobj_ary_pop(nesting);
752
- if (fiobj_ary_entry(nesting, -1)->type != FIOBJ_T_HASH)
706
+ if (fiobj_ary_index(nesting, -1)->type != FIOBJ_T_HASH)
753
707
  goto error;
754
- fiobj_hash_set(fiobj_ary_entry(nesting, -1), sym, obj);
708
+ fiobj_hash_set(fiobj_ary_index(nesting, -1), sym, obj);
755
709
  fiobj_free(sym);
756
710
  continue;
757
711
  }