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