blob: 4f4ab574f4df7b484514a74a836adf043bbe648f [file] [log] [blame]
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08001/* CWPack - cwpack_defines.h */
2/*
3 The MIT License (MIT)
guangcheng.qinf87ed972019-08-30 10:50:01 +08004
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08005 Copyright (c) 2017 Claes Wihlborg
guangcheng.qinf87ed972019-08-30 10:50:01 +08006
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08007 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:
guangcheng.qinf87ed972019-08-30 10:50:01 +080012
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080013 The above copyright notice and this permission notice shall be included in all copies or
14 substantial portions of the Software.
guangcheng.qinf87ed972019-08-30 10:50:01 +080015
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080016 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 */
guangcheng.qinf87ed972019-08-30 10:50:01 +080037
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080038
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/*
guangcheng.qinf87ed972019-08-30 10:50:01 +080053 * The pack/unpack routines are written in three versions: for big endian, for
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080054 * 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) \
guangcheng.qinf87ed972019-08-30 10:50:01 +080099 { \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800100 pack_context->return_code = error_code; \
101 return; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800102 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800103
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) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800117 *(uint16_t*)p = (uint16_t)((((d) >> 8) & 0x0ff) | (d) << 8)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800118
119#define cw_store32(x) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800120 *(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))); \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800125
126#define cw_store64(x) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800127 *(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))); \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800137
138#else /* Byte order undetermined */
139
140#define cw_store16(d) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800141 *p = (uint8_t)(d >> 8); \
142 p[1] = (uint8_t)d;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800143
144#define cw_store32(d) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800145 *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;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800149
150#define cw_store64(z) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800151 *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;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800159#endif
160#endif
161
162
163
164#define cw_pack_reserve_space(more) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800165 { \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800166 p = pack_context->current; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800167 nyp = p + more; \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800168 if (nyp > pack_context->end) \
169 { \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800170 if (!pack_context->handle_pack_overflow) \
171 PACK_ERROR(CWP_RC_BUFFER_OVERFLOW) \
172 rc = pack_context->handle_pack_overflow (pack_context, (unsigned long)(more)); \
173 if (rc) \
174 PACK_ERROR(rc) \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800175 p = pack_context->current; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800176 nyp = p + more; \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800177 } \
178 pack_context->current = nyp; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800179 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800180
181
182#define tryMove0(t) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800183 { \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800184 cw_pack_reserve_space(1) \
185 *p = (uint8_t)(t); \
186 return; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800187 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800188
189#define tryMove1(t,d) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800190 { \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800191 cw_pack_reserve_space(2) \
192 *p++ = (uint8_t)t; \
193 *p = (uint8_t)d; \
194 return; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800195 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800196
197#define tryMove2(t,d) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800198 { \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800199 cw_pack_reserve_space(3) \
200 *p++ = (uint8_t)t; \
201 cw_store16(d); \
202 return; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800203 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800204
205#define tryMove4(t,d) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800206 { \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800207 cw_pack_reserve_space(5) \
208 *p++ = (uint8_t)t; \
209 cw_store32(d); \
210 return; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800211 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800212
213#define tryMove8(t,d) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800214 { \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800215 cw_pack_reserve_space(9) \
216 *p++ = (uint8_t)t; \
217 cw_store64(d); \
218 return; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800219 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800220
221
222
223
224/******************************* U N P A C K **********************************/
225
226
227
228#define UNPACK_ERROR(error_code) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800229 { \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800230 unpack_context->item.type = CWP_NOT_AN_ITEM; \
231 unpack_context->return_code = error_code; \
232 return; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800233 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800234
235
236
237#ifdef COMPILE_FOR_BIG_ENDIAN
238
239#define cw_load16(ptr) tmpu16 = *(uint16_t*)ptr;
240#define cw_load32(ptr) tmpu32 = *(uint32_t*)ptr;
241#define cw_load64(ptr) tmpu64 = *(uint64_t*)ptr;
242
243#else /* Byte order little endian or undetermined */
244
245#ifdef COMPILE_FOR_LITTLE_ENDIAN
246
247#define cw_load16(ptr) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800248 tmpu16 = *(uint16_t*)ptr; \
249 tmpu16 = (uint16_t)((tmpu16<<8) | (tmpu16>>8))
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800250
251#define cw_load32(ptr) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800252 tmpu32 = *(uint32_t*)ptr; \
253 tmpu32 = (tmpu32<<24) | ((tmpu32 & 0xff00)<<8) | \
254 ((tmpu32 & 0xff0000)>>8) | (tmpu32>>24)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800255
256#define cw_load64(ptr) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800257 tmpu64 = *((uint64_t*)ptr); \
258 tmpu64 = ( \
259 (((tmpu64 >> 40) | \
260 (tmpu64 << 24)) & 0x0000ff000000ff00ULL) | \
261 (((tmpu64 >> 24) | \
262 (tmpu64 << 40)) & 0x00ff000000ff0000ULL) | \
263 ((tmpu64 & 0x000000ff00000000ULL) >> 8) | \
264 ((tmpu64 & 0x00000000ff000000ULL) << 8) | \
265 (tmpu64 >> 56) | \
266 (tmpu64 << 56) )
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800267
268#else /* Byte order undetermined */
269
270#define cw_load16(ptr) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800271 tmpu16 = (uint16_t)((*ptr++) << 8); \
272 tmpu16 |= (uint16_t)(*ptr++)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800273
274#define cw_load32(ptr) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800275 tmpu32 = (uint32_t)(*ptr++ << 24); \
276 tmpu32 |= (uint32_t)(*ptr++ << 16); \
277 tmpu32 |= (uint32_t)(*ptr++ << 8); \
278 tmpu32 |= (uint32_t)(*ptr++)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800279
280#define cw_load64(ptr) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800281 tmpu64 = ((uint64_t)*ptr++) << 56; \
282 tmpu64 |= ((uint64_t)*ptr++) << 48; \
283 tmpu64 |= ((uint64_t)*ptr++) << 40; \
284 tmpu64 |= ((uint64_t)*ptr++) << 32; \
285 tmpu64 |= ((uint64_t)*ptr++) << 24; \
286 tmpu64 |= ((uint64_t)*ptr++) << 16; \
287 tmpu64 |= ((uint64_t)*ptr++) << 8; \
288 tmpu64 |= (uint64_t)*ptr++
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800289
290#endif
291#endif
292
293
294
295#define cw_unpack_assert_space(more) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800296 { \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800297 p = unpack_context->current; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800298 nyp = p + more; \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800299 if (nyp > unpack_context->end) \
300 { \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800301 if (!unpack_context->handle_unpack_underflow) \
302 UNPACK_ERROR(buffer_end_return_code) \
303 rc = unpack_context->handle_unpack_underflow (unpack_context, (unsigned long)(more)); \
304 if (rc != CWP_RC_OK) \
305 { \
306 if (rc != CWP_RC_END_OF_INPUT) \
307 UNPACK_ERROR(rc) \
308 else \
309 UNPACK_ERROR(buffer_end_return_code) \
310 } \
311 p = unpack_context->current; \
312 nyp = p + more; \
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800313 } \
314 unpack_context->current = nyp; \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800315 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800316
317
318#define cw_unpack_assert_blob(blob) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800319 cw_unpack_assert_space(unpack_context->item.as.blob.length); \
320 unpack_context->item.as.blob.start = p; \
321 return;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800322
323
324#define getDDItem(typ,var,val) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800325 unpack_context->item.type = typ; \
326 unpack_context->item.as.var = val;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800327
328#define getDDItem1(typ,var,cast) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800329 unpack_context->item.type = typ; \
330 cw_unpack_assert_space(1); \
331 unpack_context->item.as.var = (cast)*p;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800332
333#define getDDItem2(typ,var,cast) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800334 unpack_context->item.type = typ; \
335 cw_unpack_assert_space(2); \
336 cw_load16(p); \
337 unpack_context->item.as.var = (cast)tmpu16;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800338
339#define getDDItem4(typ,var,cast) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800340 unpack_context->item.type = typ; \
341 cw_unpack_assert_space(4); \
342 cw_load32(p); \
343 unpack_context->item.as.var = (cast)tmpu32;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800344
345#define getDDItem8(typ) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800346 unpack_context->item.type = typ; \
347 cw_unpack_assert_space(8); \
348 cw_load64(p); \
349 unpack_context->item.as.u64 = tmpu64;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800350
351#define getDDItemFix(len) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800352 cw_unpack_assert_space(1); \
353 unpack_context->item.type = *(int8_t*)p; \
354 unpack_context->item.as.ext.length = len; \
355 cw_unpack_assert_blob(ext);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800356
357
358
359
360#endif /* cwpack_defines_h */