ucl 0.1.4 → 0.2.0

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