Update vendored msgpack-c to 4.0.0
[lttng-tools.git] / src / vendor / msgpack / objectc.c
CommitLineData
116a02e3
JG
1/*
2 * MessagePack for C dynamic typing routine
3 *
4 * Copyright (C) 2008-2009 FURUHASHI Sadayuki
5 *
6 * Distributed under the Boost Software License, Version 1.0.
7 * (See accompanying file LICENSE_1_0.txt or copy at
8 * http://www.boost.org/LICENSE_1_0.txt)
9 */
10#if defined(_KERNEL_MODE)
11# undef _NO_CRT_STDIO_INLINE
12# define _NO_CRT_STDIO_INLINE
13#endif
14
15#include "vendor/msgpack/object.h"
16#include "vendor/msgpack/pack.h"
17#include <ctype.h>
18
19#include <stdio.h>
20#include <string.h>
21
22#if defined(_MSC_VER)
23#if _MSC_VER >= 1800
24#include <inttypes.h>
25#else
26#define PRIu64 "I64u"
27#define PRIi64 "I64i"
28#define PRIi8 "i"
29#endif
30#else
31#include <inttypes.h>
32#endif
33
34#if defined(_KERNEL_MODE)
35# undef snprintf
36# define snprintf _snprintf
37#endif
38
39int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
40{
41 switch(d.type) {
42 case MSGPACK_OBJECT_NIL:
43 return msgpack_pack_nil(pk);
44
45 case MSGPACK_OBJECT_BOOLEAN:
46 if(d.via.boolean) {
47 return msgpack_pack_true(pk);
48 } else {
49 return msgpack_pack_false(pk);
50 }
51
52 case MSGPACK_OBJECT_POSITIVE_INTEGER:
53 return msgpack_pack_uint64(pk, d.via.u64);
54
55 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
56 return msgpack_pack_int64(pk, d.via.i64);
57
58 case MSGPACK_OBJECT_FLOAT32:
59 return msgpack_pack_float(pk, (float)d.via.f64);
60
61 case MSGPACK_OBJECT_FLOAT64:
62 return msgpack_pack_double(pk, d.via.f64);
63
64 case MSGPACK_OBJECT_STR:
65 {
66 int ret = msgpack_pack_str(pk, d.via.str.size);
67 if(ret < 0) { return ret; }
68 return msgpack_pack_str_body(pk, d.via.str.ptr, d.via.str.size);
69 }
70
71 case MSGPACK_OBJECT_BIN:
72 {
73 int ret = msgpack_pack_bin(pk, d.via.bin.size);
74 if(ret < 0) { return ret; }
75 return msgpack_pack_bin_body(pk, d.via.bin.ptr, d.via.bin.size);
76 }
77
78 case MSGPACK_OBJECT_EXT:
79 {
80 int ret = msgpack_pack_ext(pk, d.via.ext.size, d.via.ext.type);
81 if(ret < 0) { return ret; }
82 return msgpack_pack_ext_body(pk, d.via.ext.ptr, d.via.ext.size);
83 }
84
85 case MSGPACK_OBJECT_ARRAY:
86 {
87 int ret = msgpack_pack_array(pk, d.via.array.size);
88 if(ret < 0) {
89 return ret;
90 }
91 else {
92 msgpack_object* o = d.via.array.ptr;
93 msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
94 for(; o != oend; ++o) {
95 ret = msgpack_pack_object(pk, *o);
96 if(ret < 0) { return ret; }
97 }
98
99 return 0;
100 }
101 }
102
103 case MSGPACK_OBJECT_MAP:
104 {
105 int ret = msgpack_pack_map(pk, d.via.map.size);
106 if(ret < 0) {
107 return ret;
108 }
109 else {
110 msgpack_object_kv* kv = d.via.map.ptr;
111 msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size;
112 for(; kv != kvend; ++kv) {
113 ret = msgpack_pack_object(pk, kv->key);
114 if(ret < 0) { return ret; }
115 ret = msgpack_pack_object(pk, kv->val);
116 if(ret < 0) { return ret; }
117 }
118
119 return 0;
120 }
121 }
122
123 default:
124 return -1;
125 }
126}
127
128#if !defined(_KERNEL_MODE)
129
130static void msgpack_object_bin_print(FILE* out, const char *ptr, size_t size)
131{
132 size_t i;
133 for (i = 0; i < size; ++i) {
134 if (ptr[i] == '"') {
135 fputs("\\\"", out);
136 } else if (isprint((unsigned char)ptr[i])) {
137 fputc(ptr[i], out);
138 } else {
139 fprintf(out, "\\x%02x", (unsigned char)ptr[i]);
140 }
141 }
142}
143
144void msgpack_object_print(FILE* out, msgpack_object o)
145{
146 switch(o.type) {
147 case MSGPACK_OBJECT_NIL:
148 fprintf(out, "nil");
149 break;
150
151 case MSGPACK_OBJECT_BOOLEAN:
152 fprintf(out, (o.via.boolean ? "true" : "false"));
153 break;
154
155 case MSGPACK_OBJECT_POSITIVE_INTEGER:
156#if defined(PRIu64)
157 fprintf(out, "%" PRIu64, o.via.u64);
158#else
159 if (o.via.u64 > ULONG_MAX)
160 fprintf(out, "over 4294967295");
161 else
162 fprintf(out, "%lu", (unsigned long)o.via.u64);
163#endif
164 break;
165
166 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
167#if defined(PRIi64)
168 fprintf(out, "%" PRIi64, o.via.i64);
169#else
170 if (o.via.i64 > LONG_MAX)
171 fprintf(out, "over +2147483647");
172 else if (o.via.i64 < LONG_MIN)
173 fprintf(out, "under -2147483648");
174 else
175 fprintf(out, "%ld", (signed long)o.via.i64);
176#endif
177 break;
178
179 case MSGPACK_OBJECT_FLOAT32:
180 case MSGPACK_OBJECT_FLOAT64:
181 fprintf(out, "%f", o.via.f64);
182 break;
183
184 case MSGPACK_OBJECT_STR:
185 fprintf(out, "\"");
186 fwrite(o.via.str.ptr, o.via.str.size, 1, out);
187 fprintf(out, "\"");
188 break;
189
190 case MSGPACK_OBJECT_BIN:
191 fprintf(out, "\"");
192 msgpack_object_bin_print(out, o.via.bin.ptr, o.via.bin.size);
193 fprintf(out, "\"");
194 break;
195
196 case MSGPACK_OBJECT_EXT:
197#if defined(PRIi8)
198 fprintf(out, "(ext: %" PRIi8 ")", o.via.ext.type);
199#else
200 fprintf(out, "(ext: %d)", (int)o.via.ext.type);
201#endif
202 fprintf(out, "\"");
203 msgpack_object_bin_print(out, o.via.ext.ptr, o.via.ext.size);
204 fprintf(out, "\"");
205 break;
206
207 case MSGPACK_OBJECT_ARRAY:
208 fprintf(out, "[");
209 if(o.via.array.size != 0) {
210 msgpack_object* p = o.via.array.ptr;
211 msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
212 msgpack_object_print(out, *p);
213 ++p;
214 for(; p < pend; ++p) {
215 fprintf(out, ", ");
216 msgpack_object_print(out, *p);
217 }
218 }
219 fprintf(out, "]");
220 break;
221
222 case MSGPACK_OBJECT_MAP:
223 fprintf(out, "{");
224 if(o.via.map.size != 0) {
225 msgpack_object_kv* p = o.via.map.ptr;
226 msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
227 msgpack_object_print(out, p->key);
228 fprintf(out, "=>");
229 msgpack_object_print(out, p->val);
230 ++p;
231 for(; p < pend; ++p) {
232 fprintf(out, ", ");
233 msgpack_object_print(out, p->key);
234 fprintf(out, "=>");
235 msgpack_object_print(out, p->val);
236 }
237 }
238 fprintf(out, "}");
239 break;
240
241 default:
242 // FIXME
243#if defined(PRIu64)
244 fprintf(out, "#<UNKNOWN %i %" PRIu64 ">", o.type, o.via.u64);
245#else
246 if (o.via.u64 > ULONG_MAX)
247 fprintf(out, "#<UNKNOWN %i over 4294967295>", o.type);
248 else
249 fprintf(out, "#<UNKNOWN %i %lu>", o.type, (unsigned long)o.via.u64);
250#endif
251
252 }
253}
254
255#endif
256
257#define MSGPACK_CHECKED_CALL(ret, func, aux_buffer, aux_buffer_size, ...) \
258 ret = func(aux_buffer, aux_buffer_size, __VA_ARGS__); \
259 if (ret <= 0 || ret >= (int)aux_buffer_size) return 0; \
260 aux_buffer = aux_buffer + ret; \
261 aux_buffer_size = aux_buffer_size - ret \
262
263static int msgpack_object_bin_print_buffer(char *buffer, size_t buffer_size, const char *ptr, size_t size)
264{
265 size_t i;
266 char *aux_buffer = buffer;
267 size_t aux_buffer_size = buffer_size;
268 int ret;
269
270 for (i = 0; i < size; ++i) {
271 if (ptr[i] == '"') {
272 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\\\"");
273 } else if (isprint((unsigned char)ptr[i])) {
274 if (aux_buffer_size > 0) {
275 memcpy(aux_buffer, ptr + i, 1);
276 aux_buffer = aux_buffer + 1;
277 aux_buffer_size = aux_buffer_size - 1;
278 }
279 } else {
280 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\\x%02x", (unsigned char)ptr[i]);
281 }
282 }
283
284 return (int)(buffer_size - aux_buffer_size);
285}
286
287int msgpack_object_print_buffer(char *buffer, size_t buffer_size, msgpack_object o)
288{
289 char *aux_buffer = buffer;
290 size_t aux_buffer_size = buffer_size;
291 int ret;
292 switch(o.type) {
293 case MSGPACK_OBJECT_NIL:
294 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "nil");
295 break;
296
297 case MSGPACK_OBJECT_BOOLEAN:
298 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, (o.via.boolean ? "true" : "false"));
299 break;
300
301 case MSGPACK_OBJECT_POSITIVE_INTEGER:
302#if defined(PRIu64)
303 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%" PRIu64, o.via.u64);
304#else
305 if (o.via.u64 > ULONG_MAX) {
306 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "over 4294967295");
307 } else {
308 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%lu", (unsigned long)o.via.u64);
309 }
310#endif
311 break;
312
313 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
314#if defined(PRIi64)
315 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%" PRIi64, o.via.i64);
316#else
317 if (o.via.i64 > LONG_MAX) {
318 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "over +2147483647");
319 } else if (o.via.i64 < LONG_MIN) {
320 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "under -2147483648");
321 } else {
322 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%ld", (signed long)o.via.i64);
323 }
324#endif
325 break;
326
327 case MSGPACK_OBJECT_FLOAT32:
328 case MSGPACK_OBJECT_FLOAT64:
329 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%f", o.via.f64);
330 break;
331
332 case MSGPACK_OBJECT_STR:
333 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
0c07860d
MJ
334 if (o.via.str.size > 0) {
335 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%.*s", (int)o.via.str.size, o.via.str.ptr);
336 }
116a02e3
JG
337 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
338 break;
339
340 case MSGPACK_OBJECT_BIN:
341 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
342 MSGPACK_CHECKED_CALL(ret, msgpack_object_bin_print_buffer, aux_buffer, aux_buffer_size, o.via.bin.ptr, o.via.bin.size);
343 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
344 break;
345
346 case MSGPACK_OBJECT_EXT:
347#if defined(PRIi8)
348 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "(ext: %" PRIi8 ")", o.via.ext.type);
349#else
350 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "(ext: %d)", (int)o.via.ext.type);
351#endif
352 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
353 MSGPACK_CHECKED_CALL(ret, msgpack_object_bin_print_buffer, aux_buffer, aux_buffer_size, o.via.ext.ptr, o.via.ext.size);
354 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
355 break;
356
357 case MSGPACK_OBJECT_ARRAY:
358 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "[");
359 if(o.via.array.size != 0) {
360 msgpack_object* p = o.via.array.ptr;
361 msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
362 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, *p);
363 ++p;
364 for(; p < pend; ++p) {
365 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, ", ");
366 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, *p);
367 }
368 }
369 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "]");
370 break;
371
372 case MSGPACK_OBJECT_MAP:
373 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "{");
374 if(o.via.map.size != 0) {
375 msgpack_object_kv* p = o.via.map.ptr;
376 msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
377 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->key);
378 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "=>");
379 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->val);
380 ++p;
381 for(; p < pend; ++p) {
382 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, ", ");
383 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->key);
384 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "=>");
385 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->val);
386 }
387 }
388 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "}");
389 break;
390
391 default:
392 // FIXME
393#if defined(PRIu64)
394 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "#<UNKNOWN %i %" PRIu64 ">", o.type, o.via.u64);
395#else
396 if (o.via.u64 > ULONG_MAX) {
397 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "#<UNKNOWN %i over 4294967295>", o.type);
398 } else {
399 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "#<UNKNOWN %i %lu>", o.type, (unsigned long)o.via.u64);
400 }
401#endif
402 }
403
404 return (int)(buffer_size - aux_buffer_size);
405}
406
407#undef MSGPACK_CHECKED_CALL
408
409bool msgpack_object_equal(const msgpack_object x, const msgpack_object y)
410{
411 if(x.type != y.type) { return false; }
412
413 switch(x.type) {
414 case MSGPACK_OBJECT_NIL:
415 return true;
416
417 case MSGPACK_OBJECT_BOOLEAN:
418 return x.via.boolean == y.via.boolean;
419
420 case MSGPACK_OBJECT_POSITIVE_INTEGER:
421 return x.via.u64 == y.via.u64;
422
423 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
424 return x.via.i64 == y.via.i64;
425
426 case MSGPACK_OBJECT_FLOAT32:
427 case MSGPACK_OBJECT_FLOAT64:
428 return x.via.f64 == y.via.f64;
429
430 case MSGPACK_OBJECT_STR:
431 return x.via.str.size == y.via.str.size &&
432 memcmp(x.via.str.ptr, y.via.str.ptr, x.via.str.size) == 0;
433
434 case MSGPACK_OBJECT_BIN:
435 return x.via.bin.size == y.via.bin.size &&
436 memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0;
437
438 case MSGPACK_OBJECT_EXT:
439 return x.via.ext.size == y.via.ext.size &&
440 x.via.ext.type == y.via.ext.type &&
441 memcmp(x.via.ext.ptr, y.via.ext.ptr, x.via.ext.size) == 0;
442
443 case MSGPACK_OBJECT_ARRAY:
444 if(x.via.array.size != y.via.array.size) {
445 return false;
446 } else if(x.via.array.size == 0) {
447 return true;
448 } else {
449 msgpack_object* px = x.via.array.ptr;
450 msgpack_object* const pxend = x.via.array.ptr + x.via.array.size;
451 msgpack_object* py = y.via.array.ptr;
452 do {
453 if(!msgpack_object_equal(*px, *py)) {
454 return false;
455 }
456 ++px;
457 ++py;
458 } while(px < pxend);
459 return true;
460 }
461
462 case MSGPACK_OBJECT_MAP:
463 if(x.via.map.size != y.via.map.size) {
464 return false;
465 } else if(x.via.map.size == 0) {
466 return true;
467 } else {
468 msgpack_object_kv* px = x.via.map.ptr;
469 msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size;
470 msgpack_object_kv* py = y.via.map.ptr;
471 do {
472 if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) {
473 return false;
474 }
475 ++px;
476 ++py;
477 } while(px < pxend);
478 return true;
479 }
480
481 default:
482 return false;
483 }
484}
This page took 0.045316 seconds and 4 git commands to generate.