summaryrefslogtreecommitdiff
path: root/msgpack/unpack_template.h
diff options
context:
space:
mode:
authorINADA Naoki <inada-n@klab.com>2012-10-01 01:31:58 +0900
committerINADA Naoki <inada-n@klab.com>2012-10-01 01:31:58 +0900
commite016b3dca0d8ca71fa54ffadfa1e5d9f3e4b3f06 (patch)
tree45daae42bfd00afdc27a7565f32ec061eb771bd7 /msgpack/unpack_template.h
parent1526316a0803c233a6752aff1bab6e951447d12a (diff)
parent9d9c3eecb846c6a927a31aae394dea39fa75aef4 (diff)
downloadmsgpack-python-e016b3dca0d8ca71fa54ffadfa1e5d9f3e4b3f06.tar.gz
Merge remote-tracking branch 'jnothman/read_size_cpp'
Conflicts: msgpack/_msgpack.pyx setup.py
Diffstat (limited to 'msgpack/unpack_template.h')
-rw-r--r--msgpack/unpack_template.h84
1 files changed, 76 insertions, 8 deletions
diff --git a/msgpack/unpack_template.h b/msgpack/unpack_template.h
index 6080a51..7d07601 100644
--- a/msgpack/unpack_template.h
+++ b/msgpack/unpack_template.h
@@ -95,7 +95,8 @@ msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context
}
-msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off, int construct)
+template <bool construct>
+msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off)
{
assert(len >= *off);
@@ -380,6 +381,8 @@ _header_again:
_finish:
+ if (!construct)
+ msgpack_unpack_callback(_nil)(user, &obj);
stack[0].obj = obj;
++p;
ret = 1;
@@ -405,13 +408,10 @@ _end:
#undef construct_cb
}
-
-#undef msgpack_unpack_func
-#undef msgpack_unpack_callback
-#undef msgpack_unpack_struct
-#undef msgpack_unpack_object
-#undef msgpack_unpack_user
-
+#undef SWITCH_RANGE_BEGIN
+#undef SWITCH_RANGE
+#undef SWITCH_RANGE_DEFAULT
+#undef SWITCH_RANGE_END
#undef push_simple_value
#undef push_fixed_value
#undef push_variable_value
@@ -419,6 +419,74 @@ _end:
#undef again_fixed_trail_if_zero
#undef start_container
+template <unsigned int fixed_offset, unsigned int var_offset>
+msgpack_unpack_func(int, _container_header)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off)
+{
+ assert(len >= *off);
+ uint32_t size;
+ const unsigned char *const p = (unsigned char*)data + *off;
+
+#define inc_offset(inc) \
+ if (len - *off < inc) \
+ return 0; \
+ *off += inc;
+
+ switch (*p) {
+ case var_offset:
+ inc_offset(3);
+ size = _msgpack_load16(uint16_t, p + 1);
+ break;
+ case var_offset + 1:
+ inc_offset(5);
+ size = _msgpack_load32(uint32_t, p + 1);
+ break;
+#ifdef USE_CASE_RANGE
+ case fixed_offset + 0x0 ... fixed_offset + 0xf:
+#else
+ case fixed_offset + 0x0:
+ case fixed_offset + 0x1:
+ case fixed_offset + 0x2:
+ case fixed_offset + 0x3:
+ case fixed_offset + 0x4:
+ case fixed_offset + 0x5:
+ case fixed_offset + 0x6:
+ case fixed_offset + 0x7:
+ case fixed_offset + 0x8:
+ case fixed_offset + 0x9:
+ case fixed_offset + 0xa:
+ case fixed_offset + 0xb:
+ case fixed_offset + 0xc:
+ case fixed_offset + 0xd:
+ case fixed_offset + 0xe:
+ case fixed_offset + 0xf:
+#endif
+ ++*off;
+ size = ((unsigned int)*p) & 0x0f;
+ break;
+ default:
+ PyErr_SetString(PyExc_ValueError, "Unexpected type header on stream");
+ return -1;
+ }
+ msgpack_unpack_callback(_uint32)(&ctx->user, size, &ctx->stack[0].obj);
+ return 1;
+}
+
+#undef SWITCH_RANGE_BEGIN
+#undef SWITCH_RANGE
+#undef SWITCH_RANGE_DEFAULT
+#undef SWITCH_RANGE_END
+
+static const execute_fn template_construct = &template_execute<true>;
+static const execute_fn template_skip = &template_execute<false>;
+static const execute_fn read_array_header = &template_container_header<0x90, 0xdc>;
+static const execute_fn read_map_header = &template_container_header<0x80, 0xde>;
+
+#undef msgpack_unpack_func
+#undef msgpack_unpack_callback
+#undef msgpack_unpack_struct
+#undef msgpack_unpack_object
+#undef msgpack_unpack_user
+
#undef NEXT_CS
/* vim: set ts=4 sw=4 noexpandtab */