2 * MessagePack for C dynamic typing routine
4 * Copyright (C) 2008-2009 FURUHASHI Sadayuki
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)
10 #if defined(_KERNEL_MODE)
11 # undef _NO_CRT_STDIO_INLINE
12 # define _NO_CRT_STDIO_INLINE
15 #include "vendor/msgpack/object.h"
16 #include "vendor/msgpack/pack.h"
34 #if defined(_KERNEL_MODE)
36 # define snprintf _snprintf
39 int msgpack_pack_object(msgpack_packer
* pk
, msgpack_object d
)
42 case MSGPACK_OBJECT_NIL
:
43 return msgpack_pack_nil(pk
);
45 case MSGPACK_OBJECT_BOOLEAN
:
47 return msgpack_pack_true(pk
);
49 return msgpack_pack_false(pk
);
52 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
53 return msgpack_pack_uint64(pk
, d
.via
.u64
);
55 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
56 return msgpack_pack_int64(pk
, d
.via
.i64
);
58 case MSGPACK_OBJECT_FLOAT32
:
59 return msgpack_pack_float(pk
, (float)d
.via
.f64
);
61 case MSGPACK_OBJECT_FLOAT64
:
62 return msgpack_pack_double(pk
, d
.via
.f64
);
64 case MSGPACK_OBJECT_STR
:
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
);
71 case MSGPACK_OBJECT_BIN
:
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
);
78 case MSGPACK_OBJECT_EXT
:
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
);
85 case MSGPACK_OBJECT_ARRAY
:
87 int ret
= msgpack_pack_array(pk
, d
.via
.array
.size
);
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
; }
103 case MSGPACK_OBJECT_MAP
:
105 int ret
= msgpack_pack_map(pk
, d
.via
.map
.size
);
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
; }
128 #if !defined(_KERNEL_MODE)
130 static void msgpack_object_bin_print(FILE* out
, const char *ptr
, size_t size
)
133 for (i
= 0; i
< size
; ++i
) {
136 } else if (isprint((unsigned char)ptr
[i
])) {
139 fprintf(out
, "\\x%02x", (unsigned char)ptr
[i
]);
144 void msgpack_object_print(FILE* out
, msgpack_object o
)
147 case MSGPACK_OBJECT_NIL
:
151 case MSGPACK_OBJECT_BOOLEAN
:
152 fprintf(out
, (o
.via
.boolean
? "true" : "false"));
155 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
157 fprintf(out
, "%" PRIu64
, o
.via
.u64
);
159 if (o
.via
.u64
> ULONG_MAX
)
160 fprintf(out
, "over 4294967295");
162 fprintf(out
, "%lu", (unsigned long)o
.via
.u64
);
166 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
168 fprintf(out
, "%" PRIi64
, o
.via
.i64
);
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");
175 fprintf(out
, "%ld", (signed long)o
.via
.i64
);
179 case MSGPACK_OBJECT_FLOAT32
:
180 case MSGPACK_OBJECT_FLOAT64
:
181 fprintf(out
, "%f", o
.via
.f64
);
184 case MSGPACK_OBJECT_STR
:
186 fwrite(o
.via
.str
.ptr
, o
.via
.str
.size
, 1, out
);
190 case MSGPACK_OBJECT_BIN
:
192 msgpack_object_bin_print(out
, o
.via
.bin
.ptr
, o
.via
.bin
.size
);
196 case MSGPACK_OBJECT_EXT
:
198 fprintf(out
, "(ext: %" PRIi8
")", o
.via
.ext
.type
);
200 fprintf(out
, "(ext: %d)", (int)o
.via
.ext
.type
);
203 msgpack_object_bin_print(out
, o
.via
.ext
.ptr
, o
.via
.ext
.size
);
207 case MSGPACK_OBJECT_ARRAY
:
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
);
214 for(; p
< pend
; ++p
) {
216 msgpack_object_print(out
, *p
);
222 case MSGPACK_OBJECT_MAP
:
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
);
229 msgpack_object_print(out
, p
->val
);
231 for(; p
< pend
; ++p
) {
233 msgpack_object_print(out
, p
->key
);
235 msgpack_object_print(out
, p
->val
);
244 fprintf(out
, "#<UNKNOWN %i %" PRIu64
">", o
.type
, o
.via
.u64
);
246 if (o
.via
.u64
> ULONG_MAX
)
247 fprintf(out
, "#<UNKNOWN %i over 4294967295>", o
.type
);
249 fprintf(out
, "#<UNKNOWN %i %lu>", o
.type
, (unsigned long)o
.via
.u64
);
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 \
263 static int msgpack_object_bin_print_buffer(char *buffer, size_t buffer_size, const char *ptr, size_t size)
266 char *aux_buffer
= buffer
;
267 size_t aux_buffer_size
= buffer_size
;
270 for (i
= 0; i
< size
; ++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;
280 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "\\x%02x", (unsigned char)ptr
[i
]);
284 return (int)(buffer_size
- aux_buffer_size
);
287 int msgpack_object_print_buffer(char *buffer
, size_t buffer_size
, msgpack_object o
)
289 char *aux_buffer
= buffer
;
290 size_t aux_buffer_size
= buffer_size
;
293 case MSGPACK_OBJECT_NIL
:
294 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "nil");
297 case MSGPACK_OBJECT_BOOLEAN
:
298 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, (o
.via
.boolean
? "true" : "false"));
301 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
303 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "%" PRIu64
, o
.via
.u64
);
305 if (o
.via
.u64
> ULONG_MAX
) {
306 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "over 4294967295");
308 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "%lu", (unsigned long)o
.via
.u64
);
313 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
315 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "%" PRIi64
, o
.via
.i64
);
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");
322 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "%ld", (signed long)o
.via
.i64
);
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
);
332 case MSGPACK_OBJECT_STR
:
333 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "\"");
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
);
337 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "\"");
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
, "\"");
346 case MSGPACK_OBJECT_EXT
:
348 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "(ext: %" PRIi8
")", o
.via
.ext
.type
);
350 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "(ext: %d)", (int)o
.via
.ext
.type
);
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
, "\"");
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
);
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
);
369 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "]");
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
);
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
);
388 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "}");
394 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "#<UNKNOWN %i %" PRIu64
">", o
.type
, o
.via
.u64
);
396 if (o
.via
.u64
> ULONG_MAX
) {
397 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "#<UNKNOWN %i over 4294967295>", o
.type
);
399 MSGPACK_CHECKED_CALL(ret
, snprintf
, aux_buffer
, aux_buffer_size
, "#<UNKNOWN %i %lu>", o
.type
, (unsigned long)o
.via
.u64
);
404 return (int)(buffer_size
- aux_buffer_size
);
407 #undef MSGPACK_CHECKED_CALL
409 bool msgpack_object_equal(const msgpack_object x
, const msgpack_object y
)
411 if(x
.type
!= y
.type
) { return false; }
414 case MSGPACK_OBJECT_NIL
:
417 case MSGPACK_OBJECT_BOOLEAN
:
418 return x
.via
.boolean
== y
.via
.boolean
;
420 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
421 return x
.via
.u64
== y
.via
.u64
;
423 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
424 return x
.via
.i64
== y
.via
.i64
;
426 case MSGPACK_OBJECT_FLOAT32
:
427 case MSGPACK_OBJECT_FLOAT64
:
428 return x
.via
.f64
== y
.via
.f64
;
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;
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;
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;
443 case MSGPACK_OBJECT_ARRAY
:
444 if(x
.via
.array
.size
!= y
.via
.array
.size
) {
446 } else if(x
.via
.array
.size
== 0) {
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
;
453 if(!msgpack_object_equal(*px
, *py
)) {
462 case MSGPACK_OBJECT_MAP
:
463 if(x
.via
.map
.size
!= y
.via
.map
.size
) {
465 } else if(x
.via
.map
.size
== 0) {
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
;
472 if(!msgpack_object_equal(px
->key
, py
->key
) || !msgpack_object_equal(px
->val
, py
->val
)) {