File Coverage

deps/msgpack-c/src/objectc.c
Criterion Covered Total %
statement 0 211 0.0
branch 0 218 0.0
condition n/a
subroutine n/a
pod n/a
total 0 429 0.0


line stmt bran cond sub pod time code
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 "msgpack/object.h"
16             #include "msgpack/pack.h"
17             #include
18              
19             #include
20             #include
21              
22             #if defined(_MSC_VER)
23             #if _MSC_VER >= 1800
24             #include
25             #else
26             #define PRIu64 "I64u"
27             #define PRIi64 "I64i"
28             #define PRIi8 "i"
29             #endif
30             #else
31             #include
32             #endif
33              
34             #if defined(_KERNEL_MODE)
35             # undef snprintf
36             # define snprintf _snprintf
37             #endif
38              
39 0           int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
40             {
41 0           switch(d.type) {
42             case MSGPACK_OBJECT_NIL:
43 0           return msgpack_pack_nil(pk);
44              
45             case MSGPACK_OBJECT_BOOLEAN:
46 0 0         if(d.via.boolean) {
47 0           return msgpack_pack_true(pk);
48             } else {
49 0           return msgpack_pack_false(pk);
50             }
51              
52             case MSGPACK_OBJECT_POSITIVE_INTEGER:
53 0           return msgpack_pack_uint64(pk, d.via.u64);
54              
55             case MSGPACK_OBJECT_NEGATIVE_INTEGER:
56 0           return msgpack_pack_int64(pk, d.via.i64);
57              
58             case MSGPACK_OBJECT_FLOAT32:
59 0           return msgpack_pack_float(pk, (float)d.via.f64);
60              
61             case MSGPACK_OBJECT_FLOAT64:
62 0           return msgpack_pack_double(pk, d.via.f64);
63              
64             case MSGPACK_OBJECT_STR:
65             {
66 0           int ret = msgpack_pack_str(pk, d.via.str.size);
67 0 0         if(ret < 0) { return ret; }
68 0           return msgpack_pack_str_body(pk, d.via.str.ptr, d.via.str.size);
69             }
70              
71             case MSGPACK_OBJECT_BIN:
72             {
73 0           int ret = msgpack_pack_bin(pk, d.via.bin.size);
74 0 0         if(ret < 0) { return ret; }
75 0           return msgpack_pack_bin_body(pk, d.via.bin.ptr, d.via.bin.size);
76             }
77              
78             case MSGPACK_OBJECT_EXT:
79             {
80 0           int ret = msgpack_pack_ext(pk, d.via.ext.size, d.via.ext.type);
81 0 0         if(ret < 0) { return ret; }
82 0           return msgpack_pack_ext_body(pk, d.via.ext.ptr, d.via.ext.size);
83             }
84              
85             case MSGPACK_OBJECT_ARRAY:
86             {
87 0           int ret = msgpack_pack_array(pk, d.via.array.size);
88 0 0         if(ret < 0) {
89 0           return ret;
90             }
91             else {
92 0           msgpack_object* o = d.via.array.ptr;
93 0           msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
94 0 0         for(; o != oend; ++o) {
95 0           ret = msgpack_pack_object(pk, *o);
96 0 0         if(ret < 0) { return ret; }
97             }
98              
99 0           return 0;
100             }
101             }
102              
103             case MSGPACK_OBJECT_MAP:
104             {
105 0           int ret = msgpack_pack_map(pk, d.via.map.size);
106 0 0         if(ret < 0) {
107 0           return ret;
108             }
109             else {
110 0           msgpack_object_kv* kv = d.via.map.ptr;
111 0           msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size;
112 0 0         for(; kv != kvend; ++kv) {
113 0           ret = msgpack_pack_object(pk, kv->key);
114 0 0         if(ret < 0) { return ret; }
115 0           ret = msgpack_pack_object(pk, kv->val);
116 0 0         if(ret < 0) { return ret; }
117             }
118              
119 0           return 0;
120             }
121             }
122              
123             default:
124 0           return -1;
125             }
126             }
127              
128             #if !defined(_KERNEL_MODE)
129              
130 0           static void msgpack_object_bin_print(FILE* out, const char *ptr, size_t size)
131             {
132             size_t i;
133 0 0         for (i = 0; i < size; ++i) {
134 0 0         if (ptr[i] == '"') {
135 0           fputs("\\\"", out);
136 0 0         } else if (isprint((unsigned char)ptr[i])) {
137 0           fputc(ptr[i], out);
138             } else {
139 0           fprintf(out, "\\x%02x", (unsigned char)ptr[i]);
140             }
141             }
142 0           }
143              
144 0           void msgpack_object_print(FILE* out, msgpack_object o)
145             {
146 0           switch(o.type) {
147             case MSGPACK_OBJECT_NIL:
148 0           fprintf(out, "nil");
149 0           break;
150              
151             case MSGPACK_OBJECT_BOOLEAN:
152 0 0         fprintf(out, (o.via.boolean ? "true" : "false"));
153 0           break;
154              
155             case MSGPACK_OBJECT_POSITIVE_INTEGER:
156             #if defined(PRIu64)
157 0           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 0           break;
165              
166             case MSGPACK_OBJECT_NEGATIVE_INTEGER:
167             #if defined(PRIi64)
168 0           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 0           break;
178              
179             case MSGPACK_OBJECT_FLOAT32:
180             case MSGPACK_OBJECT_FLOAT64:
181 0           fprintf(out, "%f", o.via.f64);
182 0           break;
183              
184             case MSGPACK_OBJECT_STR:
185 0           fprintf(out, "\"");
186 0           fwrite(o.via.str.ptr, o.via.str.size, 1, out);
187 0           fprintf(out, "\"");
188 0           break;
189              
190             case MSGPACK_OBJECT_BIN:
191 0           fprintf(out, "\"");
192 0           msgpack_object_bin_print(out, o.via.bin.ptr, o.via.bin.size);
193 0           fprintf(out, "\"");
194 0           break;
195              
196             case MSGPACK_OBJECT_EXT:
197             #if defined(PRIi8)
198 0           fprintf(out, "(ext: %" PRIi8 ")", o.via.ext.type);
199             #else
200             fprintf(out, "(ext: %d)", (int)o.via.ext.type);
201             #endif
202 0           fprintf(out, "\"");
203 0           msgpack_object_bin_print(out, o.via.ext.ptr, o.via.ext.size);
204 0           fprintf(out, "\"");
205 0           break;
206              
207             case MSGPACK_OBJECT_ARRAY:
208 0           fprintf(out, "[");
209 0 0         if(o.via.array.size != 0) {
210 0           msgpack_object* p = o.via.array.ptr;
211 0           msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
212 0           msgpack_object_print(out, *p);
213 0           ++p;
214 0 0         for(; p < pend; ++p) {
215 0           fprintf(out, ", ");
216 0           msgpack_object_print(out, *p);
217             }
218             }
219 0           fprintf(out, "]");
220 0           break;
221              
222             case MSGPACK_OBJECT_MAP:
223 0           fprintf(out, "{");
224 0 0         if(o.via.map.size != 0) {
225 0           msgpack_object_kv* p = o.via.map.ptr;
226 0           msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
227 0           msgpack_object_print(out, p->key);
228 0           fprintf(out, "=>");
229 0           msgpack_object_print(out, p->val);
230 0           ++p;
231 0 0         for(; p < pend; ++p) {
232 0           fprintf(out, ", ");
233 0           msgpack_object_print(out, p->key);
234 0           fprintf(out, "=>");
235 0           msgpack_object_print(out, p->val);
236             }
237             }
238 0           fprintf(out, "}");
239 0           break;
240              
241             default:
242             // FIXME
243             #if defined(PRIu64)
244 0           fprintf(out, "#", o.type, o.via.u64);
245             #else
246             if (o.via.u64 > ULONG_MAX)
247             fprintf(out, "#", o.type);
248             else
249             fprintf(out, "#", o.type, (unsigned long)o.via.u64);
250             #endif
251              
252             }
253 0           }
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 0           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 0           char *aux_buffer = buffer;
267 0           size_t aux_buffer_size = buffer_size;
268             int ret;
269              
270 0 0         for (i = 0; i < size; ++i) {
271 0 0         if (ptr[i] == '"') {
272 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\\\"");
    0          
273 0 0         } else if (isprint((unsigned char)ptr[i])) {
274 0 0         if (aux_buffer_size > 0) {
275 0           memcpy(aux_buffer, ptr + i, 1);
276 0           aux_buffer = aux_buffer + 1;
277 0           aux_buffer_size = aux_buffer_size - 1;
278             }
279             } else {
280 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\\x%02x", (unsigned char)ptr[i]);
    0          
281             }
282             }
283              
284 0           return (int)(buffer_size - aux_buffer_size);
285             }
286              
287 0           int msgpack_object_print_buffer(char *buffer, size_t buffer_size, msgpack_object o)
288             {
289 0           char *aux_buffer = buffer;
290 0           size_t aux_buffer_size = buffer_size;
291             int ret;
292 0           switch(o.type) {
293             case MSGPACK_OBJECT_NIL:
294 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "nil");
    0          
295 0           break;
296              
297             case MSGPACK_OBJECT_BOOLEAN:
298 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, (o.via.boolean ? "true" : "false"));
    0          
    0          
