blob: b2f29f630ebe3a0852ba3b6146d49724b9ba8c8b [file] [log] [blame]
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08001/* CWPack - cwpack_defines.h */
2/*
3 The MIT License (MIT)
4
5 Copyright (c) 2017 Claes Wihlborg
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy of this
8 software and associated documentation files (the "Software"), to deal in the Software
9 without restriction, including without limitation the rights to use, copy, modify,
10 merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
11 persons to whom the Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in all copies or
14 substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
17 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23
24#ifndef cwpack_defines_h
25#define cwpack_defines_h
26
27
28
29/************************* A L I G N M E N T ******************************/
30
31/*
32 * Sometime the processor demands that integer access is to an even memory address.
33 * In that case define FORCE_ALIGNMENT
34 */
35
36/* #define FORCE_ALIGNMENT */
37
38
39/************************* C S Y S T E M L I B R A R Y ****************/
40
41/*
42 * The packer uses "memcpy" to move blobs. If you dont want to load C system library
43 * for just that, define FORCE_NO_LIBRARY and CWPack will use an internal "memcpy"
44 */
45
46/* #define FORCE_NO_LIBRARY */
47
48
49
50/************************* B Y T E O R D E R ****************************/
51
52/*
53 * The pack/unpack routines are written in three versions: for big endian, for
54 * little endian and insensitive to byte order. As you can get some speed gain
55 * if the byte order is known, we try that when we can certainly detect it.
56 * Define COMPILE_FOR_BIG_ENDIAN or COMPILE_FOR_LITTLE_ENDIAN if you know.
57 */
58
59#ifndef FORCE_ALIGNMENT
60#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__)
61
62#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
63#define COMPILE_FOR_BIG_ENDIAN
64#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
65#define COMPILE_FOR_LITTLE_ENDIAN
66#endif
67
68#elif defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
69
70#if __BYTE_ORDER == __BIG_ENDIAN
71#define COMPILE_FOR_BIG_ENDIAN
72#elif __BYTE_ORDER == __LITTLE_ENDIAN
73#define COMPILE_FOR_LITTLE_ENDIAN
74#endif
75
76#elif defined(__BIG_ENDIAN__)
77#define COMPILE_FOR_BIG_ENDIAN
78
79#elif defined(__LITTLE_ENDIAN__)
80#define COMPILE_FOR_LITTLE_ENDIAN
81
82#elif defined(__i386__) || defined(__x86_64__)
83#define COMPILE_FOR_LITTLE_ENDIAN
84
85#endif
86#endif
87
88//zzq add
89#include "stdint.h"
90
91//#undef COMPILE_FOR_LITTLE_ENDIAN
92
93
94/******************************* P A C K **********************************/
95
96
97
98#define PACK_ERROR(error_code) \
99{ \
100 pack_context->return_code = error_code; \
101 return; \
102}
103
104
105
106#ifdef COMPILE_FOR_BIG_ENDIAN
107
108#define cw_store16(x) *(uint16_t*)p = *(uint16_t*)&x;
109#define cw_store32(x) *(uint32_t*)p = *(uint32_t*)&x;
110#define cw_store64(x) *(uint64_t*)p = *(uint64_t*)&x;
111
112#else /* Byte order little endian or undetermined */
113
114#ifdef COMPILE_FOR_LITTLE_ENDIAN
115
116#define cw_store16(d) \
117 *(uint16_t*)p = (uint16_t)((((d) >> 8) & 0x0ff) | (d) << 8)
118
119#define cw_store32(x) \
120 *(uint32_t*)p = \
121 ((uint32_t)((((uint32_t)(x)) >> 24) | \
122 (((uint32_t)(x) & 0x00ff0000) >> 8) | \
123 (((uint32_t)(x) & 0x0000ff00) << 8) | \
124 (((uint32_t)(x)) << 24))); \
125
126#define cw_store64(x) \
127 *(uint64_t*)p = \
128 ((uint64_t)( \
129 (((((uint64_t)(x)) >> 40) | \
130 (((uint64_t)(x)) << 24)) & 0x0000ff000000ff00ULL) | \
131 (((((uint64_t)(x)) >> 24) | \
132 (((uint64_t)(x)) << 40)) & 0x00ff000000ff0000ULL) | \
133 (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
134 (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
135 (((uint64_t)(x)) >> 56) | \
136 (((uint64_t)(x)) << 56))); \
137
138#else /* Byte order undetermined */
139
140#define cw_store16(d) \
141 *p = (uint8_t)(d >> 8); \
142 p[1] = (uint8_t)d;
143
144#define cw_store32(d) \
145 *p = (uint8_t)(d >> 24); \
146 p[1] = (uint8_t)(d >> 16); \
147 p[2] = (uint8_t)(d >> 8); \
148 p[3] = (uint8_t)d;
149
150#define cw_store64(z) \
151 *p = (uint8_t)(z >> 56); \
152 p[1] = (uint8_t)(z >> 48); \
153 p[2] = (uint8_t)(z >> 40); \
154 p[3] = (uint8_t)(z >> 32); \
155 p[4] = (uint8_t)(z >> 24); \
156 p[5] = (uint8_t)(z >> 16); \
157 p[6] = (uint8_t)(z >> 8); \
158 p[7] = (uint8_t)z;
159#endif
160#endif
161
162
163
164#define cw_pack_reserve_space(more) \
165{ \
166 p = pack_context->current; \
167 uint8_t* nyp = p + more; \
168 if (nyp > pack_context->end) \
169 { \
170 if (!pack_context->handle_pack_overflow) \
171 PACK_ERROR(CWP_RC_BUFFER_OVERFLOW) \
172 int rc = pack_context->handle_pack_overflow (pack_context, (unsigned long)(more)); \
173 if (rc) \
174 PACK_ERROR(rc) \
175 p = pack_context->current; \
176 nyp = p + more; \
177 } \
178 pack_context->current = nyp; \
179}
180
181
182#define tryMove0(t) \
183{ \
184 uint8_t *p; \
185 cw_pack_reserve_space(1) \
186 *p = (uint8_t)(t); \
187 return; \
188}
189
190#define tryMove1(t,d) \
191{ \
192 uint8_t *p; \
193 cw_pack_reserve_space(2) \
194 *p++ = (uint8_t)t; \
195 *p = (uint8_t)d; \
196 return; \
197}
198
199#define tryMove2(t,d) \
200{ \
201 uint8_t *p; \
202 cw_pack_reserve_space(3) \
203 *p++ = (uint8_t)t; \
204 cw_store16(d); \
205 return; \
206}
207
208#define tryMove4(t,d) \
209{ \
210 uint8_t *p; \
211 cw_pack_reserve_space(5) \
212 *p++ = (uint8_t)t; \
213 cw_store32(d); \
214 return; \
215}
216
217#define tryMove8(t,d) \
218{ \
219 uint8_t *p; \
220 cw_pack_reserve_space(9) \
221 *p++ = (uint8_t)t; \
222 cw_store64(d); \
223 return; \
224}
225
226
227
228
229/******************************* U N P A C K **********************************/
230
231
232
233#define UNPACK_ERROR(error_code) \
234{ \
235 unpack_context->item.type = CWP_NOT_AN_ITEM; \
236 unpack_context->return_code = error_code; \
237 return; \
238}
239
240
241
242#ifdef COMPILE_FOR_BIG_ENDIAN
243
244#define cw_load16(ptr) tmpu16 = *(uint16_t*)ptr;
245#define cw_load32(ptr) tmpu32 = *(uint32_t*)ptr;
246#define cw_load64(ptr) tmpu64 = *(uint64_t*)ptr;
247
248#else /* Byte order little endian or undetermined */
249
250#ifdef COMPILE_FOR_LITTLE_ENDIAN
251
252#define cw_load16(ptr) \
253 tmpu16 = *(uint16_t*)ptr; \
254 tmpu16 = (uint16_t)((tmpu16<<8) | (tmpu16>>8))
255
256#define cw_load32(ptr) \
257 tmpu32 = *(uint32_t*)ptr; \
258 tmpu32 = (tmpu32<<24) | ((tmpu32 & 0xff00)<<8) | \
259 ((tmpu32 & 0xff0000)>>8) | (tmpu32>>24)
260
261#define cw_load64(ptr) \
262 tmpu64 = *((uint64_t*)ptr); \
263 tmpu64 = ( \
264 (((tmpu64 >> 40) | \
265 (tmpu64 << 24)) & 0x0000ff000000ff00ULL) | \
266 (((tmpu64 >> 24) | \
267 (tmpu64 << 40)) & 0x00ff000000ff0000ULL) | \
268 ((tmpu64 & 0x000000ff00000000ULL) >> 8) | \
269 ((tmpu64 & 0x00000000ff000000ULL) << 8) | \
270 (tmpu64 >> 56) | \
271 (tmpu64 << 56) )
272
273#else /* Byte order undetermined */
274
275#define cw_load16(ptr) \
276 tmpu16 = (uint16_t)((*ptr++) << 8); \
277 tmpu16 |= (uint16_t)(*ptr++)
278
279#define cw_load32(ptr) \
280 tmpu32 = (uint32_t)(*ptr++ << 24); \
281 tmpu32 |= (uint32_t)(*ptr++ << 16); \
282 tmpu32 |= (uint32_t)(*ptr++ << 8); \
283 tmpu32 |= (uint32_t)(*ptr++)
284
285#define cw_load64(ptr) \
286 tmpu64 = ((uint64_t)*ptr++) << 56; \
287 tmpu64 |= ((uint64_t)*ptr++) << 48; \
288 tmpu64 |= ((uint64_t)*ptr++) << 40; \
289 tmpu64 |= ((uint64_t)*ptr++) << 32; \
290 tmpu64 |= ((uint64_t)*ptr++) << 24; \
291 tmpu64 |= ((uint64_t)*ptr++) << 16; \
292 tmpu64 |= ((uint64_t)*ptr++) << 8; \
293 tmpu64 |= (uint64_t)*ptr++
294
295#endif
296#endif
297
298
299
300#define cw_unpack_assert_space(more) \
301{ \
302 p = unpack_context->current; \
303 uint8_t* nyp = p + more; \
304 if (nyp > unpack_context->end) \
305 { \
306 if (!unpack_context->handle_unpack_underflow) \
307 UNPACK_ERROR(buffer_end_return_code) \
308 int rc = unpack_context->handle_unpack_underflow (unpack_context, (unsigned long)(more)); \
309 if (rc != CWP_RC_OK) \
310 { \
311 if (rc != CWP_RC_END_OF_INPUT) \
312 UNPACK_ERROR(rc) \
313 else \
314 UNPACK_ERROR(buffer_end_return_code) \
315 } \
316 p = unpack_context->current; \
317 nyp = p + more; \
318 } \
319 unpack_context->current = nyp; \
320}
321
322
323#define cw_unpack_assert_blob(blob) \
324 cw_unpack_assert_space(unpack_context->item.as.blob.length); \
325 unpack_context->item.as.blob.start = p; \
326 return;
327
328
329#define getDDItem(typ,var,val) \
330 unpack_context->item.type = typ; \
331 unpack_context->item.as.var = val;
332
333#define getDDItem1(typ,var,cast) \
334 unpack_context->item.type = typ; \
335 cw_unpack_assert_space(1); \
336 unpack_context->item.as.var = (cast)*p;
337
338#define getDDItem2(typ,var,cast) \
339 unpack_context->item.type = typ; \
340 cw_unpack_assert_space(2); \
341 cw_load16(p); \
342 unpack_context->item.as.var = (cast)tmpu16;
343
344#define getDDItem4(typ,var,cast) \
345 unpack_context->item.type = typ; \
346 cw_unpack_assert_space(4); \
347 cw_load32(p); \
348 unpack_context->item.as.var = (cast)tmpu32;
349
350#define getDDItem8(typ) \
351 unpack_context->item.type = typ; \
352 cw_unpack_assert_space(8); \
353 cw_load64(p); \
354 unpack_context->item.as.u64 = tmpu64;
355
356#define getDDItemFix(len) \
357 cw_unpack_assert_space(1); \
358 unpack_context->item.type = *(int8_t*)p; \
359 unpack_context->item.as.ext.length = len; \
360 cw_unpack_assert_blob(ext);
361
362
363
364
365#endif /* cwpack_defines_h */