sessiond: Add msgpack-c 3.3.0 to the tree
[lttng-tools.git] / src / vendor / msgpack / objectc.c
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
39 int 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
130 static 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
144 void 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
263 static 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
287 int 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, "\"");
334 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%.*s", (int)o.via.str.size, o.via.str.ptr);
335 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
336 break;
337
338 case MSGPACK_OBJECT_BIN:
339 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
340 MSGPACK_CHECKED_CALL(ret, msgpack_object_bin_print_buffer, aux_buffer, aux_buffer_size, o.via.bin.ptr, o.via.bin.size);
341 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
342 break;
343
344 case MSGPACK_OBJECT_EXT:
345 #if defined(PRIi8)
346 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "(ext: %" PRIi8 ")", o.via.ext.type);
347 #else
348 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "(ext: %d)", (int)o.via.ext.type);
349 #endif
350 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
351 MSGPACK_CHECKED_CALL(ret, msgpack_object_bin_print_buffer, aux_buffer, aux_buffer_size, o.via.ext.ptr, o.via.ext.size);
352 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
353 break;
354
355 case MSGPACK_OBJECT_ARRAY:
356 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "[");
357 if(o.via.array.size != 0) {
358 msgpack_object* p = o.via.array.ptr;
359 msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
360 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, *p);
361 ++p;
362 for(; p < pend; ++p) {
363 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, ", ");
364 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, *p);
365 }
366 }
367 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "]");
368 break;
369
370 case MSGPACK_OBJECT_MAP:
371 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "{");
372 if(o.via.map.size != 0) {
373 msgpack_object_kv* p = o.via.map.ptr;
374 msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
375 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->key);
376 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "=>");
377 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->val);
378 ++p;
379 for(; p < pend; ++p) {
380 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, ", ");
381 MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->key);
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->val);
384 }
385 }
386 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "}");
387 break;
388
389 default:
390 // FIXME
391 #if defined(PRIu64)
392 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "#<UNKNOWN %i %" PRIu64 ">", o.type, o.via.u64);
393 #else
394 if (o.via.u64 > ULONG_MAX) {
395 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "#<UNKNOWN %i over 4294967295>", o.type);
396 } else {
397 MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "#<UNKNOWN %i %lu>", o.type, (unsigned long)o.via.u64);
398 }
399 #endif
400 }
401
402 return (int)(buffer_size - aux_buffer_size);
403 }
404
405 #undef MSGPACK_CHECKED_CALL
406
407 bool msgpack_object_equal(const msgpack_object x, const msgpack_object y)
408 {
409 if(x.type != y.type) { return false; }
410
411 switch(x.type) {
412 case MSGPACK_OBJECT_NIL:
413 return true;
414
415 case MSGPACK_OBJECT_BOOLEAN:
416 return x.via.boolean == y.via.boolean;
417
418 case MSGPACK_OBJECT_POSITIVE_INTEGER:
419 return x.via.u64 == y.via.u64;
420
421 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
422 return x.via.i64 == y.via.i64;
423
424 case MSGPACK_OBJECT_FLOAT32:
425 case MSGPACK_OBJECT_FLOAT64:
426 return x.via.f64 == y.via.f64;
427
428 case MSGPACK_OBJECT_STR:
429 return x.via.str.size == y.via.str.size &&
430 memcmp(x.via.str.ptr, y.via.str.ptr, x.via.str.size) == 0;
431
432 case MSGPACK_OBJECT_BIN:
433 return x.via.bin.size == y.via.bin.size &&
434 memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0;
435
436 case MSGPACK_OBJECT_EXT:
437 return x.via.ext.size == y.via.ext.size &&
438 x.via.ext.type == y.via.ext.type &&
439 memcmp(x.via.ext.ptr, y.via.ext.ptr, x.via.ext.size) == 0;
440
441 case MSGPACK_OBJECT_ARRAY:
442 if(x.via.array.size != y.via.array.size) {
443 return false;
444 } else if(x.via.array.size == 0) {
445 return true;
446 } else {
447 msgpack_object* px = x.via.array.ptr;
448 msgpack_object* const pxend = x.via.array.ptr + x.via.array.size;
449 msgpack_object* py = y.via.array.ptr;
450 do {
451 if(!msgpack_object_equal(*px, *py)) {
452 return false;
453 }
454 ++px;
455 ++py;
456 } while(px < pxend);
457 return true;
458 }
459
460 case MSGPACK_OBJECT_MAP:
461 if(x.via.map.size != y.via.map.size) {
462 return false;
463 } else if(x.via.map.size == 0) {
464 return true;
465 } else {
466 msgpack_object_kv* px = x.via.map.ptr;
467 msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size;
468 msgpack_object_kv* py = y.via.map.ptr;
469 do {
470 if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) {
471 return false;
472 }
473 ++px;
474 ++py;
475 } while(px < pxend);
476 return true;
477 }
478
479 default:
480 return false;
481 }
482 }
This page took 0.065566 seconds and 4 git commands to generate.