299 0           break;
300              
301             case MSGPACK_OBJECT_POSITIVE_INTEGER:
302             #if defined(PRIu64)
303 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%" PRIu64, o.via.u64);
    0          
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 0           break;
312              
313             case MSGPACK_OBJECT_NEGATIVE_INTEGER:
314             #if defined(PRIi64)
315 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%" PRIi64, o.via.i64);
    0          
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 0           break;
326              
327             case MSGPACK_OBJECT_FLOAT32:
328             case MSGPACK_OBJECT_FLOAT64:
329 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%f", o.via.f64);
    0          
330 0           break;
331              
332             case MSGPACK_OBJECT_STR:
333 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
    0          
334 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%.*s", (int)o.via.str.size, o.via.str.ptr);
    0          
335 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
    0          
336 0           break;
337              
338             case MSGPACK_OBJECT_BIN:
339 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
    0          
340 0 0         MSGPACK_CHECKED_CALL(ret, msgpack_object_bin_print_buffer, aux_buffer, aux_buffer_size, o.via.bin.ptr, o.via.bin.size);
    0          
341 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
    0          
342 0           break;
343              
344             case MSGPACK_OBJECT_EXT:
345             #if defined(PRIi8)
346 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "(ext: %" PRIi8 ")", o.via.ext.type);
    0          
