… | |
… | |
16 | |
16 | |
17 | #define INIT_SIZE 32 // initial scalar size to be allocated |
17 | #define INIT_SIZE 32 // initial scalar size to be allocated |
18 | |
18 | |
19 | #define SB do { |
19 | #define SB do { |
20 | #define SE } while (0) |
20 | #define SE } while (0) |
21 | |
|
|
22 | #if __GNUC__ >= 3 |
|
|
23 | # define expect(expr,value) __builtin_expect ((expr), (value)) |
|
|
24 | # define INLINE static inline |
|
|
25 | #else |
|
|
26 | # define expect(expr,value) (expr) |
|
|
27 | # define INLINE static |
|
|
28 | #endif |
|
|
29 | |
|
|
30 | #define expect_false(expr) expect ((expr) != 0, 0) |
|
|
31 | #define expect_true(expr) expect ((expr) != 0, 1) |
|
|
32 | |
21 | |
33 | #define IN_RANGE_INC(type,val,beg,end) \ |
22 | #define IN_RANGE_INC(type,val,beg,end) \ |
34 | ((unsigned type)((unsigned type)(val) - (unsigned type)(beg)) \ |
23 | ((unsigned type)((unsigned type)(val) - (unsigned type)(beg)) \ |
35 | <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg))) |
24 | <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg))) |
36 | |
25 | |
… | |
… | |
54 | |
43 | |
55 | SV *cb_object; |
44 | SV *cb_object; |
56 | HV *cb_sk_object; |
45 | HV *cb_sk_object; |
57 | } CBOR; |
46 | } CBOR; |
58 | |
47 | |
59 | INLINE void |
48 | ecb_inline void |
60 | cbor_init (CBOR *cbor) |
49 | cbor_init (CBOR *cbor) |
61 | { |
50 | { |
62 | Zero (cbor, 1, CBOR); |
51 | Zero (cbor, 1, CBOR); |
63 | cbor->max_depth = 512; |
52 | cbor->max_depth = 512; |
64 | } |
53 | } |
65 | |
54 | |
66 | ///////////////////////////////////////////////////////////////////////////// |
55 | ///////////////////////////////////////////////////////////////////////////// |
67 | // utility functions |
56 | // utility functions |
68 | |
57 | |
69 | INLINE SV * |
58 | ecb_inline SV * |
70 | get_bool (const char *name) |
59 | get_bool (const char *name) |
71 | { |
60 | { |
72 | SV *sv = get_sv (name, 1); |
61 | SV *sv = get_sv (name, 1); |
73 | |
62 | |
74 | SvREADONLY_on (sv); |
63 | SvREADONLY_on (sv); |
75 | SvREADONLY_on (SvRV (sv)); |
64 | SvREADONLY_on (SvRV (sv)); |
76 | |
65 | |
77 | return sv; |
66 | return sv; |
78 | } |
67 | } |
79 | |
68 | |
80 | INLINE void |
69 | ecb_inline void |
81 | shrink (SV *sv) |
70 | shrink (SV *sv) |
82 | { |
71 | { |
83 | sv_utf8_downgrade (sv, 1); |
72 | sv_utf8_downgrade (sv, 1); |
84 | |
73 | |
85 | if (SvLEN (sv) > SvCUR (sv) + 1) |
74 | if (SvLEN (sv) > SvCUR (sv) + 1) |
… | |
… | |
108 | SV *sv; // result scalar |
97 | SV *sv; // result scalar |
109 | CBOR cbor; |
98 | CBOR cbor; |
110 | U32 depth; // recursion level |
99 | U32 depth; // recursion level |
111 | } enc_t; |
100 | } enc_t; |
112 | |
101 | |
113 | INLINE void |
102 | ecb_inline void |
114 | need (enc_t *enc, STRLEN len) |
103 | need (enc_t *enc, STRLEN len) |
115 | { |
104 | { |
116 | if (expect_false (enc->cur + len >= enc->end)) |
105 | if (ecb_expect_false (enc->cur + len >= enc->end)) |
117 | { |
106 | { |
118 | STRLEN cur = enc->cur - (char *)SvPVX (enc->sv); |
107 | STRLEN cur = enc->cur - (char *)SvPVX (enc->sv); |
119 | SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1); |
108 | SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1); |
120 | enc->cur = SvPVX (enc->sv) + cur; |
109 | enc->cur = SvPVX (enc->sv) + cur; |
121 | enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1; |
110 | enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1; |
122 | } |
111 | } |
123 | } |
112 | } |
124 | |
113 | |
125 | INLINE void |
114 | ecb_inline void |
126 | encode_ch (enc_t *enc, char ch) |
115 | encode_ch (enc_t *enc, char ch) |
127 | { |
116 | { |
128 | need (enc, 1); |
117 | need (enc, 1); |
129 | *enc->cur++ = ch; |
118 | *enc->cur++ = ch; |
130 | } |
119 | } |
… | |
… | |
224 | if (HeKLEN (he) == HEf_SVKEY) |
213 | if (HeKLEN (he) == HEf_SVKEY) |
225 | encode_sv (enc, HeSVKEY (he)); |
214 | encode_sv (enc, HeSVKEY (he)); |
226 | else |
215 | else |
227 | encode_str (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he)); |
216 | encode_str (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he)); |
228 | |
217 | |
229 | encode_sv (enc, expect_false (mg) ? hv_iterval (hv, he) : HeVAL (he)); |
218 | encode_sv (enc, ecb_expect_false (mg) ? hv_iterval (hv, he) : HeVAL (he)); |
230 | } |
219 | } |
231 | |
220 | |
232 | if (mg) |
221 | if (mg) |
233 | encode_ch (enc, 0xe0 | 31); |
222 | encode_ch (enc, 0xe0 | 31); |
234 | |
223 | |
… | |
… | |
242 | svtype svt; |
231 | svtype svt; |
243 | |
232 | |
244 | SvGETMAGIC (sv); |
233 | SvGETMAGIC (sv); |
245 | svt = SvTYPE (sv); |
234 | svt = SvTYPE (sv); |
246 | |
235 | |
247 | if (expect_false (SvOBJECT (sv))) |
236 | if (ecb_expect_false (SvOBJECT (sv))) |
248 | { |
237 | { |
249 | HV *stash = !CBOR_SLOW || cbor_boolean_stash |
238 | HV *stash = !CBOR_SLOW || cbor_boolean_stash |
250 | ? cbor_boolean_stash |
239 | ? cbor_boolean_stash |
251 | : gv_stashpv ("CBOR::XS::Boolean", 1); |
240 | : gv_stashpv ("CBOR::XS::Boolean", 1); |
252 | |
241 | |
… | |
… | |
328 | { |
317 | { |
329 | double nv = SvNVX (sv); |
318 | double nv = SvNVX (sv); |
330 | |
319 | |
331 | need (enc, 9); |
320 | need (enc, 9); |
332 | |
321 | |
333 | if (expect_false (nv == (U32)nv)) |
322 | if (ecb_expect_false (nv == (U32)nv)) |
334 | encode_uint (enc, 0x00, (U32)nv); |
323 | encode_uint (enc, 0x00, (U32)nv); |
335 | //TODO: maybe I32? |
324 | //TODO: maybe I32? |
336 | else if (expect_false (nv == (float)nv)) |
325 | else if (ecb_expect_false (nv == (float)nv)) |
337 | { |
326 | { |
338 | uint32_t fp = ecb_float_to_binary32 (nv); |
327 | uint32_t fp = ecb_float_to_binary32 (nv); |
339 | |
328 | |
340 | *enc->cur++ = 0xe0 | 26; |
329 | *enc->cur++ = 0xe0 | 26; |
341 | |
330 | |
… | |
… | |
429 | U32 maxdepth; // recursion depth limit |
418 | U32 maxdepth; // recursion depth limit |
430 | } dec_t; |
419 | } dec_t; |
431 | |
420 | |
432 | #define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE |
421 | #define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE |
433 | |
422 | |
434 | #define WANT(len) if (expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data"); |
423 | #define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data") |
435 | |
424 | |
436 | #define DEC_INC_DEPTH if (++dec->depth > dec->cbor.max_depth) ERR (ERR_NESTING_EXCEEDED) |
425 | #define DEC_INC_DEPTH if (++dec->depth > dec->cbor.max_depth) ERR (ERR_NESTING_EXCEEDED) |
437 | #define DEC_DEC_DEPTH --dec->depth |
426 | #define DEC_DEC_DEPTH --dec->depth |
438 | |
427 | |
439 | static UV |
428 | static UV |