iodine 0.7.3 → 0.7.4

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.

@@ -7,11 +7,13 @@ License: MIT
7
7
 
8
8
  #include <assert.h>
9
9
  #include <fiobj_hash.h>
10
+
10
11
  #define FIO_SET_CALLOC(size, count) fio_calloc((size), (count))
11
12
  #define FIO_SET_REALLOC(ptr, original_size, size, valid_data_length) \
12
13
  fio_realloc2((ptr), (size), (valid_data_length))
13
14
  #define FIO_SET_FREE(ptr, size) fio_free((ptr))
14
- #define FIO_SET_NAME fio_hash
15
+
16
+ #define FIO_SET_NAME fio_hash__
15
17
  #define FIO_SET_KEY_TYPE FIOBJ
16
18
  #define FIO_SET_KEY_COMPARE(o1, o2) \
17
19
  ((o2) == ((FIOBJ)-1) || (o1) == ((FIOBJ)-1) || fiobj_iseq((o1), (o2)))
@@ -30,7 +32,6 @@ License: MIT
30
32
  (obj) = FIOBJ_INVALID; \
31
33
  } while (0)
32
34
 
33
- #define FIO_OVERRIDE_MALLOC 1
34
35
  #include <fio.h>
35
36
 
36
37
  #include <errno.h>
@@ -40,14 +41,14 @@ Hash types
40
41
  ***************************************************************************** */
41
42
  typedef struct {
42
43
  fiobj_object_header_s head;
43
- fio_hash_s hash;
44
+ fio_hash___s hash;
44
45
  } fiobj_hash_s;
45
46
 
46
47
  #define obj2hash(o) ((fiobj_hash_s *)(FIOBJ2PTR(o)))
47
48
 
48
49
  void fiobj_hash_rehash(FIOBJ h) {
49
50
  assert(h && FIOBJ_TYPE_IS(h, FIOBJ_T_HASH));
50
- fio_hash_rehash(&obj2hash(h)->hash);
51
+ fio_hash___rehash(&obj2hash(h)->hash);
51
52
  }
52
53
 
53
54
  /* *****************************************************************************
@@ -64,8 +65,8 @@ static void fiobj_hash_dealloc(FIOBJ o, void (*task)(FIOBJ, void *),
64
65
  i->obj.obj = FIOBJ_INVALID;
65
66
  }
66
67
  obj2hash(o)->hash.count = 0;
67
- fio_hash_free(&obj2hash(o)->hash);
68
- free(FIOBJ2PTR(o));
68
+ fio_hash___free(&obj2hash(o)->hash);
69
+ fio_free(FIOBJ2PTR(o));
69
70
  }
70
71
 
71
72
  static __thread FIOBJ each_at_key = FIOBJ_INVALID;
@@ -74,7 +75,7 @@ static size_t fiobj_hash_each1(FIOBJ o, size_t start_at,
74
75
  int (*task)(FIOBJ obj, void *arg), void *arg) {
75
76
  assert(o && FIOBJ_TYPE_IS(o, FIOBJ_T_HASH));
76
77
  FIOBJ old_each_at_key = each_at_key;
77
- fio_hash_s *hash = &obj2hash(o)->hash;
78
+ fio_hash___s *hash = &obj2hash(o)->hash;
78
79
  size_t count = 0;
79
80
  if (hash->count == hash->pos) {
80
81
  /* no holes in the hash, we can work as we please. */
@@ -112,8 +113,8 @@ end:
112
113
  FIOBJ fiobj_hash_key_in_loop(void) { return each_at_key; }
113
114
 
114
115
  static size_t fiobj_hash_is_eq(const FIOBJ self, const FIOBJ other) {
115
- if (fio_hash_count(&obj2hash(self)->hash) !=
116
- fio_hash_count(&obj2hash(other)->hash))
116
+ if (fio_hash___count(&obj2hash(self)->hash) !=
117
+ fio_hash___count(&obj2hash(other)->hash))
117
118
  return 0;
118
119
  return 1;
119
120
  }
