0.9.8.10
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Modules
Pages
home
doug
src
hypertable
src
cc
Common
serialization-c.h
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2007-2015 Hypertable, Inc.
3
*
4
* This file is part of Hypertable.
5
*
6
* Hypertable is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 3
9
* of the License, or any later version.
10
*
11
* Hypertable is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
* 02110-1301, USA.
20
*/
21
27
#ifndef HT_SERIALIZATION_C_H
28
#define HT_SERIALIZATION_C_H
29
30
/* Check if stdint is included correctly */
31
#ifndef SIZE_MAX
32
# error Forgot to include "Common/Compat.h" _first_ in your *.cc or *.c?
33
#endif
34
35
/* Selection of implementation */
36
#ifdef HT_SERIALIZATION_GENERIC
37
#undef HT_LITTLE_ENDIAN
38
#else
39
#include "
endian-c.h
"
40
#endif
41
42
/* Overridable error handling helper macros */
43
#ifdef __cplusplus
44
# include "
Common/Error.h
"
45
# ifndef HT_THROW_INPUT_OVERRUN
46
# define HT_THROW_INPUT_OVERRUN(_r_, _l_) \
47
HT_THROWF(Error::SERIALIZATION_INPUT_OVERRUN, \
48
"Need %lu bytes but only %lu remain", (Lu)(_l_), (Lu)(_r_))
49
# endif
50
# ifndef HT_THROW_BAD_VSTR
51
# define HT_THROW_BAD_VSTR(_s_) \
52
HT_THROWF(Error::SERIALIZATION_BAD_VSTR, "Error decoding %s", _s_)
53
# endif
54
# ifndef HT_THROW_BAD_VINT
55
# define HT_THROW_BAD_VINT(_s_) \
56
HT_THROWF(Error::SERIALIZATION_BAD_VINT, "Error decoding %s", _s_)
57
# endif
58
# ifndef HT_THROW_UNPOSSIBLE
59
# define HT_THROW_UNPOSSIBLE(_s_) \
60
HT_THROWF(Error::UNPOSSIBLE, "%s", _s_)
61
# endif
62
#else
63
# include <cstdio>
64
# ifndef HT_THROW_INPUT_OVERRUN
65
# define HT_THROW_INPUT_OVERRUN(_s_) do { \
66
std::fprintf(stderr, "Error: %s (%s:%d): input overrun deocding %s", \
67
HT_FUNC, __FILE__, __LINE__, _s_); \
68
abort(); \
69
} while (0)
70
# endif
71
# ifndef HT_THROW_BAD_VSTR
72
# define HT_THROW_BAD_VSTR(_s_) do { \
73
std::fprintf(stderr, "Error: %s (%s:%d): malformed input decoding %s", \
74
HT_FUNC, __FILE__, __LINE__, _s_); \
75
abort(); \
76
} while (0)
77
# endif
78
# ifndef HT_THROW_BAD_VINT
79
# define HT_THROW_BAD_VINT(_s_) do { \
80
std::fprintf(stderr, "Error: %s (%s:%d): malformed input decoding %s", \
81
HT_FUNC, __FILE__, __LINE__, _s_); \
82
abort(); \
83
} while (0)
84
# endif
85
# ifndef HT_THROW_UNPOSSIBLE
86
# define HT_THROW_UNPOSSIBLE(_s_) do { \
87
std::fprintf(stderr, "Error: %s (%s:%d): unpossible!: %s", \
88
HT_FUNC, __FILE__, __LINE__, _s_); \
89
abort(); \
90
} while (0)
91
# endif
92
#endif
93
94
#define HT_DECODE_NEED(_r_, _l_) do { \
95
if (_r_ < _l_) \
96
HT_THROW_INPUT_OVERRUN(_r_, _l_); \
97
_r_ -= _l_; \
98
} while (0)
99
100
101
/*
102
* Encode a boolean value
103
*/
104
#define HT_ENCODE_BOOL(_op_, _v_) *(_op_)++ = (_v_) ? 1 : 0
105
106
107
/*
108
* Encode a 8-bit integer (byte)
109
*/
110
#define HT_ENCODE_I8(_op_, _v_) *(_op_)++ = _v_
111
112
/*
113
* Decode a 8-bit integer (a byte/character)
114
*/
115
#define HT_DECODE_I8(_ip_, _r_, _v_) do { \
116
HT_DECODE_NEED(_r_, 1); \
117
_v_ = *(_ip_)++; \
118
} while (0)
119
120
/*
121
* Encode a 16 bit integer in little endian format
122
*/
123
#ifdef HT_LITTLE_ENDIAN
124
# define HT_ENCODE_I16(_op_, _v_) do { \
125
memcpy(_op_, &(_v_), 2); \
126
_op_ += 2; \
127
} while (0)
128
#else
129
# define HT_ENCODE_I16(_op_, _v_) do { \
130
*(_op_)++ = (uint8_t)(_v_); \
131
*(_op_)++ = (uint8_t)((_v_) >> 8); \
132
} while (0)
133
#endif
134
135
/*
136
* Decoded a 16 bit integer encoded in little endian format
137
*/
138
#ifdef HT_LITTLE_ENDIAN
139
# define HT_DECODE_I16(_ip_, _r_, _v_) do { \
140
HT_DECODE_NEED(_r_, 2); \
141
memcpy(&(_v_), _ip_, 2); \
142
_ip_ += 2; \
143
} while (0)
144
#else
145
# define HT_DECODE_I16(_ip_, _r_, _v_) do { \
146
HT_DECODE_NEED(_r_, 2); \
147
_v_ = *(_ip_)++; \
148
_v_ |= (*(_ip_)++ << 8); \
149
} while (0)
150
#endif
151
152
153
/*
154
* Enocde a 32-bit integer in little endian format
155
*/
156
#ifdef HT_LITTLE_ENDIAN
157
# define HT_ENCODE_I32(_op_, _v_) do { \
158
memcpy(_op_, &(_v_), 4); \
159
_op_ += 4; \
160
} while (0)
161
#else
162
# define HT_ENCODE_I32(_op_, _v_) do { \
163
*(_op_)++ = (uint8_t)(_v_); \
164
*(_op_)++ = (uint8_t)((_v_) >> 8); \
165
*(_op_)++ = (uint8_t)((_v_) >> 16); \
166
*(_op_)++ = (uint8_t)((_v_) >> 24); \
167
} while (0)
168
#endif
169
170
/*
171
* Decode a 32-bit integer encoded in little endian format
172
*/
173
#ifdef HT_LITTLE_ENDIAN
174
# define HT_DECODE_I32(_ip_, _r_, _v_) do { \
175
HT_DECODE_NEED(_r_, 4); \
176
memcpy(&_v_, _ip_, 4); \
177
_ip_ += 4; \
178
} while (0)
179
#else
180
# define HT_DECODE_I32(_ip_, _r_, _v_) do { \
181
HT_DECODE_NEED(_r_, 4); \
182
_v_ = *(_ip_)++; \
183
_v_ |= (*(_ip_)++ << 8); \
184
_v_ |= (*(_ip_)++ << 16); \
185
_v_ |= (*(_ip_)++ << 24); \
186
} while (0)
187
#endif
188
189
190
/*
191
* Encode a 64-bit integer in little endian format
192
*/
193
#ifdef HT_LITTLE_ENDIAN
194
# define HT_ENCODE_I64(_op_, _v_) do { \
195
memcpy(_op_, &(_v_), 8); \
196
_op_ += 8; \
197
} while (0)
198
#else
199
# define HT_ENCODE_I64(_op_, _v_) do { \
200
*(_op_)++ = (uint8_t)(_v_); \
201
*(_op_)++ = (uint8_t)((_v_) >> 8); \
202
*(_op_)++ = (uint8_t)((_v_) >> 16); \
203
*(_op_)++ = (uint8_t)((_v_) >> 24); \
204
*(_op_)++ = (uint8_t)((_v_) >> 32); \
205
*(_op_)++ = (uint8_t)((_v_) >> 40); \
206
*(_op_)++ = (uint8_t)((_v_) >> 48); \
207
*(_op_)++ = (uint8_t)((_v_) >> 56); \
208
} while (0)
209
#endif
210
211
/*
212
* Decode a 64-bit integer encoded in little endian format
213
*/
214
#ifdef HT_LITTLE_ENDIAN
215
# define HT_DECODE_I64(_ip_, _r_, _v_) do { \
216
HT_DECODE_NEED(_r_, 8); \
217
memcpy(&(_v_), _ip_, 8); \
218
_ip_ += 8; \
219
} while (0)
220
#else
221
# define HT_DECODE_I64(_ip_, _r_, _v_) do { \
222
HT_DECODE_NEED(_r_, 8); \
223
_v_ = *(_ip_)++; \
224
_v_ |= (*(_ip_)++ << 8); \
225
_v_ |= (*(_ip_)++ << 16); \
226
_v_ |= ((uint64_t)(*(_ip_)++) << 24); \
227
_v_ |= ((uint64_t)(*(_ip_)++) << 32); \
228
_v_ |= ((uint64_t)(*(_ip_)++) << 40); \
229
_v_ |= ((uint64_t)(*(_ip_)++) << 48); \
230
_v_ |= ((uint64_t)(*(_ip_)++) << 56); \
231
} while (0)
232
#endif
233
234
235
/* vint limits */
236
#define HT_MAX_V1B 0x7f
237
#define HT_MAX_V2B 0x3fff
238
#define HT_MAX_V3B 0x1fffff
239
#define HT_MAX_V4B 0xfffffff
240
#define HT_MAX_V5B 0x7ffffffffull
241
#define HT_MAX_V6B 0x3ffffffffffull
242
#define HT_MAX_V7B 0x1ffffffffffffull
243
#define HT_MAX_V8B 0xffffffffffffffull
244
#define HT_MAX_V9B 0x7fffffffffffffffull
245
246
#define HT_MAX_LEN_VINT32 5
247
#define HT_MAX_LEN_VINT64 10
248
249
/*
250
* vint encoded length of a 32-bit integer
251
*/
252
#define HT_ENCODED_LEN_VI32(_v_) \
253
(_v_ <= HT_MAX_V1B ? 1 : \
254
(_v_ <= HT_MAX_V2B ? 2 : \
255
(_v_ <= HT_MAX_V3B ? 3 : \
256
(_v_ <= HT_MAX_V4B ? 4 : 5))))
257
258
/*
259
* vint encoded length of a 64-bit integer
260
*/
261
#define HT_ENCODED_LEN_VI64(_v_) \
262
(val <= HT_MAX_V1B ? 1 : \
263
(val <= HT_MAX_V2B ? 2 : \
264
(val <= HT_MAX_V3B ? 3 : \
265
(val <= HT_MAX_V4B ? 4 : \
266
(val <= HT_MAX_V5B ? 5 : \
267
(val <= HT_MAX_V6B ? 6 : \
268
(val <= HT_MAX_V7B ? 7 : \
269
(val <= HT_MAX_V8B ? 8 : \
270
(val <= HT_MAX_V9B ? 9 : 10)))))))))
271
272
/* vint encode helpers */
273
#define HT_ENCODE_VINT0(_op_, _v_, _done_) \
274
if (_v_ <= HT_MAX_V1B) { \
275
*(_op_)++ = (uint8_t)((_v_) & 0x7f); \
276
_done_; \
277
}
278
279
#define HT_ENCODE_VINT_(_op_, _v_, _done_) \
280
*(_op_)++ = (uint8_t)((_v_) | 0x80); \
281
_v_ >>= 7; \
282
HT_ENCODE_VINT0(_op_, _v_, _done_)
283
284
#define HT_ENCODE_VINT4(_op_, _v_, _done_) \
285
HT_ENCODE_VINT_(_op_, _v_, _done_) \
286
HT_ENCODE_VINT_(_op_, _v_, _done_) \
287
HT_ENCODE_VINT_(_op_, _v_, _done_) \
288
HT_ENCODE_VINT_(_op_, _v_, _done_)
289
290
/*
291
* Encode a 32-bit integer in vint format
292
*
293
* @param _op_ - output buffer pointer
294
* @param _v_ - value to encode
295
* @param _done_ - return or break
296
*/
297
#define HT_ENCODE_VI32(_op_, _v_, _done_) do { \
298
uint32_t _evtmp32_ = _v_;
/* make sure these var names are not the same */
\
299
HT_ENCODE_VINT0(_op_, _evtmp32_, _done_) \
300
HT_ENCODE_VINT4(_op_, _evtmp32_, _done_) \
301
HT_ENCODE_VINT_(_op_, _evtmp32_, _done_) \
302
HT_THROW_UNPOSSIBLE("reach here encoding vint32"); \
303
} while (0)
304
305
/*
306
* Encode a 64-bit integer in vint format
307
*
308
* @param _op_ - output buffer pointer
309
* @param _v_ - value to encode
310
* @param _done_ - return or break
311
*/
312
#define HT_ENCODE_VI64(_op_, _v_, _done_) do { \
313
uint64_t _evtmp64_ = _v_;
/* ditto */
\
314
HT_ENCODE_VINT0(_op_, _evtmp64_, _done_) \
315
HT_ENCODE_VINT4(_op_, _evtmp64_, _done_) \
316
HT_ENCODE_VINT4(_op_, _evtmp64_, _done_) \
317
HT_ENCODE_VINT_(_op_, _evtmp64_, _done_) \
318
HT_ENCODE_VINT_(_op_, _evtmp64_, _done_) \
319
HT_THROW_UNPOSSIBLE("reach here encoding vint64"); \
320
} while (0)
321
322
/* vint decode helpers */
323
#define HT_DECODE_VINT0(_type_, _v_, _ip_, _r_) \
324
uint32_t _shift_ = 0; \
325
HT_DECODE_NEED(_r_, 1); \
326
_v_ = (*(_ip_)++ & 0x7f);
327
328
#define HT_DECODE_VINT_(_type_, _v_, _ip_, _r_, _done_) \
329
_shift_ += 7; \
330
if ((_ip_)[-1] & 0x80) { \
331
HT_DECODE_NEED(_r_, 1); \
332
_v_ |= ((_type_)(*(_ip_)++ & 0x7f) << _shift_); \
333
} else _done_;
334
335
#define HT_DECODE_VINT4(_type_, _v_, _ip_, _r_, _done_) \
336
HT_DECODE_VINT_(_type_, _v_, _ip_, _r_, _done_) \
337
HT_DECODE_VINT_(_type_, _v_, _ip_, _r_, _done_) \
338
HT_DECODE_VINT_(_type_, _v_, _ip_, _r_, _done_) \
339
HT_DECODE_VINT_(_type_, _v_, _ip_, _r_, _done_)
340
341
/*
342
* Decode a 32-bit integer encoded in vint format
343
*
344
* @param _ip_ - input buffer pointer
345
* @param _r_ - varable with remaining bytes
346
* @param _v_ - variable for result
347
* @param _done_ - return _v_ or break
348
*/
349
#define HT_DECODE_VI32(_ip_, _r_, _v_, _done_) do { \
350
HT_DECODE_VINT0(uint32_t, _v_, _ip_, _r_) \
351
HT_DECODE_VINT4(uint32_t, _v_, _ip_, _r_, _done_) \
352
HT_DECODE_VINT_(uint32_t, _v_, _ip_, _r_, _done_) \
353
HT_THROW_BAD_VINT("vint32"); \
354
} while (0)
355
356
/*
357
* Decode a 64-bit integer encoded in vint format
358
*
359
* @param _ip_ - input buffer pointer
360
* @param _r_ - varable with remaining bytes
361
* @param _v_ - variable for result
362
* @param _done_ - return _v_ or break
363
*/
364
#define HT_DECODE_VI64(_ip_, _r_, _v_, _done_) do { \
365
HT_DECODE_VINT0(uint64_t, _v_, _ip_, _r_) \
366
HT_DECODE_VINT4(uint64_t, _v_, _ip_, _r_, _done_) \
367
HT_DECODE_VINT4(uint64_t, _v_, _ip_, _r_, _done_) \
368
HT_DECODE_VINT_(uint64_t, _v_, _ip_, _r_, _done_) \
369
HT_DECODE_VINT_(uint64_t, _v_, _ip_, _r_, _done_) \
370
HT_THROW_BAD_VINT("vint64"); \
371
} while (0)
372
373
374
/*
375
* Encode a buffer in bytes32 format (i32, data)
376
*
377
* @param _op_ - output buffer pointer
378
* @param _ip_ - input buffer pointer
379
* @param _len_ - input buffer length
380
*/
381
#define HT_ENCODE_BYTES32(_op_, _ip_, _len_) do { \
382
HT_ENCODE_I32(_op_, _len_); \
383
memcpy(_op_, _ip_, _len_); \
384
_op_ += _len_; \
385
} while (0)
386
387
/*
388
* Decode bytes32 (i32, data)
389
*
390
* @param _ip_ - input buffer pointer
391
* @param _r_ - varable with remaining bytes
392
* @param _out_ - variable for output
393
* @param _len_ - variable for result length
394
*/
395
#define HT_DECODE_BYTES32(_ip_, _r_, _out_, _len_) do { \
396
uint32_t _tmp_; \
397
HT_DECODE_I32(_ip_, _r_, _tmp_); \
398
HT_DECODE_NEED(_r_, _tmp_); \
399
_out_ = (uint8_t *)(_ip_); \
400
_ip_ += _tmp_; \
401
_len_ = _tmp_; \
402
} while (0)
403
404
/*
405
* Encode a string buffer in str16 format (i16, data, null)
406
*
407
* @param _op_ - output buffer pointer
408
* @param _s_ - input buffer pointer
409
* @param _len_ - input buffer length
410
*/
411
#define HT_ENCODE_STR16(_op_, _s_, _len_) do { \
412
uint16_t _s16tmp_ = _len_;
/* just to be cautious */
\
413
HT_ENCODE_I16(_op_, _s16tmp_);
/* length */
\
414
if (_s16tmp_ > 0) { \
415
memcpy(_op_, _s_, _s16tmp_);
/* data */
\
416
_op_ += len; \
417
} \
418
*(*bufp)++ = 0;
/* null */
\
419
} while (0)
420
421
/*
422
* Decode str16 (i16, data, null)
423
*
424
* @param _ip_ - input buffer pointer
425
* @param _r_ - varable with remaining bytes
426
* @param _s_ - variable for result
427
* @param _len_ - variable for result length
428
*/
429
#define HT_DECODE_STR16(_ip_, _r_, _s_, _len_) do { \
430
HT_DECODE_I16(_ip_, _r_, _len_); \
431
_s_ = (char *)(_ip_); \
432
_r_ -= (size_t)(_len_) + 1; \
433
_ip_ += (size_t)(_len_) + 1; \
434
} while (0)
435
436
437
/*
438
* Encode in vstr format (vint, data, null)
439
*
440
* @param _op_ - output buffer pointer
441
* @param _s_ - input buffer pointer
442
* @param _len_ - input buffer length
443
*/
444
#define HT_ENCODE_VSTR(_op_, _s_, _len_) do { \
445
size_t _vs64tmp_ = _len_;
/* ditto */
\
446
HT_ENCODE_VI64(_op_, _vs64tmp_, break); \
447
if (_vs64tmp_) { \
448
memcpy((_op_), _s_, _vs64tmp_); \
449
(_op_) += _vs64tmp_; \
450
} \
451
*(_op_)++ = 0; \
452
} while (0)
453
454
/*
455
* Decode a vstr (vint, data, null)
456
*/
457
#define HT_DECODE_VSTR(_ip_, _r_, _out_, _len_) do { \
458
uint64_t _tmp_; \
459
HT_DECODE_VI64(_ip_, _r_, _tmp_, break); \
460
if (_tmp_ > (uint64_t)(SIZE_MAX)) \
461
HT_THROW_BAD_VSTR("long vstr on 32-bit platform"); \
462
_out_ = (char *)(_ip_); \
463
_len_ = _tmp_++; \
464
HT_DECODE_NEED(_r_, _tmp_); \
465
_ip_ += _tmp_; \
466
if ((_ip_)[-1])
/* should be null */
\
467
HT_THROW_BAD_VSTR("vstr"); \
468
} while (0)
469
470
471
#endif
/* HT_SERIALIZATION_C_H */
endian-c.h
Endian conversion macros.
Error.h
Error codes, Exception handling, error logging.
Generated on Tue Dec 22 2015 18:43:07 for Hypertable by
1.8.8