Commit | Line | Data |
---|---|---|
116a02e3 JG |
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 | #ifndef MSGPACK_UNPACKER_H | |
11 | #define MSGPACK_UNPACKER_H | |
12 | ||
13 | #include "zone.h" | |
14 | #include "object.h" | |
15 | #include <string.h> | |
16 | ||
17 | #ifdef __cplusplus | |
18 | extern "C" { | |
19 | #endif | |
20 | ||
21 | ||
22 | /** | |
23 | * @defgroup msgpack_unpack Deserializer | |
24 | * @ingroup msgpack | |
25 | * @{ | |
26 | */ | |
27 | ||
28 | typedef struct msgpack_unpacked { | |
29 | msgpack_zone* zone; | |
30 | msgpack_object data; | |
31 | } msgpack_unpacked; | |
32 | ||
33 | typedef enum { | |
34 | MSGPACK_UNPACK_SUCCESS = 2, | |
35 | MSGPACK_UNPACK_EXTRA_BYTES = 1, | |
36 | MSGPACK_UNPACK_CONTINUE = 0, | |
37 | MSGPACK_UNPACK_PARSE_ERROR = -1, | |
38 | MSGPACK_UNPACK_NOMEM_ERROR = -2 | |
39 | } msgpack_unpack_return; | |
40 | ||
41 | ||
42 | MSGPACK_DLLEXPORT | |
43 | msgpack_unpack_return | |
44 | msgpack_unpack_next(msgpack_unpacked* result, | |
45 | const char* data, size_t len, size_t* off); | |
46 | ||
47 | /** @} */ | |
48 | ||
49 | ||
50 | /** | |
51 | * @defgroup msgpack_unpacker Streaming deserializer | |
52 | * @ingroup msgpack | |
53 | * @{ | |
54 | */ | |
55 | ||
56 | typedef struct msgpack_unpacker { | |
57 | char* buffer; | |
58 | size_t used; | |
59 | size_t free; | |
60 | size_t off; | |
61 | size_t parsed; | |
62 | msgpack_zone* z; | |
63 | size_t initial_buffer_size; | |
64 | void* ctx; | |
65 | } msgpack_unpacker; | |
66 | ||
67 | ||
68 | #ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE | |
69 | #define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (64*1024) | |
70 | #endif | |
71 | ||
72 | /** | |
73 | * Initializes a streaming deserializer. | |
74 | * The initialized deserializer must be destroyed by msgpack_unpacker_destroy(msgpack_unpacker*). | |
75 | */ | |
76 | MSGPACK_DLLEXPORT | |
77 | bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size); | |
78 | ||
79 | /** | |
80 | * Destroys a streaming deserializer initialized by msgpack_unpacker_init(msgpack_unpacker*, size_t). | |
81 | */ | |
82 | MSGPACK_DLLEXPORT | |
83 | void msgpack_unpacker_destroy(msgpack_unpacker* mpac); | |
84 | ||
85 | ||
86 | /** | |
87 | * Creates a streaming deserializer. | |
88 | * The created deserializer must be destroyed by msgpack_unpacker_free(msgpack_unpacker*). | |
89 | */ | |
90 | MSGPACK_DLLEXPORT | |
91 | msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size); | |
92 | ||
93 | /** | |
94 | * Frees a streaming deserializer created by msgpack_unpacker_new(size_t). | |
95 | */ | |
96 | MSGPACK_DLLEXPORT | |
97 | void msgpack_unpacker_free(msgpack_unpacker* mpac); | |
98 | ||
99 | ||
100 | #ifndef MSGPACK_UNPACKER_RESERVE_SIZE | |
101 | #define MSGPACK_UNPACKER_RESERVE_SIZE (32*1024) | |
102 | #endif | |
103 | ||
104 | /** | |
105 | * Reserves free space of the internal buffer. | |
106 | * Use this function to fill the internal buffer with | |
107 | * msgpack_unpacker_buffer(msgpack_unpacker*), | |
108 | * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and | |
109 | * msgpack_unpacker_buffer_consumed(msgpack_unpacker*). | |
110 | */ | |
111 | static inline bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size); | |
112 | ||
113 | /** | |
114 | * Gets pointer to the free space of the internal buffer. | |
115 | * Use this function to fill the internal buffer with | |
116 | * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t), | |
117 | * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and | |
118 | * msgpack_unpacker_buffer_consumed(msgpack_unpacker*). | |
119 | */ | |
120 | static inline char* msgpack_unpacker_buffer(msgpack_unpacker* mpac); | |
121 | ||
122 | /** | |
123 | * Gets size of the free space of the internal buffer. | |
124 | * Use this function to fill the internal buffer with | |
125 | * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t), | |
126 | * msgpack_unpacker_buffer(const msgpack_unpacker*) and | |
127 | * msgpack_unpacker_buffer_consumed(msgpack_unpacker*). | |
128 | */ | |
129 | static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac); | |
130 | ||
131 | /** | |
132 | * Notifies the deserializer that the internal buffer filled. | |
133 | * Use this function to fill the internal buffer with | |
134 | * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t), | |
135 | * msgpack_unpacker_buffer(msgpack_unpacker*) and | |
136 | * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*). | |
137 | */ | |
138 | static inline void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size); | |
139 | ||
140 | ||
141 | /** | |
142 | * Deserializes one object. | |
143 | * Returns true if it successes. Otherwise false is returned. | |
144 | * @param pac pointer to an initialized msgpack_unpacked object. | |
145 | */ | |
146 | MSGPACK_DLLEXPORT | |
147 | msgpack_unpack_return msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* pac); | |
148 | ||
149 | /** | |
150 | * Deserializes one object and set the number of parsed bytes involved. | |
151 | * Returns true if it successes. Otherwise false is returned. | |
152 | * @param mpac pointer to an initialized msgpack_unpacker object. | |
153 | * @param result pointer to an initialized msgpack_unpacked object. | |
154 | * @param p_bytes pointer to variable that will be set with the number of parsed bytes. | |
155 | */ | |
156 | MSGPACK_DLLEXPORT | |
157 | msgpack_unpack_return msgpack_unpacker_next_with_size(msgpack_unpacker* mpac, | |
158 | msgpack_unpacked* result, | |
159 | size_t *p_bytes); | |
160 | ||
161 | /** | |
162 | * Initializes a msgpack_unpacked object. | |
163 | * The initialized object must be destroyed by msgpack_unpacked_destroy(msgpack_unpacker*). | |
164 | * Use the object with msgpack_unpacker_next(msgpack_unpacker*, msgpack_unpacked*) or | |
165 | * msgpack_unpack_next(msgpack_unpacked*, const char*, size_t, size_t*). | |
166 | */ | |
167 | static inline void msgpack_unpacked_init(msgpack_unpacked* result); | |
168 | ||
169 | /** | |
170 | * Destroys a streaming deserializer initialized by msgpack_unpacked(). | |
171 | */ | |
172 | static inline void msgpack_unpacked_destroy(msgpack_unpacked* result); | |
173 | ||
174 | /** | |
175 | * Releases the memory zone from msgpack_unpacked object. | |
176 | * The released zone must be freed by msgpack_zone_free(msgpack_zone*). | |
177 | */ | |
178 | static inline msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result); | |
179 | ||
180 | ||
181 | MSGPACK_DLLEXPORT | |
182 | int msgpack_unpacker_execute(msgpack_unpacker* mpac); | |
183 | ||
184 | MSGPACK_DLLEXPORT | |
185 | msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac); | |
186 | ||
187 | MSGPACK_DLLEXPORT | |
188 | msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac); | |
189 | ||
190 | MSGPACK_DLLEXPORT | |
191 | void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac); | |
192 | ||
193 | MSGPACK_DLLEXPORT | |
194 | void msgpack_unpacker_reset(msgpack_unpacker* mpac); | |
195 | ||
196 | static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac); | |
197 | ||
198 | ||
199 | /** @} */ | |
200 | ||
201 | ||
202 | // obsolete | |
203 | MSGPACK_DLLEXPORT | |
204 | msgpack_unpack_return | |
205 | msgpack_unpack(const char* data, size_t len, size_t* off, | |
206 | msgpack_zone* result_zone, msgpack_object* result); | |
207 | ||
208 | ||
209 | ||
210 | ||
211 | static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac); | |
212 | ||
213 | MSGPACK_DLLEXPORT | |
214 | bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac); | |
215 | ||
216 | MSGPACK_DLLEXPORT | |
217 | bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size); | |
218 | ||
219 | static inline bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size) | |
220 | { | |
221 | if(mpac->free >= size) { return true; } | |
222 | return msgpack_unpacker_expand_buffer(mpac, size); | |
223 | } | |
224 | ||
225 | static inline char* msgpack_unpacker_buffer(msgpack_unpacker* mpac) | |
226 | { | |
227 | return mpac->buffer + mpac->used; | |
228 | } | |
229 | ||
230 | static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac) | |
231 | { | |
232 | return mpac->free; | |
233 | } | |
234 | ||
235 | static inline void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size) | |
236 | { | |
237 | mpac->used += size; | |
238 | mpac->free -= size; | |
239 | } | |
240 | ||
241 | static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac) | |
242 | { | |
243 | return mpac->parsed - mpac->off + mpac->used; | |
244 | } | |
245 | ||
246 | static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac) | |
247 | { | |
248 | return mpac->parsed; | |
249 | } | |
250 | ||
251 | ||
252 | static inline void msgpack_unpacked_init(msgpack_unpacked* result) | |
253 | { | |
254 | memset(result, 0, sizeof(msgpack_unpacked)); | |
255 | } | |
256 | ||
257 | static inline void msgpack_unpacked_destroy(msgpack_unpacked* result) | |
258 | { | |
259 | if(result->zone != NULL) { | |
260 | msgpack_zone_free(result->zone); | |
261 | result->zone = NULL; | |
262 | memset(&result->data, 0, sizeof(msgpack_object)); | |
263 | } | |
264 | } | |
265 | ||
266 | static inline msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result) | |
267 | { | |
268 | if(result->zone != NULL) { | |
269 | msgpack_zone* z = result->zone; | |
270 | result->zone = NULL; | |
271 | return z; | |
272 | } | |
273 | return NULL; | |
274 | } | |
275 | ||
276 | ||
277 | #ifdef __cplusplus | |
278 | } | |
279 | #endif | |
280 | ||
281 | #endif /* msgpack/unpack.h */ |