347             #else
348             MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "(ext: %d)", (int)o.via.ext.type);
349             #endif
350 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
    0          
351 0 0         MSGPACK_CHECKED_CALL(ret, msgpack_object_bin_print_buffer, aux_buffer, aux_buffer_size, o.via.ext.ptr, o.via.ext.size);
    0          
352 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
    0          
353 0           break;
354              
355             case MSGPACK_OBJECT_ARRAY:
356 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "[");
    0          
357 0 0         if(o.via.array.size != 0) {
358 0           msgpack_object* p = o.via.array.ptr;
359 0           msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
360 0 0         MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, *p);
    0          
361 0           ++p;
362 0 0         for(; p < pend; ++p) {
363 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, ", ");
    0          
364 0 0         MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, *p);
    0          
365             }
366             }
367 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "]");
    0          
368 0           break;
369              
370             case MSGPACK_OBJECT_MAP:
371 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "{");
    0          
372 0 0         if(o.via.map.size != 0) {
373 0           msgpack_object_kv* p = o.via.map.ptr;
374 0           msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
375 0 0         MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->key);
    0          
376 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "=>");
    0          
377 0 0         MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->val);
    0          
378 0           ++p;
379 0 0         for(; p < pend; ++p) {
380 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, ", ");
    0          