@@ -121,7 +122,7 @@ static size_t fiobj_hash_is_eq(const FIOBJ self, const FIOBJ other) {
121
122
  /** Returns the number of elements in the Array. */
122
123
  size_t fiobj_hash_count(const FIOBJ o) {
123
124
  assert(o && FIOBJ_TYPE_IS(o, FIOBJ_T_HASH));
124
- return fio_hash_count(&obj2hash(o)->hash);
125
+ return fio_hash___count(&obj2hash(o)->hash);
125
126
  }
126
127
 
127
128
  intptr_t fiobj_hash2num(const FIOBJ o) { return (intptr_t)fiobj_hash_count(o); }
@@ -157,7 +158,7 @@ Hash API
157
158
  * retain order of object insertion.
158
159
  */
159
160
  FIOBJ fiobj_hash_new(void) {
160
- fiobj_hash_s *h = malloc(sizeof(*h));
161
+ fiobj_hash_s *h = fio_malloc(sizeof(*h));
161
162
  FIO_ASSERT_ALLOC(h);
162
163
  *h = (fiobj_hash_s){.head = {.ref = 1, .type = FIOBJ_T_HASH},
163
164
  .hash = FIO_SET_INIT};
@@ -172,11 +173,11 @@ FIOBJ fiobj_hash_new(void) {
172
173
  * retain order of object insertion.
173
174
  */
174
175
  FIOBJ fiobj_hash_new2(size_t capa) {
175
- fiobj_hash_s *h = malloc(sizeof(*h));
176
+ fiobj_hash_s *h = fio_malloc(sizeof(*h));
176
177
  FIO_ASSERT_ALLOC(h);
177
178
  *h = (fiobj_hash_s){.head = {.ref = 1, .type = FIOBJ_T_HASH},
178
179
  .hash = FIO_SET_INIT};
179
- fio_hash_capa_require(&h->hash, capa);
180
+ fio_hash___capa_require(&h->hash, capa);
180
181
  return (FIOBJ)h | FIOBJECT_HASH_FLAG;
181
182
  }
182
183
 
@@ -186,7 +187,7 @@ FIOBJ fiobj_hash_new2(size_t capa) {
186
187
  */
187
188
  size_t fiobj_hash_capa(const FIOBJ hash) {
188
189
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
189
- return fio_hash_capa(&obj2hash(hash)->hash);
190
+ return fio_hash___capa(&obj2hash(hash)->hash);
190
191
  }
191
192
 
192
193
  /**
@@ -199,7 +200,7 @@ int fiobj_hash_set(FIOBJ hash, FIOBJ key, FIOBJ obj) {
199
200
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
200
201
  if (FIOBJ_TYPE_IS(key, FIOBJ_T_STRING))
201
202
  fiobj_str_freeze(key);
202
- fio_hash_insert(&obj2hash(hash)->hash, fiobj_obj2hash(key), key, obj, NULL);
203
+ fio_hash___insert(&obj2hash(hash)->hash, fiobj_obj2hash(key), key, obj, NULL);
203
204
  return 0;
204
205
  }
205
206
 
@@ -216,12 +217,12 @@ int fiobj_hash_set(FIOBJ hash, FIOBJ key, FIOBJ obj) {
216
217
  FIOBJ fiobj_hash_pop(FIOBJ hash, FIOBJ *key) {
217
218
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
218
219
  FIOBJ old;
219
- if (fio_hash_count(&obj2hash(hash)->hash))
220
+ if (fio_hash___count(&obj2hash(hash)->hash))
220
221
  return FIOBJ_INVALID;
221
- old = fiobj_dup(fio_hash_last(&obj2hash(hash)->hash).obj);
222
+ old = fiobj_dup(fio_hash___last(&obj2hash(hash)->hash).obj);
222
223
  if (key)
223
- *key = fiobj_dup(fio_hash_last(&obj2hash(hash)->hash).key);
224
- fio_hash_pop(&obj2hash(hash)->hash);
224
+ *key = fiobj_dup(fio_hash___last(&obj2hash(hash)->hash).key);
225
+ fio_hash___pop(&obj2hash(hash)->hash);
225
226
  return old;
226
227
  }
227
228
 
@@ -237,7 +238,7 @@ FIOBJ fiobj_hash_pop(FIOBJ hash, FIOBJ *key) {
237
238
  FIOBJ fiobj_hash_replace(FIOBJ hash, FIOBJ key, FIOBJ obj) {
238
239
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
239
240
  FIOBJ old = FIOBJ_INVALID;
240
- fio_hash_insert(&obj2hash(hash)->hash, fiobj_obj2hash(key), key, obj, &old);
241
+ fio_hash___insert(&obj2hash(hash)->hash, fiobj_obj2hash(key), key, obj, &old);
241
242
  return old;
242
243
  }
243
244
 
@@ -247,7 +248,7 @@ FIOBJ fiobj_hash_replace(FIOBJ hash, FIOBJ key, FIOBJ obj) {
247
248
  FIOBJ fiobj_hash_remove(FIOBJ hash, FIOBJ key) {
248
249
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
249
250
  FIOBJ old = FIOBJ_INVALID;
250
- fio_hash_remove(&obj2hash(hash)->hash, fiobj_obj2hash(key), key, &old);
251
+ fio_hash___remove(&obj2hash(hash)->hash, fiobj_obj2hash(key), key, &old);
251
252
  return old;
252
253
  }
253
254
 
@@ -258,7 +259,7 @@ FIOBJ fiobj_hash_remove(FIOBJ hash, FIOBJ key) {
258
259
  FIOBJ fiobj_hash_remove2(FIOBJ hash, uint64_t hash_value) {
259
260
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
260
261
  FIOBJ old = FIOBJ_INVALID;
261
- fio_hash_remove(&obj2hash(hash)->hash, hash_value, -1, &old);
262
+ fio_hash___remove(&obj2hash(hash)->hash, hash_value, -1, &old);
262
263
  return old;
263
264
  }
264
265
 
@@ -283,7 +284,7 @@ int fiobj_hash_delete(FIOBJ hash, FIOBJ key) {
283
284
  * Returns -1 on type error or if the object never existed.
284
285
  */
285
286
  int fiobj_hash_delete2(FIOBJ hash, uint64_t key_hash) {
286
- return fio_hash_remove(&obj2hash(hash)->hash, key_hash, -1, NULL);
287
+ return fio_hash___remove(&obj2hash(hash)->hash, key_hash, -1, NULL);
287
288
  }
288
289
 
289
290
  /**
@@ -292,7 +293,7 @@ int fiobj_hash_delete2(FIOBJ hash, uint64_t key_hash) {
292
293
  */
293
294
  FIOBJ fiobj_hash_get(const FIOBJ hash, FIOBJ key) {
294
295
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
295
- return fio_hash_find(&obj2hash(hash)->hash, fiobj_obj2hash(key), key);
296
+ return fio_hash___find(&obj2hash(hash)->hash, fiobj_obj2hash(key), key);
296
297
  ;
297
298
  }
298
299
 
@@ -306,7 +307,7 @@ FIOBJ fiobj_hash_get(const FIOBJ hash, FIOBJ key) {
306
307
  */
307
308
  FIOBJ fiobj_hash_get2(const FIOBJ hash, uint64_t key_hash) {
308
309
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
309
- return fio_hash_find(&obj2hash(hash)->hash, key_hash, -1);
310
+ return fio_hash___find(&obj2hash(hash)->hash, key_hash, -1);
310
311
  ;
311
312
  }
312
313
 
@@ -315,7 +316,7 @@ FIOBJ fiobj_hash_get2(const FIOBJ hash, uint64_t key_hash) {
315
316
  */
316
317
  int fiobj_hash_haskey(const FIOBJ hash, FIOBJ key) {
317
318
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
318
- return fio_hash_find(&obj2hash(hash)->hash, fiobj_obj2hash(key), key) !=
319
+ return fio_hash___find(&obj2hash(hash)->hash, fiobj_obj2hash(key), key) !=
319
320
  FIOBJ_INVALID;
320
321
  }
321
322
 
@@ -324,7 +325,7 @@ int fiobj_hash_haskey(const FIOBJ hash, FIOBJ key) {
324
325
  */
325
326
  void fiobj_hash_clear(const FIOBJ hash) {
326
327
  assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
327
- fio_hash_free(&obj2hash(hash)->hash);
328
+ fio_hash___free(&obj2hash(hash)->hash);
328
329
  }
329
330
 
330
331
  /* *****************************************************************************
@@ -2,10 +2,11 @@
2
2
  Copyright: Boaz Segev, 2017-2018
3
3
  License: MIT
4
4
  */
5
- #include <fio.h>
6
5
  #include <fiobj_json.h>
6
+ #define FIO_ARY_NAME fio_json_stack
7
+ #define FIO_ARY_TYPE FIOBJ
8
+ #include <fio.h>
7
9
 
8
- #include <fio_ary.h>
9
10
  #include <fio_json_parser.h>
10
11
 
11
12
  #include <assert.h>
@@ -37,7 +38,7 @@ typedef struct {
37
38
  FIOBJ key;
38
39
  FIOBJ top;
39
40
  FIOBJ target;
40
- fio_ary_s stack;
41
+ fio_json_stack_s stack;
41
42
  uint8_t is_hash;
42
43
  } fiobj_json_parser_s;
43
44
 
@@ -95,13 +96,13 @@ static int fio_json_on_start_object(json_parser_s *p) {
95
96
  fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
96
97
  if (pr->target) {
97
98
  /* push NULL, don't free the objects */
98
- fio_ary_push(&pr->stack, (void *)pr->top);
99
+ fio_json_stack_push(&pr->stack, pr->top);
99
100
  pr->top = pr->target;
100
101
  pr->target = FIOBJ_INVALID;
101
102
  } else {
102
103
  FIOBJ hash = fiobj_hash_new();
103
104
  fiobj_json_add2parser(pr, hash);
104
- fio_ary_push(&pr->stack, (void *)pr->top);
105
+ fio_json_stack_push(&pr->stack, pr->top);
105
106
  pr->top = hash;
106
107
  }
107
108
  pr->is_hash = 1;
@@ -116,7 +117,8 @@ static void fio_json_on_end_object(json_parser_s *p) {
116
117
  fiobj_free(pr->key);
117
118
  pr->key = FIOBJ_INVALID;
118
119
  }
119
- pr->top = (FIOBJ)fio_ary_pop(&pr->stack);
120
+ pr->top = FIOBJ_INVALID;
121
+ fio_json_stack_pop(&pr->stack, &pr->top);
120
122
  pr->is_hash = FIOBJ_TYPE_IS(pr->top, FIOBJ_T_HASH);
121
123
  }
122
124
  /** an array object was detected */
@@ -124,9 +126,9 @@ static int fio_json_on_start_array(json_parser_s *p) {
124
126
  fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
125
127
  if (pr->target)
126
128
  return -1;
127
- FIOBJ ary = fiobj_ary_new2(4);
129
+ FIOBJ ary = fiobj_ary_new();
128
130
  fiobj_json_add2parser(pr, ary);
129
- fio_ary_push(&pr->stack, (void *)pr->top);
131
+ fio_json_stack_push(&pr->stack, pr->top);
130
132
  pr->top = ary;
131
133
  pr->is_hash = 0;
132
134
  return 0;
@@ -134,14 +136,15 @@ static int fio_json_on_start_array(json_parser_s *p) {
134
136
  /** an array closure was detected */
135
137
  static void fio_json_on_end_array(json_parser_s *p) {
136
138
  fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
137
- pr->top = (FIOBJ)fio_ary_pop(&pr->stack);
139
+ pr->top = FIOBJ_INVALID;
140
+ fio_json_stack_pop(&pr->stack, &pr->top);
138
141
  pr->is_hash = FIOBJ_TYPE_IS(pr->top, FIOBJ_T_HASH);
139
142
  }
140
143
  /** the JSON parsing is complete */
141
144
  static void fio_json_on_json(json_parser_s *p) {
142
145
  // fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
143
146
  // FIO_ARY_FOR(&pr->stack, pos) { fiobj_free((FIOBJ)pos.obj); }
144
- // fio_ary_free(&pr->stack);
147
+ // fio_json_stack_free(&pr->stack);
145
148
  (void)p; /* nothing special... right? */
146
149
  }
147
150
  /** the JSON parsing is complete */
@@ -150,10 +153,9 @@ static void fio_json_on_error(json_parser_s *p) {
150
153
  #if DEBUG
151
154
  FIO_LOG_DEBUG("JSON on error called.");
152
155
  #endif
153
- fiobj_free((FIOBJ)fio_ary_index(&pr->stack, 0));
156
+ fiobj_free((FIOBJ)fio_json_stack_get(&pr->stack, 0));
154
157
  fiobj_free(pr->key);
155
- fio_ary_free(&pr->stack);
156
- pr->stack = FIO_ARY_INIT;
158
+ fio_json_stack_free(&pr->stack);
157
159
  *pr = (fiobj_json_parser_s){.top = FIOBJ_INVALID};
158
160
  }
159
161
 
@@ -260,7 +262,7 @@ static void write_safe_str(FIOBJ dest, const FIOBJ str) {
260
262
  typedef struct {
261
263
  FIOBJ dest;
262
264
  FIOBJ parent;
263
- fio_ary_s *stack;
265
+ fio_json_stack_s *stack;
264
266
  uintptr_t count;
265
267
  uint8_t pretty;
266
268
  } obj2json_data_s;
@@ -291,8 +293,8 @@ static int fiobj_obj2json_task(FIOBJ o, void *data_) {
291
293
 
292
294
  case FIOBJ_T_ARRAY:
293
295
  --data->count;
294
- fio_ary_push(data->stack, (void *)data->parent);
295
- fio_ary_push(data->stack, (void *)data->count);
296
+ fio_json_stack_push(data->stack, data->parent);
297
+ fio_json_stack_push(data->stack, (FIOBJ)data->count);
296
298
  data->parent = o;
297
299
  data->count = fiobj_ary_count(o);
298
300
  fiobj_str_write(data->dest, "[", 1);
@@ -301,8 +303,8 @@ static int fiobj_obj2json_task(FIOBJ o, void *data_) {
301
303
 
302
304
  case FIOBJ_T_HASH:
303
305
  --data->count;
304
- fio_ary_push(data->stack, (void *)data->parent);
305
- fio_ary_push(data->stack, (void *)data->count);
306
+ fio_json_stack_push(data->stack, data->parent);
307
+ fio_json_stack_push(data->stack, (FIOBJ)data->count);
306
308
  data->parent = o;
307
309
  data->count = fiobj_hash_count(o);
308
310
  fiobj_str_write(data->dest, "{", 1);
@@ -310,8 +312,9 @@ static int fiobj_obj2json_task(FIOBJ o, void *data_) {
310
312
  break;
311
313
  }
312
314
  if (data->pretty) {
313
- fiobj_str_capa_assert(data->dest, fiobj_obj2cstr(data->dest).len +
314
- (fio_ary_count(data->stack) * 5));
315
+ fiobj_str_capa_assert(data->dest,
316
+ fiobj_obj2cstr(data->dest).len +
317
+ (fio_json_stack_count(data->stack) * 5));
315
318
  while (!data->count && data->parent) {
316
319
  if (FIOBJ_TYPE_IS(data->parent, FIOBJ_T_HASH)) {
317
320
  fiobj_str_write(data->dest, "}", 1);
@@ -319,13 +322,15 @@ static int fiobj_obj2json_task(FIOBJ o, void *data_) {
319
322
  fiobj_str_write(data->dest, "]", 1);
320
323
  }
321
324
  add_seperator = 1;
322
- data->count = (uintptr_t)fio_ary_pop(data->stack);
323
- data->parent = (FIOBJ)fio_ary_pop(data->stack);
325
+ data->count = 0;
326
+ fio_json_stack_pop(data->stack, &data->count);
327
+ data->parent = FIOBJ_INVALID;
328
+ fio_json_stack_pop(data->stack, &data->parent);
324
329
  }
325
330
 
326
331
  if (add_seperator && data->parent) {
327
332
  fiobj_str_write(data->dest, ",\n", 2);
328
- uintptr_t indent = fio_ary_count(data->stack) - 1;
333
+ uintptr_t indent = fio_json_stack_count(data->stack) - 1;
329
334
  fiobj_str_capa_assert(data->dest,
330
335
  fiobj_obj2cstr(data->dest).len + (indent * 2));
331
336
  fio_str_info_s buf = fiobj_obj2cstr(data->dest);
@@ -336,8 +341,9 @@ static int fiobj_obj2json_task(FIOBJ o, void *data_) {
336
341
  fiobj_str_resize(data->dest, buf.len);
337
342
  }
338
343
  } else {
339
- fiobj_str_capa_assert(data->dest, fiobj_obj2cstr(data->dest).len +
340
- (fio_ary_count(data->stack) << 1));
344
+ fiobj_str_capa_assert(data->dest,
345
+ fiobj_obj2cstr(data->dest).len +
346
+ (fio_json_stack_count(data->stack) << 1));
341
347
  while (!data->count && data->parent) {
342
348
  if (FIOBJ_TYPE_IS(data->parent, FIOBJ_T_HASH)) {
343
349
  fiobj_str_write(data->dest, "}", 1);
@@ -345,8 +351,10 @@ static int fiobj_obj2json_task(FIOBJ o, void *data_) {
345
351
  fiobj_str_write(data->dest, "]", 1);
346
352
  }
347
353
  add_seperator = 1;
348
- data->count = (uintptr_t)fio_ary_pop(data->stack);
349
- data->parent = (FIOBJ)fio_ary_pop(data->stack);
354
+ data->count = 0;
355
+ data->parent = FIOBJ_INVALID;
356
+ fio_json_stack_pop(data->stack, &data->count);
357
+ fio_json_stack_pop(data->stack, &data->parent);
350
358
  }
351
359
 
352
360
  if (add_seperator && data->parent) {
@@ -371,10 +379,10 @@ size_t fiobj_json2obj(FIOBJ *pobj, const void *data, size_t len) {
371
379
  fiobj_json_parser_s p = {.top = FIOBJ_INVALID};
372
380
  size_t consumed = fio_json_parse(&p.p, data, len);
373
381
  if (!consumed || p.p.depth) {
374
- fiobj_free((FIOBJ)fio_ary_index(&p.stack, 0));
382
+ fiobj_free(fio_json_stack_get(&p.stack, 0));
375
383
  p.top = FIOBJ_INVALID;
376
384
  }
377
- fio_ary_free(&p.stack);
385
+ fio_json_stack_free(&p.stack);
378
386
  fiobj_free(p.key);
379
387
  *pobj = p.top;
380
388
  return consumed;
@@ -397,7 +405,7 @@ size_t fiobj_hash_update_json(FIOBJ hash, const void *data, size_t len) {
397
405
  return 0;
398
406
  fiobj_json_parser_s p = {.top = FIOBJ_INVALID, .target = hash};
399
407
  size_t consumed = fio_json_parse(&p.p, data, len);
400
- fio_ary_free(&p.stack);
408
+ fio_json_stack_free(&p.stack);
401
409
  fiobj_free(p.key);
402
410
  if (p.top != hash)
403
411
  fiobj_free(p.top);
@@ -414,7 +422,7 @@ FIOBJ fiobj_obj2json2(FIOBJ dest, FIOBJ o, uint8_t pretty) {
414
422
  fiobj_str_write(dest, "null", 4);
415
423
  return 0;
416
424
  }
417
- fio_ary_s stack = FIO_ARY_INIT;
425
+ fio_json_stack_s stack = FIO_ARY_INIT;
418
426
  obj2json_data_s data = {
419
427
  .dest = dest,
420
428
  .stack = &stack,
@@ -425,9 +433,8 @@ FIOBJ fiobj_obj2json2(FIOBJ dest, FIOBJ o, uint8_t pretty) {
425
433
  fiobj_obj2json_task(o, &data);
426
434
  return dest;
427
435
  }
428
- fio_ary_new(&stack, 0);
429
436
  fiobj_each2(o, fiobj_obj2json_task, &data);
430
- fio_ary_free(&stack);
437
+ fio_json_stack_free(&stack);
431
438
  return dest;
432
439
  }
433
440
 
@@ -6,7 +6,6 @@ License: MIT
6
6
  #include <fiobj_numbers.h>
7
7
  #include <fiobject.h>
8
8
 
9
- #define FIO_OVERRIDE_MALLOC 1
10
9
  #include <fio.h>
11
10
 
12
11
  #include <assert.h>
@@ -105,7 +104,7 @@ Number API
105
104
 
106
105
  /** Creates a Number object. Remember to use `fiobj_free`. */
107
106
  FIOBJ fiobj_num_new_bignum(intptr_t num) {
108
- fiobj_num_s *o = malloc(sizeof(*o));
107
+ fiobj_num_s *o = fio_malloc(sizeof(*o));
109
108
  if (!o) {
110
109
  perror("ERROR: fiobj number couldn't allocate memory");
111
110
  exit(errno);
@@ -143,7 +142,7 @@ Float API
143
142
 
144
143
  /** Creates a Float object. Remember to use `fiobj_free`. */
145
144
  FIOBJ fiobj_float_new(double num) {
146
- fiobj_float_s *o = malloc(sizeof(*o));
145
+ fiobj_float_s *o = fio_malloc(sizeof(*o));
147
146
  if (!o) {
148
147
  perror("ERROR: fiobj float couldn't allocate memory");
149
148
  exit(errno);
@@ -179,307 +178,6 @@ FIOBJ fiobj_float_tmp(double num) {
179
178
  return (FIOBJ)&ret;
180
179
  }
181
180
 
182
- /* *****************************************************************************
183
- Strings to Numbers
184
- ***************************************************************************** */
185
-
186
- /**
187
- * A helper function that converts between String data to a signed int64_t.
188
- *
189
- * Numbers are assumed to be in base 10. Octal (`0###`), Hex (`0x##`/`x##`) and
190
- * binary (`0b##`/ `b##`) are recognized as well. For binary Most Significant
191
- * Bit must come first.
192
- *
193
- * The most significant differance between this function and `strtol` (aside of
194
- * API design), is the added support for binary representations.
195
- */
196
- #pragma weak fio_atol
197
- int64_t __attribute__((weak)) fio_atol(char **pstr) {
198
- /* No binary representation in strtol */
199
- char *str = *pstr;
200
- uint64_t result = 0;
201
- uint8_t invert = 0;
202
- while (str[0] == '-') {
203
- invert ^= 1;
204
- ++str;
205
- }
206
- if (str[0] == 'B' || str[0] == 'b' ||
207
- (str[0] == '0' && (str[1] == 'b' || str[1] == 'B'))) {
208
- /* base 2 */
209
- if (str[0] == '0')
210
- str++;
211
- str++;
212
- while (str[0] == '0' || str[0] == '1') {
213
- result = (result << 1) | (str[0] == '1');
214
- str++;
215
- }
216
- } else if (str[0] == 'x' || str[0] == 'X' ||
217
- (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))) {
218
- /* base 16 */
219
- uint8_t tmp;
220
- if (str[0] == '0')
221
- str++;
222
- str++;
223
- for (;;) {
224
- if (str[0] >= '0' && str[0] <= '9')
225
- tmp = str[0] - '0';
226
- else if (str[0] >= 'A' && str[0] <= 'F')
227
- tmp = str[0] - ('A' - 10);
228
- else if (str[0] >= 'a' && str[0] <= 'f')
229
- tmp = str[0] - ('a' - 10);
230
- else
231
- goto finish;
232
- result = (result << 4) | tmp;
233
- str++;
234
- }
235
- } else if (str[0] == '0') {
236
- ++str;
237
- /* base 8 */
238
- const char *end = str;
239
- while (end[0] >= '0' && end[0] <= '7' && (uintptr_t)(end - str) < 22)
240
- end++;
241
- if ((uintptr_t)(end - str) > 21) /* TODO: fix too large for a number */
242
- return 0;
243
-
244
- while (str < end) {
245
- result = (result * 8) + (str[0] - '0');
246
- str++;
247
- }
248
- } else {
249
- /* base 10 */
250
- const char *end = str;
251
- while (end[0] >= '0' && end[0] <= '9' && (uintptr_t)(end - str) < 22)
252
- end++;
253
- if ((uintptr_t)(end - str) > 21) /* too large for a number */
254
- return 0;
255
-
256
- while (str < end) {
257
- result = (result * 10) + (str[0] - '0');
258
- str++;
259
- }
260
- }
261
- finish:
262
- if (invert)
263
- result = 0 - result;
264
- *pstr = str;
265
- return (int64_t)result;
266
- }
267
-
268
- /** A helper function that converts between String data to a signed double. */
269
- #pragma weak fio_atof
270
- double __attribute__((weak)) fio_atof(char **pstr) {
271
- return strtold(*pstr, pstr);
272
- }
273
-
274
- /* *****************************************************************************
275
- Numbers to Strings
276
- ***************************************************************************** */
277
-
278
- /**
279
- * A helper function that writes a signed int64_t to a string.
280
- *
281
- * No overflow guard is provided, make sure there's at least 68 bytes
282
- * available (for base 2).
283
- *
284
- * Offers special support for base 2 (binary), base 8 (octal), base 10 and base
285
- * 16 (hex). An unsupported base will silently default to base 10. Prefixes
286
- * are automatically added (i.e., "0x" for hex and "0b" for base 2).
287
- *
288
- * Returns the number of bytes actually written (excluding the NUL
289
- * terminator).
290
- */
291
- #pragma weak fio_ltoa
292
- size_t __attribute__((weak)) fio_ltoa(char *dest, int64_t num, uint8_t base) {
293
- const char notation[] = {'0', '1', '2', '3', '4', '5', '6', '7',
294
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
295
-
296
- size_t len = 0;
297
- char buf[48]; /* we only need up to 20 for base 10, but base 3 needs 41... */
298
-
299
- if (!num)
300
- goto zero;
301
-
302
- switch (base) {
303
- case 1:
304
- case 2:
305
- /* Base 2 */
306
- {
307
- uint64_t n = num; /* avoid bit shifting inconsistencies with signed bit */
308
- uint8_t i = 0; /* counting bits */
309
- dest[len++] = '0';
310
- dest[len++] = 'b';
311
-
312
- while ((i < 64) && (n & 0x8000000000000000) == 0) {
313
- n = n << 1;
314
- i++;
315
- }
316
- /* make sure the Binary representation doesn't appear signed. */
317
- if (i) {
318
- dest[len++] = '0';
319
- }
320
- /* write to dest. */
321
- while (i < 64) {
322
- dest[len++] = ((n & 0x8000000000000000) ? '1' : '0');
323
- n = n << 1;
324
- i++;
325
- }
326
- dest[len] = 0;
327
- return len;
328
- }
329
- case 8:
330
- /* Base 8 */
331
- {
332
- uint64_t l = 0;
333
- if (num < 0) {
334
- dest[len++] = '-';
335
- num = 0 - num;
336
- }
337
- dest[len++] = '0';
338
-
339
- while (num) {
340
- buf[l++] = '0' + (num & 7);
341
- num = num >> 3;
342
- }
343
- while (l) {
344
- --l;
345
- dest[len++] = buf[l];
346
- }
347
- dest[len] = 0;
348
- return len;
349
- }
350
-
351
- case 16:
352
- /* Base 16 */
353
- {
354
- uint64_t n = num; /* avoid bit shifting inconsistencies with signed bit */
355
- uint8_t i = 0; /* counting bits */
356
- dest[len++] = '0';
357
- dest[len++] = 'x';
358
- while (i < 8 && (n & 0xFF00000000000000) == 0) {
359
- n = n << 8;
360
- i++;
361
- }
362
- /* make sure the Hex representation doesn't appear signed. */
363
- if (i && (n & 0x8000000000000000)) {
364
- dest[len++] = '0';
365
- dest[len++] = '0';
366
- }
367
- /* write the damn thing */
368
- while (i < 8) {
369
- uint8_t tmp = (n & 0xF000000000000000) >> 60;
370
- dest[len++] = notation[tmp];
371
- tmp = (n & 0x0F00000000000000) >> 56;
372
- dest[len++] = notation[tmp];
373
- i++;
374
- n = n << 8;
375
- }
376
- dest[len] = 0;
377
- return len;
378
- }
379
- case 3:
380
- case 4:
381
- case 5:
382
- case 6:
383
- case 7:
384
- case 9:
385
- /* rare bases */
386
- if (num < 0) {
387
- dest[len++] = '-';
388
- num = 0 - num;
389
- }
390
- uint64_t l = 0;
391
- while (num) {
392
- uint64_t t = num / base;
393
- buf[l++] = '0' + (num - (t * base));
394
- num = t;
395
- }
396
- while (l) {
397
- --l;
398
- dest[len++] = buf[l];
399
- }
400
- dest[len] = 0;
401
- return len;
402
-
403
- default:
404
- break;
405
- }
406
- /* Base 10, the default base */
407
-
408
- if (num < 0) {
409
- dest[len++] = '-';
410
- num = 0 - num;
411
- }
412
- uint64_t l = 0;
413
- while (num) {
414
- uint64_t t = num / 10;
415
- buf[l++] = '0' + (num - (t * 10));
416
- num = t;
417
- }
418
- while (l) {
419
- --l;
420
- dest[len++] = buf[l];
421
- }
422
- dest[len] = 0;
423
- return len;
424
-
425
- zero:
426
- switch (base) {
427
- case 1:
428
- case 2:
429
- dest[len++] = '0';
430
- dest[len++] = 'b';
431
- case 16:
432
- dest[len++] = '0';
433
- dest[len++] = 'x';
434
- dest[len++] = '0';
435
- }
436
- dest[len++] = '0';
437
- dest[len] = 0;
438
- return len;
439
- }
440
-
441
- /**
442
- * A helper function that converts between a double to a string.
443
- *
444
- * No overflow guard is provided, make sure there's at least 130 bytes
445
- * available (for base 2).
446
- *
447
- * Supports base 2, base 10 and base 16. An unsupported base will silently
448
- * default to base 10. Prefixes aren't added (i.e., no "0x" or "0b" at the
449
- * beginning of the string).
450
- *
451
- * Returns the number of bytes actually written (excluding the NUL
452
- * terminator).
453
- */
454
- #pragma weak fio_ftoa
455
- size_t __attribute__((weak)) fio_ftoa(char *dest, double num, uint8_t base) {
456
- if (base == 2 || base == 16) {
457
- /* handle the binary / Hex representation the same as if it were an
458
- * int64_t
459
- */
460
- int64_t *i = (void *)&num;
461
- return fio_ltoa(dest, *i, base);
462
- }
463
-
464
- size_t written = sprintf(dest, "%g", num);
465
- uint8_t need_zero = 1;
466
- char *start = dest;
467
- while (*start) {
468
- if (*start == ',') // locale issues?
469
- *start = '.';
470
- if (*start == '.' || *start == 'e') {
471
- need_zero = 0;
472
- break;
473
- }
474
- start++;
475
- }
476
- if (need_zero) {
477
- dest[written++] = '.';
478
- dest[written++] = '0';
479
- }
480
- return written;
481
- }
482
-
483
181
  /* *****************************************************************************
484
182
  Numbers to Strings - Buffered
485
183
  ***************************************************************************** */