1 #include <stdbool.h>
2 #include <stddef.h>
3 #include <stdint.h>
4
5 #include "cmp.h"
6
7 static const uint32_t version = 10;
8 static const uint32_t mp_version = 5;
9
10 enum {
11 POSITIVE_FIXNUM_MARKER = 0x00,
12 FIXMAP_MARKER = 0x80,
13 FIXARRAY_MARKER = 0x90,
14 FIXSTR_MARKER = 0xA0,
15 NIL_MARKER = 0xC0,
16 FALSE_MARKER = 0xC2,
17 TRUE_MARKER = 0xC3,
18 BIN8_MARKER = 0xC4,
19 BIN16_MARKER = 0xC5,
20 BIN32_MARKER = 0xC6,
21 EXT8_MARKER = 0xC7,
22 EXT16_MARKER = 0xC8,
23 EXT32_MARKER = 0xC9,
24 FLOAT_MARKER = 0xCA,
25 DOUBLE_MARKER = 0xCB,
26 U8_MARKER = 0xCC,
27 U16_MARKER = 0xCD,
28 U32_MARKER = 0xCE,
29 U64_MARKER = 0xCF,
30 S8_MARKER = 0xD0,
31 S16_MARKER = 0xD1,
32 S32_MARKER = 0xD2,
33 S64_MARKER = 0xD3,
34 FIXEXT1_MARKER = 0xD4,
35 FIXEXT2_MARKER = 0xD5,
36 FIXEXT4_MARKER = 0xD6,
37 FIXEXT8_MARKER = 0xD7,
38 FIXEXT16_MARKER = 0xD8,
39 STR8_MARKER = 0xD9,
40 STR16_MARKER = 0xDA,
41 STR32_MARKER = 0xDB,
42 ARRAY16_MARKER = 0xDC,
43 ARRAY32_MARKER = 0xDD,
44 MAP16_MARKER = 0xDE,
45 MAP32_MARKER = 0xDF,
46 NEGATIVE_FIXNUM_MARKER = 0xE0
47 };
48
49 enum {
50 FIXARRAY_SIZE = 0xF,
51 FIXMAP_SIZE = 0xF,
52 FIXSTR_SIZE = 0x1F
53 };
54
55 enum {
56 ERROR_NONE,
57 STR_DATA_LENGTH_TOO_LONG_ERROR,
58 BIN_DATA_LENGTH_TOO_LONG_ERROR,
59 ARRAY_LENGTH_TOO_LONG_ERROR,
60 MAP_LENGTH_TOO_LONG_ERROR,
61 INPUT_VALUE_TOO_LARGE_ERROR,
62 FIXED_VALUE_WRITING_ERROR,
63 TYPE_MARKER_READING_ERROR,
64 TYPE_MARKER_WRITING_ERROR,
65 DATA_READING_ERROR,
66 DATA_WRITING_ERROR,
67 EXT_TYPE_READING_ERROR,
68 EXT_TYPE_WRITING_ERROR,
69 INVALID_TYPE_ERROR,
70 LENGTH_READING_ERROR,
71 LENGTH_WRITING_ERROR,
72 ERROR_MAX
73 };
74
75 const char *cmp_error_messages[ERROR_MAX + 1] = {
76 "No Error",
77 "Specified string data length is too long (> 0xFFFFFFFF)",
78 "Specified binary data length is too long (> 0xFFFFFFFF)",
79 "Specified array length is too long (> 0xFFFFFFFF)",
80 "Specified map length is too long (> 0xFFFFFFFF)",
81 "Input value is too large",
82 "Error writing fixed value",
83 "Error reading type marker",
84 "Error writing type marker",
85 "Error reading packed data",
86 "Error writing packed data",
87 "Error reading ext type",
88 "Error writing ext type",
89 "Invalid type",
90 "Error reading size",
91 "Error writing size",
92 "Max Error"
93 };
94
95 static const int32_t _i = 1;
96 #define is_bigendian() ((*(char *)&_i) == 0)
97
be16(uint16_t x)98 static uint16_t be16(uint16_t x) {
99 char *b = (char *)&x;
100
101 if (!is_bigendian()) {
102 char swap = 0;
103
104 swap = b[0];
105 b[0] = b[1];
106 b[1] = swap;
107 }
108
109 return x;
110 }
111
be32(uint32_t x)112 static uint32_t be32(uint32_t x) {
113 char *b = (char *)&x;
114
115 if (!is_bigendian()) {
116 char swap = 0;
117
118 swap = b[0];
119 b[0] = b[3];
120 b[3] = swap;
121
122 swap = b[1];
123 b[1] = b[2];
124 b[2] = swap;
125 }
126
127 return x;
128 }
129
be64(uint64_t x)130 static uint64_t be64(uint64_t x) {
131 char *b = (char *)&x;
132
133 if (!is_bigendian()) {
134 char swap = 0;
135
136 swap = b[0];
137 b[0] = b[7];
138 b[7] = swap;
139
140 swap = b[1];
141 b[1] = b[6];
142 b[6] = swap;
143
144 swap = b[2];
145 b[2] = b[5];
146 b[5] = swap;
147
148 swap = b[3];
149 b[3] = b[4];
150 b[4] = swap;
151 }
152
153 return x;
154 }
155
befloat(float x)156 static float befloat(float x) {
157 char *b = (char *)&x;
158
159 if (!is_bigendian()) {
160 char swap = 0;
161
162 swap = b[0];
163 b[0] = b[3];
164 b[3] = swap;
165
166 swap = b[1];
167 b[1] = b[2];
168 b[2] = swap;
169 }
170
171 return x;
172 }
173
bedouble(double x)174 static double bedouble(double x) {
175 char *b = (char *)&x;
176
177 if (!is_bigendian()) {
178 char swap = 0;
179
180 swap = b[0];
181 b[0] = b[7];
182 b[7] = swap;
183
184 swap = b[1];
185 b[1] = b[6];
186 b[6] = swap;
187
188 swap = b[2];
189 b[2] = b[5];
190 b[5] = swap;
191
192 swap = b[3];
193 b[3] = b[4];
194 b[4] = swap;
195 }
196
197 return x;
198 }
199
read_byte(cmp_ctx_t * ctx,uint8_t * x)200 static bool read_byte(cmp_ctx_t *ctx, uint8_t *x) {
201 return ctx->read(ctx, x, sizeof(uint8_t));
202 }
203
write_byte(cmp_ctx_t * ctx,uint8_t x)204 static bool write_byte(cmp_ctx_t *ctx, uint8_t x) {
205 return (ctx->write(ctx, &x, sizeof(uint8_t)) == (sizeof(uint8_t)));
206 }
207
read_type_marker(cmp_ctx_t * ctx,uint8_t * marker)208 static bool read_type_marker(cmp_ctx_t *ctx, uint8_t *marker) {
209 if (read_byte(ctx, marker))
210 return true;
211
212 ctx->error = TYPE_MARKER_READING_ERROR;
213 return false;
214 }
215
write_type_marker(cmp_ctx_t * ctx,uint8_t marker)216 static bool write_type_marker(cmp_ctx_t *ctx, uint8_t marker) {
217 if (write_byte(ctx, marker))
218 return true;
219
220 ctx->error = TYPE_MARKER_WRITING_ERROR;
221 return false;
222 }
223
write_fixed_value(cmp_ctx_t * ctx,uint8_t value)224 static bool write_fixed_value(cmp_ctx_t *ctx, uint8_t value) {
225 if (write_byte(ctx, value))
226 return true;
227
228 ctx->error = FIXED_VALUE_WRITING_ERROR;
229 return false;
230 }
231
cmp_init(cmp_ctx_t * ctx,void * buf,cmp_reader read,cmp_writer write)232 void cmp_init(cmp_ctx_t *ctx, void *buf, cmp_reader read, cmp_writer write) {
233 ctx->error = ERROR_NONE;
234 ctx->buf = buf;
235 ctx->read = read;
236 ctx->write = write;
237 }
238
cmp_version(void)239 uint32_t cmp_version(void) {
240 return version;
241 }
242
cmp_mp_version(void)243 uint32_t cmp_mp_version(void) {
244 return mp_version;
245 }
246
cmp_strerror(cmp_ctx_t * ctx)247 const char* cmp_strerror(cmp_ctx_t *ctx) {
248 if (ctx->error > ERROR_NONE && ctx->error < ERROR_MAX)
249 return cmp_error_messages[ctx->error];
250
251 return "";
252 }
253
cmp_write_pfix(cmp_ctx_t * ctx,uint8_t c)254 bool cmp_write_pfix(cmp_ctx_t *ctx, uint8_t c) {
255 if (c <= 0x7F)
256 return write_fixed_value(ctx, c);
257
258 ctx->error = INPUT_VALUE_TOO_LARGE_ERROR;
259 return false;
260 }
261
cmp_write_nfix(cmp_ctx_t * ctx,int8_t c)262 bool cmp_write_nfix(cmp_ctx_t *ctx, int8_t c) {
263 if (c >= -32 && c <= -1)
264 return write_fixed_value(ctx, c);
265
266 ctx->error = INPUT_VALUE_TOO_LARGE_ERROR;
267 return false;
268 }
269
cmp_write_sfix(cmp_ctx_t * ctx,int8_t c)270 bool cmp_write_sfix(cmp_ctx_t *ctx, int8_t c) {
271 if (c >= 0)
272 return cmp_write_pfix(ctx, c);
273 if (c >= -32 && c <= -1)
274 return cmp_write_nfix(ctx, c);
275
276 ctx->error = INPUT_VALUE_TOO_LARGE_ERROR;
277 return false;
278 }
279
cmp_write_s8(cmp_ctx_t * ctx,int8_t c)280 bool cmp_write_s8(cmp_ctx_t *ctx, int8_t c) {
281 if (!write_type_marker(ctx, S8_MARKER))
282 return false;
283
284 return ctx->write(ctx, &c, sizeof(int8_t));
285 }
286
cmp_write_s16(cmp_ctx_t * ctx,int16_t s)287 bool cmp_write_s16(cmp_ctx_t *ctx, int16_t s) {
288 if (!write_type_marker(ctx, S16_MARKER))
289 return false;
290
291 s = be16(s);
292
293 return ctx->write(ctx, &s, sizeof(int16_t));
294 }
295
cmp_write_s32(cmp_ctx_t * ctx,int32_t i)296 bool cmp_write_s32(cmp_ctx_t *ctx, int32_t i) {
297 if (!write_type_marker(ctx, S32_MARKER))
298 return false;
299
300 i = be32(i);
301
302 return ctx->write(ctx, &i, sizeof(int32_t));
303 }
304
cmp_write_s64(cmp_ctx_t * ctx,int64_t l)305 bool cmp_write_s64(cmp_ctx_t *ctx, int64_t l) {
306 if (!write_type_marker(ctx, S64_MARKER))
307 return false;
308
309 l = be64(l);
310
311 return ctx->write(ctx, &l, sizeof(int64_t));
312 }
313
cmp_write_sint(cmp_ctx_t * ctx,int64_t d)314 bool cmp_write_sint(cmp_ctx_t *ctx, int64_t d) {
315 if (d >= 0)
316 return cmp_write_uint(ctx, d);
317 if (d >= -32)
318 return cmp_write_nfix(ctx, d);
319 if (d >= -128)
320 return cmp_write_s8(ctx, d);
321 if (d >= -32768)
322 return cmp_write_s16(ctx, d);
323 if (d >= (-2147483647 - 1))
324 return cmp_write_s32(ctx, d);
325
326 return cmp_write_s64(ctx, d);
327 }
328
cmp_write_ufix(cmp_ctx_t * ctx,uint8_t c)329 bool cmp_write_ufix(cmp_ctx_t *ctx, uint8_t c) {
330 return cmp_write_pfix(ctx, c);
331 }
332
cmp_write_u8(cmp_ctx_t * ctx,uint8_t c)333 bool cmp_write_u8(cmp_ctx_t *ctx, uint8_t c) {
334 if (!write_type_marker(ctx, U8_MARKER))
335 return false;
336
337 return ctx->write(ctx, &c, sizeof(uint8_t));
338 }
339
cmp_write_u16(cmp_ctx_t * ctx,uint16_t s)340 bool cmp_write_u16(cmp_ctx_t *ctx, uint16_t s) {
341 if (!write_type_marker(ctx, U16_MARKER))
342 return false;
343
344 s = be16(s);
345
346 return ctx->write(ctx, &s, sizeof(uint16_t));
347 }
348
cmp_write_u32(cmp_ctx_t * ctx,uint32_t i)349 bool cmp_write_u32(cmp_ctx_t *ctx, uint32_t i) {
350 if (!write_type_marker(ctx, U32_MARKER))
351 return false;
352
353 i = be32(i);
354
355 return ctx->write(ctx, &i, sizeof(uint32_t));
356 }
357
cmp_write_u64(cmp_ctx_t * ctx,uint64_t l)358 bool cmp_write_u64(cmp_ctx_t *ctx, uint64_t l) {
359 if (!write_type_marker(ctx, U64_MARKER))
360 return false;
361
362 l = be64(l);
363
364 return ctx->write(ctx, &l, sizeof(uint64_t));
365 }
366
cmp_write_uint(cmp_ctx_t * ctx,uint64_t u)367 bool cmp_write_uint(cmp_ctx_t *ctx, uint64_t u) {
368 if (u <= 0x7F)
369 return cmp_write_pfix(ctx, u);
370 if (u <= 0xFF)
371 return cmp_write_u8(ctx, u);
372 if (u <= 0xFFFF)
373 return cmp_write_u16(ctx, u);
374 if (u <= 0xFFFFFFFF)
375 return cmp_write_u32(ctx, u);
376
377 return cmp_write_u64(ctx, u);
378 }
379
cmp_write_float(cmp_ctx_t * ctx,float f)380 bool cmp_write_float(cmp_ctx_t *ctx, float f) {
381 if (!write_type_marker(ctx, FLOAT_MARKER))
382 return false;
383
384 f = befloat(f);
385
386 return ctx->write(ctx, &f, sizeof(float));
387 }
388
cmp_write_double(cmp_ctx_t * ctx,double d)389 bool cmp_write_double(cmp_ctx_t *ctx, double d) {
390 if (!write_type_marker(ctx, DOUBLE_MARKER))
391 return false;
392
393 d = bedouble(d);
394
395 return ctx->write(ctx, &d, sizeof(double));
396 }
397
cmp_write_nil(cmp_ctx_t * ctx)398 bool cmp_write_nil(cmp_ctx_t *ctx) {
399 return write_type_marker(ctx, NIL_MARKER);
400 }
401
cmp_write_true(cmp_ctx_t * ctx)402 bool cmp_write_true(cmp_ctx_t *ctx) {
403 return write_type_marker(ctx, TRUE_MARKER);
404 }
405
cmp_write_false(cmp_ctx_t * ctx)406 bool cmp_write_false(cmp_ctx_t *ctx) {
407 return write_type_marker(ctx, FALSE_MARKER);
408 }
409
cmp_write_bool(cmp_ctx_t * ctx,bool b)410 bool cmp_write_bool(cmp_ctx_t *ctx, bool b) {
411 if (b)
412 return cmp_write_true(ctx);
413
414 return cmp_write_false(ctx);
415 }
416
cmp_write_u8_as_bool(cmp_ctx_t * ctx,uint8_t b)417 bool cmp_write_u8_as_bool(cmp_ctx_t *ctx, uint8_t b) {
418 if (b)
419 return cmp_write_true(ctx);
420
421 return cmp_write_false(ctx);
422 }
423
cmp_write_fixstr_marker(cmp_ctx_t * ctx,uint8_t size)424 bool cmp_write_fixstr_marker(cmp_ctx_t *ctx, uint8_t size) {
425 if (size <= FIXSTR_SIZE)
426 return write_fixed_value(ctx, FIXSTR_MARKER | size);
427
428 ctx->error = INPUT_VALUE_TOO_LARGE_ERROR;
429 return false;
430 }
431
cmp_write_fixstr(cmp_ctx_t * ctx,const char * data,uint8_t size)432 bool cmp_write_fixstr(cmp_ctx_t *ctx, const char *data, uint8_t size) {
433 if (!cmp_write_fixstr_marker(ctx, size))
434 return false;
435
436 if (size == 0)
437 return true;
438
439 if (ctx->write(ctx, data, size))
440 return true;
441
442 ctx->error = DATA_WRITING_ERROR;
443 return false;
444 }
445
cmp_write_str8_marker(cmp_ctx_t * ctx,uint8_t size)446 bool cmp_write_str8_marker(cmp_ctx_t *ctx, uint8_t size) {
447 if (!write_type_marker(ctx, STR8_MARKER))
448 return false;
449
450 if (ctx->write(ctx, &size, sizeof(uint8_t)))
451 return true;
452
453 ctx->error = LENGTH_WRITING_ERROR;
454 return false;
455 }
456
cmp_write_str8(cmp_ctx_t * ctx,const char * data,uint8_t size)457 bool cmp_write_str8(cmp_ctx_t *ctx, const char *data, uint8_t size) {
458 if (!cmp_write_str8_marker(ctx, size))
459 return false;
460
461 if (size == 0)
462 return true;
463
464 if (ctx->write(ctx, data, size))
465 return true;
466
467 ctx->error = DATA_WRITING_ERROR;
468 return false;
469 }
470
cmp_write_str16_marker(cmp_ctx_t * ctx,uint16_t size)471 bool cmp_write_str16_marker(cmp_ctx_t *ctx, uint16_t size) {
472 if (!write_type_marker(ctx, STR16_MARKER))
473 return false;
474
475 size = be16(size);
476
477 if (ctx->write(ctx, &size, sizeof(uint16_t)))
478 return true;
479
480 ctx->error = LENGTH_WRITING_ERROR;
481 return false;
482 }
483
cmp_write_str16(cmp_ctx_t * ctx,const char * data,uint16_t size)484 bool cmp_write_str16(cmp_ctx_t *ctx, const char *data, uint16_t size) {
485 if (!cmp_write_str16_marker(ctx, size))
486 return false;
487
488 if (size == 0)
489 return true;
490
491 if (ctx->write(ctx, data, size))
492 return true;
493
494 ctx->error = DATA_WRITING_ERROR;
495 return false;
496 }
497
cmp_write_str32_marker(cmp_ctx_t * ctx,uint32_t size)498 bool cmp_write_str32_marker(cmp_ctx_t *ctx, uint32_t size) {
499 if (!write_type_marker(ctx, STR32_MARKER))
500 return false;
501
502 size = be32(size);
503
504 if (ctx->write(ctx, &size, sizeof(uint32_t)))
505 return true;
506
507 ctx->error = LENGTH_WRITING_ERROR;
508 return false;
509 }
510
cmp_write_str32(cmp_ctx_t * ctx,const char * data,uint32_t size)511 bool cmp_write_str32(cmp_ctx_t *ctx, const char *data, uint32_t size) {
512 if (!cmp_write_str32_marker(ctx, size))
513 return false;
514
515 if (size == 0)
516 return true;
517
518 if (ctx->write(ctx, data, size))
519 return true;
520
521 ctx->error = DATA_WRITING_ERROR;
522 return false;
523 }
524
cmp_write_str_marker(cmp_ctx_t * ctx,uint32_t size)525 bool cmp_write_str_marker(cmp_ctx_t *ctx, uint32_t size) {
526 if (size <= FIXSTR_SIZE)
527 return cmp_write_fixstr_marker(ctx, size);
528 if (size <= 0xFF)
529 return cmp_write_str8_marker(ctx, size);
530 if (size <= 0xFFFF)
531 return cmp_write_str16_marker(ctx, size);
532
533 return cmp_write_str32_marker(ctx, size);
534 }
535
cmp_write_str(cmp_ctx_t * ctx,const char * data,uint32_t size)536 bool cmp_write_str(cmp_ctx_t *ctx, const char *data, uint32_t size) {
537 if (size <= FIXSTR_SIZE)
538 return cmp_write_fixstr(ctx, data, size);
539 if (size <= 0xFF)
540 return cmp_write_str8(ctx, data, size);
541 if (size <= 0xFFFF)
542 return cmp_write_str16(ctx, data, size);
543
544 return cmp_write_str32(ctx, data, size);
545 }
546
cmp_write_bin8_marker(cmp_ctx_t * ctx,uint8_t size)547 bool cmp_write_bin8_marker(cmp_ctx_t *ctx, uint8_t size) {
548 if (!write_type_marker(ctx, BIN8_MARKER))
549 return false;
550
551 if (ctx->write(ctx, &size, sizeof(uint8_t)))
552 return true;
553
554 ctx->error = LENGTH_WRITING_ERROR;
555 return false;
556 }
557
cmp_write_bin8(cmp_ctx_t * ctx,const void * data,uint8_t size)558 bool cmp_write_bin8(cmp_ctx_t *ctx, const void *data, uint8_t size) {
559 if (!cmp_write_bin8_marker(ctx, size))
560 return false;
561
562 if (size == 0)
563 return true;
564
565 if (ctx->write(ctx, data, size))
566 return true;
567
568 ctx->error = DATA_WRITING_ERROR;
569 return false;
570 }
571
cmp_write_bin16_marker(cmp_ctx_t * ctx,uint16_t size)572 bool cmp_write_bin16_marker(cmp_ctx_t *ctx, uint16_t size) {
573 if (!write_type_marker(ctx, BIN16_MARKER))
574 return false;
575
576 size = be16(size);
577
578 if (ctx->write(ctx, &size, sizeof(uint16_t)))
579 return true;
580
581 ctx->error = LENGTH_WRITING_ERROR;
582 return false;
583 }
584
cmp_write_bin16(cmp_ctx_t * ctx,const void * data,uint16_t size)585 bool cmp_write_bin16(cmp_ctx_t *ctx, const void *data, uint16_t size) {
586 if (!cmp_write_bin16_marker(ctx, size))
587 return false;
588
589 if (size == 0)
590 return true;
591
592 if (ctx->write(ctx, data, size))
593 return true;
594
595 ctx->error = DATA_WRITING_ERROR;
596 return false;
597 }
598
cmp_write_bin32_marker(cmp_ctx_t * ctx,uint32_t size)599 bool cmp_write_bin32_marker(cmp_ctx_t *ctx, uint32_t size) {
600 if (!write_type_marker(ctx, BIN32_MARKER))
601 return false;
602
603 size = be32(size);
604
605 if (ctx->write(ctx, &size, sizeof(uint32_t)))
606 return true;
607
608 ctx->error = LENGTH_WRITING_ERROR;
609 return false;
610 }
611
cmp_write_bin32(cmp_ctx_t * ctx,const void * data,uint32_t size)612 bool cmp_write_bin32(cmp_ctx_t *ctx, const void *data, uint32_t size) {
613 if (!cmp_write_bin32_marker(ctx, size))
614 return false;
615
616 if (size == 0)
617 return true;
618
619 if (ctx->write(ctx, data, size))
620 return true;
621
622 ctx->error = DATA_WRITING_ERROR;
623 return false;
624 }
625
cmp_write_bin_marker(cmp_ctx_t * ctx,uint32_t size)626 bool cmp_write_bin_marker(cmp_ctx_t *ctx, uint32_t size) {
627 if (size <= 0xFF)
628 return cmp_write_bin8_marker(ctx, size);
629 if (size <= 0xFFFF)
630 return cmp_write_bin16_marker(ctx, size);
631
632 return cmp_write_bin32_marker(ctx, size);
633 }
634
cmp_write_bin(cmp_ctx_t * ctx,const void * data,uint32_t size)635 bool cmp_write_bin(cmp_ctx_t *ctx, const void *data, uint32_t size) {
636 if (size <= 0xFF)
637 return cmp_write_bin8(ctx, data, size);
638 if (size <= 0xFFFF)
639 return cmp_write_bin16(ctx, data, size);
640
641 return cmp_write_bin32(ctx, data, size);
642 }
643
cmp_write_fixarray(cmp_ctx_t * ctx,uint8_t size)644 bool cmp_write_fixarray(cmp_ctx_t *ctx, uint8_t size) {
645 if (size <= FIXARRAY_SIZE)
646 return write_fixed_value(ctx, FIXARRAY_MARKER | size);
647
648 ctx->error = INPUT_VALUE_TOO_LARGE_ERROR;
649 return false;
650 }
651
cmp_write_array16(cmp_ctx_t * ctx,uint16_t size)652 bool cmp_write_array16(cmp_ctx_t *ctx, uint16_t size) {
653 if (!write_type_marker(ctx, ARRAY16_MARKER))
654 return false;
655
656 size = be16(size);
657
658 if (ctx->write(ctx, &size, sizeof(uint16_t)))
659 return true;
660
661 ctx->error = LENGTH_WRITING_ERROR;
662 return false;
663 }
664
cmp_write_array32(cmp_ctx_t * ctx,uint32_t size)665 bool cmp_write_array32(cmp_ctx_t *ctx, uint32_t size) {
666 if (!write_type_marker(ctx, ARRAY32_MARKER))
667 return false;
668
669 size = be32(size);
670
671 if (ctx->write(ctx, &size, sizeof(uint32_t)))
672 return true;
673
674 ctx->error = LENGTH_WRITING_ERROR;
675 return false;
676 }
677
cmp_write_array(cmp_ctx_t * ctx,uint32_t size)678 bool cmp_write_array(cmp_ctx_t *ctx, uint32_t size) {
679 if (size <= FIXARRAY_SIZE)
680 return cmp_write_fixarray(ctx, size);
681 if (size <= 0xFFFF)
682 return cmp_write_array16(ctx, size);
683
684 return cmp_write_array32(ctx, size);
685 }
686
cmp_write_fixmap(cmp_ctx_t * ctx,uint8_t size)687 bool cmp_write_fixmap(cmp_ctx_t *ctx, uint8_t size) {
688 if (size <= FIXMAP_SIZE)
689 return write_fixed_value(ctx, FIXMAP_MARKER | size);
690
691 ctx->error = INPUT_VALUE_TOO_LARGE_ERROR;
692 return false;
693 }
694
cmp_write_map16(cmp_ctx_t * ctx,uint16_t size)695 bool cmp_write_map16(cmp_ctx_t *ctx, uint16_t size) {
696 if (!write_type_marker(ctx, MAP16_MARKER))
697 return false;
698
699 size = be16(size);
700
701 if (ctx->write(ctx, &size, sizeof(uint16_t)))
702 return true;
703
704 ctx->error = LENGTH_WRITING_ERROR;
705 return false;
706 }
707
cmp_write_map32(cmp_ctx_t * ctx,uint32_t size)708 bool cmp_write_map32(cmp_ctx_t *ctx, uint32_t size) {
709 if (!write_type_marker(ctx, MAP32_MARKER))
710 return false;
711
712 size = be32(size);
713
714 if (ctx->write(ctx, &size, sizeof(uint32_t)))
715 return true;
716
717 ctx->error = LENGTH_WRITING_ERROR;
718 return false;
719 }
720
cmp_write_map(cmp_ctx_t * ctx,uint32_t size)721 bool cmp_write_map(cmp_ctx_t *ctx, uint32_t size) {
722 if (size <= FIXMAP_SIZE)
723 return cmp_write_fixmap(ctx, size);
724 if (size <= 0xFFFF)
725 return cmp_write_map16(ctx, size);
726
727 return cmp_write_map32(ctx, size);
728 }
729
cmp_write_fixext1_marker(cmp_ctx_t * ctx,int8_t type)730 bool cmp_write_fixext1_marker(cmp_ctx_t *ctx, int8_t type) {
731 if (!write_type_marker(ctx, FIXEXT1_MARKER))
732 return false;
733
734 if (ctx->write(ctx, &type, sizeof(int8_t)))
735 return true;
736
737 ctx->error = EXT_TYPE_WRITING_ERROR;
738 return false;
739 }
740
cmp_write_fixext1(cmp_ctx_t * ctx,int8_t type,const void * data)741 bool cmp_write_fixext1(cmp_ctx_t *ctx, int8_t type, const void *data) {
742 if (!cmp_write_fixext1_marker(ctx, type))
743 return false;
744
745 if (ctx->write(ctx, data, 1))
746 return true;
747
748 ctx->error = DATA_WRITING_ERROR;
749 return false;
750 }
751
cmp_write_fixext2_marker(cmp_ctx_t * ctx,int8_t type)752 bool cmp_write_fixext2_marker(cmp_ctx_t *ctx, int8_t type) {
753 if (!write_type_marker(ctx, FIXEXT2_MARKER))
754 return false;
755
756 if (ctx->write(ctx, &type, sizeof(int8_t)))
757 return true;
758
759 ctx->error = EXT_TYPE_WRITING_ERROR;
760 return false;
761 }
762
cmp_write_fixext2(cmp_ctx_t * ctx,int8_t type,const void * data)763 bool cmp_write_fixext2(cmp_ctx_t *ctx, int8_t type, const void *data) {
764 if (!cmp_write_fixext2_marker(ctx, type))
765 return false;
766
767 if (ctx->write(ctx, data, 2))
768 return true;
769
770 ctx->error = DATA_WRITING_ERROR;
771 return false;
772 }
773
cmp_write_fixext4_marker(cmp_ctx_t * ctx,int8_t type)774 bool cmp_write_fixext4_marker(cmp_ctx_t *ctx, int8_t type) {
775 if (!write_type_marker(ctx, FIXEXT4_MARKER))
776 return false;
777
778 if (ctx->write(ctx, &type, sizeof(int8_t)))
779 return true;
780
781 ctx->error = EXT_TYPE_WRITING_ERROR;
782 return false;
783 }
784
cmp_write_fixext4(cmp_ctx_t * ctx,int8_t type,const void * data)785 bool cmp_write_fixext4(cmp_ctx_t *ctx, int8_t type, const void *data) {
786 if (!cmp_write_fixext4_marker(ctx, type))
787 return false;
788
789 if (ctx->write(ctx, data, 4))
790 return true;
791
792 ctx->error = DATA_WRITING_ERROR;
793 return false;
794 }
795
cmp_write_fixext8_marker(cmp_ctx_t * ctx,int8_t type)796 bool cmp_write_fixext8_marker(cmp_ctx_t *ctx, int8_t type) {
797 if (!write_type_marker(ctx, FIXEXT8_MARKER))
798 return false;
799
800 if (ctx->write(ctx, &type, sizeof(int8_t)))
801 return true;
802
803 ctx->error = EXT_TYPE_WRITING_ERROR;
804 return false;
805 }
806
cmp_write_fixext8(cmp_ctx_t * ctx,int8_t type,const void * data)807 bool cmp_write_fixext8(cmp_ctx_t *ctx, int8_t type, const void *data) {
808 if (!cmp_write_fixext8_marker(ctx, type))
809 return false;
810
811 if (ctx->write(ctx, data, 8))
812 return true;
813
814 ctx->error = DATA_WRITING_ERROR;
815 return false;
816 }
817
cmp_write_fixext16_marker(cmp_ctx_t * ctx,int8_t type)818 bool cmp_write_fixext16_marker(cmp_ctx_t *ctx, int8_t type) {
819 if (!write_type_marker(ctx, FIXEXT16_MARKER))
820 return false;
821
822 if (ctx->write(ctx, &type, sizeof(int8_t)))
823 return true;
824
825 ctx->error = EXT_TYPE_WRITING_ERROR;
826 return false;
827 }
828
cmp_write_fixext16(cmp_ctx_t * ctx,int8_t type,const void * data)829 bool cmp_write_fixext16(cmp_ctx_t *ctx, int8_t type, const void *data) {
830 if (!cmp_write_fixext16_marker(ctx, type))
831 return false;
832
833 if (ctx->write(ctx, data, 16))
834 return true;
835
836 ctx->error = DATA_WRITING_ERROR;
837 return false;
838 }
839
cmp_write_ext8_marker(cmp_ctx_t * ctx,int8_t type,uint8_t size)840 bool cmp_write_ext8_marker(cmp_ctx_t *ctx, int8_t type, uint8_t size) {
841 if (!write_type_marker(ctx, EXT8_MARKER))
842 return false;
843
844 if (!ctx->write(ctx, &size, sizeof(uint8_t))) {
845 ctx->error = LENGTH_WRITING_ERROR;
846 return false;
847 }
848
849 if (ctx->write(ctx, &type, sizeof(int8_t)))
850 return true;
851
852 ctx->error = EXT_TYPE_WRITING_ERROR;
853 return false;
854 }
855
cmp_write_ext8(cmp_ctx_t * ctx,int8_t tp,uint8_t sz,const void * data)856 bool cmp_write_ext8(cmp_ctx_t *ctx, int8_t tp, uint8_t sz, const void *data) {
857 if (!cmp_write_ext8_marker(ctx, tp, sz))
858 return false;
859
860 if (ctx->write(ctx, data, sz))
861 return true;
862
863 ctx->error = DATA_WRITING_ERROR;
864 return false;
865 }
866
cmp_write_ext16_marker(cmp_ctx_t * ctx,int8_t type,uint16_t size)867 bool cmp_write_ext16_marker(cmp_ctx_t *ctx, int8_t type, uint16_t size) {
868 if (!write_type_marker(ctx, EXT16_MARKER))
869 return false;
870
871 size = be16(size);
872
873 if (!ctx->write(ctx, &size, sizeof(uint16_t))) {
874 ctx->error = LENGTH_WRITING_ERROR;
875 return false;
876 }
877
878 if (ctx->write(ctx, &type, sizeof(int8_t)))
879 return true;
880
881 ctx->error = EXT_TYPE_WRITING_ERROR;
882 return false;
883 }
884
cmp_write_ext16(cmp_ctx_t * ctx,int8_t tp,uint16_t sz,const void * data)885 bool cmp_write_ext16(cmp_ctx_t *ctx, int8_t tp, uint16_t sz, const void *data) {
886 if (!cmp_write_ext16_marker(ctx, tp, sz))
887 return false;
888
889 if (ctx->write(ctx, data, sz))
890 return true;
891
892 ctx->error = DATA_WRITING_ERROR;
893 return false;
894 }
895
cmp_write_ext32_marker(cmp_ctx_t * ctx,int8_t type,uint32_t size)896 bool cmp_write_ext32_marker(cmp_ctx_t *ctx, int8_t type, uint32_t size) {
897 if (!write_type_marker(ctx, EXT32_MARKER))
898 return false;
899
900 size = be32(size);
901
902 if (!ctx->write(ctx, &size, sizeof(uint32_t))) {
903 ctx->error = LENGTH_WRITING_ERROR;
904 return false;
905 }
906
907 if (ctx->write(ctx, &type, sizeof(int8_t)))
908 return true;
909
910 ctx->error = EXT_TYPE_WRITING_ERROR;
911 return false;
912 }
913
cmp_write_ext32(cmp_ctx_t * ctx,int8_t tp,uint32_t sz,const void * data)914 bool cmp_write_ext32(cmp_ctx_t *ctx, int8_t tp, uint32_t sz, const void *data) {
915 if (!cmp_write_ext32_marker(ctx, tp, sz))
916 return false;
917
918 if (ctx->write(ctx, data, sz))
919 return true;
920
921 ctx->error = DATA_WRITING_ERROR;
922 return false;
923 }
924
cmp_write_ext_marker(cmp_ctx_t * ctx,int8_t tp,uint32_t sz)925 bool cmp_write_ext_marker(cmp_ctx_t *ctx, int8_t tp, uint32_t sz) {
926 if (sz == 1)
927 return cmp_write_fixext1_marker(ctx, tp);
928 if (sz == 2)
929 return cmp_write_fixext2_marker(ctx, tp);
930 if (sz == 4)
931 return cmp_write_fixext4_marker(ctx, tp);
932 if (sz == 8)
933 return cmp_write_fixext8_marker(ctx, tp);
934 if (sz == 16)
935 return cmp_write_fixext16_marker(ctx, tp);
936 if (sz <= 0xFF)
937 return cmp_write_ext8_marker(ctx, tp, sz);
938 if (sz <= 0xFFFF)
939 return cmp_write_ext16_marker(ctx, tp, sz);
940
941 return cmp_write_ext32_marker(ctx, tp, sz);
942 }
943
cmp_write_ext(cmp_ctx_t * ctx,int8_t tp,uint32_t sz,const void * data)944 bool cmp_write_ext(cmp_ctx_t *ctx, int8_t tp, uint32_t sz, const void *data) {
945 if (sz == 1)
946 return cmp_write_fixext1(ctx, tp, data);
947 if (sz == 2)
948 return cmp_write_fixext2(ctx, tp, data);
949 if (sz == 4)
950 return cmp_write_fixext4(ctx, tp, data);
951 if (sz == 8)
952 return cmp_write_fixext8(ctx, tp, data);
953 if (sz == 16)
954 return cmp_write_fixext16(ctx, tp, data);
955 if (sz <= 0xFF)
956 return cmp_write_ext8(ctx, tp, sz, data);
957 if (sz <= 0xFFFF)
958 return cmp_write_ext16(ctx, tp, sz, data);
959
960 return cmp_write_ext32(ctx, tp, sz, data);
961 }
962
cmp_write_object(cmp_ctx_t * ctx,cmp_object_t * obj)963 bool cmp_write_object(cmp_ctx_t *ctx, cmp_object_t *obj) {
964 switch(obj->type) {
965 case CMP_TYPE_POSITIVE_FIXNUM:
966 return cmp_write_pfix(ctx, obj->as.u8);
967 case CMP_TYPE_FIXMAP:
968 return cmp_write_fixmap(ctx, obj->as.map_size);
969 case CMP_TYPE_FIXARRAY:
970 return cmp_write_fixarray(ctx, obj->as.array_size);
971 case CMP_TYPE_FIXSTR:
972 return cmp_write_fixstr_marker(ctx, obj->as.str_size);
973 case CMP_TYPE_NIL:
974 return cmp_write_nil(ctx);
975 case CMP_TYPE_BOOLEAN:
976 if (obj->as.boolean)
977 return cmp_write_true(ctx);
978 return cmp_write_false(ctx);
979 case CMP_TYPE_BIN8:
980 return cmp_write_bin8_marker(ctx, obj->as.bin_size);
981 case CMP_TYPE_BIN16:
982 return cmp_write_bin16_marker(ctx, obj->as.bin_size);
983 case CMP_TYPE_BIN32:
984 return cmp_write_bin32_marker(ctx, obj->as.bin_size);
985 case CMP_TYPE_EXT8:
986 return cmp_write_ext8_marker(ctx, obj->as.ext.type, obj->as.ext.size);
987 case CMP_TYPE_EXT16:
988 return cmp_write_ext16_marker(ctx, obj->as.ext.type, obj->as.ext.size);
989 case CMP_TYPE_EXT32:
990 return cmp_write_ext32_marker(ctx, obj->as.ext.type, obj->as.ext.size);
991 case CMP_TYPE_FLOAT:
992 return cmp_write_float(ctx, obj->as.flt);
993 case CMP_TYPE_DOUBLE:
994 return cmp_write_double(ctx, obj->as.dbl);
995 case CMP_TYPE_UINT8:
996 return cmp_write_u8(ctx, obj->as.u8);
997 case CMP_TYPE_UINT16:
998 return cmp_write_u16(ctx, obj->as.u16);
999 case CMP_TYPE_UINT32:
1000 return cmp_write_u32(ctx, obj->as.u32);
1001 case CMP_TYPE_UINT64:
1002 return cmp_write_u64(ctx, obj->as.u64);
1003 case CMP_TYPE_SINT8:
1004 return cmp_write_s8(ctx, obj->as.s8);
1005 case CMP_TYPE_SINT16:
1006 return cmp_write_s16(ctx, obj->as.s16);
1007 case CMP_TYPE_SINT32:
1008 return cmp_write_s32(ctx, obj->as.s32);
1009 case CMP_TYPE_SINT64:
1010 return cmp_write_s64(ctx, obj->as.s64);
1011 case CMP_TYPE_FIXEXT1:
1012 return cmp_write_fixext1_marker(ctx, obj->as.ext.type);
1013 case CMP_TYPE_FIXEXT2:
1014 return cmp_write_fixext2_marker(ctx, obj->as.ext.type);
1015 case CMP_TYPE_FIXEXT4:
1016 return cmp_write_fixext4_marker(ctx, obj->as.ext.type);
1017 case CMP_TYPE_FIXEXT8:
1018 return cmp_write_fixext8_marker(ctx, obj->as.ext.type);
1019 case CMP_TYPE_FIXEXT16:
1020 return cmp_write_fixext16_marker(ctx, obj->as.ext.type);
1021 case CMP_TYPE_STR8:
1022 return cmp_write_str8_marker(ctx, obj->as.str_size);
1023 case CMP_TYPE_STR16:
1024 return cmp_write_str16_marker(ctx, obj->as.str_size);
1025 case CMP_TYPE_STR32:
1026 return cmp_write_str32_marker(ctx, obj->as.str_size);
1027 case CMP_TYPE_ARRAY16:
1028 return cmp_write_array16(ctx, obj->as.array_size);
1029 case CMP_TYPE_ARRAY32:
1030 return cmp_write_array32(ctx, obj->as.array_size);
1031 case CMP_TYPE_MAP16:
1032 return cmp_write_map16(ctx, obj->as.map_size);
1033 case CMP_TYPE_MAP32:
1034 return cmp_write_map32(ctx, obj->as.map_size);
1035 case CMP_TYPE_NEGATIVE_FIXNUM:
1036 return cmp_write_nfix(ctx, obj->as.s8);
1037 default:
1038 ctx->error = INVALID_TYPE_ERROR;
1039 return false;
1040 }
1041 }
1042
cmp_read_pfix(cmp_ctx_t * ctx,uint8_t * c)1043 bool cmp_read_pfix(cmp_ctx_t *ctx, uint8_t *c) {
1044 cmp_object_t obj;
1045
1046 if (!cmp_read_object(ctx, &obj))
1047 return false;
1048
1049 if (obj.type != CMP_TYPE_POSITIVE_FIXNUM) {
1050 ctx->error = INVALID_TYPE_ERROR;
1051 return false;
1052 }
1053
1054 *c = obj.as.u8;
1055 return true;
1056 }
1057
cmp_read_nfix(cmp_ctx_t * ctx,int8_t * c)1058 bool cmp_read_nfix(cmp_ctx_t *ctx, int8_t *c) {
1059 cmp_object_t obj;
1060
1061 if (!cmp_read_object(ctx, &obj))
1062 return false;
1063
1064 if (obj.type != CMP_TYPE_NEGATIVE_FIXNUM) {
1065 ctx->error = INVALID_TYPE_ERROR;
1066 return false;
1067 }
1068
1069 *c = obj.as.s8;
1070 return true;
1071 }
1072
cmp_read_sfix(cmp_ctx_t * ctx,int8_t * c)1073 bool cmp_read_sfix(cmp_ctx_t *ctx, int8_t *c) {
1074 cmp_object_t obj;
1075
1076 if (!cmp_read_object(ctx, &obj))
1077 return false;
1078
1079 switch (obj.type) {
1080 case CMP_TYPE_POSITIVE_FIXNUM:
1081 case CMP_TYPE_NEGATIVE_FIXNUM:
1082 *c = obj.as.s8;
1083 return true;
1084 default:
1085 ctx->error = INVALID_TYPE_ERROR;
1086 return false;
1087 }
1088 }
1089
cmp_read_s8(cmp_ctx_t * ctx,int8_t * c)1090 bool cmp_read_s8(cmp_ctx_t *ctx, int8_t *c) {
1091 cmp_object_t obj;
1092
1093 if (!cmp_read_object(ctx, &obj))
1094 return false;
1095
1096 if (obj.type != CMP_TYPE_SINT8) {
1097 ctx->error = INVALID_TYPE_ERROR;
1098 return false;
1099 }
1100
1101 *c = obj.as.s8;
1102 return true;
1103 }
1104
cmp_read_s16(cmp_ctx_t * ctx,int16_t * s)1105 bool cmp_read_s16(cmp_ctx_t *ctx, int16_t *s) {
1106 cmp_object_t obj;
1107
1108 if (!cmp_read_object(ctx, &obj))
1109 return false;
1110
1111 if (obj.type != CMP_TYPE_SINT16) {
1112 ctx->error = INVALID_TYPE_ERROR;
1113 return false;
1114 }
1115
1116 *s = obj.as.s16;
1117 return true;
1118 }
1119
cmp_read_s32(cmp_ctx_t * ctx,int32_t * i)1120 bool cmp_read_s32(cmp_ctx_t *ctx, int32_t *i) {
1121 cmp_object_t obj;
1122
1123 if (!cmp_read_object(ctx, &obj))
1124 return false;
1125
1126 if (obj.type != CMP_TYPE_SINT32) {
1127 ctx->error = INVALID_TYPE_ERROR;
1128 return false;
1129 }
1130
1131 *i = obj.as.s32;
1132 return true;
1133 }
1134
cmp_read_s64(cmp_ctx_t * ctx,int64_t * l)1135 bool cmp_read_s64(cmp_ctx_t *ctx, int64_t *l) {
1136 cmp_object_t obj;
1137
1138 if (!cmp_read_object(ctx, &obj))
1139 return false;
1140
1141 if (obj.type != CMP_TYPE_SINT64) {
1142 ctx->error = INVALID_TYPE_ERROR;
1143 return false;
1144 }
1145
1146 *l = obj.as.s64;
1147 return true;
1148 }
1149
cmp_read_char(cmp_ctx_t * ctx,int8_t * c)1150 bool cmp_read_char(cmp_ctx_t *ctx, int8_t *c) {
1151 cmp_object_t obj;
1152
1153 if (!cmp_read_object(ctx, &obj))
1154 return false;
1155
1156 switch (obj.type) {
1157 case CMP_TYPE_POSITIVE_FIXNUM:
1158 case CMP_TYPE_NEGATIVE_FIXNUM:
1159 case CMP_TYPE_SINT8:
1160 *c = obj.as.s8;
1161 return true;
1162 case CMP_TYPE_UINT8:
1163 if (obj.as.u8 <= 127) {
1164 *c = obj.as.u8;
1165 return true;
1166 }
1167 default:
1168 ctx->error = INVALID_TYPE_ERROR;
1169 return false;
1170 }
1171 }
1172
cmp_read_short(cmp_ctx_t * ctx,int16_t * s)1173 bool cmp_read_short(cmp_ctx_t *ctx, int16_t *s) {
1174 cmp_object_t obj;
1175
1176 if (!cmp_read_object(ctx, &obj))
1177 return false;
1178
1179 switch (obj.type) {
1180 case CMP_TYPE_POSITIVE_FIXNUM:
1181 case CMP_TYPE_NEGATIVE_FIXNUM:
1182 case CMP_TYPE_SINT8:
1183 *s = obj.as.s8;
1184 return true;
1185 case CMP_TYPE_UINT8:
1186 *s = obj.as.u8;
1187 return true;
1188 case CMP_TYPE_SINT16:
1189 *s = obj.as.s16;
1190 return true;
1191 case CMP_TYPE_UINT16:
1192 if (obj.as.u16 <= 32767) {
1193 *s = obj.as.u16;
1194 return true;
1195 }
1196 default:
1197 ctx->error = INVALID_TYPE_ERROR;
1198 return false;
1199 }
1200 }
1201
cmp_read_int(cmp_ctx_t * ctx,int32_t * i)1202 bool cmp_read_int(cmp_ctx_t *ctx, int32_t *i) {
1203 cmp_object_t obj;
1204
1205 if (!cmp_read_object(ctx, &obj))
1206 return false;
1207
1208 switch (obj.type) {
1209 case CMP_TYPE_POSITIVE_FIXNUM:
1210 case CMP_TYPE_NEGATIVE_FIXNUM:
1211 case CMP_TYPE_SINT8:
1212 *i = obj.as.s8;
1213 return true;
1214 case CMP_TYPE_UINT8:
1215 *i = obj.as.u8;
1216 return true;
1217 case CMP_TYPE_SINT16:
1218 *i = obj.as.s16;
1219 return true;
1220 case CMP_TYPE_UINT16:
1221 *i = obj.as.u16;
1222 return true;
1223 case CMP_TYPE_SINT32:
1224 *i = obj.as.s32;
1225 return true;
1226 case CMP_TYPE_UINT32:
1227 if (obj.as.u32 <= 2147483647) {
1228 *i = obj.as.u32;
1229 return true;
1230 }
1231 default:
1232 ctx->error = INVALID_TYPE_ERROR;
1233 return false;
1234 }
1235 }
1236
cmp_read_long(cmp_ctx_t * ctx,int64_t * d)1237 bool cmp_read_long(cmp_ctx_t *ctx, int64_t *d) {
1238 cmp_object_t obj;
1239
1240 if (!cmp_read_object(ctx, &obj))
1241 return false;
1242
1243 switch (obj.type) {
1244 case CMP_TYPE_POSITIVE_FIXNUM:
1245 case CMP_TYPE_NEGATIVE_FIXNUM:
1246 case CMP_TYPE_SINT8:
1247 *d = obj.as.s8;
1248 return true;
1249 case CMP_TYPE_UINT8:
1250 *d = obj.as.u8;
1251 return true;
1252 case CMP_TYPE_SINT16:
1253 *d = obj.as.s16;
1254 return true;
1255 case CMP_TYPE_UINT16:
1256 *d = obj.as.u16;
1257 return true;
1258 case CMP_TYPE_SINT32:
1259 *d = obj.as.s32;
1260 return true;
1261 case CMP_TYPE_UINT32:
1262 *d = obj.as.u32;
1263 return true;
1264 case CMP_TYPE_SINT64:
1265 *d = obj.as.s64;
1266 return true;
1267 case CMP_TYPE_UINT64:
1268 if (obj.as.u64 <= 9223372036854775807) {
1269 *d = obj.as.u64;
1270 return true;
1271 }
1272 default:
1273 ctx->error = INVALID_TYPE_ERROR;
1274 return false;
1275 }
1276 }
1277
cmp_read_sinteger(cmp_ctx_t * ctx,int64_t * d)1278 bool cmp_read_sinteger(cmp_ctx_t *ctx, int64_t *d) {
1279 return cmp_read_long(ctx, d);
1280 }
1281
cmp_read_ufix(cmp_ctx_t * ctx,uint8_t * c)1282 bool cmp_read_ufix(cmp_ctx_t *ctx, uint8_t *c) {
1283 cmp_object_t obj;
1284
1285 if (!cmp_read_object(ctx, &obj))
1286 return false;
1287
1288 if (obj.type != CMP_TYPE_NEGATIVE_FIXNUM) {
1289 ctx->error = INVALID_TYPE_ERROR;
1290 return false;
1291 }
1292
1293 *c = obj.as.u8;
1294 return true;
1295 }
1296
cmp_read_u8(cmp_ctx_t * ctx,uint8_t * c)1297 bool cmp_read_u8(cmp_ctx_t *ctx, uint8_t *c) {
1298 cmp_object_t obj;
1299
1300 if (!cmp_read_object(ctx, &obj))
1301 return false;
1302
1303 if (obj.type != CMP_TYPE_UINT8) {
1304 ctx->error = INVALID_TYPE_ERROR;
1305 return false;
1306 }
1307
1308 *c = obj.as.u8;
1309 return true;
1310 }
1311
cmp_read_u16(cmp_ctx_t * ctx,uint16_t * s)1312 bool cmp_read_u16(cmp_ctx_t *ctx, uint16_t *s) {
1313 cmp_object_t obj;
1314
1315 if (!cmp_read_object(ctx, &obj))
1316 return false;
1317
1318 if (obj.type != CMP_TYPE_UINT16) {
1319 ctx->error = INVALID_TYPE_ERROR;
1320 return false;
1321 }
1322
1323 *s = obj.as.u16;
1324 return true;
1325 }
1326
cmp_read_u32(cmp_ctx_t * ctx,uint32_t * i)1327 bool cmp_read_u32(cmp_ctx_t *ctx, uint32_t *i) {
1328 cmp_object_t obj;
1329
1330 if (!cmp_read_object(ctx, &obj))
1331 return false;
1332
1333 if (obj.type != CMP_TYPE_UINT32) {
1334 ctx->error = INVALID_TYPE_ERROR;
1335 return false;
1336 }
1337
1338 *i = obj.as.u32;
1339 return true;
1340 }
1341
cmp_read_u64(cmp_ctx_t * ctx,uint64_t * l)1342 bool cmp_read_u64(cmp_ctx_t *ctx, uint64_t *l) {
1343 cmp_object_t obj;
1344
1345 if (!cmp_read_object(ctx, &obj))
1346 return false;
1347
1348 if (obj.type != CMP_TYPE_UINT64) {
1349 ctx->error = INVALID_TYPE_ERROR;
1350 return false;
1351 }
1352
1353 *l = obj.as.u64;
1354 return true;
1355 }
1356
cmp_read_uchar(cmp_ctx_t * ctx,uint8_t * c)1357 bool cmp_read_uchar(cmp_ctx_t *ctx, uint8_t *c) {
1358 cmp_object_t obj;
1359
1360 if (!cmp_read_object(ctx, &obj))
1361 return false;
1362
1363 switch (obj.type) {
1364 case CMP_TYPE_POSITIVE_FIXNUM:
1365 case CMP_TYPE_UINT8:
1366 *c = obj.as.u8;
1367 return true;
1368 default:
1369 ctx->error = INVALID_TYPE_ERROR;
1370 return false;
1371 }
1372 }
1373
cmp_read_ushort(cmp_ctx_t * ctx,uint16_t * s)1374 bool cmp_read_ushort(cmp_ctx_t *ctx, uint16_t *s) {
1375 cmp_object_t obj;
1376
1377 if (!cmp_read_object(ctx, &obj))
1378 return false;
1379
1380 switch (obj.type) {
1381 case CMP_TYPE_POSITIVE_FIXNUM:
1382 case CMP_TYPE_UINT8:
1383 *s = obj.as.u8;
1384 return true;
1385 case CMP_TYPE_UINT16:
1386 *s = obj.as.u16;
1387 return true;
1388 default:
1389 ctx->error = INVALID_TYPE_ERROR;
1390 return false;
1391 }
1392 }
1393
cmp_read_uint(cmp_ctx_t * ctx,uint32_t * i)1394 bool cmp_read_uint(cmp_ctx_t *ctx, uint32_t *i) {
1395 cmp_object_t obj;
1396
1397 if (!cmp_read_object(ctx, &obj))
1398 return false;
1399
1400 switch (obj.type) {
1401 case CMP_TYPE_POSITIVE_FIXNUM:
1402 case CMP_TYPE_UINT8:
1403 *i = obj.as.u8;
1404 return true;
1405 case CMP_TYPE_UINT16:
1406 *i = obj.as.u16;
1407 return true;
1408 case CMP_TYPE_UINT32:
1409 *i = obj.as.u32;
1410 return true;
1411 default:
1412 ctx->error = INVALID_TYPE_ERROR;
1413 return false;
1414 }
1415 }
1416
cmp_read_ulong(cmp_ctx_t * ctx,uint64_t * u)1417 bool cmp_read_ulong(cmp_ctx_t *ctx, uint64_t *u) {
1418 cmp_object_t obj;
1419
1420 if (!cmp_read_object(ctx, &obj))
1421 return false;
1422
1423 switch (obj.type) {
1424 case CMP_TYPE_POSITIVE_FIXNUM:
1425 case CMP_TYPE_UINT8:
1426 *u = obj.as.u8;
1427 return true;
1428 case CMP_TYPE_UINT16:
1429 *u = obj.as.u16;
1430 return true;
1431 case CMP_TYPE_UINT32:
1432 *u = obj.as.u32;
1433 return true;
1434 case CMP_TYPE_UINT64:
1435 *u = obj.as.u64;
1436 return true;
1437 default:
1438 ctx->error = INVALID_TYPE_ERROR;
1439 return false;
1440 }
1441 }
1442
cmp_read_uinteger(cmp_ctx_t * ctx,uint64_t * d)1443 bool cmp_read_uinteger(cmp_ctx_t *ctx, uint64_t *d) {
1444 return cmp_read_ulong(ctx, d);
1445 }
1446
cmp_read_float(cmp_ctx_t * ctx,float * f)1447 bool cmp_read_float(cmp_ctx_t *ctx, float *f) {
1448 cmp_object_t obj;
1449
1450 if (!cmp_read_object(ctx, &obj))
1451 return false;
1452
1453 if (obj.type != CMP_TYPE_FLOAT) {
1454 ctx->error = INVALID_TYPE_ERROR;
1455 return false;
1456 }
1457
1458 *f = obj.as.flt;
1459
1460 return true;
1461 }
1462
cmp_read_double(cmp_ctx_t * ctx,double * d)1463 bool cmp_read_double(cmp_ctx_t *ctx, double *d) {
1464 cmp_object_t obj;
1465
1466 if (!cmp_read_object(ctx, &obj))
1467 return false;
1468
1469 if (obj.type != CMP_TYPE_DOUBLE) {
1470 ctx->error = INVALID_TYPE_ERROR;
1471 return false;
1472 }
1473
1474 *d = obj.as.dbl;
1475
1476 return true;
1477 }
1478
cmp_read_nil(cmp_ctx_t * ctx)1479 bool cmp_read_nil(cmp_ctx_t *ctx) {
1480 cmp_object_t obj;
1481
1482 if (!cmp_read_object(ctx, &obj))
1483 return false;
1484
1485 if (obj.type == CMP_TYPE_NIL)
1486 return true;
1487
1488 ctx->error = INVALID_TYPE_ERROR;
1489 return false;
1490 }
1491
cmp_read_bool(cmp_ctx_t * ctx,bool * b)1492 bool cmp_read_bool(cmp_ctx_t *ctx, bool *b) {
1493 cmp_object_t obj;
1494
1495 if (!cmp_read_object(ctx, &obj))
1496 return false;
1497
1498 if (obj.type != CMP_TYPE_BOOLEAN) {
1499 ctx->error = INVALID_TYPE_ERROR;
1500 return false;
1501 }
1502
1503 if (obj.as.boolean)
1504 *b = true;
1505 else
1506 *b = false;
1507
1508 return true;
1509 }
1510
cmp_read_bool_as_u8(cmp_ctx_t * ctx,uint8_t * b)1511 bool cmp_read_bool_as_u8(cmp_ctx_t *ctx, uint8_t *b) {
1512 cmp_object_t obj;
1513
1514 if (!cmp_read_object(ctx, &obj))
1515 return false;
1516
1517 if (obj.type != CMP_TYPE_BOOLEAN) {
1518 ctx->error = INVALID_TYPE_ERROR;
1519 return false;
1520 }
1521
1522 if (obj.as.boolean)
1523 *b = 1;
1524 else
1525 *b = 0;
1526
1527 return true;
1528 }
1529
cmp_read_str_size(cmp_ctx_t * ctx,uint32_t * size)1530 bool cmp_read_str_size(cmp_ctx_t *ctx, uint32_t *size) {
1531 cmp_object_t obj;
1532
1533 if (!cmp_read_object(ctx, &obj))
1534 return false;
1535
1536 switch (obj.type) {
1537 case CMP_TYPE_FIXSTR:
1538 case CMP_TYPE_STR8:
1539 case CMP_TYPE_STR16:
1540 case CMP_TYPE_STR32:
1541 *size = obj.as.str_size;
1542 return true;
1543 default:
1544 ctx->error = INVALID_TYPE_ERROR;
1545 return false;
1546 }
1547 }
1548
cmp_read_str(cmp_ctx_t * ctx,char * data,uint32_t * size)1549 bool cmp_read_str(cmp_ctx_t *ctx, char *data, uint32_t *size) {
1550 uint32_t str_size = 0;
1551
1552 if (!cmp_read_str_size(ctx, &str_size))
1553 return false;
1554
1555 if ((str_size + 1) > *size) {
1556 *size = str_size;
1557 ctx->error = STR_DATA_LENGTH_TOO_LONG_ERROR;
1558 return false;
1559 }
1560
1561 if (!ctx->read(ctx, data, str_size)) {
1562 ctx->error = DATA_READING_ERROR;
1563 return false;
1564 }
1565
1566 data[str_size] = 0;
1567
1568 *size = str_size;
1569 return true;
1570 }
1571
cmp_read_bin_size(cmp_ctx_t * ctx,uint32_t * size)1572 bool cmp_read_bin_size(cmp_ctx_t *ctx, uint32_t *size) {
1573 cmp_object_t obj;
1574
1575 if (!cmp_read_object(ctx, &obj))
1576 return false;
1577
1578 switch (obj.type) {
1579 case CMP_TYPE_BIN8:
1580 case CMP_TYPE_BIN16:
1581 case CMP_TYPE_BIN32:
1582 *size = obj.as.bin_size;
1583 return true;
1584 default:
1585 ctx->error = INVALID_TYPE_ERROR;
1586 return false;
1587 }
1588 }
1589
cmp_read_bin(cmp_ctx_t * ctx,void * data,uint32_t * size)1590 bool cmp_read_bin(cmp_ctx_t *ctx, void *data, uint32_t *size) {
1591 uint32_t bin_size = 0;
1592
1593 if (!cmp_read_bin_size(ctx, &bin_size))
1594 return false;
1595
1596 if (bin_size > *size) {
1597 ctx->error = BIN_DATA_LENGTH_TOO_LONG_ERROR;
1598 return false;
1599 }
1600
1601 if (!ctx->read(ctx, data, bin_size)) {
1602 ctx->error = DATA_READING_ERROR;
1603 return false;
1604 }
1605
1606 *size = bin_size;
1607 return true;
1608 }
1609
cmp_read_array(cmp_ctx_t * ctx,uint32_t * size)1610 bool cmp_read_array(cmp_ctx_t *ctx, uint32_t *size) {
1611 cmp_object_t obj;
1612
1613 if (!cmp_read_object(ctx, &obj))
1614 return false;
1615
1616 switch (obj.type) {
1617 case CMP_TYPE_FIXARRAY:
1618 case CMP_TYPE_ARRAY16:
1619 case CMP_TYPE_ARRAY32:
1620 *size = obj.as.array_size;
1621 return true;
1622 default:
1623 ctx->error = INVALID_TYPE_ERROR;
1624 return false;
1625 }
1626 }
1627
cmp_read_map(cmp_ctx_t * ctx,uint32_t * size)1628 bool cmp_read_map(cmp_ctx_t *ctx, uint32_t *size) {
1629 cmp_object_t obj;
1630
1631 if (!cmp_read_object(ctx, &obj))
1632 return false;
1633
1634 switch (obj.type) {
1635 case CMP_TYPE_FIXMAP:
1636 case CMP_TYPE_MAP16:
1637 case CMP_TYPE_MAP32:
1638 *size = obj.as.map_size;
1639 return true;
1640 default:
1641 ctx->error = INVALID_TYPE_ERROR;
1642 return false;
1643 }
1644 }
1645
cmp_read_fixext1_marker(cmp_ctx_t * ctx,int8_t * type)1646 bool cmp_read_fixext1_marker(cmp_ctx_t *ctx, int8_t *type) {
1647 cmp_object_t obj;
1648
1649 if (!cmp_read_object(ctx, &obj))
1650 return false;
1651
1652 if (obj.type != CMP_TYPE_FIXEXT1) {
1653 ctx->error = INVALID_TYPE_ERROR;
1654 return false;
1655 }
1656
1657 *type = obj.as.ext.type;
1658 return true;
1659 }
1660
cmp_read_fixext1(cmp_ctx_t * ctx,int8_t * type,void * data)1661 bool cmp_read_fixext1(cmp_ctx_t *ctx, int8_t *type, void *data) {
1662 if (!cmp_read_fixext1_marker(ctx, type))
1663 return false;
1664
1665 if (ctx->read(ctx, data, 1))
1666 return true;
1667
1668 ctx->error = DATA_READING_ERROR;
1669 return false;
1670 }
1671
cmp_read_fixext2_marker(cmp_ctx_t * ctx,int8_t * type)1672 bool cmp_read_fixext2_marker(cmp_ctx_t *ctx, int8_t *type) {
1673 cmp_object_t obj;
1674
1675 if (!cmp_read_object(ctx, &obj))
1676 return false;
1677
1678 if (obj.type != CMP_TYPE_FIXEXT2) {
1679 ctx->error = INVALID_TYPE_ERROR;
1680 return false;
1681 }
1682
1683 *type = obj.as.ext.type;
1684 return true;
1685 }
1686
cmp_read_fixext2(cmp_ctx_t * ctx,int8_t * type,void * data)1687 bool cmp_read_fixext2(cmp_ctx_t *ctx, int8_t *type, void *data) {
1688 if (!cmp_read_fixext2_marker(ctx, type))
1689 return false;
1690
1691 if (ctx->read(ctx, data, 2))
1692 return true;
1693
1694 ctx->error = DATA_READING_ERROR;
1695 return false;
1696 }
1697
cmp_read_fixext4_marker(cmp_ctx_t * ctx,int8_t * type)1698 bool cmp_read_fixext4_marker(cmp_ctx_t *ctx, int8_t *type) {
1699 cmp_object_t obj;
1700
1701 if (!cmp_read_object(ctx, &obj))
1702 return false;
1703
1704 if (obj.type != CMP_TYPE_FIXEXT4) {
1705 ctx->error = INVALID_TYPE_ERROR;
1706 return false;
1707 }
1708
1709 *type = obj.as.ext.type;
1710 return true;
1711 }
1712
cmp_read_fixext4(cmp_ctx_t * ctx,int8_t * type,void * data)1713 bool cmp_read_fixext4(cmp_ctx_t *ctx, int8_t *type, void *data) {
1714 if (!cmp_read_fixext4_marker(ctx, type))
1715 return false;
1716
1717 if (ctx->read(ctx, data, 4))
1718 return true;
1719
1720 ctx->error = DATA_READING_ERROR;
1721 return false;
1722 }
1723
cmp_read_fixext8_marker(cmp_ctx_t * ctx,int8_t * type)1724 bool cmp_read_fixext8_marker(cmp_ctx_t *ctx, int8_t *type) {
1725 cmp_object_t obj;
1726
1727 if (!cmp_read_object(ctx, &obj))
1728 return false;
1729
1730 if (obj.type != CMP_TYPE_FIXEXT8) {
1731 ctx->error = INVALID_TYPE_ERROR;
1732 return false;
1733 }
1734
1735 *type = obj.as.ext.type;
1736 return true;
1737 }
1738
cmp_read_fixext8(cmp_ctx_t * ctx,int8_t * type,void * data)1739 bool cmp_read_fixext8(cmp_ctx_t *ctx, int8_t *type, void *data) {
1740 if (!cmp_read_fixext8_marker(ctx, type))
1741 return false;
1742
1743 if (ctx->read(ctx, data, 8))
1744 return true;
1745
1746 ctx->error = DATA_READING_ERROR;
1747 return false;
1748 }
1749
cmp_read_fixext16_marker(cmp_ctx_t * ctx,int8_t * type)1750 bool cmp_read_fixext16_marker(cmp_ctx_t *ctx, int8_t *type) {
1751 cmp_object_t obj;
1752
1753 if (!cmp_read_object(ctx, &obj))
1754 return false;
1755
1756 if (obj.type != CMP_TYPE_FIXEXT16) {
1757 ctx->error = INVALID_TYPE_ERROR;
1758 return false;
1759 }
1760
1761 *type = obj.as.ext.type;
1762 return true;
1763 }
1764
cmp_read_fixext16(cmp_ctx_t * ctx,int8_t * type,void * data)1765 bool cmp_read_fixext16(cmp_ctx_t *ctx, int8_t *type, void *data) {
1766 if (!cmp_read_fixext16_marker(ctx, type))
1767 return false;
1768
1769 if (ctx->read(ctx, data, 16))
1770 return true;
1771
1772 ctx->error = DATA_READING_ERROR;
1773 return false;
1774 }
1775
cmp_read_ext8_marker(cmp_ctx_t * ctx,int8_t * type,uint8_t * size)1776 bool cmp_read_ext8_marker(cmp_ctx_t *ctx, int8_t *type, uint8_t *size) {
1777 cmp_object_t obj;
1778
1779 if (!cmp_read_object(ctx, &obj))
1780 return false;
1781
1782 if (obj.type != CMP_TYPE_EXT8) {
1783 ctx->error = INVALID_TYPE_ERROR;
1784 return false;
1785 }
1786
1787 *type = obj.as.ext.type;
1788 *size = obj.as.ext.size;
1789
1790 return true;
1791 }
1792
cmp_read_ext8(cmp_ctx_t * ctx,int8_t * type,uint8_t * size,void * data)1793 bool cmp_read_ext8(cmp_ctx_t *ctx, int8_t *type, uint8_t *size, void *data) {
1794 if (!cmp_read_ext8_marker(ctx, type, size))
1795 return false;
1796
1797 if (ctx->read(ctx, data, *size))
1798 return true;
1799
1800 ctx->error = DATA_READING_ERROR;
1801 return false;
1802 }
1803
cmp_read_ext16_marker(cmp_ctx_t * ctx,int8_t * type,uint16_t * size)1804 bool cmp_read_ext16_marker(cmp_ctx_t *ctx, int8_t *type, uint16_t *size) {
1805 cmp_object_t obj;
1806
1807 if (!cmp_read_object(ctx, &obj))
1808 return false;
1809
1810 if (obj.type != CMP_TYPE_EXT16) {
1811 ctx->error = INVALID_TYPE_ERROR;
1812 return false;
1813 }
1814
1815 *type = obj.as.ext.type;
1816 *size = obj.as.ext.size;
1817
1818 return true;
1819 }
1820
cmp_read_ext16(cmp_ctx_t * ctx,int8_t * type,uint16_t * size,void * data)1821 bool cmp_read_ext16(cmp_ctx_t *ctx, int8_t *type, uint16_t *size, void *data) {
1822 if (!cmp_read_ext16_marker(ctx, type, size))
1823 return false;
1824
1825 if (ctx->read(ctx, data, *size))
1826 return true;
1827
1828 ctx->error = DATA_READING_ERROR;
1829 return false;
1830 }
1831
cmp_read_ext32_marker(cmp_ctx_t * ctx,int8_t * type,uint32_t * size)1832 bool cmp_read_ext32_marker(cmp_ctx_t *ctx, int8_t *type, uint32_t *size) {
1833 cmp_object_t obj;
1834
1835 if (!cmp_read_object(ctx, &obj))
1836 return false;
1837
1838 if (obj.type != CMP_TYPE_EXT32) {
1839 ctx->error = INVALID_TYPE_ERROR;
1840 return false;
1841 }
1842
1843 *type = obj.as.ext.type;
1844 *size = obj.as.ext.size;
1845
1846 return true;
1847 }
1848
cmp_read_ext32(cmp_ctx_t * ctx,int8_t * type,uint32_t * size,void * data)1849 bool cmp_read_ext32(cmp_ctx_t *ctx, int8_t *type, uint32_t *size, void *data) {
1850 if (!cmp_read_ext32_marker(ctx, type, size))
1851 return false;
1852
1853 if (ctx->read(ctx, data, *size))
1854 return true;
1855
1856 ctx->error = DATA_READING_ERROR;
1857 return false;
1858 }
1859
cmp_read_ext_marker(cmp_ctx_t * ctx,int8_t * type,uint32_t * size)1860 bool cmp_read_ext_marker(cmp_ctx_t *ctx, int8_t *type, uint32_t *size) {
1861 cmp_object_t obj;
1862
1863 if (!cmp_read_object(ctx, &obj))
1864 return false;
1865
1866 switch (obj.type) {
1867 case CMP_TYPE_FIXEXT1:
1868 case CMP_TYPE_FIXEXT2:
1869 case CMP_TYPE_FIXEXT4:
1870 case CMP_TYPE_FIXEXT8:
1871 case CMP_TYPE_FIXEXT16:
1872 case CMP_TYPE_EXT8:
1873 case CMP_TYPE_EXT16:
1874 case CMP_TYPE_EXT32:
1875 *type = obj.as.ext.type;
1876 *size = obj.as.ext.size;
1877 return true;
1878 default:
1879 ctx->error = INVALID_TYPE_ERROR;
1880 return false;
1881 }
1882 }
1883
cmp_read_ext(cmp_ctx_t * ctx,int8_t * type,uint32_t * size,void * data)1884 bool cmp_read_ext(cmp_ctx_t *ctx, int8_t *type, uint32_t *size, void *data) {
1885 if (!cmp_read_ext_marker(ctx, type, size))
1886 return false;
1887
1888 if (ctx->read(ctx, data, *size))
1889 return true;
1890
1891 ctx->error = DATA_READING_ERROR;
1892 return false;
1893 }
1894
cmp_read_object(cmp_ctx_t * ctx,cmp_object_t * obj)1895 bool cmp_read_object(cmp_ctx_t *ctx, cmp_object_t *obj) {
1896 uint8_t type_marker = 0;
1897
1898 if (!read_type_marker(ctx, &type_marker))
1899 return false;
1900
1901 if (type_marker <= 0x7F) {
1902 obj->type = CMP_TYPE_POSITIVE_FIXNUM;
1903 obj->as.u8 = type_marker;
1904 }
1905 else if (type_marker <= 0x8F) {
1906 obj->type = CMP_TYPE_FIXMAP;
1907 obj->as.map_size = type_marker & FIXMAP_SIZE;
1908 }
1909 else if (type_marker <= 0x9F) {
1910 obj->type = CMP_TYPE_FIXARRAY;
1911 obj->as.array_size = type_marker & FIXARRAY_SIZE;
1912 }
1913 else if (type_marker <= 0xBF) {
1914 obj->type = CMP_TYPE_FIXSTR;
1915 obj->as.str_size = type_marker & FIXSTR_SIZE;
1916 }
1917 else if (type_marker == NIL_MARKER) {
1918 obj->type = CMP_TYPE_NIL;
1919 obj->as.u8 = 0;
1920 }
1921 else if (type_marker == FALSE_MARKER) {
1922 obj->type = CMP_TYPE_BOOLEAN;
1923 obj->as.boolean = false;
1924 }
1925 else if (type_marker == TRUE_MARKER) {
1926 obj->type = CMP_TYPE_BOOLEAN;
1927 obj->as.boolean = true;
1928 }
1929 else if (type_marker == BIN8_MARKER) {
1930 obj->type = CMP_TYPE_BIN8;
1931 if (!ctx->read(ctx, &obj->as.u8, sizeof(uint8_t))) {
1932 ctx->error = LENGTH_READING_ERROR;
1933 return false;
1934 }
1935 obj->as.bin_size = obj->as.u8;
1936 }
1937 else if (type_marker == BIN16_MARKER) {
1938 obj->type = CMP_TYPE_BIN16;
1939 if (!ctx->read(ctx, &obj->as.u16, sizeof(uint16_t))) {
1940 ctx->error = LENGTH_READING_ERROR;
1941 return false;
1942 }
1943 obj->as.bin_size = be16(obj->as.u16);
1944 }
1945 else if (type_marker == BIN32_MARKER) {
1946 obj->type = CMP_TYPE_BIN32;
1947 if (!ctx->read(ctx, &obj->as.u32, sizeof(uint32_t))) {
1948 ctx->error = LENGTH_READING_ERROR;
1949 return false;
1950 }
1951 obj->as.bin_size = be32(obj->as.u32);
1952 }
1953 else if (type_marker == EXT8_MARKER) {
1954 uint8_t ext_size;
1955 int8_t ext_type;
1956
1957 obj->type = CMP_TYPE_EXT8;
1958 if (!ctx->read(ctx, &ext_size, sizeof(uint8_t))) {
1959 ctx->error = LENGTH_READING_ERROR;
1960 return false;
1961 }
1962 if (!ctx->read(ctx, &ext_type, sizeof(int8_t))) {
1963 ctx->error = EXT_TYPE_READING_ERROR;
1964 return false;
1965 }
1966 obj->as.ext.size = ext_size;
1967 obj->as.ext.type = ext_type;
1968 }
1969 else if (type_marker == EXT16_MARKER) {
1970 int8_t ext_type;
1971 uint16_t ext_size;
1972
1973 obj->type = CMP_TYPE_EXT16;
1974 if (!ctx->read(ctx, &ext_size, sizeof(uint16_t))) {
1975 ctx->error = LENGTH_READING_ERROR;
1976 return false;
1977 }
1978 if (!ctx->read(ctx, &ext_type, sizeof(int8_t))) {
1979 ctx->error = EXT_TYPE_READING_ERROR;
1980 return false;
1981 }
1982 obj->as.ext.size = be16(ext_size);
1983 obj->as.ext.type = ext_type;
1984 }
1985 else if (type_marker == EXT32_MARKER) {
1986 int8_t ext_type;
1987 uint32_t ext_size;
1988
1989 obj->type = CMP_TYPE_EXT32;
1990 if (!ctx->read(ctx, &ext_size, sizeof(uint32_t))) {
1991 ctx->error = LENGTH_READING_ERROR;
1992 return false;
1993 }
1994 if (!ctx->read(ctx, &ext_type, sizeof(int8_t))) {
1995 ctx->error = EXT_TYPE_READING_ERROR;
1996 return false;
1997 }
1998 obj->as.ext.size = be32(ext_size);
1999 obj->as.ext.type = ext_type;
2000 }
2001 else if (type_marker == FLOAT_MARKER) {
2002 obj->type = CMP_TYPE_FLOAT;
2003 if (!ctx->read(ctx, &obj->as.flt, sizeof(float))) {
2004 ctx->error = DATA_READING_ERROR;
2005 return false;
2006 }
2007 obj->as.flt = befloat(obj->as.flt);
2008 }
2009 else if (type_marker == DOUBLE_MARKER) {
2010 obj->type = CMP_TYPE_DOUBLE;
2011 if (!ctx->read(ctx, &obj->as.dbl, sizeof(double))) {
2012 ctx->error = DATA_READING_ERROR;
2013 return false;
2014 }
2015 obj->as.dbl = bedouble(obj->as.dbl);
2016 }
2017 else if (type_marker == U8_MARKER) {
2018 obj->type = CMP_TYPE_UINT8;
2019 if (!ctx->read(ctx, &obj->as.u8, sizeof(uint8_t))) {
2020 ctx->error = DATA_READING_ERROR;
2021 return false;
2022 }
2023 }
2024 else if (type_marker == U16_MARKER) {
2025 obj->type = CMP_TYPE_UINT16;
2026 if (!ctx->read(ctx, &obj->as.u16, sizeof(uint16_t))) {
2027 ctx->error = DATA_READING_ERROR;
2028 return false;
2029 }
2030 obj->as.u16 = be16(obj->as.u16);
2031 }
2032 else if (type_marker == U32_MARKER) {
2033 obj->type = CMP_TYPE_UINT32;
2034 if (!ctx->read(ctx, &obj->as.u32, sizeof(uint32_t))) {
2035 ctx->error = DATA_READING_ERROR;
2036 return false;
2037 }
2038 obj->as.u32 = be32(obj->as.u32);
2039 }
2040 else if (type_marker == U64_MARKER) {
2041 obj->type = CMP_TYPE_UINT64;
2042 if (!ctx->read(ctx, &obj->as.u64, sizeof(uint64_t))) {
2043 ctx->error = DATA_READING_ERROR;
2044 return false;
2045 }
2046 obj->as.u64 = be64(obj->as.u64);
2047 }
2048 else if (type_marker == S8_MARKER) {
2049 obj->type = CMP_TYPE_SINT8;
2050 if (!ctx->read(ctx, &obj->as.s8, sizeof(int8_t))) {
2051 ctx->error = DATA_READING_ERROR;
2052 return false;
2053 }
2054 }
2055 else if (type_marker == S16_MARKER) {
2056 obj->type = CMP_TYPE_SINT16;
2057 if (!ctx->read(ctx, &obj->as.s16, sizeof(int16_t))) {
2058 ctx->error = DATA_READING_ERROR;
2059 return false;
2060 }
2061 obj->as.s16 = be16(obj->as.s16);
2062 }
2063 else if (type_marker == S32_MARKER) {
2064 obj->type = CMP_TYPE_SINT32;
2065 if (!ctx->read(ctx, &obj->as.s32, sizeof(int32_t))) {
2066 ctx->error = DATA_READING_ERROR;
2067 return false;
2068 }
2069 obj->as.s32 = be32(obj->as.s32);
2070 }
2071 else if (type_marker == S64_MARKER) {
2072 obj->type = CMP_TYPE_SINT64;
2073 if (!ctx->read(ctx, &obj->as.s64, sizeof(int64_t))) {
2074 ctx->error = DATA_READING_ERROR;
2075 return false;
2076 }
2077 obj->as.s64 = be64(obj->as.s64);
2078 }
2079 else if (type_marker == FIXEXT1_MARKER) {
2080 obj->type = CMP_TYPE_FIXEXT1;
2081 if (!ctx->read(ctx, &obj->as.ext.type, sizeof(int8_t))) {
2082 ctx->error = EXT_TYPE_READING_ERROR;
2083 return false;
2084 }
2085 obj->as.ext.size = 1;
2086 }
2087 else if (type_marker == FIXEXT2_MARKER) {
2088 obj->type = CMP_TYPE_FIXEXT2;
2089 if (!ctx->read(ctx, &obj->as.ext.type, sizeof(int8_t))) {
2090 ctx->error = EXT_TYPE_READING_ERROR;
2091 return false;
2092 }
2093 obj->as.ext.size = 2;
2094 }
2095 else if (type_marker == FIXEXT4_MARKER) {
2096 obj->type = CMP_TYPE_FIXEXT4;
2097 if (!ctx->read(ctx, &obj->as.ext.type, sizeof(int8_t))) {
2098 ctx->error = EXT_TYPE_READING_ERROR;
2099 return false;
2100 }
2101 obj->as.ext.size = 4;
2102 }
2103 else if (type_marker == FIXEXT8_MARKER) {
2104 obj->type = CMP_TYPE_FIXEXT8;
2105 if (!ctx->read(ctx, &obj->as.ext.type, sizeof(int8_t))) {
2106 ctx->error = EXT_TYPE_READING_ERROR;
2107 return false;
2108 }
2109 obj->as.ext.size = 8;
2110 }
2111 else if (type_marker == FIXEXT16_MARKER) {
2112 obj->type = CMP_TYPE_FIXEXT16;
2113 if (!ctx->read(ctx, &obj->as.ext.type, sizeof(int8_t))) {
2114 ctx->error = EXT_TYPE_READING_ERROR;
2115 return false;
2116 }
2117 obj->as.ext.size = 16;
2118 }
2119 else if (type_marker == STR8_MARKER) {
2120 obj->type = CMP_TYPE_STR8;
2121 if (!ctx->read(ctx, &obj->as.u8, sizeof(uint8_t))) {
2122 ctx->error = DATA_READING_ERROR;
2123 return false;
2124 }
2125 obj->as.str_size = obj->as.u8;
2126 }
2127 else if (type_marker == STR16_MARKER) {
2128 obj->type = CMP_TYPE_STR16;
2129 if (!ctx->read(ctx, &obj->as.u16, sizeof(uint16_t))) {
2130 ctx->error = DATA_READING_ERROR;
2131 return false;
2132 }
2133 obj->as.str_size = be16(obj->as.u16);
2134 }
2135 else if (type_marker == STR32_MARKER) {
2136 obj->type = CMP_TYPE_STR32;
2137 if (!ctx->read(ctx, &obj->as.u32, sizeof(uint32_t))) {
2138 ctx->error = DATA_READING_ERROR;
2139 return false;
2140 }
2141 obj->as.str_size = be32(obj->as.u32);
2142 }
2143 else if (type_marker == ARRAY16_MARKER) {
2144 obj->type = CMP_TYPE_ARRAY16;
2145 if (!ctx->read(ctx, &obj->as.u16, sizeof(uint16_t))) {
2146 ctx->error = DATA_READING_ERROR;
2147 return false;
2148 }
2149 obj->as.array_size = be16(obj->as.u16);
2150 }
2151 else if (type_marker == ARRAY32_MARKER) {
2152 obj->type = CMP_TYPE_ARRAY32;
2153 if (!ctx->read(ctx, &obj->as.u32, sizeof(uint32_t))) {
2154 ctx->error = DATA_READING_ERROR;
2155 return false;
2156 }
2157 obj->as.array_size = be32(obj->as.u32);
2158 }
2159 else if (type_marker == MAP16_MARKER) {
2160 obj->type = CMP_TYPE_MAP16;
2161 if (!ctx->read(ctx, &obj->as.u16, sizeof(uint16_t))) {
2162 ctx->error = DATA_READING_ERROR;
2163 return false;
2164 }
2165 obj->as.map_size = be16(obj->as.u16);
2166 }
2167 else if (type_marker == MAP32_MARKER) {
2168 obj->type = CMP_TYPE_MAP32;
2169 if (!ctx->read(ctx, &obj->as.u32, sizeof(uint32_t))) {
2170 ctx->error = DATA_READING_ERROR;
2171 return false;
2172 }
2173 obj->as.map_size = be32(obj->as.u32);
2174 }
2175 else if (type_marker >= NEGATIVE_FIXNUM_MARKER) {
2176 obj->type = CMP_TYPE_NEGATIVE_FIXNUM;
2177 obj->as.s8 = type_marker;
2178 }
2179 else {
2180 ctx->error = INVALID_TYPE_ERROR;
2181 return false;
2182 }
2183
2184 return true;
2185 }
2186
cmp_object_is_char(cmp_object_t * obj)2187 bool cmp_object_is_char(cmp_object_t *obj) {
2188 switch (obj->type) {
2189 case CMP_TYPE_NEGATIVE_FIXNUM:
2190 case CMP_TYPE_SINT8:
2191 return true;
2192 default:
2193 return false;
2194 }
2195 }
2196
cmp_object_is_short(cmp_object_t * obj)2197 bool cmp_object_is_short(cmp_object_t *obj) {
2198 switch (obj->type) {
2199 case CMP_TYPE_NEGATIVE_FIXNUM:
2200 case CMP_TYPE_SINT8:
2201 case CMP_TYPE_SINT16:
2202 return true;
2203 default:
2204 return false;
2205 }
2206 }
2207
cmp_object_is_int(cmp_object_t * obj)2208 bool cmp_object_is_int(cmp_object_t *obj) {
2209 switch (obj->type) {
2210 case CMP_TYPE_NEGATIVE_FIXNUM:
2211 case CMP_TYPE_SINT8:
2212 case CMP_TYPE_SINT16:
2213 case CMP_TYPE_SINT32:
2214 return true;
2215 default:
2216 return false;
2217 }
2218 }
2219
cmp_object_is_long(cmp_object_t * obj)2220 bool cmp_object_is_long(cmp_object_t *obj) {
2221 switch (obj->type) {
2222 case CMP_TYPE_NEGATIVE_FIXNUM:
2223 case CMP_TYPE_SINT8:
2224 case CMP_TYPE_SINT16:
2225 case CMP_TYPE_SINT32:
2226 case CMP_TYPE_SINT64:
2227 return true;
2228 default:
2229 return false;
2230 }
2231 }
2232
cmp_object_is_sinteger(cmp_object_t * obj)2233 bool cmp_object_is_sinteger(cmp_object_t *obj) {
2234 return cmp_object_is_long(obj);
2235 }
2236
cmp_object_is_uchar(cmp_object_t * obj)2237 bool cmp_object_is_uchar(cmp_object_t *obj) {
2238 switch (obj->type) {
2239 case CMP_TYPE_POSITIVE_FIXNUM:
2240 case CMP_TYPE_UINT8:
2241 return true;
2242 default:
2243 return false;
2244 }
2245 }
2246
cmp_object_is_ushort(cmp_object_t * obj)2247 bool cmp_object_is_ushort(cmp_object_t *obj) {
2248 switch (obj->type) {
2249 case CMP_TYPE_POSITIVE_FIXNUM:
2250 case CMP_TYPE_UINT8:
2251 return true;
2252 case CMP_TYPE_UINT16:
2253 return true;
2254 default:
2255 return false;
2256 }
2257 }
2258
cmp_object_is_uint(cmp_object_t * obj)2259 bool cmp_object_is_uint(cmp_object_t *obj) {
2260 switch (obj->type) {
2261 case CMP_TYPE_POSITIVE_FIXNUM:
2262 case CMP_TYPE_UINT8:
2263 case CMP_TYPE_UINT16:
2264 case CMP_TYPE_UINT32:
2265 return true;
2266 default:
2267 return false;
2268 }
2269 }
2270
cmp_object_is_ulong(cmp_object_t * obj)2271 bool cmp_object_is_ulong(cmp_object_t *obj) {
2272 switch (obj->type) {
2273 case CMP_TYPE_POSITIVE_FIXNUM:
2274 case CMP_TYPE_UINT8:
2275 case CMP_TYPE_UINT16:
2276 case CMP_TYPE_UINT32:
2277 case CMP_TYPE_UINT64:
2278 return true;
2279 default:
2280 return false;
2281 }
2282 }
2283
cmp_object_is_uinteger(cmp_object_t * obj)2284 bool cmp_object_is_uinteger(cmp_object_t *obj) {
2285 return cmp_object_is_ulong(obj);
2286 }
2287
cmp_object_is_float(cmp_object_t * obj)2288 bool cmp_object_is_float(cmp_object_t *obj) {
2289 if (obj->type == CMP_TYPE_FLOAT)
2290 return true;
2291
2292 return false;
2293 }
2294
cmp_object_is_double(cmp_object_t * obj)2295 bool cmp_object_is_double(cmp_object_t *obj) {
2296 if (obj->type == CMP_TYPE_DOUBLE)
2297 return true;
2298
2299 return false;
2300 }
2301
cmp_object_is_nil(cmp_object_t * obj)2302 bool cmp_object_is_nil(cmp_object_t *obj) {
2303 if (obj->type == CMP_TYPE_NIL)
2304 return true;
2305
2306 return false;
2307 }
2308
cmp_object_is_bool(cmp_object_t * obj)2309 bool cmp_object_is_bool(cmp_object_t *obj) {
2310 if (obj->type == CMP_TYPE_BOOLEAN)
2311 return true;
2312
2313 return false;
2314 }
2315
cmp_object_is_str(cmp_object_t * obj)2316 bool cmp_object_is_str(cmp_object_t *obj) {
2317 switch (obj->type) {
2318 case CMP_TYPE_FIXSTR:
2319 case CMP_TYPE_STR8:
2320 case CMP_TYPE_STR16:
2321 case CMP_TYPE_STR32:
2322 return true;
2323 default:
2324 return false;
2325 }
2326 }
2327
cmp_object_is_bin(cmp_object_t * obj)2328 bool cmp_object_is_bin(cmp_object_t *obj) {
2329 switch (obj->type) {
2330 case CMP_TYPE_BIN8:
2331 case CMP_TYPE_BIN16:
2332 case CMP_TYPE_BIN32:
2333 return true;
2334 default:
2335 return false;
2336 }
2337 }
2338
cmp_object_is_array(cmp_object_t * obj)2339 bool cmp_object_is_array(cmp_object_t *obj) {
2340 switch (obj->type) {
2341 case CMP_TYPE_FIXARRAY:
2342 case CMP_TYPE_ARRAY16:
2343 case CMP_TYPE_ARRAY32:
2344 return true;
2345 default:
2346 return false;
2347 }
2348 }
2349
cmp_object_is_map(cmp_object_t * obj)2350 bool cmp_object_is_map(cmp_object_t *obj) {
2351 switch (obj->type) {
2352 case CMP_TYPE_FIXMAP:
2353 case CMP_TYPE_MAP16:
2354 case CMP_TYPE_MAP32:
2355 return true;
2356 default:
2357 return false;
2358 }
2359 }
2360
cmp_object_is_ext(cmp_object_t * obj)2361 bool cmp_object_is_ext(cmp_object_t *obj) {
2362 switch (obj->type) {
2363 case CMP_TYPE_FIXEXT1:
2364 case CMP_TYPE_FIXEXT2:
2365 case CMP_TYPE_FIXEXT4:
2366 case CMP_TYPE_FIXEXT8:
2367 case CMP_TYPE_FIXEXT16:
2368 case CMP_TYPE_EXT8:
2369 case CMP_TYPE_EXT16:
2370 case CMP_TYPE_EXT32:
2371 return true;
2372 default:
2373 return false;
2374 }
2375 }
2376
cmp_object_as_char(cmp_object_t * obj,int8_t * c)2377 bool cmp_object_as_char(cmp_object_t *obj, int8_t *c) {
2378 switch (obj->type) {
2379 case CMP_TYPE_POSITIVE_FIXNUM:
2380 case CMP_TYPE_NEGATIVE_FIXNUM:
2381 case CMP_TYPE_SINT8:
2382 *c = obj->as.s8;
2383 return true;
2384 case CMP_TYPE_UINT8:
2385 if (obj->as.u8 <= 127) {
2386 *c = obj->as.s8;
2387 return true;
2388 }
2389 }
2390
2391 return false;
2392 }
2393
cmp_object_as_short(cmp_object_t * obj,int16_t * s)2394 bool cmp_object_as_short(cmp_object_t *obj, int16_t *s) {
2395 switch (obj->type) {
2396 case CMP_TYPE_POSITIVE_FIXNUM:
2397 case CMP_TYPE_NEGATIVE_FIXNUM:
2398 case CMP_TYPE_SINT8:
2399 *s = obj->as.s8;
2400 return true;
2401 case CMP_TYPE_UINT8:
2402 *s = obj->as.u8;
2403 return true;
2404 case CMP_TYPE_SINT16:
2405 *s = obj->as.s16;
2406 return true;
2407 case CMP_TYPE_UINT16:
2408 if (obj->as.u16 <= 32767) {
2409 *s = obj->as.u16;
2410 return true;
2411 }
2412 }
2413
2414 return false;
2415 }
2416
cmp_object_as_int(cmp_object_t * obj,int32_t * i)2417 bool cmp_object_as_int(cmp_object_t *obj, int32_t *i) {
2418 switch (obj->type) {
2419 case CMP_TYPE_POSITIVE_FIXNUM:
2420 case CMP_TYPE_NEGATIVE_FIXNUM:
2421 case CMP_TYPE_SINT8:
2422 *i = obj->as.s8;
2423 return true;
2424 case CMP_TYPE_UINT8:
2425 *i = obj->as.u8;
2426 return true;
2427 case CMP_TYPE_SINT16:
2428 *i = obj->as.s16;
2429 return true;
2430 case CMP_TYPE_UINT16:
2431 *i = obj->as.u16;
2432 return true;
2433 case CMP_TYPE_SINT32:
2434 *i = obj->as.s32;
2435 return true;
2436 case CMP_TYPE_UINT32:
2437 if (obj->as.u32 <= 2147483647) {
2438 *i = obj->as.u32;
2439 return true;
2440 }
2441 }
2442
2443 return false;
2444 }
2445
cmp_object_as_long(cmp_object_t * obj,int64_t * d)2446 bool cmp_object_as_long(cmp_object_t *obj, int64_t *d) {
2447 switch (obj->type) {
2448 case CMP_TYPE_POSITIVE_FIXNUM:
2449 case CMP_TYPE_NEGATIVE_FIXNUM:
2450 case CMP_TYPE_SINT8:
2451 *d = obj->as.s8;
2452 return true;
2453 case CMP_TYPE_UINT8:
2454 *d = obj->as.u8;
2455 return true;
2456 case CMP_TYPE_SINT16:
2457 *d = obj->as.s16;
2458 return true;
2459 case CMP_TYPE_UINT16:
2460 *d = obj->as.u16;
2461 return true;
2462 case CMP_TYPE_SINT32:
2463 *d = obj->as.s32;
2464 return true;
2465 case CMP_TYPE_UINT32:
2466 *d = obj->as.u32;
2467 return true;
2468 case CMP_TYPE_SINT64:
2469 *d = obj->as.s64;
2470 return true;
2471 case CMP_TYPE_UINT64:
2472 if (obj->as.u64 <= 9223372036854775807) {
2473 *d = obj->as.u64;
2474 return true;
2475 }
2476 }
2477
2478 return false;
2479 }
2480
cmp_object_as_sinteger(cmp_object_t * obj,int64_t * d)2481 bool cmp_object_as_sinteger(cmp_object_t *obj, int64_t *d) {
2482 return cmp_object_as_long(obj, d);
2483 }
2484
cmp_object_as_uchar(cmp_object_t * obj,uint8_t * c)2485 bool cmp_object_as_uchar(cmp_object_t *obj, uint8_t *c) {
2486 switch (obj->type) {
2487 case CMP_TYPE_POSITIVE_FIXNUM:
2488 case CMP_TYPE_UINT8:
2489 *c = obj->as.u8;
2490 return true;
2491 }
2492
2493 return false;
2494 }
2495
cmp_object_as_ushort(cmp_object_t * obj,uint16_t * s)2496 bool cmp_object_as_ushort(cmp_object_t *obj, uint16_t *s) {
2497 switch (obj->type) {
2498 case CMP_TYPE_POSITIVE_FIXNUM:
2499 case CMP_TYPE_UINT8:
2500 *s = obj->as.u8;
2501 return true;
2502 case CMP_TYPE_UINT16:
2503 *s = obj->as.u16;
2504 return true;
2505 }
2506
2507 return false;
2508 }
2509
cmp_object_as_uint(cmp_object_t * obj,uint32_t * i)2510 bool cmp_object_as_uint(cmp_object_t *obj, uint32_t *i) {
2511 switch (obj->type) {
2512 case CMP_TYPE_POSITIVE_FIXNUM:
2513 case CMP_TYPE_UINT8:
2514 *i = obj->as.u8;
2515 return true;
2516 case CMP_TYPE_UINT16:
2517 *i = obj->as.u16;
2518 return true;
2519 case CMP_TYPE_UINT32:
2520 *i = obj->as.u32;
2521 return true;
2522 }
2523
2524 return false;
2525 }
2526
cmp_object_as_ulong(cmp_object_t * obj,uint64_t * u)2527 bool cmp_object_as_ulong(cmp_object_t *obj, uint64_t *u) {
2528 switch (obj->type) {
2529 case CMP_TYPE_POSITIVE_FIXNUM:
2530 case CMP_TYPE_UINT8:
2531 *u = obj->as.u8;
2532 return true;
2533 case CMP_TYPE_UINT16:
2534 *u = obj->as.u16;
2535 return true;
2536 case CMP_TYPE_UINT32:
2537 *u = obj->as.u32;
2538 return true;
2539 case CMP_TYPE_UINT64:
2540 *u = obj->as.u64;
2541 return true;
2542 }
2543
2544 return false;
2545 }
2546
cmp_object_as_uinteger(cmp_object_t * obj,uint64_t * d)2547 bool cmp_object_as_uinteger(cmp_object_t *obj, uint64_t *d) {
2548 return cmp_object_as_ulong(obj, d);
2549 }
2550
cmp_object_as_float(cmp_object_t * obj,float * f)2551 bool cmp_object_as_float(cmp_object_t *obj, float *f) {
2552 if (obj->type == CMP_TYPE_FLOAT) {
2553 *f = obj->as.flt;
2554 return true;
2555 }
2556
2557 return false;
2558 }
2559
cmp_object_as_double(cmp_object_t * obj,double * d)2560 bool cmp_object_as_double(cmp_object_t *obj, double *d) {
2561 if (obj->type == CMP_TYPE_DOUBLE) {
2562 *d = obj->as.dbl;
2563 return true;
2564 }
2565
2566 return false;
2567 }
2568
cmp_object_as_bool(cmp_object_t * obj,bool * b)2569 bool cmp_object_as_bool(cmp_object_t *obj, bool *b) {
2570 if (obj->type == CMP_TYPE_BOOLEAN) {
2571 if (obj->as.boolean)
2572 *b = true;
2573 else
2574 *b = false;
2575
2576 return true;
2577 }
2578
2579 return false;
2580 }
2581
cmp_object_as_str(cmp_object_t * obj,uint32_t * size)2582 bool cmp_object_as_str(cmp_object_t *obj, uint32_t *size) {
2583 switch (obj->type) {
2584 case CMP_TYPE_FIXSTR:
2585 case CMP_TYPE_STR8:
2586 case CMP_TYPE_STR16:
2587 case CMP_TYPE_STR32:
2588 *size = obj->as.str_size;
2589 return true;
2590 }
2591
2592 return false;
2593 }
2594
cmp_object_as_bin(cmp_object_t * obj,uint32_t * size)2595 bool cmp_object_as_bin(cmp_object_t *obj, uint32_t *size) {
2596 switch (obj->type) {
2597 case CMP_TYPE_BIN8:
2598 case CMP_TYPE_BIN16:
2599 case CMP_TYPE_BIN32:
2600 *size = obj->as.bin_size;
2601 return true;
2602 }
2603
2604 return false;
2605 }
2606
cmp_object_as_array(cmp_object_t * obj,uint32_t * size)2607 bool cmp_object_as_array(cmp_object_t *obj, uint32_t *size) {
2608 switch (obj->type) {
2609 case CMP_TYPE_FIXARRAY:
2610 case CMP_TYPE_ARRAY16:
2611 case CMP_TYPE_ARRAY32:
2612 *size = obj->as.array_size;
2613 return true;
2614 }
2615
2616 return false;
2617 }
2618
cmp_object_as_map(cmp_object_t * obj,uint32_t * size)2619 bool cmp_object_as_map(cmp_object_t *obj, uint32_t *size) {
2620 switch (obj->type) {
2621 case CMP_TYPE_FIXMAP:
2622 case CMP_TYPE_MAP16:
2623 case CMP_TYPE_MAP32:
2624 *size = obj->as.map_size;
2625 return true;
2626 }
2627
2628 return false;
2629 }
2630
cmp_object_as_ext(cmp_object_t * obj,int8_t * type,uint32_t * size)2631 bool cmp_object_as_ext(cmp_object_t *obj, int8_t *type, uint32_t *size) {
2632 switch (obj->type) {
2633 case CMP_TYPE_FIXEXT1:
2634 case CMP_TYPE_FIXEXT2:
2635 case CMP_TYPE_FIXEXT4:
2636 case CMP_TYPE_FIXEXT8:
2637 case CMP_TYPE_FIXEXT16:
2638 case CMP_TYPE_EXT8:
2639 case CMP_TYPE_EXT16:
2640 case CMP_TYPE_EXT32:
2641 *type = obj->as.ext.type;
2642 *size = obj->as.ext.size;
2643 return true;
2644 }
2645
2646 return false;
2647 }
2648
2649 /* vi: set et ts=2 sw=2: */
2650
2651