381 0 0         MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->key);
    0          
382 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "=>");
    0          
383 0 0         MSGPACK_CHECKED_CALL(ret, msgpack_object_print_buffer, aux_buffer, aux_buffer_size, p->val);
    0          
384             }
385             }
386 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "}");
    0          
387 0           break;
388              
389             default:
390             // FIXME
391             #if defined(PRIu64)
392 0 0         MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "#", o.type, o.via.u64);
    0          
393             #else
394             if (o.via.u64 > ULONG_MAX) {
395             MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "#", o.type);
396             } else {
397             MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "#", o.type, (unsigned long)o.via.u64);
398             }
399             #endif
400             }
401              
402 0           return (int)(buffer_size - aux_buffer_size);
403             }
404              
405             #undef MSGPACK_CHECKED_CALL
406              
407 0           bool msgpack_object_equal(const msgpack_object x, const msgpack_object y)
408             {
409 0 0         if(x.type != y.type) { return false; }
410              
411 0           switch(x.type) {
412             case MSGPACK_OBJECT_NIL:
413 0           return true;
414              
415             case MSGPACK_OBJECT_BOOLEAN:
416 0           return x.via.boolean == y.via.boolean;
417              
418             case MSGPACK_OBJECT_POSITIVE_INTEGER:
419 0           return x.via.u64 == y.via.u64;
420              
421             case MSGPACK_OBJECT_NEGATIVE_INTEGER:
422 0           return x.via.i64 == y.via.i64;
423              
424             case MSGPACK_OBJECT_FLOAT32:
425             case MSGPACK_OBJECT_FLOAT64:
426 0           return x.via.f64 == y.via.f64;
427              
428             case MSGPACK_OBJECT_STR:
429 0 0         return x.via.str.size == y.via.str.size &&
    0          
430 0           memcmp(x.via.str.ptr, y.via.str.ptr, x.via.str.size) == 0;
431              
432             case MSGPACK_OBJECT_BIN:
433 0 0         return x.via.bin.size == y.via.bin.size &&
    0          
434 0           memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0;
435              
436             case MSGPACK_OBJECT_EXT:
437 0 0         return x.via.ext.size == y.via.ext.size &&
438 0 0         x.via.ext.type == y.via.ext.type &&
    0          
439 0           memcmp(x.via.ext.ptr, y.via.ext.ptr, x.via.ext.size) == 0;
440              
441             case MSGPACK_OBJECT_ARRAY:
442 0 0         if(x.via.array.size != y.via.array.size) {
443 0           return false;
444 0 0         } else if(x.via.array.size == 0) {
445 0           return true;
446             } else {
447 0           msgpack_object* px = x.via.array.ptr;
448 0           msgpack_object* const pxend = x.via.array.ptr + x.via.array.size;
449 0           msgpack_object* py = y.via.array.ptr;
450             do {
451 0 0         if(!msgpack_object_equal(*px, *py)) {
452 0           return false;
453             }
454 0           ++px;
455 0           ++py;
456 0 0         } while(px < pxend);
457 0           return true;
458             }
459              
460             case MSGPACK_OBJECT_MAP:
461 0 0         if(x.via.map.size != y.via.map.size) {
462 0           return false;
463 0 0         } else if(x.via.map.size == 0) {
464 0           return true;
465             } else {
466 0           msgpack_object_kv* px = x.via.map.ptr;
467 0           msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size;
468 0           msgpack_object_kv* py = y.via.map.ptr;
469             do {
470 0 0         if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) {
    0          
471 0           return false;
472             }
473 0           ++px;
474 0           ++py;
475 0 0         } while(px < pxend);
476 0           return true;
477             }
478              
479             default:
480 0           return false;
481             }
482             }