Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/libucl/src/ucl_msgpack.c
2066 views
1
/*
2
* Copyright (c) 2015, Vsevolod Stakhov
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
7
* * Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* * Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
*
13
* THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
14
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
* DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
17
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
*/
24
25
26
#ifdef HAVE_CONFIG_H
27
#include "config.h"
28
#endif
29
30
#include "ucl.h"
31
#include "ucl_internal.h"
32
33
#ifdef HAVE_ENDIAN_H
34
#include <endian.h>
35
#elif defined(HAVE_SYS_ENDIAN_H)
36
#include <sys/endian.h>
37
#elif defined(HAVE_MACHINE_ENDIAN_H)
38
#include <machine/endian.h>
39
#endif
40
41
#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
42
#if __BYTE_ORDER == __LITTLE_ENDIAN
43
#define __LITTLE_ENDIAN__
44
#elif __BYTE_ORDER == __BIG_ENDIAN
45
#define __BIG_ENDIAN__
46
#elif _WIN32
47
#define __LITTLE_ENDIAN__
48
#endif
49
#endif
50
51
#define SWAP_LE_BE16(val) ((uint16_t) ( \
52
(uint16_t) ((uint16_t) (val) >> 8) | \
53
(uint16_t) ((uint16_t) (val) << 8)))
54
55
#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3)
56
# define SWAP_LE_BE32(val) ((uint32_t)__builtin_bswap32 ((uint32_t)(val)))
57
# define SWAP_LE_BE64(val) ((uint64_t)__builtin_bswap64 ((uint64_t)(val)))
58
#else
59
#define SWAP_LE_BE32(val) ((uint32_t)( \
60
(((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \
61
(((uint32_t)(val) & (uint32_t)0x0000ff00U) << 8) | \
62
(((uint32_t)(val) & (uint32_t)0x00ff0000U) >> 8) | \
63
(((uint32_t)(val) & (uint32_t)0xff000000U) >> 24)))
64
65
#define SWAP_LE_BE64(val) ((uint64_t)( \
66
(((uint64_t)(val) & \
67
(uint64_t)(0x00000000000000ffULL)) << 56) | \
68
(((uint64_t)(val) & \
69
(uint64_t)(0x000000000000ff00ULL)) << 40) | \
70
(((uint64_t)(val) & \
71
(uint64_t)(0x0000000000ff0000ULL)) << 24) | \
72
(((uint64_t)(val) & \
73
(uint64_t) (0x00000000ff000000ULL)) << 8) | \
74
(((uint64_t)(val) & \
75
(uint64_t)(0x000000ff00000000ULL)) >> 8) | \
76
(((uint64_t)(val) & \
77
(uint64_t)(0x0000ff0000000000ULL)) >> 24) | \
78
(((uint64_t)(val) & \
79
(uint64_t)(0x00ff000000000000ULL)) >> 40) | \
80
(((uint64_t)(val) & \
81
(uint64_t)(0xff00000000000000ULL)) >> 56)))
82
#endif
83
84
#ifdef __LITTLE_ENDIAN__
85
#define TO_BE16 SWAP_LE_BE16
86
#define TO_BE32 SWAP_LE_BE32
87
#define TO_BE64 SWAP_LE_BE64
88
#define FROM_BE16 SWAP_LE_BE16
89
#define FROM_BE32 SWAP_LE_BE32
90
#define FROM_BE64 SWAP_LE_BE64
91
#else
92
#define TO_BE16(val) (uint16_t)(val)
93
#define TO_BE32(val) (uint32_t)(val)
94
#define TO_BE64(val) (uint64_t)(val)
95
#define FROM_BE16(val) (uint16_t)(val)
96
#define FROM_BE32(val) (uint32_t)(val)
97
#define FROM_BE64(val) (uint64_t)(val)
98
#endif
99
100
void
101
ucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, int64_t val)
102
{
103
const struct ucl_emitter_functions *func = ctx->func;
104
unsigned char buf[sizeof(uint64_t) + 1];
105
const unsigned char mask_positive = 0x7f, mask_negative = 0xe0,
106
uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf,
107
int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3;
108
unsigned len;
109
110
if (val >= 0) {
111
if (val <= 0x7f) {
112
/* Fixed num 7 bits */
113
len = 1;
114
buf[0] = mask_positive & val;
115
}
116
else if (val <= UINT8_MAX) {
117
len = 2;
118
buf[0] = uint8_ch;
119
buf[1] = val & 0xff;
120
}
121
else if (val <= UINT16_MAX) {
122
uint16_t v = TO_BE16 (val);
123
124
len = 3;
125
buf[0] = uint16_ch;
126
memcpy (&buf[1], &v, sizeof (v));
127
}
128
else if (val <= UINT32_MAX) {
129
uint32_t v = TO_BE32 (val);
130
131
len = 5;
132
buf[0] = uint32_ch;
133
memcpy (&buf[1], &v, sizeof (v));
134
}
135
else {
136
uint64_t v = TO_BE64 (val);
137
138
len = 9;
139
buf[0] = uint64_ch;
140
memcpy (&buf[1], &v, sizeof (v));
141
}
142
}
143
else {
144
uint64_t uval;
145
/* Bithack abs */
146
uval = ((val ^ (val >> 63)) - (val >> 63));
147
148
if (val > -(1 << 5)) {
149
len = 1;
150
buf[0] = (mask_negative | uval) & 0xff;
151
}
152
else if (uval <= INT8_MAX) {
153
uint8_t v = (uint8_t)val;
154
len = 2;
155
buf[0] = int8_ch;
156
buf[1] = v;
157
}
158
else if (uval <= INT16_MAX) {
159
uint16_t v = TO_BE16 (val);
160
161
len = 3;
162
buf[0] = int16_ch;
163
memcpy (&buf[1], &v, sizeof (v));
164
}
165
else if (uval <= INT32_MAX) {
166
uint32_t v = TO_BE32 (val);
167
168
len = 5;
169
buf[0] = int32_ch;
170
memcpy (&buf[1], &v, sizeof (v));
171
}
172
else {
173
uint64_t v = TO_BE64 (val);
174
175
len = 9;
176
buf[0] = int64_ch;
177
memcpy (&buf[1], &v, sizeof (v));
178
}
179
}
180
181
func->ucl_emitter_append_len (buf, len, func->ud);
182
}
183
184
void
185
ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val)
186
{
187
const struct ucl_emitter_functions *func = ctx->func;
188
union {
189
double d;
190
uint64_t i;
191
} u;
192
const unsigned char dbl_ch = 0xcb;
193
unsigned char buf[sizeof(double) + 1];
194
195
/* Convert to big endian */
196
u.d = val;
197
u.i = TO_BE64 (u.i);
198
199
buf[0] = dbl_ch;
200
memcpy (&buf[1], &u.d, sizeof (double));
201
func->ucl_emitter_append_len (buf, sizeof (buf), func->ud);
202
}
203
204
void
205
ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val)
206
{
207
const struct ucl_emitter_functions *func = ctx->func;
208
const unsigned char true_ch = 0xc3, false_ch = 0xc2;
209
210
func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud);
211
}
212
213
void
214
ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx,
215
const char *s, size_t len)
216
{
217
const struct ucl_emitter_functions *func = ctx->func;
218
const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb;
219
unsigned char buf[5];
220
unsigned blen;
221
222
if (len <= 0x1F) {
223
blen = 1;
224
buf[0] = (len | fix_mask) & 0xff;
225
}
226
else if (len <= 0xff) {
227
blen = 2;
228
buf[0] = l8_ch;
229
buf[1] = len & 0xff;
230
}
231
else if (len <= 0xffff) {
232
uint16_t bl = TO_BE16 (len);
233
234
blen = 3;
235
buf[0] = l16_ch;
236
memcpy (&buf[1], &bl, sizeof (bl));
237
}
238
else {
239
uint32_t bl = TO_BE32 (len);
240
241
blen = 5;
242
buf[0] = l32_ch;
243
memcpy (&buf[1], &bl, sizeof (bl));
244
}
245
246
func->ucl_emitter_append_len (buf, blen, func->ud);
247
func->ucl_emitter_append_len (s, len, func->ud);
248
}
249
250
void
251
ucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx,
252
const char *s, size_t len)
253
{
254
const struct ucl_emitter_functions *func = ctx->func;
255
const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6;
256
unsigned char buf[5];
257
unsigned blen;
258
259
if (len <= 0xff) {
260
blen = 2;
261
buf[0] = l8_ch;
262
buf[1] = len & 0xff;
263
}
264
else if (len <= 0xffff) {
265
uint16_t bl = TO_BE16 (len);
266
267
blen = 3;
268
buf[0] = l16_ch;
269
memcpy (&buf[1], &bl, sizeof (bl));
270
}
271
else {
272
uint32_t bl = TO_BE32 (len);
273
274
blen = 5;
275
buf[0] = l32_ch;
276
memcpy (&buf[1], &bl, sizeof (bl));
277
}
278
279
func->ucl_emitter_append_len (buf, blen, func->ud);
280
func->ucl_emitter_append_len (s, len, func->ud);
281
}
282
283
void
284
ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx)
285
{
286
const struct ucl_emitter_functions *func = ctx->func;
287
const unsigned char nil = 0xc0;
288
289
func->ucl_emitter_append_character (nil, 1, func->ud);
290
}
291
292
void
293
ucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx,
294
const ucl_object_t *obj)
295
{
296
if (print_key) {
297
ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen);
298
}
299
}
300
301
void
302
ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len)
303
{
304
const struct ucl_emitter_functions *func = ctx->func;
305
const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd;
306
unsigned char buf[5];
307
unsigned blen;
308
309
if (len <= 0xF) {
310
blen = 1;
311
buf[0] = (len | fix_mask) & 0xff;
312
}
313
else if (len <= 0xffff) {
314
uint16_t bl = TO_BE16 (len);
315
316
blen = 3;
317
buf[0] = l16_ch;
318
memcpy (&buf[1], &bl, sizeof (bl));
319
}
320
else {
321
uint32_t bl = TO_BE32 (len);
322
323
blen = 5;
324
buf[0] = l32_ch;
325
memcpy (&buf[1], &bl, sizeof (bl));
326
}
327
328
func->ucl_emitter_append_len (buf, blen, func->ud);
329
}
330
331
void
332
ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len)
333
{
334
const struct ucl_emitter_functions *func = ctx->func;
335
const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf;
336
unsigned char buf[5];
337
unsigned blen;
338
339
if (len <= 0xF) {
340
blen = 1;
341
buf[0] = (len | fix_mask) & 0xff;
342
}
343
else if (len <= 0xffff) {
344
uint16_t bl = TO_BE16 (len);
345
346
blen = 3;
347
buf[0] = l16_ch;
348
memcpy (&buf[1], &bl, sizeof (bl));
349
}
350
else {
351
uint32_t bl = TO_BE32 (len);
352
353
blen = 5;
354
buf[0] = l32_ch;
355
memcpy (&buf[1], &bl, sizeof (bl));
356
}
357
358
func->ucl_emitter_append_len (buf, blen, func->ud);
359
}
360
361
362
enum ucl_msgpack_format {
363
msgpack_positive_fixint = 0,
364
msgpack_fixmap,
365
msgpack_fixarray,
366
msgpack_fixstr,
367
msgpack_nil,
368
msgpack_false,
369
msgpack_true,
370
msgpack_bin8,
371
msgpack_bin16,
372
msgpack_bin32,
373
msgpack_ext8,
374
msgpack_ext16,
375
msgpack_ext32,
376
msgpack_float32,
377
msgpack_float64,
378
msgpack_uint8,
379
msgpack_uint16,
380
msgpack_uint32,
381
msgpack_uint64,
382
msgpack_int8,
383
msgpack_int16,
384
msgpack_int32,
385
msgpack_int64,
386
msgpack_fixext1,
387
msgpack_fixext2,
388
msgpack_fixext4,
389
msgpack_fixext8,
390
msgpack_fixext16,
391
msgpack_str8,
392
msgpack_str16,
393
msgpack_str32,
394
msgpack_array16,
395
msgpack_array32,
396
msgpack_map16,
397
msgpack_map32,
398
msgpack_negative_fixint,
399
msgpack_invalid
400
};
401
402
typedef ssize_t (*ucl_msgpack_parse_function)(struct ucl_parser *parser,
403
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
404
const unsigned char *pos, size_t remain);
405
406
static ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser,
407
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
408
const unsigned char *pos, size_t remain);
409
static ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser,
410
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
411
const unsigned char *pos, size_t remain);
412
static ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser,
413
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
414
const unsigned char *pos, size_t remain);
415
static ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser,
416
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
417
const unsigned char *pos, size_t remain);
418
static ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser,
419
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
420
const unsigned char *pos, size_t remain);
421
static ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser,
422
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
423
const unsigned char *pos, size_t remain);
424
static ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser,
425
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
426
const unsigned char *pos, size_t remain);
427
static ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser,
428
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
429
const unsigned char *pos, size_t remain);
430
431
#define MSGPACK_FLAG_FIXED (1 << 0)
432
#define MSGPACK_FLAG_CONTAINER (1 << 1)
433
#define MSGPACK_FLAG_TYPEVALUE (1 << 2)
434
#define MSGPACK_FLAG_EXT (1 << 3)
435
#define MSGPACK_FLAG_ASSOC (1 << 4)
436
#define MSGPACK_FLAG_KEY (1 << 5)
437
438
/*
439
* Search tree packed in array
440
*/
441
struct ucl_msgpack_parser {
442
uint8_t prefix; /* Prefix byte */
443
uint8_t prefixlen; /* Length of prefix in bits */
444
uint8_t fmt; /* The desired format */
445
uint8_t len; /* Length of the object
446
(either length bytes
447
or length of value in case
448
of fixed objects */
449
uint8_t flags; /* Flags of the specified type */
450
ucl_msgpack_parse_function func; /* Parser function */
451
} parsers[] = {
452
{
453
0xa0,
454
3,
455
msgpack_fixstr,
456
0,
457
MSGPACK_FLAG_FIXED|MSGPACK_FLAG_KEY,
458
ucl_msgpack_parse_string
459
},
460
{
461
0x0,
462
1,
463
msgpack_positive_fixint,
464
0,
465
MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
466
ucl_msgpack_parse_int
467
},
468
{
469
0xe0,
470
3,
471
msgpack_negative_fixint,
472
0,
473
MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
474
ucl_msgpack_parse_int
475
},
476
{
477
0x80,
478
4,
479
msgpack_fixmap,
480
0,
481
MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
482
ucl_msgpack_parse_map
483
},
484
{
485
0x90,
486
4,
487
msgpack_fixarray,
488
0,
489
MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER,
490
ucl_msgpack_parse_array
491
},
492
{
493
0xd9,
494
8,
495
msgpack_str8,
496
1,
497
MSGPACK_FLAG_KEY,
498
ucl_msgpack_parse_string
499
},
500
{
501
0xc4,
502
8,
503
msgpack_bin8,
504
1,
505
MSGPACK_FLAG_KEY,
506
ucl_msgpack_parse_string
507
},
508
{
509
0xcf,
510
8,
511
msgpack_uint64,
512
8,
513
MSGPACK_FLAG_FIXED,
514
ucl_msgpack_parse_int
515
},
516
{
517
0xd3,
518
8,
519
msgpack_int64,
520
8,
521
MSGPACK_FLAG_FIXED,
522
ucl_msgpack_parse_int
523
},
524
{
525
0xce,
526
8,
527
msgpack_uint32,
528
4,
529
MSGPACK_FLAG_FIXED,
530
ucl_msgpack_parse_int
531
},
532
{
533
0xd2,
534
8,
535
msgpack_int32,
536
4,
537
MSGPACK_FLAG_FIXED,
538
ucl_msgpack_parse_int
539
},
540
{
541
0xcb,
542
8,
543
msgpack_float64,
544
8,
545
MSGPACK_FLAG_FIXED,
546
ucl_msgpack_parse_float
547
},
548
{
549
0xca,
550
8,
551
msgpack_float32,
552
4,
553
MSGPACK_FLAG_FIXED,
554
ucl_msgpack_parse_float
555
},
556
{
557
0xc2,
558
8,
559
msgpack_false,
560
1,
561
MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
562
ucl_msgpack_parse_bool
563
},
564
{
565
0xc3,
566
8,
567
msgpack_true,
568
1,
569
MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
570
ucl_msgpack_parse_bool
571
},
572
{
573
0xcc,
574
8,
575
msgpack_uint8,
576
1,
577
MSGPACK_FLAG_FIXED,
578
ucl_msgpack_parse_int
579
},
580
{
581
0xcd,
582
8,
583
msgpack_uint16,
584
2,
585
MSGPACK_FLAG_FIXED,
586
ucl_msgpack_parse_int
587
},
588
{
589
0xd0,
590
8,
591
msgpack_int8,
592
1,
593
MSGPACK_FLAG_FIXED,
594
ucl_msgpack_parse_int
595
},
596
{
597
0xd1,
598
8,
599
msgpack_int16,
600
2,
601
MSGPACK_FLAG_FIXED,
602
ucl_msgpack_parse_int
603
},
604
{
605
0xc0,
606
8,
607
msgpack_nil,
608
0,
609
MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
610
ucl_msgpack_parse_null
611
},
612
{
613
0xda,
614
8,
615
msgpack_str16,
616
2,
617
MSGPACK_FLAG_KEY,
618
ucl_msgpack_parse_string
619
},
620
{
621
0xdb,
622
8,
623
msgpack_str32,
624
4,
625
MSGPACK_FLAG_KEY,
626
ucl_msgpack_parse_string
627
},
628
{
629
0xc5,
630
8,
631
msgpack_bin16,
632
2,
633
MSGPACK_FLAG_KEY,
634
ucl_msgpack_parse_string
635
},
636
{
637
0xc6,
638
8,
639
msgpack_bin32,
640
4,
641
MSGPACK_FLAG_KEY,
642
ucl_msgpack_parse_string
643
},
644
{
645
0xdc,
646
8,
647
msgpack_array16,
648
2,
649
MSGPACK_FLAG_CONTAINER,
650
ucl_msgpack_parse_array
651
},
652
{
653
0xdd,
654
8,
655
msgpack_array32,
656
4,
657
MSGPACK_FLAG_CONTAINER,
658
ucl_msgpack_parse_array
659
},
660
{
661
0xde,
662
8,
663
msgpack_map16,
664
2,
665
MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
666
ucl_msgpack_parse_map
667
},
668
{
669
0xdf,
670
8,
671
msgpack_map32,
672
4,
673
MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
674
ucl_msgpack_parse_map
675
},
676
{
677
0xc7,
678
8,
679
msgpack_ext8,
680
1,
681
MSGPACK_FLAG_EXT,
682
ucl_msgpack_parse_ignore
683
},
684
{
685
0xc8,
686
8,
687
msgpack_ext16,
688
2,
689
MSGPACK_FLAG_EXT,
690
ucl_msgpack_parse_ignore
691
},
692
{
693
0xc9,
694
8,
695
msgpack_ext32,
696
4,
697
MSGPACK_FLAG_EXT,
698
ucl_msgpack_parse_ignore
699
},
700
{
701
0xd4,
702
8,
703
msgpack_fixext1,
704
1,
705
MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
706
ucl_msgpack_parse_ignore
707
},
708
{
709
0xd5,
710
8,
711
msgpack_fixext2,
712
2,
713
MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
714
ucl_msgpack_parse_ignore
715
},
716
{
717
0xd6,
718
8,
719
msgpack_fixext4,
720
4,
721
MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
722
ucl_msgpack_parse_ignore
723
},
724
{
725
0xd7,
726
8,
727
msgpack_fixext8,
728
8,
729
MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
730
ucl_msgpack_parse_ignore
731
},
732
{
733
0xd8,
734
8,
735
msgpack_fixext16,
736
16,
737
MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
738
ucl_msgpack_parse_ignore
739
}
740
};
741
742
#undef MSGPACK_DEBUG_PARSER
743
744
static inline struct ucl_msgpack_parser *
745
ucl_msgpack_get_parser_from_type (unsigned char t)
746
{
747
unsigned int i, shift, mask;
748
749
for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) {
750
shift = CHAR_BIT - parsers[i].prefixlen;
751
mask = parsers[i].prefix >> shift;
752
753
if (mask == (((unsigned int)t) >> shift)) {
754
return &parsers[i];
755
}
756
}
757
758
return NULL;
759
}
760
761
static inline struct ucl_stack *
762
ucl_msgpack_get_container (struct ucl_parser *parser,
763
struct ucl_msgpack_parser *obj_parser, uint64_t len)
764
{
765
struct ucl_stack *stack;
766
767
assert (obj_parser != NULL);
768
769
if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) {
770
/*
771
* Insert new container to the stack
772
*/
773
if (parser->stack == NULL) {
774
parser->stack = calloc (1, sizeof (struct ucl_stack));
775
776
if (parser->stack == NULL) {
777
ucl_create_err (&parser->err, "no memory");
778
return NULL;
779
}
780
781
parser->stack->chunk = parser->chunks;
782
}
783
else {
784
stack = calloc (1, sizeof (struct ucl_stack));
785
786
if (stack == NULL) {
787
ucl_create_err (&parser->err, "no memory");
788
return NULL;
789
}
790
791
stack->chunk = parser->chunks;
792
stack->next = parser->stack;
793
parser->stack = stack;
794
}
795
796
parser->stack->e.len = len;
797
798
#ifdef MSGPACK_DEBUG_PARSER
799
stack = parser->stack;
800
while (stack) {
801
fprintf(stderr, "+");
802
stack = stack->next;
803
}
804
805
fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len);
806
#endif
807
}
808
else {
809
/*
810
* Get the current stack top
811
*/
812
if (parser->stack) {
813
return parser->stack;
814
}
815
else {
816
ucl_create_err (&parser->err, "bad top level object for msgpack");
817
return NULL;
818
}
819
}
820
821
return parser->stack;
822
}
823
824
static bool
825
ucl_msgpack_is_container_finished (struct ucl_stack *container)
826
{
827
assert (container != NULL);
828
829
830
if (container->e.len == 0) {
831
return true;
832
}
833
834
return false;
835
}
836
837
static bool
838
ucl_msgpack_insert_object (struct ucl_parser *parser,
839
const unsigned char *key,
840
size_t keylen, ucl_object_t *obj)
841
{
842
struct ucl_stack *container;
843
844
container = parser->stack;
845
assert (container != NULL);
846
assert (container->e.len > 0);
847
assert (obj != NULL);
848
assert (container->obj != NULL);
849
850
if (container->obj->type == UCL_ARRAY) {
851
ucl_array_append (container->obj, obj);
852
}
853
else if (container->obj->type == UCL_OBJECT) {
854
if (key == NULL || keylen == 0) {
855
ucl_create_err (&parser->err, "cannot insert object with no key");
856
return false;
857
}
858
859
obj->key = key;
860
obj->keylen = keylen;
861
862
if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
863
ucl_copy_key_trash (obj);
864
}
865
866
ucl_parser_process_object_element (parser, obj);
867
}
868
else {
869
ucl_create_err (&parser->err, "bad container type");
870
return false;
871
}
872
873
container->e.len--;
874
875
return true;
876
}
877
878
static struct ucl_stack *
879
ucl_msgpack_get_next_container (struct ucl_parser *parser)
880
{
881
struct ucl_stack *cur = NULL;
882
uint64_t len;
883
884
cur = parser->stack;
885
886
if (cur == NULL) {
887
return NULL;
888
}
889
890
len = cur->e.len;
891
892
if (len == 0) {
893
/* We need to switch to the previous container */
894
parser->stack = cur->next;
895
parser->cur_obj = cur->obj;
896
free (cur);
897
898
#ifdef MSGPACK_DEBUG_PARSER
899
cur = parser->stack;
900
while (cur) {
901
fprintf(stderr, "-");
902
cur = cur->next;
903
}
904
fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
905
#endif
906
907
return ucl_msgpack_get_next_container (parser);
908
}
909
910
/*
911
* For UCL containers we don't know length, so we just insert the whole
912
* message pack blob into the top level container
913
*/
914
915
assert (cur->obj != NULL);
916
917
return cur;
918
}
919
920
#define CONSUME_RET do { \
921
if (ret != -1) { \
922
p += ret; \
923
remain -= ret; \
924
obj_parser = NULL; \
925
assert (remain >= 0); \
926
} \
927
else { \
928
ucl_create_err (&parser->err, \
929
"cannot parse type %d of len %u", \
930
(int)obj_parser->fmt, \
931
(unsigned)len); \
932
return false; \
933
} \
934
} while(0)
935
936
#define GET_NEXT_STATE do { \
937
container = ucl_msgpack_get_next_container (parser); \
938
if (container == NULL) { \
939
ucl_create_err (&parser->err, \
940
"empty container"); \
941
return false; \
942
} \
943
next_state = container->obj->type == UCL_OBJECT ? \
944
read_assoc_key : read_array_value; \
945
} while(0)
946
947
static bool
948
ucl_msgpack_consume (struct ucl_parser *parser)
949
{
950
const unsigned char *p, *end, *key = NULL;
951
struct ucl_stack *container;
952
enum e_msgpack_parser_state {
953
read_type,
954
start_assoc,
955
start_array,
956
read_assoc_key,
957
read_assoc_value,
958
finish_assoc_value,
959
read_array_value,
960
finish_array_value,
961
error_state
962
} state = read_type, next_state = error_state;
963
struct ucl_msgpack_parser *obj_parser = NULL;
964
uint64_t len = 0;
965
ssize_t ret, remain, keylen = 0;
966
#ifdef MSGPACK_DEBUG_PARSER
967
uint64_t i;
968
enum e_msgpack_parser_state hist[256];
969
#endif
970
971
p = parser->chunks->begin;
972
remain = parser->chunks->remain;
973
end = p + remain;
974
975
976
while (p < end) {
977
#ifdef MSGPACK_DEBUG_PARSER
978
hist[i++ % 256] = state;
979
#endif
980
switch (state) {
981
case read_type:
982
obj_parser = ucl_msgpack_get_parser_from_type (*p);
983
984
if (obj_parser == NULL) {
985
ucl_create_err (&parser->err, "unknown msgpack format: %x",
986
(unsigned int)*p);
987
988
return false;
989
}
990
/* Now check length sanity */
991
if (obj_parser->flags & MSGPACK_FLAG_FIXED) {
992
if (obj_parser->len == 0) {
993
/* We have an embedded size */
994
len = *p & ~obj_parser->prefix;
995
}
996
else {
997
if (remain < obj_parser->len) {
998
ucl_create_err (&parser->err, "not enough data remain to "
999
"read object's length: %u remain, %u needed",
1000
(unsigned)remain, obj_parser->len);
1001
1002
return false;
1003
}
1004
1005
len = obj_parser->len;
1006
}
1007
1008
if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) {
1009
/* We must pass value as the second byte */
1010
if (remain > 0) {
1011
p ++;
1012
remain --;
1013
}
1014
}
1015
else {
1016
/* Len is irrelevant now */
1017
len = 0;
1018
}
1019
}
1020
else {
1021
/* Length is not embedded */
1022
remain --;
1023
1024
if (remain < obj_parser->len) {
1025
ucl_create_err (&parser->err, "not enough data remain to "
1026
"read object's length: %u remain, %u needed",
1027
(unsigned)remain, obj_parser->len);
1028
1029
return false;
1030
}
1031
1032
p ++;
1033
1034
switch (obj_parser->len) {
1035
case 1:
1036
len = *p;
1037
break;
1038
case 2:
1039
len = FROM_BE16 (*(uint16_t *)p);
1040
break;
1041
case 4:
1042
len = FROM_BE32 (*(uint32_t *)p);
1043
break;
1044
case 8:
1045
len = FROM_BE64 (*(uint64_t *)p);
1046
break;
1047
default:
1048
ucl_create_err (&parser->err, "invalid length of the length field: %u",
1049
(unsigned)obj_parser->len);
1050
1051
return false;
1052
}
1053
1054
p += obj_parser->len;
1055
remain -= obj_parser->len;
1056
}
1057
1058
if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
1059
/* We have just read the new associative map */
1060
state = start_assoc;
1061
}
1062
else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){
1063
state = start_array;
1064
}
1065
else {
1066
state = next_state;
1067
}
1068
1069
break;
1070
case start_assoc:
1071
parser->cur_obj = ucl_object_new_full (UCL_OBJECT,
1072
parser->chunks->priority);
1073
/* Insert to the previous level container */
1074
if (parser->stack && !ucl_msgpack_insert_object (parser,
1075
key, keylen, parser->cur_obj)) {
1076
return false;
1077
}
1078
/* Get new container */
1079
container = ucl_msgpack_get_container (parser, obj_parser, len);
1080
1081
if (container == NULL) {
1082
return false;
1083
}
1084
1085
ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1086
p, remain);
1087
CONSUME_RET;
1088
key = NULL;
1089
keylen = 0;
1090
1091
if (len > 0) {
1092
state = read_type;
1093
next_state = read_assoc_key;
1094
}
1095
else {
1096
/* Empty object */
1097
state = finish_assoc_value;
1098
}
1099
break;
1100
1101
case start_array:
1102
parser->cur_obj = ucl_object_new_full (UCL_ARRAY,
1103
parser->chunks->priority);
1104
/* Insert to the previous level container */
1105
if (parser->stack && !ucl_msgpack_insert_object (parser,
1106
key, keylen, parser->cur_obj)) {
1107
return false;
1108
}
1109
/* Get new container */
1110
container = ucl_msgpack_get_container (parser, obj_parser, len);
1111
1112
if (container == NULL) {
1113
return false;
1114
}
1115
1116
ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1117
p, remain);
1118
CONSUME_RET;
1119
1120
if (len > 0) {
1121
state = read_type;
1122
next_state = read_array_value;
1123
}
1124
else {
1125
/* Empty array */
1126
state = finish_array_value;
1127
}
1128
break;
1129
1130
case read_array_value:
1131
/*
1132
* p is now at the value start, len now contains length read and
1133
* obj_parser contains the corresponding specific parser
1134
*/
1135
container = parser->stack;
1136
1137
if (parser->stack == NULL) {
1138
ucl_create_err (&parser->err,
1139
"read assoc value when no container represented");
1140
return false;
1141
}
1142
1143
ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1144
p, remain);
1145
CONSUME_RET;
1146
1147
1148
/* Insert value to the container and check if we have finished array */
1149
if (!ucl_msgpack_insert_object (parser, NULL, 0,
1150
parser->cur_obj)) {
1151
return false;
1152
}
1153
1154
if (ucl_msgpack_is_container_finished (container)) {
1155
state = finish_array_value;
1156
}
1157
else {
1158
/* Read more elements */
1159
state = read_type;
1160
next_state = read_array_value;
1161
}
1162
1163
break;
1164
1165
case read_assoc_key:
1166
/*
1167
* Keys must have string type for ucl msgpack
1168
*/
1169
if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) {
1170
ucl_create_err (&parser->err, "bad type for key: %u, expected "
1171
"string", (unsigned)obj_parser->fmt);
1172
1173
return false;
1174
}
1175
1176
key = p;
1177
keylen = len;
1178
1179
if (keylen > remain || keylen == 0) {
1180
ucl_create_err (&parser->err, "too long or empty key");
1181
return false;
1182
}
1183
1184
p += len;
1185
remain -= len;
1186
1187
state = read_type;
1188
next_state = read_assoc_value;
1189
break;
1190
1191
case read_assoc_value:
1192
/*
1193
* p is now at the value start, len now contains length read and
1194
* obj_parser contains the corresponding specific parser
1195
*/
1196
container = parser->stack;
1197
1198
if (container == NULL) {
1199
ucl_create_err (&parser->err,
1200
"read assoc value when no container represented");
1201
return false;
1202
}
1203
1204
ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1205
p, remain);
1206
CONSUME_RET;
1207
1208
assert (key != NULL && keylen > 0);
1209
1210
if (!ucl_msgpack_insert_object (parser, key, keylen,
1211
parser->cur_obj)) {
1212
1213
return false;
1214
}
1215
1216
key = NULL;
1217
keylen = 0;
1218
1219
if (ucl_msgpack_is_container_finished (container)) {
1220
state = finish_assoc_value;
1221
}
1222
else {
1223
/* Read more elements */
1224
state = read_type;
1225
next_state = read_assoc_key;
1226
}
1227
break;
1228
1229
case finish_array_value:
1230
case finish_assoc_value:
1231
GET_NEXT_STATE;
1232
state = read_type;
1233
break;
1234
1235
case error_state:
1236
ucl_create_err (&parser->err, "invalid state machine state");
1237
1238
return false;
1239
}
1240
}
1241
1242
/* Check the finishing state */
1243
switch (state) {
1244
case start_array:
1245
case start_assoc:
1246
/* Empty container at the end */
1247
if (len != 0) {
1248
ucl_create_err (&parser->err,
1249
"invalid non-empty container at the end; len=%zu",
1250
(uintmax_t)len);
1251
1252
return false;
1253
}
1254
1255
parser->cur_obj = ucl_object_new_full (
1256
state == start_array ? UCL_ARRAY : UCL_OBJECT,
1257
parser->chunks->priority);
1258
1259
if (parser->stack == NULL) {
1260
ucl_create_err (&parser->err,
1261
"read assoc value when no container represented");
1262
return false;
1263
}
1264
/* Insert to the previous level container */
1265
if (!ucl_msgpack_insert_object (parser,
1266
key, keylen, parser->cur_obj)) {
1267
return false;
1268
}
1269
/* Get new container */
1270
container = ucl_msgpack_get_container (parser, obj_parser, len);
1271
1272
if (container == NULL) {
1273
return false;
1274
}
1275
1276
ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1277
p, remain);
1278
break;
1279
1280
case read_array_value:
1281
case read_assoc_value:
1282
if (len != 0) {
1283
ucl_create_err (&parser->err, "unfinished value at the end");
1284
1285
return false;
1286
}
1287
1288
container = parser->stack;
1289
1290
if (parser->stack == NULL) {
1291
ucl_create_err (&parser->err,
1292
"read assoc value when no container represented");
1293
return false;
1294
}
1295
1296
ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1297
p, remain);
1298
CONSUME_RET;
1299
1300
1301
/* Insert value to the container and check if we have finished array */
1302
if (!ucl_msgpack_insert_object (parser, NULL, 0,
1303
parser->cur_obj)) {
1304
return false;
1305
}
1306
break;
1307
case finish_array_value:
1308
case finish_assoc_value:
1309
case read_type:
1310
/* Valid finishing state */
1311
break;
1312
default:
1313
/* Invalid finishing state */
1314
ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
1315
state);
1316
1317
return false;
1318
}
1319
1320
/* Rewind to the top level container */
1321
ucl_msgpack_get_next_container (parser);
1322
1323
if (parser->stack != NULL) {
1324
ucl_create_err (&parser->err, "incomplete container");
1325
1326
return false;
1327
}
1328
1329
return true;
1330
}
1331
1332
bool
1333
ucl_parse_msgpack (struct ucl_parser *parser)
1334
{
1335
ucl_object_t *container = NULL;
1336
const unsigned char *p;
1337
bool ret;
1338
1339
assert (parser != NULL);
1340
assert (parser->chunks != NULL);
1341
assert (parser->chunks->begin != NULL);
1342
assert (parser->chunks->remain != 0);
1343
1344
p = parser->chunks->begin;
1345
1346
if (parser->stack) {
1347
container = parser->stack->obj;
1348
}
1349
1350
/*
1351
* When we start parsing message pack chunk, we must ensure that we
1352
* have either a valid container or the top object inside message pack is
1353
* of container type
1354
*/
1355
if (container == NULL) {
1356
if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) {
1357
ucl_create_err (&parser->err, "bad top level object for msgpack");
1358
return false;
1359
}
1360
}
1361
1362
ret = ucl_msgpack_consume (parser);
1363
1364
if (ret && parser->top_obj == NULL) {
1365
parser->top_obj = parser->cur_obj;
1366
}
1367
1368
return ret;
1369
}
1370
1371
static ssize_t
1372
ucl_msgpack_parse_map (struct ucl_parser *parser,
1373
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1374
const unsigned char *pos, size_t remain)
1375
{
1376
container->obj = parser->cur_obj;
1377
1378
return 0;
1379
}
1380
1381
static ssize_t
1382
ucl_msgpack_parse_array (struct ucl_parser *parser,
1383
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1384
const unsigned char *pos, size_t remain)
1385
{
1386
container->obj = parser->cur_obj;
1387
1388
return 0;
1389
}
1390
1391
static ssize_t
1392
ucl_msgpack_parse_string (struct ucl_parser *parser,
1393
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1394
const unsigned char *pos, size_t remain)
1395
{
1396
ucl_object_t *obj;
1397
1398
if (len > remain) {
1399
return -1;
1400
}
1401
1402
obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority);
1403
obj->value.sv = pos;
1404
obj->len = len;
1405
1406
if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) {
1407
obj->flags |= UCL_OBJECT_BINARY;
1408
}
1409
1410
if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
1411
if (obj->flags & UCL_OBJECT_BINARY) {
1412
obj->trash_stack[UCL_TRASH_VALUE] = malloc (len);
1413
1414
if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) {
1415
memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len);
1416
}
1417
}
1418
else {
1419
ucl_copy_value_trash (obj);
1420
}
1421
}
1422
1423
parser->cur_obj = obj;
1424
1425
return len;
1426
}
1427
1428
static ssize_t
1429
ucl_msgpack_parse_int (struct ucl_parser *parser,
1430
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1431
const unsigned char *pos, size_t remain)
1432
{
1433
ucl_object_t *obj;
1434
int8_t iv8;
1435
int16_t iv16;
1436
int32_t iv32;
1437
int64_t iv64;
1438
uint16_t uiv16;
1439
uint32_t uiv32;
1440
uint64_t uiv64;
1441
1442
1443
if (len > remain) {
1444
return -1;
1445
}
1446
1447
obj = ucl_object_new_full (UCL_INT, parser->chunks->priority);
1448
1449
switch (fmt) {
1450
case msgpack_positive_fixint:
1451
obj->value.iv = (*pos & 0x7f);
1452
len = 1;
1453
break;
1454
case msgpack_negative_fixint:
1455
obj->value.iv = - (*pos & 0x1f);
1456
len = 1;
1457
break;
1458
case msgpack_uint8:
1459
obj->value.iv = (unsigned char)*pos;
1460
len = 1;
1461
break;
1462
case msgpack_int8:
1463
memcpy (&iv8, pos, sizeof (iv8));
1464
obj->value.iv = iv8;
1465
len = 1;
1466
break;
1467
case msgpack_int16:
1468
memcpy (&iv16, pos, sizeof (iv16));
1469
iv16 = FROM_BE16 (iv16);
1470
obj->value.iv = iv16;
1471
len = 2;
1472
break;
1473
case msgpack_uint16:
1474
memcpy (&uiv16, pos, sizeof (uiv16));
1475
uiv16 = FROM_BE16 (uiv16);
1476
obj->value.iv = uiv16;
1477
len = 2;
1478
break;
1479
case msgpack_int32:
1480
memcpy (&iv32, pos, sizeof (iv32));
1481
iv32 = FROM_BE32 (iv32);
1482
obj->value.iv = iv32;
1483
len = 4;
1484
break;
1485
case msgpack_uint32:
1486
memcpy(&uiv32, pos, sizeof(uiv32));
1487
uiv32 = FROM_BE32(uiv32);
1488
obj->value.iv = uiv32;
1489
len = 4;
1490
break;
1491
case msgpack_int64:
1492
memcpy (&iv64, pos, sizeof (iv64));
1493
iv64 = FROM_BE64 (iv64);
1494
obj->value.iv = iv64;
1495
len = 8;
1496
break;
1497
case msgpack_uint64:
1498
memcpy(&uiv64, pos, sizeof(uiv64));
1499
uiv64 = FROM_BE64(uiv64);
1500
obj->value.iv = uiv64;
1501
len = 8;
1502
break;
1503
default:
1504
assert (0);
1505
break;
1506
}
1507
1508
parser->cur_obj = obj;
1509
1510
return len;
1511
}
1512
1513
static ssize_t
1514
ucl_msgpack_parse_float (struct ucl_parser *parser,
1515
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1516
const unsigned char *pos, size_t remain)
1517
{
1518
ucl_object_t *obj;
1519
union {
1520
uint32_t i;
1521
float f;
1522
} d;
1523
uint64_t uiv64;
1524
1525
if (len > remain) {
1526
return -1;
1527
}
1528
1529
obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority);
1530
1531
switch (fmt) {
1532
case msgpack_float32:
1533
memcpy(&d.i, pos, sizeof(d.i));
1534
d.i = FROM_BE32(d.i);
1535
/* XXX: can be slow */
1536
obj->value.dv = d.f;
1537
len = 4;
1538
break;
1539
case msgpack_float64:
1540
memcpy(&uiv64, pos, sizeof(uiv64));
1541
uiv64 = FROM_BE64(uiv64);
1542
obj->value.iv = uiv64;
1543
len = 8;
1544
break;
1545
default:
1546
assert (0);
1547
break;
1548
}
1549
1550
parser->cur_obj = obj;
1551
1552
return len;
1553
}
1554
1555
static ssize_t
1556
ucl_msgpack_parse_bool (struct ucl_parser *parser,
1557
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1558
const unsigned char *pos, size_t remain)
1559
{
1560
ucl_object_t *obj;
1561
1562
if (len > remain) {
1563
return -1;
1564
}
1565
1566
obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority);
1567
1568
switch (fmt) {
1569
case msgpack_true:
1570
obj->value.iv = true;
1571
break;
1572
case msgpack_false:
1573
obj->value.iv = false;
1574
break;
1575
default:
1576
assert (0);
1577
break;
1578
}
1579
1580
parser->cur_obj = obj;
1581
1582
return 1;
1583
}
1584
1585
static ssize_t
1586
ucl_msgpack_parse_null (struct ucl_parser *parser,
1587
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1588
const unsigned char *pos, size_t remain)
1589
{
1590
ucl_object_t *obj;
1591
1592
if (len > remain) {
1593
return -1;
1594
}
1595
1596
obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
1597
parser->cur_obj = obj;
1598
1599
return 1;
1600
}
1601
1602
static ssize_t
1603
ucl_msgpack_parse_ignore (struct ucl_parser *parser,
1604
struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1605
const unsigned char *pos, size_t remain)
1606
{
1607
if (len > remain) {
1608
return -1;
1609
}
1610
1611
switch (fmt) {
1612
case msgpack_fixext1:
1613
len = 2;
1614
break;
1615
case msgpack_fixext2:
1616
len = 3;
1617
break;
1618
case msgpack_fixext4:
1619
len = 5;
1620
break;
1621
case msgpack_fixext8:
1622
len = 9;
1623
break;
1624
case msgpack_fixext16:
1625
len = 17;
1626
break;
1627
case msgpack_ext8:
1628
case msgpack_ext16:
1629
case msgpack_ext32:
1630
len = len + 1;
1631
break;
1632
default:
1633
ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt);
1634
return -1;
1635
}
1636
1637
return len;
1638
}
1639
1640