ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/CBOR-XS/XS.xs
(Generate patch)

Comparing CBOR-XS/XS.xs (file contents):
Revision 1.2 by root, Sat Oct 26 10:41:12 2013 UTC vs.
Revision 1.5 by root, Sat Oct 26 21:14:20 2013 UTC

9#include <limits.h> 9#include <limits.h>
10#include <float.h> 10#include <float.h>
11 11
12#include "ecb.h" 12#include "ecb.h"
13 13
14#if defined(__BORLANDC__) || defined(_MSC_VER)
15# define snprintf _snprintf // C compilers have this in stdio.h
16#endif
17
18#define F_SHRINK 0x00000200UL 14#define F_SHRINK 0x00000200UL
19#define F_ALLOW_UNKNOWN 0x00002000UL 15#define F_ALLOW_UNKNOWN 0x00002000UL
20 16
21#define INIT_SIZE 32 // initial scalar size to be allocated 17#define INIT_SIZE 32 // initial scalar size to be allocated
22 18
23#define SB do { 19#define SB do {
24#define SE } while (0) 20#define SE } while (0)
25
26#if __GNUC__ >= 3
27# define expect(expr,value) __builtin_expect ((expr), (value))
28# define INLINE static inline
29#else
30# define expect(expr,value) (expr)
31# define INLINE static
32#endif
33
34#define expect_false(expr) expect ((expr) != 0, 0)
35#define expect_true(expr) expect ((expr) != 0, 1)
36 21
37#define IN_RANGE_INC(type,val,beg,end) \ 22#define IN_RANGE_INC(type,val,beg,end) \
38 ((unsigned type)((unsigned type)(val) - (unsigned type)(beg)) \ 23 ((unsigned type)((unsigned type)(val) - (unsigned type)(beg)) \
39 <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg))) 24 <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg)))
40 25
58 43
59 SV *cb_object; 44 SV *cb_object;
60 HV *cb_sk_object; 45 HV *cb_sk_object;
61} CBOR; 46} CBOR;
62 47
63INLINE void 48ecb_inline void
64cbor_init (CBOR *cbor) 49cbor_init (CBOR *cbor)
65{ 50{
66 Zero (cbor, 1, CBOR); 51 Zero (cbor, 1, CBOR);
67 cbor->max_depth = 512; 52 cbor->max_depth = 512;
68} 53}
69 54
70///////////////////////////////////////////////////////////////////////////// 55/////////////////////////////////////////////////////////////////////////////
71// utility functions 56// utility functions
72 57
73INLINE SV * 58ecb_inline SV *
74get_bool (const char *name) 59get_bool (const char *name)
75{ 60{
76 SV *sv = get_sv (name, 1); 61 SV *sv = get_sv (name, 1);
77 62
78 SvREADONLY_on (sv); 63 SvREADONLY_on (sv);
79 SvREADONLY_on (SvRV (sv)); 64 SvREADONLY_on (SvRV (sv));
80 65
81 return sv; 66 return sv;
82} 67}
83 68
84INLINE void 69ecb_inline void
85shrink (SV *sv) 70shrink (SV *sv)
86{ 71{
87 sv_utf8_downgrade (sv, 1); 72 sv_utf8_downgrade (sv, 1);
88 73
89 if (SvLEN (sv) > SvCUR (sv) + 1) 74 if (SvLEN (sv) > SvCUR (sv) + 1)
112 SV *sv; // result scalar 97 SV *sv; // result scalar
113 CBOR cbor; 98 CBOR cbor;
114 U32 depth; // recursion level 99 U32 depth; // recursion level
115} enc_t; 100} enc_t;
116 101
117INLINE void 102ecb_inline void
118need (enc_t *enc, STRLEN len) 103need (enc_t *enc, STRLEN len)
119{ 104{
120 if (expect_false (enc->cur + len >= enc->end)) 105 if (ecb_expect_false (enc->cur + len >= enc->end))
121 { 106 {
122 STRLEN cur = enc->cur - (char *)SvPVX (enc->sv); 107 STRLEN cur = enc->cur - (char *)SvPVX (enc->sv);
123 SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1); 108 SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1);
124 enc->cur = SvPVX (enc->sv) + cur; 109 enc->cur = SvPVX (enc->sv) + cur;
125 enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1; 110 enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1;
126 } 111 }
127} 112}
128 113
129INLINE void 114ecb_inline void
130encode_ch (enc_t *enc, char ch) 115encode_ch (enc_t *enc, char ch)
131{ 116{
132 need (enc, 1); 117 need (enc, 1);
133 *enc->cur++ = ch; 118 *enc->cur++ = ch;
134} 119}
138{ 123{
139 need (enc, 9); 124 need (enc, 9);
140 125
141 if (len < 24) 126 if (len < 24)
142 *enc->cur++ = major | len; 127 *enc->cur++ = major | len;
143 else if (len < 0x100) 128 else if (len <= 0xff)
144 { 129 {
145 *enc->cur++ = major | 24; 130 *enc->cur++ = major | 24;
146 *enc->cur++ = len; 131 *enc->cur++ = len;
147 } 132 }
148 else if (len < 0x10000) 133 else if (len <= 0xffff)
149 { 134 {
150 *enc->cur++ = major | 25; 135 *enc->cur++ = major | 25;
151 *enc->cur++ = len >> 8; 136 *enc->cur++ = len >> 8;
152 *enc->cur++ = len; 137 *enc->cur++ = len;
153 } 138 }
154 else if (len < 0x100000000) 139 else if (len <= 0xffffffff)
155 { 140 {
156 *enc->cur++ = major | 26; 141 *enc->cur++ = major | 26;
157 *enc->cur++ = len >> 24; 142 *enc->cur++ = len >> 24;
158 *enc->cur++ = len >> 16; 143 *enc->cur++ = len >> 16;
159 *enc->cur++ = len >> 8; 144 *enc->cur++ = len >> 8;
160 *enc->cur++ = len; 145 *enc->cur++ = len;
161 } 146 }
162 else if (len) 147 else
163 { 148 {
164 *enc->cur++ = major | 27; 149 *enc->cur++ = major | 27;
165 *enc->cur++ = len >> 56; 150 *enc->cur++ = len >> 56;
166 *enc->cur++ = len >> 48; 151 *enc->cur++ = len >> 48;
167 *enc->cur++ = len >> 40; 152 *enc->cur++ = len >> 40;
228 if (HeKLEN (he) == HEf_SVKEY) 213 if (HeKLEN (he) == HEf_SVKEY)
229 encode_sv (enc, HeSVKEY (he)); 214 encode_sv (enc, HeSVKEY (he));
230 else 215 else
231 encode_str (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he)); 216 encode_str (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he));
232 217
233 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));
234 } 219 }
235 220
236 if (mg) 221 if (mg)
237 encode_ch (enc, 0xe0 | 31); 222 encode_ch (enc, 0xe0 | 31);
238 223
246 svtype svt; 231 svtype svt;
247 232
248 SvGETMAGIC (sv); 233 SvGETMAGIC (sv);
249 svt = SvTYPE (sv); 234 svt = SvTYPE (sv);
250 235
251 if (expect_false (SvOBJECT (sv))) 236 if (ecb_expect_false (SvOBJECT (sv)))
252 { 237 {
253 HV *stash = !CBOR_SLOW || cbor_boolean_stash 238 HV *stash = !CBOR_SLOW || cbor_boolean_stash
254 ? cbor_boolean_stash 239 ? cbor_boolean_stash
255 : gv_stashpv ("CBOR::XS::Boolean", 1); 240 : gv_stashpv ("CBOR::XS::Boolean", 1);
256 241
332{ 317{
333 double nv = SvNVX (sv); 318 double nv = SvNVX (sv);
334 319
335 need (enc, 9); 320 need (enc, 9);
336 321
337 if (expect_false (nv == (U32)nv)) 322 if (ecb_expect_false (nv == (U32)nv))
338 encode_uint (enc, 0x00, (U32)nv); 323 encode_uint (enc, 0x00, (U32)nv);
339 //TODO: maybe I32? 324 //TODO: maybe I32?
340 else if (expect_false (nv == (float)nv)) 325 else if (ecb_expect_false (nv == (float)nv))
341 { 326 {
342 uint32_t fp = ecb_float_to_binary32 (nv); 327 uint32_t fp = ecb_float_to_binary32 (nv);
343 328
344 *enc->cur++ = 0xe0 | 26; 329 *enc->cur++ = 0xe0 | 26;
345 330
433 U32 maxdepth; // recursion depth limit 418 U32 maxdepth; // recursion depth limit
434} dec_t; 419} dec_t;
435 420
436#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
437 422
438#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")
439 424
440#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)
441#define DEC_DEC_DEPTH --dec->depth 426#define DEC_DEC_DEPTH --dec->depth
442 427
443static UV 428static UV
778 763
779 return sv; 764 return sv;
780 765
781fail: 766fail:
782 return &PL_sv_undef; 767 return &PL_sv_undef;
768}
769
770static SV *
771decode_tagged (dec_t *dec)
772{
773 UV tag = decode_uint (dec);
774 SV *sv = decode_sv (dec);
775
776 if (tag == 55799) // 2.4.5 Self-Describe CBOR
777 return sv;
778
779 AV *av = newAV ();
780 av_push (av, newSVuv (tag));
781 av_push (av, sv);
782 return newRV_noinc ((SV *)av);
783} 783}
784 784
785static SV * 785static SV *
786decode_sv (dec_t *dec) 786decode_sv (dec_t *dec)
787{ 787{
801 case 4: // array 801 case 4: // array
802 return decode_av (dec); 802 return decode_av (dec);
803 case 5: // map 803 case 5: // map
804 return decode_hv (dec); 804 return decode_hv (dec);
805 case 6: // tag 805 case 6: // tag
806 abort (); 806 return decode_tagged (dec);
807 break;
808 case 7: // misc 807 case 7: // misc
809 switch (*dec->cur++ & 31) 808 switch (*dec->cur++ & 31)
810 { 809 {
811 case 20: 810 case 20:
812#if CBOR_SLOW 811#if CBOR_SLOW

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines