messagepack implementation for embedded systems (mbed / arduino)

Dependents:   hello_message_pack

msgpack-c & msgpack-c++ https://github.com/msgpack/msgpack-c implementation for embedded systems (mbed / Arduino)

Committer:
hideakitai
Date:
Mon Feb 22 01:43:48 2016 +0000
Revision:
4:bd0c06dd6e92
Parent:
0:3f9dbf1e2cb0
fix throw error

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hideakitai 0:3f9dbf1e2cb0 1 /*
hideakitai 0:3f9dbf1e2cb0 2 * MessagePack for C unpacking routine
hideakitai 0:3f9dbf1e2cb0 3 *
hideakitai 0:3f9dbf1e2cb0 4 * Copyright (C) 2008-2009 FURUHASHI Sadayuki
hideakitai 0:3f9dbf1e2cb0 5 *
hideakitai 0:3f9dbf1e2cb0 6 * Distributed under the Boost Software License, Version 1.0.
hideakitai 0:3f9dbf1e2cb0 7 * (See accompanying file LICENSE_1_0.txt or copy at
hideakitai 0:3f9dbf1e2cb0 8 * http://www.boost.org/LICENSE_1_0.txt)
hideakitai 0:3f9dbf1e2cb0 9 */
hideakitai 0:3f9dbf1e2cb0 10 #include "include/unpack.h"
hideakitai 0:3f9dbf1e2cb0 11 #include "include/unpack_define.h"
hideakitai 0:3f9dbf1e2cb0 12 #include "include/util.h"
hideakitai 0:3f9dbf1e2cb0 13 #include <stdlib.h>
hideakitai 0:3f9dbf1e2cb0 14
hideakitai 0:3f9dbf1e2cb0 15 #ifdef _msgpack_atomic_counter_header
hideakitai 0:3f9dbf1e2cb0 16 #include _msgpack_atomic_counter_header
hideakitai 0:3f9dbf1e2cb0 17 #endif
hideakitai 0:3f9dbf1e2cb0 18
hideakitai 0:3f9dbf1e2cb0 19
hideakitai 0:3f9dbf1e2cb0 20 typedef struct {
hideakitai 0:3f9dbf1e2cb0 21 msgpack_zone* z;
hideakitai 0:3f9dbf1e2cb0 22 bool referenced;
hideakitai 0:3f9dbf1e2cb0 23 } unpack_user;
hideakitai 0:3f9dbf1e2cb0 24
hideakitai 0:3f9dbf1e2cb0 25
hideakitai 0:3f9dbf1e2cb0 26 #define msgpack_unpack_struct(name) \
hideakitai 0:3f9dbf1e2cb0 27 struct template ## name
hideakitai 0:3f9dbf1e2cb0 28
hideakitai 0:3f9dbf1e2cb0 29 #define msgpack_unpack_func(ret, name) \
hideakitai 0:3f9dbf1e2cb0 30 ret template ## name
hideakitai 0:3f9dbf1e2cb0 31
hideakitai 0:3f9dbf1e2cb0 32 #define msgpack_unpack_callback(name) \
hideakitai 0:3f9dbf1e2cb0 33 template_callback ## name
hideakitai 0:3f9dbf1e2cb0 34
hideakitai 0:3f9dbf1e2cb0 35 #define msgpack_unpack_object msgpack_object
hideakitai 0:3f9dbf1e2cb0 36
hideakitai 0:3f9dbf1e2cb0 37 #define msgpack_unpack_user unpack_user
hideakitai 0:3f9dbf1e2cb0 38
hideakitai 0:3f9dbf1e2cb0 39
hideakitai 0:3f9dbf1e2cb0 40 struct template_context;
hideakitai 0:3f9dbf1e2cb0 41 typedef struct template_context template_context;
hideakitai 0:3f9dbf1e2cb0 42
hideakitai 0:3f9dbf1e2cb0 43 static void template_init(template_context* ctx);
hideakitai 0:3f9dbf1e2cb0 44
hideakitai 0:3f9dbf1e2cb0 45 static msgpack_object template_data(template_context* ctx);
hideakitai 0:3f9dbf1e2cb0 46
hideakitai 0:3f9dbf1e2cb0 47 static int template_execute(
hideakitai 0:3f9dbf1e2cb0 48 template_context* ctx, const char* data, size_t len, size_t* off);
hideakitai 0:3f9dbf1e2cb0 49
hideakitai 0:3f9dbf1e2cb0 50
hideakitai 0:3f9dbf1e2cb0 51 static inline msgpack_object template_callback_root(unpack_user* u)
hideakitai 0:3f9dbf1e2cb0 52 {
hideakitai 0:3f9dbf1e2cb0 53 msgpack_object o;
hideakitai 0:3f9dbf1e2cb0 54 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 55 o.type = MSGPACK_OBJECT_NIL;
hideakitai 0:3f9dbf1e2cb0 56 return o;
hideakitai 0:3f9dbf1e2cb0 57 }
hideakitai 0:3f9dbf1e2cb0 58
hideakitai 0:3f9dbf1e2cb0 59 static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 60 {
hideakitai 0:3f9dbf1e2cb0 61 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 62 o->type = MSGPACK_OBJECT_POSITIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 63 o->via.u64 = d;
hideakitai 0:3f9dbf1e2cb0 64 return 0;
hideakitai 0:3f9dbf1e2cb0 65 }
hideakitai 0:3f9dbf1e2cb0 66
hideakitai 0:3f9dbf1e2cb0 67 static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 68 {
hideakitai 0:3f9dbf1e2cb0 69 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 70 o->type = MSGPACK_OBJECT_POSITIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 71 o->via.u64 = d;
hideakitai 0:3f9dbf1e2cb0 72 return 0;
hideakitai 0:3f9dbf1e2cb0 73 }
hideakitai 0:3f9dbf1e2cb0 74
hideakitai 0:3f9dbf1e2cb0 75 static inline int template_callback_uint32(unpack_user* u, uint32_t d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 76 {
hideakitai 0:3f9dbf1e2cb0 77 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 78 o->type = MSGPACK_OBJECT_POSITIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 79 o->via.u64 = d;
hideakitai 0:3f9dbf1e2cb0 80 return 0;
hideakitai 0:3f9dbf1e2cb0 81 }
hideakitai 0:3f9dbf1e2cb0 82
hideakitai 0:3f9dbf1e2cb0 83 static inline int template_callback_uint64(unpack_user* u, uint64_t d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 84 {
hideakitai 0:3f9dbf1e2cb0 85 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 86 o->type = MSGPACK_OBJECT_POSITIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 87 o->via.u64 = d;
hideakitai 0:3f9dbf1e2cb0 88 return 0;
hideakitai 0:3f9dbf1e2cb0 89 }
hideakitai 0:3f9dbf1e2cb0 90
hideakitai 0:3f9dbf1e2cb0 91 static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 92 {
hideakitai 0:3f9dbf1e2cb0 93 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 94 if(d >= 0) {
hideakitai 0:3f9dbf1e2cb0 95 o->type = MSGPACK_OBJECT_POSITIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 96 o->via.u64 = (uint64_t)d;
hideakitai 0:3f9dbf1e2cb0 97 return 0;
hideakitai 0:3f9dbf1e2cb0 98 }
hideakitai 0:3f9dbf1e2cb0 99 else {
hideakitai 0:3f9dbf1e2cb0 100 o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 101 o->via.i64 = d;
hideakitai 0:3f9dbf1e2cb0 102 return 0;
hideakitai 0:3f9dbf1e2cb0 103 }
hideakitai 0:3f9dbf1e2cb0 104 }
hideakitai 0:3f9dbf1e2cb0 105
hideakitai 0:3f9dbf1e2cb0 106 static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 107 {
hideakitai 0:3f9dbf1e2cb0 108 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 109 if(d >= 0) {
hideakitai 0:3f9dbf1e2cb0 110 o->type = MSGPACK_OBJECT_POSITIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 111 o->via.u64 = (uint64_t)d;
hideakitai 0:3f9dbf1e2cb0 112 return 0;
hideakitai 0:3f9dbf1e2cb0 113 }
hideakitai 0:3f9dbf1e2cb0 114 else {
hideakitai 0:3f9dbf1e2cb0 115 o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 116 o->via.i64 = d;
hideakitai 0:3f9dbf1e2cb0 117 return 0;
hideakitai 0:3f9dbf1e2cb0 118 }
hideakitai 0:3f9dbf1e2cb0 119 }
hideakitai 0:3f9dbf1e2cb0 120
hideakitai 0:3f9dbf1e2cb0 121 static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 122 {
hideakitai 0:3f9dbf1e2cb0 123 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 124 if(d >= 0) {
hideakitai 0:3f9dbf1e2cb0 125 o->type = MSGPACK_OBJECT_POSITIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 126 o->via.u64 = (uint64_t)d;
hideakitai 0:3f9dbf1e2cb0 127 return 0;
hideakitai 0:3f9dbf1e2cb0 128 }
hideakitai 0:3f9dbf1e2cb0 129 else {
hideakitai 0:3f9dbf1e2cb0 130 o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 131 o->via.i64 = d;
hideakitai 0:3f9dbf1e2cb0 132 return 0;
hideakitai 0:3f9dbf1e2cb0 133 }
hideakitai 0:3f9dbf1e2cb0 134 }
hideakitai 0:3f9dbf1e2cb0 135
hideakitai 0:3f9dbf1e2cb0 136 static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 137 {
hideakitai 0:3f9dbf1e2cb0 138 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 139 if(d >= 0) {
hideakitai 0:3f9dbf1e2cb0 140 o->type = MSGPACK_OBJECT_POSITIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 141 o->via.u64 = (uint64_t)d;
hideakitai 0:3f9dbf1e2cb0 142 return 0;
hideakitai 0:3f9dbf1e2cb0 143 }
hideakitai 0:3f9dbf1e2cb0 144 else {
hideakitai 0:3f9dbf1e2cb0 145 o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER;
hideakitai 0:3f9dbf1e2cb0 146 o->via.i64 = d;
hideakitai 0:3f9dbf1e2cb0 147 return 0;
hideakitai 0:3f9dbf1e2cb0 148 }
hideakitai 0:3f9dbf1e2cb0 149 }
hideakitai 0:3f9dbf1e2cb0 150
hideakitai 0:3f9dbf1e2cb0 151 static inline int template_callback_float(unpack_user* u, float d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 152 {
hideakitai 0:3f9dbf1e2cb0 153 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 154 o->type = MSGPACK_OBJECT_FLOAT;
hideakitai 0:3f9dbf1e2cb0 155 o->via.f64 = d;
hideakitai 0:3f9dbf1e2cb0 156 return 0;
hideakitai 0:3f9dbf1e2cb0 157 }
hideakitai 0:3f9dbf1e2cb0 158
hideakitai 0:3f9dbf1e2cb0 159 static inline int template_callback_double(unpack_user* u, double d, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 160 {
hideakitai 0:3f9dbf1e2cb0 161 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 162 o->type = MSGPACK_OBJECT_FLOAT;
hideakitai 0:3f9dbf1e2cb0 163 o->via.f64 = d;
hideakitai 0:3f9dbf1e2cb0 164 return 0;
hideakitai 0:3f9dbf1e2cb0 165 }
hideakitai 0:3f9dbf1e2cb0 166
hideakitai 0:3f9dbf1e2cb0 167 static inline int template_callback_nil(unpack_user* u, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 168 {
hideakitai 0:3f9dbf1e2cb0 169 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 170 o->type = MSGPACK_OBJECT_NIL;
hideakitai 0:3f9dbf1e2cb0 171 return 0;
hideakitai 0:3f9dbf1e2cb0 172 }
hideakitai 0:3f9dbf1e2cb0 173
hideakitai 0:3f9dbf1e2cb0 174 static inline int template_callback_true(unpack_user* u, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 175 {
hideakitai 0:3f9dbf1e2cb0 176 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 177 o->type = MSGPACK_OBJECT_BOOLEAN;
hideakitai 0:3f9dbf1e2cb0 178 o->via.boolean = true;
hideakitai 0:3f9dbf1e2cb0 179 return 0;
hideakitai 0:3f9dbf1e2cb0 180 }
hideakitai 0:3f9dbf1e2cb0 181
hideakitai 0:3f9dbf1e2cb0 182 static inline int template_callback_false(unpack_user* u, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 183 {
hideakitai 0:3f9dbf1e2cb0 184 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 185 o->type = MSGPACK_OBJECT_BOOLEAN;
hideakitai 0:3f9dbf1e2cb0 186 o->via.boolean = false;
hideakitai 0:3f9dbf1e2cb0 187 return 0;
hideakitai 0:3f9dbf1e2cb0 188 }
hideakitai 0:3f9dbf1e2cb0 189
hideakitai 0:3f9dbf1e2cb0 190 static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 191 {
hideakitai 0:3f9dbf1e2cb0 192 o->type = MSGPACK_OBJECT_ARRAY;
hideakitai 0:3f9dbf1e2cb0 193 o->via.array.size = 0;
hideakitai 0:3f9dbf1e2cb0 194 o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object));
hideakitai 0:3f9dbf1e2cb0 195 if(o->via.array.ptr == NULL) { return -1; }
hideakitai 0:3f9dbf1e2cb0 196 return 0;
hideakitai 0:3f9dbf1e2cb0 197 }
hideakitai 0:3f9dbf1e2cb0 198
hideakitai 0:3f9dbf1e2cb0 199 static inline int template_callback_array_item(unpack_user* u, msgpack_object* c, msgpack_object o)
hideakitai 0:3f9dbf1e2cb0 200 {
hideakitai 0:3f9dbf1e2cb0 201 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 202 #if defined(__GNUC__) && !defined(__clang__)
hideakitai 0:3f9dbf1e2cb0 203 memcpy(&c->via.array.ptr[c->via.array.size], &o, sizeof(msgpack_object));
hideakitai 0:3f9dbf1e2cb0 204 #else /* __GNUC__ && !__clang__ */
hideakitai 0:3f9dbf1e2cb0 205 c->via.array.ptr[c->via.array.size] = o;
hideakitai 0:3f9dbf1e2cb0 206 #endif /* __GNUC__ && !__clang__ */
hideakitai 0:3f9dbf1e2cb0 207 ++c->via.array.size;
hideakitai 0:3f9dbf1e2cb0 208 return 0;
hideakitai 0:3f9dbf1e2cb0 209 }
hideakitai 0:3f9dbf1e2cb0 210
hideakitai 0:3f9dbf1e2cb0 211 static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 212 {
hideakitai 0:3f9dbf1e2cb0 213 o->type = MSGPACK_OBJECT_MAP;
hideakitai 0:3f9dbf1e2cb0 214 o->via.map.size = 0;
hideakitai 0:3f9dbf1e2cb0 215 o->via.map.ptr = (msgpack_object_kv*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object_kv));
hideakitai 0:3f9dbf1e2cb0 216 if(o->via.map.ptr == NULL) { return -1; }
hideakitai 0:3f9dbf1e2cb0 217 return 0;
hideakitai 0:3f9dbf1e2cb0 218 }
hideakitai 0:3f9dbf1e2cb0 219
hideakitai 0:3f9dbf1e2cb0 220 static inline int template_callback_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v)
hideakitai 0:3f9dbf1e2cb0 221 {
hideakitai 0:3f9dbf1e2cb0 222 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 223 #if defined(__GNUC__) && !defined(__clang__)
hideakitai 0:3f9dbf1e2cb0 224 memcpy(&c->via.map.ptr[c->via.map.size].key, &k, sizeof(msgpack_object));
hideakitai 0:3f9dbf1e2cb0 225 memcpy(&c->via.map.ptr[c->via.map.size].val, &v, sizeof(msgpack_object));
hideakitai 0:3f9dbf1e2cb0 226 #else /* __GNUC__ && !__clang__ */
hideakitai 0:3f9dbf1e2cb0 227 c->via.map.ptr[c->via.map.size].key = k;
hideakitai 0:3f9dbf1e2cb0 228 c->via.map.ptr[c->via.map.size].val = v;
hideakitai 0:3f9dbf1e2cb0 229 #endif /* __GNUC__ && !__clang__ */
hideakitai 0:3f9dbf1e2cb0 230 ++c->via.map.size;
hideakitai 0:3f9dbf1e2cb0 231 return 0;
hideakitai 0:3f9dbf1e2cb0 232 }
hideakitai 0:3f9dbf1e2cb0 233
hideakitai 0:3f9dbf1e2cb0 234 static inline int template_callback_str(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 235 {
hideakitai 0:3f9dbf1e2cb0 236 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 237 MSGPACK_UNUSED(b);
hideakitai 0:3f9dbf1e2cb0 238 o->type = MSGPACK_OBJECT_STR;
hideakitai 0:3f9dbf1e2cb0 239 o->via.str.ptr = p;
hideakitai 0:3f9dbf1e2cb0 240 o->via.str.size = l;
hideakitai 0:3f9dbf1e2cb0 241 u->referenced = true;
hideakitai 0:3f9dbf1e2cb0 242 return 0;
hideakitai 0:3f9dbf1e2cb0 243 }
hideakitai 0:3f9dbf1e2cb0 244
hideakitai 0:3f9dbf1e2cb0 245 static inline int template_callback_bin(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 246 {
hideakitai 0:3f9dbf1e2cb0 247 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 248 MSGPACK_UNUSED(b);
hideakitai 0:3f9dbf1e2cb0 249 o->type = MSGPACK_OBJECT_BIN;
hideakitai 0:3f9dbf1e2cb0 250 o->via.bin.ptr = p;
hideakitai 0:3f9dbf1e2cb0 251 o->via.bin.size = l;
hideakitai 0:3f9dbf1e2cb0 252 u->referenced = true;
hideakitai 0:3f9dbf1e2cb0 253 return 0;
hideakitai 0:3f9dbf1e2cb0 254 }
hideakitai 0:3f9dbf1e2cb0 255
hideakitai 0:3f9dbf1e2cb0 256 static inline int template_callback_ext(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
hideakitai 0:3f9dbf1e2cb0 257 {
hideakitai 0:3f9dbf1e2cb0 258 MSGPACK_UNUSED(u);
hideakitai 0:3f9dbf1e2cb0 259 MSGPACK_UNUSED(b);
hideakitai 0:3f9dbf1e2cb0 260 o->type = MSGPACK_OBJECT_EXT;
hideakitai 0:3f9dbf1e2cb0 261 o->via.ext.type = *p;
hideakitai 0:3f9dbf1e2cb0 262 o->via.ext.ptr = p + 1;
hideakitai 0:3f9dbf1e2cb0 263 o->via.ext.size = l - 1;
hideakitai 0:3f9dbf1e2cb0 264 u->referenced = true;
hideakitai 0:3f9dbf1e2cb0 265 return 0;
hideakitai 0:3f9dbf1e2cb0 266 }
hideakitai 0:3f9dbf1e2cb0 267
hideakitai 0:3f9dbf1e2cb0 268 #include "include/unpack_template.h"
hideakitai 0:3f9dbf1e2cb0 269
hideakitai 0:3f9dbf1e2cb0 270
hideakitai 0:3f9dbf1e2cb0 271 #define CTX_CAST(m) ((template_context*)(m))
hideakitai 0:3f9dbf1e2cb0 272 #define CTX_REFERENCED(mpac) CTX_CAST((mpac)->ctx)->user.referenced
hideakitai 0:3f9dbf1e2cb0 273
hideakitai 0:3f9dbf1e2cb0 274 #define COUNTER_SIZE (sizeof(_msgpack_atomic_counter_t))
hideakitai 0:3f9dbf1e2cb0 275
hideakitai 0:3f9dbf1e2cb0 276
hideakitai 0:3f9dbf1e2cb0 277 static inline void init_count(void* buffer)
hideakitai 0:3f9dbf1e2cb0 278 {
hideakitai 0:3f9dbf1e2cb0 279 *(volatile _msgpack_atomic_counter_t*)buffer = 1;
hideakitai 0:3f9dbf1e2cb0 280 }
hideakitai 0:3f9dbf1e2cb0 281
hideakitai 0:3f9dbf1e2cb0 282 static inline void decr_count(void* buffer)
hideakitai 0:3f9dbf1e2cb0 283 {
hideakitai 0:3f9dbf1e2cb0 284 // atomic if(--*(_msgpack_atomic_counter_t*)buffer == 0) { free(buffer); }
hideakitai 0:3f9dbf1e2cb0 285 if(_msgpack_sync_decr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer) == 0) {
hideakitai 0:3f9dbf1e2cb0 286 free(buffer);
hideakitai 0:3f9dbf1e2cb0 287 }
hideakitai 0:3f9dbf1e2cb0 288 }
hideakitai 0:3f9dbf1e2cb0 289
hideakitai 0:3f9dbf1e2cb0 290 static inline void incr_count(void* buffer)
hideakitai 0:3f9dbf1e2cb0 291 {
hideakitai 0:3f9dbf1e2cb0 292 // atomic ++*(_msgpack_atomic_counter_t*)buffer;
hideakitai 0:3f9dbf1e2cb0 293 _msgpack_sync_incr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer);
hideakitai 0:3f9dbf1e2cb0 294 }
hideakitai 0:3f9dbf1e2cb0 295
hideakitai 0:3f9dbf1e2cb0 296 static inline _msgpack_atomic_counter_t get_count(void* buffer)
hideakitai 0:3f9dbf1e2cb0 297 {
hideakitai 0:3f9dbf1e2cb0 298 return *(volatile _msgpack_atomic_counter_t*)buffer;
hideakitai 0:3f9dbf1e2cb0 299 }
hideakitai 0:3f9dbf1e2cb0 300
hideakitai 0:3f9dbf1e2cb0 301 bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size)
hideakitai 0:3f9dbf1e2cb0 302 {
hideakitai 0:3f9dbf1e2cb0 303 char* buffer;
hideakitai 0:3f9dbf1e2cb0 304 void* ctx;
hideakitai 0:3f9dbf1e2cb0 305 msgpack_zone* z;
hideakitai 0:3f9dbf1e2cb0 306
hideakitai 0:3f9dbf1e2cb0 307 if(initial_buffer_size < COUNTER_SIZE) {
hideakitai 0:3f9dbf1e2cb0 308 initial_buffer_size = COUNTER_SIZE;
hideakitai 0:3f9dbf1e2cb0 309 }
hideakitai 0:3f9dbf1e2cb0 310
hideakitai 0:3f9dbf1e2cb0 311 buffer = (char*)malloc(initial_buffer_size);
hideakitai 0:3f9dbf1e2cb0 312 if(buffer == NULL) {
hideakitai 0:3f9dbf1e2cb0 313 return false;
hideakitai 0:3f9dbf1e2cb0 314 }
hideakitai 0:3f9dbf1e2cb0 315
hideakitai 0:3f9dbf1e2cb0 316 ctx = malloc(sizeof(template_context));
hideakitai 0:3f9dbf1e2cb0 317 if(ctx == NULL) {
hideakitai 0:3f9dbf1e2cb0 318 free(buffer);
hideakitai 0:3f9dbf1e2cb0 319 return false;
hideakitai 0:3f9dbf1e2cb0 320 }
hideakitai 0:3f9dbf1e2cb0 321
hideakitai 0:3f9dbf1e2cb0 322 z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
hideakitai 0:3f9dbf1e2cb0 323 if(z == NULL) {
hideakitai 0:3f9dbf1e2cb0 324 free(ctx);
hideakitai 0:3f9dbf1e2cb0 325 free(buffer);
hideakitai 0:3f9dbf1e2cb0 326 return false;
hideakitai 0:3f9dbf1e2cb0 327 }
hideakitai 0:3f9dbf1e2cb0 328
hideakitai 0:3f9dbf1e2cb0 329 mpac->buffer = buffer;
hideakitai 0:3f9dbf1e2cb0 330 mpac->used = COUNTER_SIZE;
hideakitai 0:3f9dbf1e2cb0 331 mpac->free = initial_buffer_size - mpac->used;
hideakitai 0:3f9dbf1e2cb0 332 mpac->off = COUNTER_SIZE;
hideakitai 0:3f9dbf1e2cb0 333 mpac->parsed = 0;
hideakitai 0:3f9dbf1e2cb0 334 mpac->initial_buffer_size = initial_buffer_size;
hideakitai 0:3f9dbf1e2cb0 335 mpac->z = z;
hideakitai 0:3f9dbf1e2cb0 336 mpac->ctx = ctx;
hideakitai 0:3f9dbf1e2cb0 337
hideakitai 0:3f9dbf1e2cb0 338 init_count(mpac->buffer);
hideakitai 0:3f9dbf1e2cb0 339
hideakitai 0:3f9dbf1e2cb0 340 template_init(CTX_CAST(mpac->ctx));
hideakitai 0:3f9dbf1e2cb0 341 CTX_CAST(mpac->ctx)->user.z = mpac->z;
hideakitai 0:3f9dbf1e2cb0 342 CTX_CAST(mpac->ctx)->user.referenced = false;
hideakitai 0:3f9dbf1e2cb0 343
hideakitai 0:3f9dbf1e2cb0 344 return true;
hideakitai 0:3f9dbf1e2cb0 345 }
hideakitai 0:3f9dbf1e2cb0 346
hideakitai 0:3f9dbf1e2cb0 347 void msgpack_unpacker_destroy(msgpack_unpacker* mpac)
hideakitai 0:3f9dbf1e2cb0 348 {
hideakitai 0:3f9dbf1e2cb0 349 msgpack_zone_free(mpac->z);
hideakitai 0:3f9dbf1e2cb0 350 free(mpac->ctx);
hideakitai 0:3f9dbf1e2cb0 351 decr_count(mpac->buffer);
hideakitai 0:3f9dbf1e2cb0 352 }
hideakitai 0:3f9dbf1e2cb0 353
hideakitai 0:3f9dbf1e2cb0 354 msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size)
hideakitai 0:3f9dbf1e2cb0 355 {
hideakitai 0:3f9dbf1e2cb0 356 msgpack_unpacker* mpac = (msgpack_unpacker*)malloc(sizeof(msgpack_unpacker));
hideakitai 0:3f9dbf1e2cb0 357 if(mpac == NULL) {
hideakitai 0:3f9dbf1e2cb0 358 return NULL;
hideakitai 0:3f9dbf1e2cb0 359 }
hideakitai 0:3f9dbf1e2cb0 360
hideakitai 0:3f9dbf1e2cb0 361 if(!msgpack_unpacker_init(mpac, initial_buffer_size)) {
hideakitai 0:3f9dbf1e2cb0 362 free(mpac);
hideakitai 0:3f9dbf1e2cb0 363 return NULL;
hideakitai 0:3f9dbf1e2cb0 364 }
hideakitai 0:3f9dbf1e2cb0 365
hideakitai 0:3f9dbf1e2cb0 366 return mpac;
hideakitai 0:3f9dbf1e2cb0 367 }
hideakitai 0:3f9dbf1e2cb0 368
hideakitai 0:3f9dbf1e2cb0 369 void msgpack_unpacker_free(msgpack_unpacker* mpac)
hideakitai 0:3f9dbf1e2cb0 370 {
hideakitai 0:3f9dbf1e2cb0 371 msgpack_unpacker_destroy(mpac);
hideakitai 0:3f9dbf1e2cb0 372 free(mpac);
hideakitai 0:3f9dbf1e2cb0 373 }
hideakitai 0:3f9dbf1e2cb0 374
hideakitai 0:3f9dbf1e2cb0 375 bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size)
hideakitai 0:3f9dbf1e2cb0 376 {
hideakitai 0:3f9dbf1e2cb0 377 if(mpac->used == mpac->off && get_count(mpac->buffer) == 1
hideakitai 0:3f9dbf1e2cb0 378 && !CTX_REFERENCED(mpac)) {
hideakitai 0:3f9dbf1e2cb0 379 // rewind buffer
hideakitai 0:3f9dbf1e2cb0 380 mpac->free += mpac->used - COUNTER_SIZE;
hideakitai 0:3f9dbf1e2cb0 381 mpac->used = COUNTER_SIZE;
hideakitai 0:3f9dbf1e2cb0 382 mpac->off = COUNTER_SIZE;
hideakitai 0:3f9dbf1e2cb0 383
hideakitai 0:3f9dbf1e2cb0 384 if(mpac->free >= size) {
hideakitai 0:3f9dbf1e2cb0 385 return true;
hideakitai 0:3f9dbf1e2cb0 386 }
hideakitai 0:3f9dbf1e2cb0 387 }
hideakitai 0:3f9dbf1e2cb0 388
hideakitai 0:3f9dbf1e2cb0 389 if(mpac->off == COUNTER_SIZE) {
hideakitai 0:3f9dbf1e2cb0 390 char* tmp;
hideakitai 0:3f9dbf1e2cb0 391 size_t next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE
hideakitai 0:3f9dbf1e2cb0 392 while(next_size < size + mpac->used) {
hideakitai 0:3f9dbf1e2cb0 393 size_t tmp_next_size = next_size * 2;
hideakitai 0:3f9dbf1e2cb0 394 if (tmp_next_size <= next_size) {
hideakitai 0:3f9dbf1e2cb0 395 next_size = size + mpac->used;
hideakitai 0:3f9dbf1e2cb0 396 break;
hideakitai 0:3f9dbf1e2cb0 397 }
hideakitai 0:3f9dbf1e2cb0 398 next_size = tmp_next_size;
hideakitai 0:3f9dbf1e2cb0 399 }
hideakitai 0:3f9dbf1e2cb0 400
hideakitai 0:3f9dbf1e2cb0 401 tmp = (char*)realloc(mpac->buffer, next_size);
hideakitai 0:3f9dbf1e2cb0 402 if(tmp == NULL) {
hideakitai 0:3f9dbf1e2cb0 403 return false;
hideakitai 0:3f9dbf1e2cb0 404 }
hideakitai 0:3f9dbf1e2cb0 405
hideakitai 0:3f9dbf1e2cb0 406 mpac->buffer = tmp;
hideakitai 0:3f9dbf1e2cb0 407 mpac->free = next_size - mpac->used;
hideakitai 0:3f9dbf1e2cb0 408
hideakitai 0:3f9dbf1e2cb0 409 } else {
hideakitai 0:3f9dbf1e2cb0 410 char* tmp;
hideakitai 0:3f9dbf1e2cb0 411 size_t next_size = mpac->initial_buffer_size; // include COUNTER_SIZE
hideakitai 0:3f9dbf1e2cb0 412 size_t not_parsed = mpac->used - mpac->off;
hideakitai 0:3f9dbf1e2cb0 413 while(next_size < size + not_parsed + COUNTER_SIZE) {
hideakitai 0:3f9dbf1e2cb0 414 size_t tmp_next_size = next_size * 2;
hideakitai 0:3f9dbf1e2cb0 415 if (tmp_next_size <= next_size) {
hideakitai 0:3f9dbf1e2cb0 416 next_size = size + not_parsed + COUNTER_SIZE;
hideakitai 0:3f9dbf1e2cb0 417 break;
hideakitai 0:3f9dbf1e2cb0 418 }
hideakitai 0:3f9dbf1e2cb0 419 next_size = tmp_next_size;
hideakitai 0:3f9dbf1e2cb0 420 }
hideakitai 0:3f9dbf1e2cb0 421
hideakitai 0:3f9dbf1e2cb0 422 tmp = (char*)malloc(next_size);
hideakitai 0:3f9dbf1e2cb0 423 if(tmp == NULL) {
hideakitai 0:3f9dbf1e2cb0 424 return false;
hideakitai 0:3f9dbf1e2cb0 425 }
hideakitai 0:3f9dbf1e2cb0 426
hideakitai 0:3f9dbf1e2cb0 427 init_count(tmp);
hideakitai 0:3f9dbf1e2cb0 428
hideakitai 0:3f9dbf1e2cb0 429 memcpy(tmp+COUNTER_SIZE, mpac->buffer+mpac->off, not_parsed);
hideakitai 0:3f9dbf1e2cb0 430
hideakitai 0:3f9dbf1e2cb0 431 if(CTX_REFERENCED(mpac)) {
hideakitai 0:3f9dbf1e2cb0 432 if(!msgpack_zone_push_finalizer(mpac->z, decr_count, mpac->buffer)) {
hideakitai 0:3f9dbf1e2cb0 433 free(tmp);
hideakitai 0:3f9dbf1e2cb0 434 return false;
hideakitai 0:3f9dbf1e2cb0 435 }
hideakitai 0:3f9dbf1e2cb0 436 CTX_REFERENCED(mpac) = false;
hideakitai 0:3f9dbf1e2cb0 437 } else {
hideakitai 0:3f9dbf1e2cb0 438 decr_count(mpac->buffer);
hideakitai 0:3f9dbf1e2cb0 439 }
hideakitai 0:3f9dbf1e2cb0 440
hideakitai 0:3f9dbf1e2cb0 441 mpac->buffer = tmp;
hideakitai 0:3f9dbf1e2cb0 442 mpac->used = not_parsed + COUNTER_SIZE;
hideakitai 0:3f9dbf1e2cb0 443 mpac->free = next_size - mpac->used;
hideakitai 0:3f9dbf1e2cb0 444 mpac->off = COUNTER_SIZE;
hideakitai 0:3f9dbf1e2cb0 445 }
hideakitai 0:3f9dbf1e2cb0 446
hideakitai 0:3f9dbf1e2cb0 447 return true;
hideakitai 0:3f9dbf1e2cb0 448 }
hideakitai 0:3f9dbf1e2cb0 449
hideakitai 0:3f9dbf1e2cb0 450 int msgpack_unpacker_execute(msgpack_unpacker* mpac)
hideakitai 0:3f9dbf1e2cb0 451 {
hideakitai 0:3f9dbf1e2cb0 452 size_t off = mpac->off;
hideakitai 0:3f9dbf1e2cb0 453 int ret = template_execute(CTX_CAST(mpac->ctx),
hideakitai 0:3f9dbf1e2cb0 454 mpac->buffer, mpac->used, &mpac->off);
hideakitai 0:3f9dbf1e2cb0 455 if(mpac->off > off) {
hideakitai 0:3f9dbf1e2cb0 456 mpac->parsed += mpac->off - off;
hideakitai 0:3f9dbf1e2cb0 457 }
hideakitai 0:3f9dbf1e2cb0 458 return ret;
hideakitai 0:3f9dbf1e2cb0 459 }
hideakitai 0:3f9dbf1e2cb0 460
hideakitai 0:3f9dbf1e2cb0 461 msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac)
hideakitai 0:3f9dbf1e2cb0 462 {
hideakitai 0:3f9dbf1e2cb0 463 return template_data(CTX_CAST(mpac->ctx));
hideakitai 0:3f9dbf1e2cb0 464 }
hideakitai 0:3f9dbf1e2cb0 465
hideakitai 0:3f9dbf1e2cb0 466 msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac)
hideakitai 0:3f9dbf1e2cb0 467 {
hideakitai 0:3f9dbf1e2cb0 468 msgpack_zone* r;
hideakitai 0:3f9dbf1e2cb0 469 msgpack_zone* old;
hideakitai 0:3f9dbf1e2cb0 470
hideakitai 0:3f9dbf1e2cb0 471 if(!msgpack_unpacker_flush_zone(mpac)) {
hideakitai 0:3f9dbf1e2cb0 472 return NULL;
hideakitai 0:3f9dbf1e2cb0 473 }
hideakitai 0:3f9dbf1e2cb0 474
hideakitai 0:3f9dbf1e2cb0 475 r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
hideakitai 0:3f9dbf1e2cb0 476 if(r == NULL) {
hideakitai 0:3f9dbf1e2cb0 477 return NULL;
hideakitai 0:3f9dbf1e2cb0 478 }
hideakitai 0:3f9dbf1e2cb0 479
hideakitai 0:3f9dbf1e2cb0 480 old = mpac->z;
hideakitai 0:3f9dbf1e2cb0 481 mpac->z = r;
hideakitai 0:3f9dbf1e2cb0 482 CTX_CAST(mpac->ctx)->user.z = mpac->z;
hideakitai 0:3f9dbf1e2cb0 483
hideakitai 0:3f9dbf1e2cb0 484 return old;
hideakitai 0:3f9dbf1e2cb0 485 }
hideakitai 0:3f9dbf1e2cb0 486
hideakitai 0:3f9dbf1e2cb0 487 void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac)
hideakitai 0:3f9dbf1e2cb0 488 {
hideakitai 0:3f9dbf1e2cb0 489 msgpack_zone_clear(mpac->z);
hideakitai 0:3f9dbf1e2cb0 490 }
hideakitai 0:3f9dbf1e2cb0 491
hideakitai 0:3f9dbf1e2cb0 492 bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac)
hideakitai 0:3f9dbf1e2cb0 493 {
hideakitai 0:3f9dbf1e2cb0 494 if(CTX_REFERENCED(mpac)) {
hideakitai 0:3f9dbf1e2cb0 495 if(!msgpack_zone_push_finalizer(mpac->z, decr_count, mpac->buffer)) {
hideakitai 0:3f9dbf1e2cb0 496 return false;
hideakitai 0:3f9dbf1e2cb0 497 }
hideakitai 0:3f9dbf1e2cb0 498 CTX_REFERENCED(mpac) = false;
hideakitai 0:3f9dbf1e2cb0 499
hideakitai 0:3f9dbf1e2cb0 500 incr_count(mpac->buffer);
hideakitai 0:3f9dbf1e2cb0 501 }
hideakitai 0:3f9dbf1e2cb0 502
hideakitai 0:3f9dbf1e2cb0 503 return true;
hideakitai 0:3f9dbf1e2cb0 504 }
hideakitai 0:3f9dbf1e2cb0 505
hideakitai 0:3f9dbf1e2cb0 506 void msgpack_unpacker_reset(msgpack_unpacker* mpac)
hideakitai 0:3f9dbf1e2cb0 507 {
hideakitai 0:3f9dbf1e2cb0 508 template_init(CTX_CAST(mpac->ctx));
hideakitai 0:3f9dbf1e2cb0 509 // don't reset referenced flag
hideakitai 0:3f9dbf1e2cb0 510 mpac->parsed = 0;
hideakitai 0:3f9dbf1e2cb0 511 }
hideakitai 0:3f9dbf1e2cb0 512
hideakitai 0:3f9dbf1e2cb0 513 msgpack_unpack_return msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* result)
hideakitai 0:3f9dbf1e2cb0 514 {
hideakitai 0:3f9dbf1e2cb0 515 int ret;
hideakitai 0:3f9dbf1e2cb0 516
hideakitai 0:3f9dbf1e2cb0 517 msgpack_unpacked_destroy(result);
hideakitai 0:3f9dbf1e2cb0 518
hideakitai 0:3f9dbf1e2cb0 519 ret = msgpack_unpacker_execute(mpac);
hideakitai 0:3f9dbf1e2cb0 520
hideakitai 0:3f9dbf1e2cb0 521 if(ret < 0) {
hideakitai 0:3f9dbf1e2cb0 522 result->zone = NULL;
hideakitai 0:3f9dbf1e2cb0 523 memset(&result->data, 0, sizeof(msgpack_object));
hideakitai 0:3f9dbf1e2cb0 524 return MSGPACK_UNPACK_PARSE_ERROR;
hideakitai 0:3f9dbf1e2cb0 525 }
hideakitai 0:3f9dbf1e2cb0 526
hideakitai 0:3f9dbf1e2cb0 527 if(ret == 0) {
hideakitai 0:3f9dbf1e2cb0 528 return MSGPACK_UNPACK_CONTINUE;
hideakitai 0:3f9dbf1e2cb0 529 }
hideakitai 0:3f9dbf1e2cb0 530 result->zone = msgpack_unpacker_release_zone(mpac);
hideakitai 0:3f9dbf1e2cb0 531 result->data = msgpack_unpacker_data(mpac);
hideakitai 0:3f9dbf1e2cb0 532 msgpack_unpacker_reset(mpac);
hideakitai 0:3f9dbf1e2cb0 533
hideakitai 0:3f9dbf1e2cb0 534 return MSGPACK_UNPACK_SUCCESS;
hideakitai 0:3f9dbf1e2cb0 535 }
hideakitai 0:3f9dbf1e2cb0 536
hideakitai 0:3f9dbf1e2cb0 537
hideakitai 0:3f9dbf1e2cb0 538 msgpack_unpack_return
hideakitai 0:3f9dbf1e2cb0 539 msgpack_unpack(const char* data, size_t len, size_t* off,
hideakitai 0:3f9dbf1e2cb0 540 msgpack_zone* result_zone, msgpack_object* result)
hideakitai 0:3f9dbf1e2cb0 541 {
hideakitai 0:3f9dbf1e2cb0 542 size_t noff = 0;
hideakitai 0:3f9dbf1e2cb0 543 if(off != NULL) { noff = *off; }
hideakitai 0:3f9dbf1e2cb0 544
hideakitai 0:3f9dbf1e2cb0 545 if(len <= noff) {
hideakitai 0:3f9dbf1e2cb0 546 // FIXME
hideakitai 0:3f9dbf1e2cb0 547 return MSGPACK_UNPACK_CONTINUE;
hideakitai 0:3f9dbf1e2cb0 548 }
hideakitai 0:3f9dbf1e2cb0 549 else {
hideakitai 0:3f9dbf1e2cb0 550 int e;
hideakitai 0:3f9dbf1e2cb0 551 template_context ctx;
hideakitai 0:3f9dbf1e2cb0 552 template_init(&ctx);
hideakitai 0:3f9dbf1e2cb0 553
hideakitai 0:3f9dbf1e2cb0 554 ctx.user.z = result_zone;
hideakitai 0:3f9dbf1e2cb0 555 ctx.user.referenced = false;
hideakitai 0:3f9dbf1e2cb0 556
hideakitai 0:3f9dbf1e2cb0 557 e = template_execute(&ctx, data, len, &noff);
hideakitai 0:3f9dbf1e2cb0 558 if(e < 0) {
hideakitai 0:3f9dbf1e2cb0 559 return MSGPACK_UNPACK_PARSE_ERROR;
hideakitai 0:3f9dbf1e2cb0 560 }
hideakitai 0:3f9dbf1e2cb0 561
hideakitai 0:3f9dbf1e2cb0 562 if(off != NULL) { *off = noff; }
hideakitai 0:3f9dbf1e2cb0 563
hideakitai 0:3f9dbf1e2cb0 564 if(e == 0) {
hideakitai 0:3f9dbf1e2cb0 565 return MSGPACK_UNPACK_CONTINUE;
hideakitai 0:3f9dbf1e2cb0 566 }
hideakitai 0:3f9dbf1e2cb0 567
hideakitai 0:3f9dbf1e2cb0 568 *result = template_data(&ctx);
hideakitai 0:3f9dbf1e2cb0 569
hideakitai 0:3f9dbf1e2cb0 570 if(noff < len) {
hideakitai 0:3f9dbf1e2cb0 571 return MSGPACK_UNPACK_EXTRA_BYTES;
hideakitai 0:3f9dbf1e2cb0 572 }
hideakitai 0:3f9dbf1e2cb0 573
hideakitai 0:3f9dbf1e2cb0 574 return MSGPACK_UNPACK_SUCCESS;
hideakitai 0:3f9dbf1e2cb0 575 }
hideakitai 0:3f9dbf1e2cb0 576 }
hideakitai 0:3f9dbf1e2cb0 577
hideakitai 0:3f9dbf1e2cb0 578 msgpack_unpack_return
hideakitai 0:3f9dbf1e2cb0 579 msgpack_unpack_next(msgpack_unpacked* result,
hideakitai 0:3f9dbf1e2cb0 580 const char* data, size_t len, size_t* off)
hideakitai 0:3f9dbf1e2cb0 581 {
hideakitai 0:3f9dbf1e2cb0 582 size_t noff = 0;
hideakitai 0:3f9dbf1e2cb0 583 msgpack_unpacked_destroy(result);
hideakitai 0:3f9dbf1e2cb0 584
hideakitai 0:3f9dbf1e2cb0 585 if(off != NULL) { noff = *off; }
hideakitai 0:3f9dbf1e2cb0 586
hideakitai 0:3f9dbf1e2cb0 587 if(len <= noff) {
hideakitai 0:3f9dbf1e2cb0 588 return MSGPACK_UNPACK_CONTINUE;
hideakitai 0:3f9dbf1e2cb0 589 }
hideakitai 0:3f9dbf1e2cb0 590
hideakitai 0:3f9dbf1e2cb0 591 if (!result->zone) {
hideakitai 0:3f9dbf1e2cb0 592 result->zone = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
hideakitai 0:3f9dbf1e2cb0 593 }
hideakitai 0:3f9dbf1e2cb0 594
hideakitai 0:3f9dbf1e2cb0 595 if (!result->zone) {
hideakitai 0:3f9dbf1e2cb0 596 return MSGPACK_UNPACK_NOMEM_ERROR;
hideakitai 0:3f9dbf1e2cb0 597 }
hideakitai 0:3f9dbf1e2cb0 598 else {
hideakitai 0:3f9dbf1e2cb0 599 int e;
hideakitai 0:3f9dbf1e2cb0 600 template_context ctx;
hideakitai 0:3f9dbf1e2cb0 601 template_init(&ctx);
hideakitai 0:3f9dbf1e2cb0 602
hideakitai 0:3f9dbf1e2cb0 603 ctx.user.z = result->zone;
hideakitai 0:3f9dbf1e2cb0 604 ctx.user.referenced = false;
hideakitai 0:3f9dbf1e2cb0 605
hideakitai 0:3f9dbf1e2cb0 606 e = template_execute(&ctx, data, len, &noff);
hideakitai 0:3f9dbf1e2cb0 607 if(e < 0) {
hideakitai 0:3f9dbf1e2cb0 608 msgpack_zone_free(result->zone);
hideakitai 0:3f9dbf1e2cb0 609 result->zone = NULL;
hideakitai 0:3f9dbf1e2cb0 610 return MSGPACK_UNPACK_PARSE_ERROR;
hideakitai 0:3f9dbf1e2cb0 611 }
hideakitai 0:3f9dbf1e2cb0 612
hideakitai 0:3f9dbf1e2cb0 613
hideakitai 0:3f9dbf1e2cb0 614 if(e == 0) {
hideakitai 0:3f9dbf1e2cb0 615 return MSGPACK_UNPACK_CONTINUE;
hideakitai 0:3f9dbf1e2cb0 616 }
hideakitai 0:3f9dbf1e2cb0 617
hideakitai 0:3f9dbf1e2cb0 618 if(off != NULL) { *off = noff; }
hideakitai 0:3f9dbf1e2cb0 619
hideakitai 0:3f9dbf1e2cb0 620 result->data = template_data(&ctx);
hideakitai 0:3f9dbf1e2cb0 621
hideakitai 0:3f9dbf1e2cb0 622 return MSGPACK_UNPACK_SUCCESS;
hideakitai 0:3f9dbf1e2cb0 623 }
hideakitai 0:3f9dbf1e2cb0 624 }
hideakitai 0:3f9dbf1e2cb0 625
hideakitai 0:3f9dbf1e2cb0 626 #if defined(MSGPACK_OLD_COMPILER_BUS_ERROR_WORKAROUND)
hideakitai 0:3f9dbf1e2cb0 627 // FIXME: Dirty hack to avoid a bus error caused by OS X's old gcc.
hideakitai 0:3f9dbf1e2cb0 628 static void dummy_function_to_avoid_bus_error()
hideakitai 0:3f9dbf1e2cb0 629 {
hideakitai 0:3f9dbf1e2cb0 630 }
hideakitai 0:3f9dbf1e2cb0 631 #endif