ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/CBOR-XS/XS.xs
Revision: 1.52
Committed: Sun Apr 24 19:31:55 2016 UTC (8 years ago) by root
Branch: MAIN
Changes since 1.51: +18 -6 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5     #include <assert.h>
6     #include <string.h>
7     #include <stdlib.h>
8     #include <stdio.h>
9     #include <limits.h>
10     #include <float.h>
11    
12 root 1.44 #define ECB_NO_THREADS 1
13 root 1.1 #include "ecb.h"
14    
15 root 1.14 // compatibility with perl <5.18
16     #ifndef HvNAMELEN_get
17     # define HvNAMELEN_get(hv) strlen (HvNAME (hv))
18     #endif
19     #ifndef HvNAMELEN
20     # define HvNAMELEN(hv) HvNAMELEN_get (hv)
21     #endif
22     #ifndef HvNAMEUTF8
23     # define HvNAMEUTF8(hv) 0
24     #endif
25 root 1.28 #ifndef SvREFCNT_dec_NN
26     # define SvREFCNT_dec_NN(sv) SvREFCNT_dec (sv)
27     #endif
28 root 1.14
29 root 1.35 // known major and minor types
30     enum cbor_type
31     {
32     MAJOR_SHIFT = 5,
33     MINOR_MASK = 0x1f,
34    
35     MAJOR_POS_INT = 0 << MAJOR_SHIFT,
36     MAJOR_NEG_INT = 1 << MAJOR_SHIFT,
37     MAJOR_BYTES = 2 << MAJOR_SHIFT,
38     MAJOR_TEXT = 3 << MAJOR_SHIFT,
39     MAJOR_ARRAY = 4 << MAJOR_SHIFT,
40     MAJOR_MAP = 5 << MAJOR_SHIFT,
41     MAJOR_TAG = 6 << MAJOR_SHIFT,
42     MAJOR_MISC = 7 << MAJOR_SHIFT,
43    
44     // INT/STRING/ARRAY/MAP subtypes
45     LENGTH_EXT1 = 24,
46     LENGTH_EXT2 = 25,
47     LENGTH_EXT4 = 26,
48     LENGTH_EXT8 = 27,
49    
50     // SIMPLE types (effectively MISC subtypes)
51     SIMPLE_FALSE = 20,
52     SIMPLE_TRUE = 21,
53     SIMPLE_NULL = 22,
54     SIMPLE_UNDEF = 23,
55    
56     // MISC subtype (unused)
57     MISC_EXT1 = 24,
58     MISC_FLOAT16 = 25,
59     MISC_FLOAT32 = 26,
60     MISC_FLOAT64 = 27,
61    
62     // BYTES/TEXT/ARRAY/MAP
63     MINOR_INDEF = 31,
64     };
65    
66 root 1.9 // known tags
67 root 1.8 enum cbor_tag
68     {
69 root 1.35 // extensions
70     CBOR_TAG_STRINGREF = 25, // http://cbor.schmorp.de/stringref
71     CBOR_TAG_PERL_OBJECT = 26, // http://cbor.schmorp.de/perl-object
72     CBOR_TAG_GENERIC_OBJECT = 27, // http://cbor.schmorp.de/generic-object
73     CBOR_TAG_VALUE_SHAREABLE = 28, // http://cbor.schmorp.de/value-sharing
74     CBOR_TAG_VALUE_SHAREDREF = 29, // http://cbor.schmorp.de/value-sharing
75     CBOR_TAG_STRINGREF_NAMESPACE = 256, // http://cbor.schmorp.de/stringref
76     CBOR_TAG_INDIRECTION = 22098, // http://cbor.schmorp.de/indirection
77    
78     // rfc7049
79     CBOR_TAG_DATETIME = 0, // rfc4287, utf-8
80     CBOR_TAG_TIMESTAMP = 1, // unix timestamp, any
81     CBOR_TAG_POS_BIGNUM = 2, // byte string
82     CBOR_TAG_NEG_BIGNUM = 3, // byte string
83     CBOR_TAG_DECIMAL = 4, // decimal fraction, array
84     CBOR_TAG_BIGFLOAT = 5, // array
85    
86     CBOR_TAG_CONV_B64U = 21, // base64url, any
87     CBOR_TAG_CONV_B64 = 22, // base64, any
88     CBOR_TAG_CONV_HEX = 23, // base16, any
89     CBOR_TAG_CBOR = 24, // embedded cbor, byte string
90    
91     CBOR_TAG_URI = 32, // URI rfc3986, utf-8
92     CBOR_TAG_B64U = 33, // base64url rfc4648, utf-8
93     CBOR_TAG_B64 = 34, // base6 rfc46484, utf-8
94     CBOR_TAG_REGEX = 35, // regex pcre/ecma262, utf-8
95     CBOR_TAG_MIME = 36, // mime message rfc2045, utf-8
96 root 1.8
97 root 1.35 CBOR_TAG_MAGIC = 55799, // self-describe cbor
98 root 1.8 };
99    
100 root 1.24 #define F_SHRINK 0x00000001UL
101     #define F_ALLOW_UNKNOWN 0x00000002UL
102 root 1.32 #define F_ALLOW_SHARING 0x00000004UL
103 root 1.37 #define F_ALLOW_CYCLES 0x00000008UL
104     #define F_PACK_STRINGS 0x00000010UL
105 root 1.51 #define F_UTF8_STRINGS 0x00000020UL
106     #define F_VALIDATE_UTF8 0x00000040UL
107 root 1.1
108     #define INIT_SIZE 32 // initial scalar size to be allocated
109    
110     #define SB do {
111     #define SE } while (0)
112    
113     #define IN_RANGE_INC(type,val,beg,end) \
114     ((unsigned type)((unsigned type)(val) - (unsigned type)(beg)) \
115     <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg)))
116    
117     #define ERR_NESTING_EXCEEDED "cbor text or perl structure exceeds maximum nesting level (max_depth set too low?)"
118    
119     #ifdef USE_ITHREADS
120     # define CBOR_SLOW 1
121     # define CBOR_STASH (cbor_stash ? cbor_stash : gv_stashpv ("CBOR::XS", 1))
122     #else
123     # define CBOR_SLOW 0
124     # define CBOR_STASH cbor_stash
125     #endif
126    
127 root 1.10 static HV *cbor_stash, *types_boolean_stash, *types_error_stash, *cbor_tagged_stash; // CBOR::XS::
128 root 1.27 static SV *types_true, *types_false, *types_error, *sv_cbor, *default_filter;
129 root 1.1
130     typedef struct {
131     U32 flags;
132     U32 max_depth;
133     STRLEN max_size;
134 root 1.27 SV *filter;
135 root 1.40
136     // for the incremental parser
137     STRLEN incr_pos; // the current offset into the text
138     STRLEN incr_need; // minimum bytes needed to decode
139     AV *incr_count; // for every nesting level, the number of outstanding values, or -1 for indef.
140 root 1.1 } CBOR;
141    
142 root 1.5 ecb_inline void
143 root 1.1 cbor_init (CBOR *cbor)
144     {
145     Zero (cbor, 1, CBOR);
146     cbor->max_depth = 512;
147     }
148    
149 root 1.27 ecb_inline void
150     cbor_free (CBOR *cbor)
151     {
152     SvREFCNT_dec (cbor->filter);
153 root 1.40 SvREFCNT_dec (cbor->incr_count);
154 root 1.27 }
155    
156 root 1.1 /////////////////////////////////////////////////////////////////////////////
157     // utility functions
158    
159 root 1.5 ecb_inline SV *
160 root 1.1 get_bool (const char *name)
161     {
162     SV *sv = get_sv (name, 1);
163    
164     SvREADONLY_on (sv);
165     SvREADONLY_on (SvRV (sv));
166    
167     return sv;
168     }
169    
170 root 1.5 ecb_inline void
171 root 1.1 shrink (SV *sv)
172     {
173     sv_utf8_downgrade (sv, 1);
174    
175     if (SvLEN (sv) > SvCUR (sv) + 1)
176     {
177     #ifdef SvPV_shrink_to_cur
178     SvPV_shrink_to_cur (sv);
179     #elif defined (SvPV_renew)
180     SvPV_renew (sv, SvCUR (sv) + 1);
181     #endif
182     }
183     }
184    
185 root 1.21 // minimum length of a string to be registered for stringref
186     ecb_inline int
187     minimum_string_length (UV idx)
188     {
189     return idx > 23
190     ? idx > 0xffU
191     ? idx > 0xffffU
192     ? idx > 0xffffffffU
193 root 1.29 ? 11
194     : 7
195 root 1.21 : 5
196     : 4
197     : 3;
198     }
199    
200 root 1.1 /////////////////////////////////////////////////////////////////////////////
201     // encoder
202    
203     // structure used for encoding CBOR
204     typedef struct
205     {
206     char *cur; // SvPVX (sv) + current output position
207     char *end; // SvEND (sv)
208     SV *sv; // result scalar
209     CBOR cbor;
210     U32 depth; // recursion level
211 root 1.20 HV *stringref[2]; // string => index, or 0 ([0] = bytes, [1] = utf-8)
212     UV stringref_idx;
213 root 1.19 HV *shareable; // ptr => index, or 0
214     UV shareable_idx;
215 root 1.1 } enc_t;
216    
217 root 1.5 ecb_inline void
218 root 1.1 need (enc_t *enc, STRLEN len)
219     {
220 root 1.5 if (ecb_expect_false (enc->cur + len >= enc->end))
221 root 1.1 {
222     STRLEN cur = enc->cur - (char *)SvPVX (enc->sv);
223     SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1);
224     enc->cur = SvPVX (enc->sv) + cur;
225     enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1;
226     }
227     }
228    
229 root 1.5 ecb_inline void
230 root 1.1 encode_ch (enc_t *enc, char ch)
231     {
232     need (enc, 1);
233     *enc->cur++ = ch;
234     }
235    
236     static void
237     encode_uint (enc_t *enc, int major, UV len)
238     {
239     need (enc, 9);
240    
241 root 1.35 if (ecb_expect_true (len < LENGTH_EXT1))
242 root 1.1 *enc->cur++ = major | len;
243 root 1.36 else if (ecb_expect_true (len <= 0xffU))
244 root 1.1 {
245 root 1.35 *enc->cur++ = major | LENGTH_EXT1;
246 root 1.1 *enc->cur++ = len;
247     }
248 root 1.36 else if (len <= 0xffffU)
249 root 1.1 {
250 root 1.35 *enc->cur++ = major | LENGTH_EXT2;
251 root 1.1 *enc->cur++ = len >> 8;
252     *enc->cur++ = len;
253     }
254 root 1.36 else if (len <= 0xffffffffU)
255 root 1.1 {
256 root 1.35 *enc->cur++ = major | LENGTH_EXT4;
257 root 1.1 *enc->cur++ = len >> 24;
258     *enc->cur++ = len >> 16;
259     *enc->cur++ = len >> 8;
260     *enc->cur++ = len;
261     }
262 root 1.4 else
263 root 1.1 {
264 root 1.35 *enc->cur++ = major | LENGTH_EXT8;
265 root 1.1 *enc->cur++ = len >> 56;
266     *enc->cur++ = len >> 48;
267     *enc->cur++ = len >> 40;
268     *enc->cur++ = len >> 32;
269     *enc->cur++ = len >> 24;
270     *enc->cur++ = len >> 16;
271     *enc->cur++ = len >> 8;
272     *enc->cur++ = len;
273     }
274     }
275    
276 root 1.21 ecb_inline void
277     encode_tag (enc_t *enc, UV tag)
278     {
279 root 1.35 encode_uint (enc, MAJOR_TAG, tag);
280 root 1.21 }
281    
282 root 1.30 ecb_inline void
283     encode_str (enc_t *enc, int utf8, char *str, STRLEN len)
284     {
285 root 1.51 if (ecb_expect_false (enc->cbor.flags & F_UTF8_STRINGS))
286     if (!utf8)
287     {
288 root 1.52 // exceptional path for bytze strings that need to be utf8-encoded
289     STRLEN ulen = len;
290     U8 *p, *pend = (U8 *)str + len;
291    
292     for (p = (U8 *)str; p < pend; ++p)
293     ulen += *p >> 7; // count set high bits
294    
295     encode_uint (enc, MAJOR_TEXT, ulen);
296    
297     need (enc, ulen);
298     for (p = (U8 *)str; p < pend; ++p)
299     if (*p < 0x80)
300     *enc->cur++ = *p;
301     else
302     {
303     *enc->cur++ = 0xc0 + (*p >> 6);
304     *enc->cur++ = 0x80 + (*p & 63);
305     }
306 root 1.51
307     return;
308     }
309    
310 root 1.35 encode_uint (enc, utf8 ? MAJOR_TEXT : MAJOR_BYTES, len);
311 root 1.30 need (enc, len);
312     memcpy (enc->cur, str, len);
313     enc->cur += len;
314     }
315    
316 root 1.1 static void
317 root 1.30 encode_strref (enc_t *enc, int utf8, char *str, STRLEN len)
318 root 1.1 {
319 root 1.32 if (ecb_expect_false (enc->cbor.flags & F_PACK_STRINGS))
320 root 1.21 {
321 root 1.22 SV **svp = hv_fetch (enc->stringref[!!utf8], str, len, 1);
322 root 1.21
323     if (SvOK (*svp))
324     {
325     // already registered, use stringref
326     encode_tag (enc, CBOR_TAG_STRINGREF);
327 root 1.35 encode_uint (enc, MAJOR_POS_INT, SvUV (*svp));
328 root 1.21 return;
329     }
330     else if (len >= minimum_string_length (enc->stringref_idx))
331     {
332     // register only
333     sv_setuv (*svp, enc->stringref_idx);
334     ++enc->stringref_idx;
335     }
336     }
337    
338 root 1.30 encode_str (enc, utf8, str, len);
339 root 1.1 }
340    
341     static void encode_sv (enc_t *enc, SV *sv);
342    
343     static void
344     encode_av (enc_t *enc, AV *av)
345     {
346     int i, len = av_len (av);
347    
348     if (enc->depth >= enc->cbor.max_depth)
349     croak (ERR_NESTING_EXCEEDED);
350    
351     ++enc->depth;
352    
353 root 1.35 encode_uint (enc, MAJOR_ARRAY, len + 1);
354 root 1.1
355 root 1.45 if (SvMAGICAL (av))
356     for (i = 0; i <= len; ++i)
357     {
358     SV **svp = av_fetch (av, i, 0);
359     encode_sv (enc, svp ? *svp : &PL_sv_undef);
360     }
361     else
362     for (i = 0; i <= len; ++i)
363 root 1.46 {
364     SV *sv = AvARRAY (av)[i];
365     encode_sv (enc, sv ? sv : &PL_sv_undef);
366     }
367 root 1.1
368     --enc->depth;
369     }
370    
371     static void
372     encode_hv (enc_t *enc, HV *hv)
373     {
374     HE *he;
375    
376     if (enc->depth >= enc->cbor.max_depth)
377     croak (ERR_NESTING_EXCEEDED);
378    
379     ++enc->depth;
380    
381     int pairs = hv_iterinit (hv);
382     int mg = SvMAGICAL (hv);
383    
384     if (mg)
385 root 1.35 encode_ch (enc, MAJOR_MAP | MINOR_INDEF);
386 root 1.1 else
387 root 1.35 encode_uint (enc, MAJOR_MAP, pairs);
388 root 1.1
389     while ((he = hv_iternext (hv)))
390     {
391 root 1.21 if (HeKLEN (he) == HEf_SVKEY)
392     encode_sv (enc, HeSVKEY (he));
393 root 1.1 else
394 root 1.30 encode_strref (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he));
395 root 1.1
396 root 1.5 encode_sv (enc, ecb_expect_false (mg) ? hv_iterval (hv, he) : HeVAL (he));
397 root 1.1 }
398    
399     if (mg)
400 root 1.35 encode_ch (enc, MAJOR_MISC | MINOR_INDEF);
401 root 1.1
402     --enc->depth;
403     }
404    
405     // encode objects, arrays and special \0=false and \1=true values.
406     static void
407     encode_rv (enc_t *enc, SV *sv)
408     {
409 root 1.19 SvGETMAGIC (sv);
410 root 1.1
411 root 1.19 svtype svt = SvTYPE (sv);
412 root 1.18
413 root 1.5 if (ecb_expect_false (SvOBJECT (sv)))
414 root 1.1 {
415 root 1.10 HV *boolean_stash = !CBOR_SLOW || types_boolean_stash
416     ? types_boolean_stash
417     : gv_stashpv ("Types::Serialiser::Boolean", 1);
418     HV *error_stash = !CBOR_SLOW || types_error_stash
419     ? types_error_stash
420     : gv_stashpv ("Types::Serialiser::Error", 1);
421 root 1.6 HV *tagged_stash = !CBOR_SLOW || cbor_tagged_stash
422     ? cbor_tagged_stash
423     : gv_stashpv ("CBOR::XS::Tagged" , 1);
424 root 1.1
425 root 1.11 HV *stash = SvSTASH (sv);
426    
427     if (stash == boolean_stash)
428 root 1.34 {
429 root 1.35 encode_ch (enc, SvIV (sv) ? MAJOR_MISC | SIMPLE_TRUE : MAJOR_MISC | SIMPLE_FALSE);
430 root 1.34 return;
431     }
432 root 1.11 else if (stash == error_stash)
433 root 1.34 {
434 root 1.35 encode_ch (enc, MAJOR_MISC | SIMPLE_UNDEF);
435 root 1.34 return;
436     }
437 root 1.11 else if (stash == tagged_stash)
438 root 1.6 {
439     if (svt != SVt_PVAV)
440     croak ("encountered CBOR::XS::Tagged object that isn't an array");
441    
442 root 1.35 encode_uint (enc, MAJOR_TAG, SvUV (*av_fetch ((AV *)sv, 0, 1)));
443 root 1.6 encode_sv (enc, *av_fetch ((AV *)sv, 1, 1));
444 root 1.34
445     return;
446 root 1.6 }
447 root 1.34 }
448    
449     if (ecb_expect_false (SvREFCNT (sv) > 1)
450     && ecb_expect_false (enc->cbor.flags & F_ALLOW_SHARING))
451     {
452     if (!enc->shareable)
453     enc->shareable = (HV *)sv_2mortal ((SV *)newHV ());
454    
455     SV **svp = hv_fetch (enc->shareable, (char *)&sv, sizeof (sv), 1);
456    
457     if (SvOK (*svp))
458     {
459     encode_tag (enc, CBOR_TAG_VALUE_SHAREDREF);
460 root 1.35 encode_uint (enc, MAJOR_POS_INT, SvUV (*svp));
461 root 1.34 return;
462     }
463     else
464     {
465     sv_setuv (*svp, enc->shareable_idx);
466     ++enc->shareable_idx;
467     encode_tag (enc, CBOR_TAG_VALUE_SHAREABLE);
468     }
469     }
470    
471     if (ecb_expect_false (SvOBJECT (sv)))
472     {
473     HV *stash = SvSTASH (sv);
474     GV *method;
475    
476     if ((method = gv_fetchmethod_autoload (stash, "TO_CBOR", 0)))
477 root 1.1 {
478 root 1.11 dSP;
479    
480 root 1.50 ENTER; SAVETMPS;
481     PUSHMARK (SP);
482 root 1.6 // we re-bless the reference to get overload and other niceties right
483 root 1.11 XPUSHs (sv_bless (sv_2mortal (newRV_inc (sv)), stash));
484    
485     PUTBACK;
486     // G_SCALAR ensures that return value is 1
487     call_sv ((SV *)GvCV (method), G_SCALAR);
488     SPAGAIN;
489    
490     // catch this surprisingly common error
491     if (SvROK (TOPs) && SvRV (TOPs) == sv)
492     croak ("%s::TO_CBOR method returned same object as was passed instead of a new one", HvNAME (stash));
493    
494     encode_sv (enc, POPs);
495    
496     PUTBACK;
497    
498     FREETMPS; LEAVE;
499     }
500     else if ((method = gv_fetchmethod_autoload (stash, "FREEZE", 0)) != 0)
501     {
502     dSP;
503 root 1.6
504 root 1.50 ENTER; SAVETMPS;
505     SAVESTACK_POS ();
506     PUSHMARK (SP);
507 root 1.11 EXTEND (SP, 2);
508     // we re-bless the reference to get overload and other niceties right
509     PUSHs (sv_bless (sv_2mortal (newRV_inc (sv)), stash));
510     PUSHs (sv_cbor);
511 root 1.1
512 root 1.11 PUTBACK;
513     int count = call_sv ((SV *)GvCV (method), G_ARRAY);
514     SPAGAIN;
515 root 1.6
516 root 1.11 // catch this surprisingly common error
517     if (count == 1 && SvROK (TOPs) && SvRV (TOPs) == sv)
518     croak ("%s::FREEZE(CBOR) method returned same object as was passed instead of a new one", HvNAME (stash));
519 root 1.6
520 root 1.18 encode_tag (enc, CBOR_TAG_PERL_OBJECT);
521 root 1.35 encode_uint (enc, MAJOR_ARRAY, count + 1);
522 root 1.30 encode_strref (enc, HvNAMEUTF8 (stash), HvNAME (stash), HvNAMELEN (stash));
523 root 1.6
524 root 1.11 while (count)
525     encode_sv (enc, SP[1 - count--]);
526 root 1.6
527 root 1.11 PUTBACK;
528 root 1.6
529 root 1.11 FREETMPS; LEAVE;
530 root 1.1 }
531 root 1.11 else
532     croak ("encountered object '%s', but no TO_CBOR or FREEZE methods available on it",
533     SvPV_nolen (sv_2mortal (newRV_inc (sv))));
534 root 1.1 }
535     else if (svt == SVt_PVHV)
536     encode_hv (enc, (HV *)sv);
537     else if (svt == SVt_PVAV)
538     encode_av (enc, (AV *)sv);
539 root 1.18 else
540 root 1.1 {
541 root 1.18 encode_tag (enc, CBOR_TAG_INDIRECTION);
542     encode_sv (enc, sv);
543 root 1.1 }
544     }
545    
546     static void
547     encode_nv (enc_t *enc, SV *sv)
548     {
549     double nv = SvNVX (sv);
550    
551     need (enc, 9);
552    
553 root 1.35 if (ecb_expect_false (nv == (NV)(U32)nv))
554     encode_uint (enc, MAJOR_POS_INT, (U32)nv);
555 root 1.1 //TODO: maybe I32?
556 root 1.5 else if (ecb_expect_false (nv == (float)nv))
557 root 1.1 {
558     uint32_t fp = ecb_float_to_binary32 (nv);
559    
560 root 1.35 *enc->cur++ = MAJOR_MISC | MISC_FLOAT32;
561 root 1.1
562     if (!ecb_big_endian ())
563     fp = ecb_bswap32 (fp);
564    
565     memcpy (enc->cur, &fp, 4);
566     enc->cur += 4;
567     }
568     else
569     {
570     uint64_t fp = ecb_double_to_binary64 (nv);
571    
572 root 1.35 *enc->cur++ = MAJOR_MISC | MISC_FLOAT64;
573 root 1.1
574     if (!ecb_big_endian ())
575     fp = ecb_bswap64 (fp);
576    
577     memcpy (enc->cur, &fp, 8);
578     enc->cur += 8;
579     }
580     }
581    
582     static void
583     encode_sv (enc_t *enc, SV *sv)
584     {
585     SvGETMAGIC (sv);
586    
587     if (SvPOKp (sv))
588     {
589     STRLEN len;
590     char *str = SvPV (sv, len);
591 root 1.30 encode_strref (enc, SvUTF8 (sv), str, len);
592 root 1.1 }
593     else if (SvNOKp (sv))
594     encode_nv (enc, sv);
595     else if (SvIOKp (sv))
596     {
597     if (SvIsUV (sv))
598 root 1.35 encode_uint (enc, MAJOR_POS_INT, SvUVX (sv));
599 root 1.1 else if (SvIVX (sv) >= 0)
600 root 1.35 encode_uint (enc, MAJOR_POS_INT, SvIVX (sv));
601 root 1.1 else
602 root 1.35 encode_uint (enc, MAJOR_NEG_INT, -(SvIVX (sv) + 1));
603 root 1.1 }
604     else if (SvROK (sv))
605     encode_rv (enc, SvRV (sv));
606     else if (!SvOK (sv))
607 root 1.35 encode_ch (enc, MAJOR_MISC | SIMPLE_NULL);
608 root 1.1 else if (enc->cbor.flags & F_ALLOW_UNKNOWN)
609 root 1.35 encode_ch (enc, MAJOR_MISC | SIMPLE_UNDEF);
610 root 1.1 else
611     croak ("encountered perl type (%s,0x%x) that CBOR cannot handle, check your input data",
612     SvPV_nolen (sv), (unsigned int)SvFLAGS (sv));
613     }
614    
615     static SV *
616     encode_cbor (SV *scalar, CBOR *cbor)
617     {
618 root 1.48 enc_t enc = { 0 };
619 root 1.1
620     enc.cbor = *cbor;
621     enc.sv = sv_2mortal (NEWSV (0, INIT_SIZE));
622     enc.cur = SvPVX (enc.sv);
623     enc.end = SvEND (enc.sv);
624    
625     SvPOK_only (enc.sv);
626 root 1.20
627 root 1.32 if (cbor->flags & F_PACK_STRINGS)
628 root 1.20 {
629     encode_tag (&enc, CBOR_TAG_STRINGREF_NAMESPACE);
630     enc.stringref[0]= (HV *)sv_2mortal ((SV *)newHV ());
631     enc.stringref[1]= (HV *)sv_2mortal ((SV *)newHV ());
632     }
633    
634 root 1.1 encode_sv (&enc, scalar);
635    
636     SvCUR_set (enc.sv, enc.cur - SvPVX (enc.sv));
637     *SvEND (enc.sv) = 0; // many xs functions expect a trailing 0 for text strings
638    
639     if (enc.cbor.flags & F_SHRINK)
640     shrink (enc.sv);
641    
642     return enc.sv;
643     }
644    
645     /////////////////////////////////////////////////////////////////////////////
646     // decoder
647    
648     // structure used for decoding CBOR
649     typedef struct
650     {
651     U8 *cur; // current parser pointer
652     U8 *end; // end of input string
653     const char *err; // parse error, if != 0
654     CBOR cbor;
655     U32 depth; // recursion depth
656     U32 maxdepth; // recursion depth limit
657 root 1.19 AV *shareable;
658 root 1.20 AV *stringref;
659 root 1.27 SV *decode_tagged;
660 root 1.1 } dec_t;
661    
662     #define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE
663    
664 root 1.5 #define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data")
665 root 1.1
666     #define DEC_INC_DEPTH if (++dec->depth > dec->cbor.max_depth) ERR (ERR_NESTING_EXCEEDED)
667     #define DEC_DEC_DEPTH --dec->depth
668    
669     static UV
670     decode_uint (dec_t *dec)
671     {
672 root 1.35 U8 m = *dec->cur & MINOR_MASK;
673     ++dec->cur;
674    
675     if (ecb_expect_true (m < LENGTH_EXT1))
676     return m;
677 root 1.36 else if (ecb_expect_true (m == LENGTH_EXT1))
678     {
679     WANT (1);
680     dec->cur += 1;
681     return dec->cur[-1];
682     }
683     else if (ecb_expect_true (m == LENGTH_EXT2))
684     {
685     WANT (2);
686     dec->cur += 2;
687     return (((UV)dec->cur[-2]) << 8)
688     | ((UV)dec->cur[-1]);
689     }
690     else if (ecb_expect_true (m == LENGTH_EXT4))
691     {
692     WANT (4);
693     dec->cur += 4;
694     return (((UV)dec->cur[-4]) << 24)
695     | (((UV)dec->cur[-3]) << 16)
696     | (((UV)dec->cur[-2]) << 8)
697     | ((UV)dec->cur[-1]);
698     }
699     else if (ecb_expect_true (m == LENGTH_EXT8))
700 root 1.1 {
701 root 1.36 WANT (8);
702     dec->cur += 8;
703 root 1.34
704 root 1.36 return
705 root 1.34 #if UVSIZE < 8
706 root 1.36 0
707 root 1.34 #else
708 root 1.36 (((UV)dec->cur[-8]) << 56)
709     | (((UV)dec->cur[-7]) << 48)
710     | (((UV)dec->cur[-6]) << 40)
711     | (((UV)dec->cur[-5]) << 32)
712 root 1.34 #endif
713 root 1.36 | (((UV)dec->cur[-4]) << 24)
714     | (((UV)dec->cur[-3]) << 16)
715     | (((UV)dec->cur[-2]) << 8)
716     | ((UV)dec->cur[-1]);
717 root 1.1 }
718 root 1.36 else
719     ERR ("corrupted CBOR data (unsupported integer minor encoding)");
720 root 1.1
721     fail:
722     return 0;
723     }
724    
725     static SV *decode_sv (dec_t *dec);
726    
727     static SV *
728     decode_av (dec_t *dec)
729     {
730     AV *av = newAV ();
731    
732     DEC_INC_DEPTH;
733    
734 root 1.35 if (*dec->cur == (MAJOR_ARRAY | MINOR_INDEF))
735 root 1.1 {
736     ++dec->cur;
737    
738     for (;;)
739     {
740     WANT (1);
741    
742 root 1.35 if (*dec->cur == (MAJOR_MISC | MINOR_INDEF))
743 root 1.1 {
744     ++dec->cur;
745     break;
746     }
747    
748     av_push (av, decode_sv (dec));
749     }
750     }
751     else
752     {
753     int i, len = decode_uint (dec);
754    
755 root 1.36 WANT (len); // complexity check for av_fill - need at least one byte per value, do not allow supersize arrays
756 root 1.1 av_fill (av, len - 1);
757    
758     for (i = 0; i < len; ++i)
759     AvARRAY (av)[i] = decode_sv (dec);
760     }
761    
762     DEC_DEC_DEPTH;
763     return newRV_noinc ((SV *)av);
764    
765     fail:
766     SvREFCNT_dec (av);
767     DEC_DEC_DEPTH;
768     return &PL_sv_undef;
769     }
770    
771 root 1.16 static void
772     decode_he (dec_t *dec, HV *hv)
773     {
774     // for speed reasons, we specialcase single-string
775 root 1.21 // byte or utf-8 strings as keys, but only when !stringref
776    
777 root 1.23 if (ecb_expect_true (!dec->stringref))
778 root 1.43 if (ecb_expect_true ((U8)(*dec->cur - MAJOR_BYTES) <= LENGTH_EXT8))
779 root 1.21 {
780     I32 len = decode_uint (dec);
781     char *key = (char *)dec->cur;
782 root 1.16
783 root 1.49 WANT (len);
784 root 1.21 dec->cur += len;
785    
786 root 1.49 hv_store (hv, key, len, decode_sv (dec), 0);
787 root 1.16
788 root 1.21 return;
789     }
790 root 1.43 else if (ecb_expect_true ((U8)(*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8))
791 root 1.21 {
792     I32 len = decode_uint (dec);
793     char *key = (char *)dec->cur;
794 root 1.16
795 root 1.49 WANT (len);
796 root 1.21 dec->cur += len;
797 root 1.20
798 root 1.38 if (ecb_expect_false (dec->cbor.flags & F_VALIDATE_UTF8))
799     if (!is_utf8_string (key, len))
800     ERR ("corrupted CBOR data (invalid UTF-8 in map key)");
801 root 1.16
802 root 1.21 hv_store (hv, key, -len, decode_sv (dec), 0);
803 root 1.16
804 root 1.21 return;
805     }
806 root 1.20
807 root 1.21 SV *k = decode_sv (dec);
808     SV *v = decode_sv (dec);
809 root 1.16
810 root 1.21 hv_store_ent (hv, k, v, 0);
811     SvREFCNT_dec (k);
812 root 1.38
813     fail:
814     ;
815 root 1.16 }
816    
817 root 1.1 static SV *
818     decode_hv (dec_t *dec)
819     {
820     HV *hv = newHV ();
821    
822     DEC_INC_DEPTH;
823    
824 root 1.35 if (*dec->cur == (MAJOR_MAP | MINOR_INDEF))
825 root 1.1 {
826     ++dec->cur;
827    
828     for (;;)
829     {
830     WANT (1);
831    
832 root 1.35 if (*dec->cur == (MAJOR_MISC | MINOR_INDEF))
833 root 1.1 {
834     ++dec->cur;
835     break;
836     }
837    
838 root 1.16 decode_he (dec, hv);
839 root 1.1 }
840     }
841     else
842     {
843 root 1.16 int pairs = decode_uint (dec);
844 root 1.1
845 root 1.16 while (pairs--)
846     decode_he (dec, hv);
847 root 1.1 }
848    
849     DEC_DEC_DEPTH;
850     return newRV_noinc ((SV *)hv);
851    
852     fail:
853     SvREFCNT_dec (hv);
854     DEC_DEC_DEPTH;
855     return &PL_sv_undef;
856     }
857    
858     static SV *
859     decode_str (dec_t *dec, int utf8)
860     {
861 root 1.6 SV *sv = 0;
862 root 1.1
863 root 1.35 if ((*dec->cur & MINOR_MASK) == MINOR_INDEF)
864 root 1.1 {
865 root 1.33 // indefinite length strings
866 root 1.1 ++dec->cur;
867    
868 root 1.35 U8 major = *dec->cur & MAJOR_MISC;
869 root 1.33
870 root 1.1 sv = newSVpvn ("", 0);
871    
872     for (;;)
873     {
874     WANT (1);
875    
876 root 1.35 if ((*dec->cur - major) > LENGTH_EXT8)
877     if (*dec->cur == (MAJOR_MISC | MINOR_INDEF))
878 root 1.33 {
879     ++dec->cur;
880     break;
881     }
882     else
883     ERR ("corrupted CBOR data (invalid chunks in indefinite length string)");
884    
885     STRLEN len = decode_uint (dec);
886 root 1.1
887 root 1.33 WANT (len);
888     sv_catpvn (sv, dec->cur, len);
889     dec->cur += len;
890 root 1.1 }
891     }
892     else
893     {
894     STRLEN len = decode_uint (dec);
895    
896     WANT (len);
897     sv = newSVpvn (dec->cur, len);
898     dec->cur += len;
899 root 1.25
900     if (ecb_expect_false (dec->stringref)
901     && SvCUR (sv) >= minimum_string_length (AvFILLp (dec->stringref) + 1))
902     av_push (dec->stringref, SvREFCNT_inc_NN (sv));
903 root 1.1 }
904    
905     if (utf8)
906 root 1.38 {
907     if (ecb_expect_false (dec->cbor.flags & F_VALIDATE_UTF8))
908     if (!is_utf8_string (SvPVX (sv), SvCUR (sv)))
909     ERR ("corrupted CBOR data (invalid UTF-8 in text string)");
910    
911     SvUTF8_on (sv);
912     }
913 root 1.1
914     return sv;
915    
916     fail:
917 root 1.6 SvREFCNT_dec (sv);
918 root 1.1 return &PL_sv_undef;
919     }
920    
921     static SV *
922 root 1.3 decode_tagged (dec_t *dec)
923     {
924 root 1.19 SV *sv = 0;
925 root 1.3 UV tag = decode_uint (dec);
926 root 1.19
927     WANT (1);
928 root 1.3
929 root 1.18 switch (tag)
930     {
931     case CBOR_TAG_MAGIC:
932 root 1.20 sv = decode_sv (dec);
933     break;
934 root 1.18
935     case CBOR_TAG_INDIRECTION:
936 root 1.20 sv = newRV_noinc (decode_sv (dec));
937     break;
938    
939     case CBOR_TAG_STRINGREF_NAMESPACE:
940     {
941     ENTER; SAVETMPS;
942    
943     SAVESPTR (dec->stringref);
944     dec->stringref = (AV *)sv_2mortal ((SV *)newAV ());
945    
946     sv = decode_sv (dec);
947    
948     FREETMPS; LEAVE;
949     }
950     break;
951    
952     case CBOR_TAG_STRINGREF:
953     {
954 root 1.35 if ((*dec->cur >> MAJOR_SHIFT) != (MAJOR_POS_INT >> MAJOR_SHIFT))
955 root 1.20 ERR ("corrupted CBOR data (stringref index not an unsigned integer)");
956    
957     UV idx = decode_uint (dec);
958    
959     if (!dec->stringref || (int)idx > AvFILLp (dec->stringref))
960     ERR ("corrupted CBOR data (stringref index out of bounds or outside namespace)");
961    
962     sv = newSVsv (AvARRAY (dec->stringref)[idx]);
963     }
964     break;
965 root 1.11
966 root 1.19 case CBOR_TAG_VALUE_SHAREABLE:
967     {
968     if (ecb_expect_false (!dec->shareable))
969     dec->shareable = (AV *)sv_2mortal ((SV *)newAV ());
970    
971 root 1.37 if (dec->cbor.flags & F_ALLOW_CYCLES)
972     {
973     sv = newSV (0);
974     av_push (dec->shareable, SvREFCNT_inc_NN (sv));
975 root 1.18
976 root 1.37 SV *osv = decode_sv (dec);
977     sv_setsv (sv, osv);
978     SvREFCNT_dec_NN (osv);
979     }
980     else
981     {
982     av_push (dec->shareable, &PL_sv_undef);
983     int idx = AvFILLp (dec->shareable);
984     sv = decode_sv (dec);
985     av_store (dec->shareable, idx, SvREFCNT_inc_NN (sv));
986     }
987 root 1.19 }
988 root 1.20 break;
989 root 1.18
990     case CBOR_TAG_VALUE_SHAREDREF:
991 root 1.17 {
992 root 1.35 if ((*dec->cur >> MAJOR_SHIFT) != (MAJOR_POS_INT >> MAJOR_SHIFT))
993 root 1.19 ERR ("corrupted CBOR data (sharedref index not an unsigned integer)");
994 root 1.18
995 root 1.19 UV idx = decode_uint (dec);
996    
997 root 1.20 if (!dec->shareable || (int)idx > AvFILLp (dec->shareable))
998 root 1.18 ERR ("corrupted CBOR data (sharedref index out of bounds)");
999    
1000 root 1.20 sv = SvREFCNT_inc_NN (AvARRAY (dec->shareable)[idx]);
1001 root 1.37
1002     if (sv == &PL_sv_undef)
1003     ERR ("cyclic CBOR data structure found, but allow_cycles is not enabled");
1004 root 1.17 }
1005 root 1.20 break;
1006 root 1.17
1007 root 1.18 case CBOR_TAG_PERL_OBJECT:
1008     {
1009 root 1.19 sv = decode_sv (dec);
1010    
1011 root 1.18 if (!SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV)
1012     ERR ("corrupted CBOR data (non-array perl object)");
1013    
1014     AV *av = (AV *)SvRV (sv);
1015     int len = av_len (av) + 1;
1016     HV *stash = gv_stashsv (*av_fetch (av, 0, 1), 0);
1017    
1018     if (!stash)
1019     ERR ("cannot decode perl-object (package does not exist)");
1020    
1021     GV *method = gv_fetchmethod_autoload (stash, "THAW", 0);
1022    
1023     if (!method)
1024     ERR ("cannot decode perl-object (package does not have a THAW method)");
1025    
1026     dSP;
1027    
1028 root 1.50 ENTER; SAVETMPS;
1029     PUSHMARK (SP);
1030 root 1.18 EXTEND (SP, len + 1);
1031     // we re-bless the reference to get overload and other niceties right
1032     PUSHs (*av_fetch (av, 0, 1));
1033     PUSHs (sv_cbor);
1034    
1035     int i;
1036    
1037     for (i = 1; i < len; ++i)
1038     PUSHs (*av_fetch (av, i, 1));
1039    
1040     PUTBACK;
1041     call_sv ((SV *)GvCV (method), G_SCALAR | G_EVAL);
1042     SPAGAIN;
1043    
1044     if (SvTRUE (ERRSV))
1045     {
1046     FREETMPS; LEAVE;
1047     ERR (SvPVutf8_nolen (sv_2mortal (SvREFCNT_inc (ERRSV))));
1048     }
1049    
1050     SvREFCNT_dec (sv);
1051     sv = SvREFCNT_inc (POPs);
1052 root 1.11
1053 root 1.18 PUTBACK;
1054 root 1.11
1055 root 1.18 FREETMPS; LEAVE;
1056     }
1057 root 1.20 break;
1058 root 1.9
1059 root 1.18 default:
1060     {
1061 root 1.19 sv = decode_sv (dec);
1062    
1063 root 1.27 dSP;
1064 root 1.50 ENTER; SAVETMPS;
1065     SAVESTACK_POS ();
1066     PUSHMARK (SP);
1067 root 1.27 EXTEND (SP, 2);
1068     PUSHs (newSVuv (tag));
1069     PUSHs (sv);
1070    
1071     PUTBACK;
1072     int count = call_sv (dec->cbor.filter ? dec->cbor.filter : default_filter, G_ARRAY | G_EVAL);
1073     SPAGAIN;
1074    
1075     if (SvTRUE (ERRSV))
1076     {
1077     FREETMPS; LEAVE;
1078     ERR (SvPVutf8_nolen (sv_2mortal (SvREFCNT_inc (ERRSV))));
1079     }
1080    
1081     if (count)
1082     {
1083     SvREFCNT_dec (sv);
1084     sv = SvREFCNT_inc (POPs);
1085     }
1086     else
1087     {
1088     AV *av = newAV ();
1089     av_push (av, newSVuv (tag));
1090     av_push (av, sv);
1091    
1092     HV *tagged_stash = !CBOR_SLOW || cbor_tagged_stash
1093     ? cbor_tagged_stash
1094     : gv_stashpv ("CBOR::XS::Tagged" , 1);
1095     sv = sv_bless (newRV_noinc ((SV *)av), tagged_stash);
1096     }
1097 root 1.7
1098 root 1.27 PUTBACK;
1099    
1100     FREETMPS; LEAVE;
1101 root 1.18 }
1102 root 1.20 break;
1103 root 1.11 }
1104 root 1.9
1105 root 1.20 return sv;
1106    
1107 root 1.9 fail:
1108     SvREFCNT_dec (sv);
1109     return &PL_sv_undef;
1110 root 1.3 }
1111    
1112     static SV *
1113 root 1.1 decode_sv (dec_t *dec)
1114     {
1115     WANT (1);
1116    
1117 root 1.35 switch (*dec->cur >> MAJOR_SHIFT)
1118 root 1.1 {
1119 root 1.35 case MAJOR_POS_INT >> MAJOR_SHIFT: return newSVuv (decode_uint (dec));
1120     case MAJOR_NEG_INT >> MAJOR_SHIFT: return newSViv (-1 - (IV)decode_uint (dec));
1121     case MAJOR_BYTES >> MAJOR_SHIFT: return decode_str (dec, 0);
1122     case MAJOR_TEXT >> MAJOR_SHIFT: return decode_str (dec, 1);
1123     case MAJOR_ARRAY >> MAJOR_SHIFT: return decode_av (dec);
1124     case MAJOR_MAP >> MAJOR_SHIFT: return decode_hv (dec);
1125     case MAJOR_TAG >> MAJOR_SHIFT: return decode_tagged (dec);
1126    
1127     case MAJOR_MISC >> MAJOR_SHIFT:
1128     switch (*dec->cur++ & MINOR_MASK)
1129 root 1.1 {
1130 root 1.35 case SIMPLE_FALSE:
1131 root 1.1 #if CBOR_SLOW
1132 root 1.10 types_false = get_bool ("Types::Serialiser::false");
1133 root 1.1 #endif
1134 root 1.10 return newSVsv (types_false);
1135 root 1.35 case SIMPLE_TRUE:
1136 root 1.1 #if CBOR_SLOW
1137 root 1.10 types_true = get_bool ("Types::Serialiser::true");
1138 root 1.1 #endif
1139 root 1.10 return newSVsv (types_true);
1140 root 1.35 case SIMPLE_NULL:
1141 root 1.1 return newSVsv (&PL_sv_undef);
1142 root 1.35 case SIMPLE_UNDEF:
1143 root 1.10 #if CBOR_SLOW
1144     types_error = get_bool ("Types::Serialiser::error");
1145     #endif
1146     return newSVsv (types_error);
1147 root 1.1
1148 root 1.35 case MISC_FLOAT16:
1149 root 1.2 {
1150     WANT (2);
1151    
1152     uint16_t fp = (dec->cur[0] << 8) | dec->cur[1];
1153     dec->cur += 2;
1154    
1155     return newSVnv (ecb_binary16_to_float (fp));
1156     }
1157 root 1.1
1158 root 1.35 case MISC_FLOAT32:
1159 root 1.1 {
1160     uint32_t fp;
1161     WANT (4);
1162     memcpy (&fp, dec->cur, 4);
1163     dec->cur += 4;
1164    
1165     if (!ecb_big_endian ())
1166     fp = ecb_bswap32 (fp);
1167    
1168     return newSVnv (ecb_binary32_to_float (fp));
1169     }
1170    
1171 root 1.35 case MISC_FLOAT64:
1172 root 1.1 {
1173     uint64_t fp;
1174     WANT (8);
1175     memcpy (&fp, dec->cur, 8);
1176     dec->cur += 8;
1177    
1178     if (!ecb_big_endian ())
1179     fp = ecb_bswap64 (fp);
1180    
1181     return newSVnv (ecb_binary64_to_double (fp));
1182     }
1183    
1184 root 1.35 // 0..19 unassigned simple
1185 root 1.40 // 24 reserved + unassigned simple (reserved values are not encodable)
1186     // 28-30 unassigned misc
1187     // 31 break code
1188 root 1.1 default:
1189 root 1.40 ERR ("corrupted CBOR data (reserved/unassigned/unexpected major 7 value)");
1190 root 1.1 }
1191    
1192     break;
1193     }
1194    
1195     fail:
1196     return &PL_sv_undef;
1197     }
1198    
1199     static SV *
1200     decode_cbor (SV *string, CBOR *cbor, char **offset_return)
1201     {
1202 root 1.48 dec_t dec = { 0 };
1203 root 1.1 SV *sv;
1204 root 1.16 STRLEN len;
1205     char *data = SvPVbyte (string, len);
1206 root 1.1
1207 root 1.16 if (len > cbor->max_size && cbor->max_size)
1208     croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu",
1209     (unsigned long)len, (unsigned long)cbor->max_size);
1210 root 1.1
1211     dec.cbor = *cbor;
1212 root 1.16 dec.cur = (U8 *)data;
1213     dec.end = (U8 *)data + len;
1214 root 1.1
1215     sv = decode_sv (&dec);
1216    
1217     if (offset_return)
1218     *offset_return = dec.cur;
1219    
1220     if (!(offset_return || !sv))
1221 root 1.2 if (dec.cur != dec.end && !dec.err)
1222     dec.err = "garbage after CBOR object";
1223    
1224     if (dec.err)
1225 root 1.1 {
1226 root 1.39 if (dec.shareable)
1227     {
1228     // need to break cyclic links, which whould all be in shareable
1229     int i;
1230     SV **svp;
1231    
1232     for (i = av_len (dec.shareable) + 1; i--; )
1233     if ((svp = av_fetch (dec.shareable, i, 0)))
1234     sv_setsv (*svp, &PL_sv_undef);
1235     }
1236    
1237 root 1.2 SvREFCNT_dec (sv);
1238 root 1.16 croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)data, (int)(uint8_t)*dec.cur);
1239 root 1.1 }
1240    
1241     sv = sv_2mortal (sv);
1242    
1243     return sv;
1244     }
1245    
1246     /////////////////////////////////////////////////////////////////////////////
1247 root 1.40 // incremental parser
1248    
1249     #define INCR_DONE(cbor) (AvFILLp (cbor->incr_count) < 0)
1250    
1251     // returns 0 for notyet, 1 for success or error
1252     static int
1253     incr_parse (CBOR *self, SV *cborstr)
1254     {
1255     STRLEN cur;
1256     SvPV (cborstr, cur);
1257    
1258     while (ecb_expect_true (self->incr_need <= cur))
1259     {
1260     // table of integer count bytes
1261     static I8 incr_len[MINOR_MASK + 1] = {
1262     0, 0, 0, 0, 0, 0, 0, 0,
1263     0, 0, 0, 0, 0, 0, 0, 0,
1264     0, 0, 0, 0, 0, 0, 0, 0,
1265     1, 2, 4, 8,-1,-1,-1,-2
1266     };
1267    
1268     const U8 *p = SvPVX (cborstr) + self->incr_pos;
1269     U8 m = *p & MINOR_MASK;
1270     IV count = SvIVX (AvARRAY (self->incr_count)[AvFILLp (self->incr_count)]);
1271     I8 ilen = incr_len[m];
1272    
1273     self->incr_need = self->incr_pos + 1;
1274    
1275     if (ecb_expect_false (ilen < 0))
1276     {
1277     if (m != MINOR_INDEF)
1278     return 1; // error
1279    
1280     if (*p == (MAJOR_MISC | MINOR_INDEF))
1281     {
1282     if (count >= 0)
1283     return 1; // error
1284    
1285     count = 1;
1286     }
1287     else
1288     {
1289     av_push (self->incr_count, newSViv (-1)); //TODO: nest
1290     count = -1;
1291     }
1292     }
1293     else
1294     {
1295     self->incr_need += ilen;
1296     if (ecb_expect_false (self->incr_need > cur))
1297     return 0;
1298    
1299     int major = *p >> MAJOR_SHIFT;
1300    
1301     switch (major)
1302     {
1303 root 1.47 case MAJOR_TAG >> MAJOR_SHIFT:
1304     ++count; // tags merely prefix another value
1305     break;
1306    
1307 root 1.40 case MAJOR_BYTES >> MAJOR_SHIFT:
1308     case MAJOR_TEXT >> MAJOR_SHIFT:
1309     case MAJOR_ARRAY >> MAJOR_SHIFT:
1310     case MAJOR_MAP >> MAJOR_SHIFT:
1311     {
1312     UV len;
1313    
1314     if (ecb_expect_false (ilen))
1315     {
1316     len = 0;
1317    
1318     do {
1319     len = (len << 8) | *++p;
1320     } while (--ilen);
1321     }
1322     else
1323     len = m;
1324    
1325     switch (major)
1326     {
1327     case MAJOR_BYTES >> MAJOR_SHIFT:
1328     case MAJOR_TEXT >> MAJOR_SHIFT:
1329     self->incr_need += len;
1330     if (ecb_expect_false (self->incr_need > cur))
1331     return 0;
1332    
1333     break;
1334    
1335     case MAJOR_MAP >> MAJOR_SHIFT:
1336     len <<= 1;
1337     case MAJOR_ARRAY >> MAJOR_SHIFT:
1338     if (len)
1339     {
1340     av_push (self->incr_count, newSViv (len + 1)); //TODO: nest
1341     count = len + 1;
1342     }
1343     break;
1344     }
1345     }
1346     }
1347     }
1348    
1349     self->incr_pos = self->incr_need;
1350    
1351     if (count > 0)
1352     {
1353     while (!--count)
1354     {
1355     if (!AvFILLp (self->incr_count))
1356     return 1; // done
1357    
1358     SvREFCNT_dec_NN (av_pop (self->incr_count));
1359     count = SvIVX (AvARRAY (self->incr_count)[AvFILLp (self->incr_count)]);
1360     }
1361    
1362     SvIVX (AvARRAY (self->incr_count)[AvFILLp (self->incr_count)]) = count;
1363     }
1364     }
1365    
1366     return 0;
1367     }
1368    
1369    
1370     /////////////////////////////////////////////////////////////////////////////
1371 root 1.1 // XS interface functions
1372    
1373     MODULE = CBOR::XS PACKAGE = CBOR::XS
1374    
1375     BOOT:
1376     {
1377     cbor_stash = gv_stashpv ("CBOR::XS" , 1);
1378 root 1.6 cbor_tagged_stash = gv_stashpv ("CBOR::XS::Tagged" , 1);
1379 root 1.1
1380 root 1.10 types_boolean_stash = gv_stashpv ("Types::Serialiser::Boolean", 1);
1381     types_error_stash = gv_stashpv ("Types::Serialiser::Error" , 1);
1382    
1383     types_true = get_bool ("Types::Serialiser::true" );
1384     types_false = get_bool ("Types::Serialiser::false");
1385     types_error = get_bool ("Types::Serialiser::error");
1386 root 1.11
1387 root 1.27 default_filter = newSVpv ("CBOR::XS::default_filter", 0);
1388    
1389 root 1.11 sv_cbor = newSVpv ("CBOR", 0);
1390     SvREADONLY_on (sv_cbor);
1391 root 1.1 }
1392    
1393     PROTOTYPES: DISABLE
1394    
1395     void CLONE (...)
1396     CODE:
1397 root 1.10 cbor_stash = 0;
1398     cbor_tagged_stash = 0;
1399     types_error_stash = 0;
1400     types_boolean_stash = 0;
1401 root 1.1
1402     void new (char *klass)
1403     PPCODE:
1404     {
1405     SV *pv = NEWSV (0, sizeof (CBOR));
1406     SvPOK_only (pv);
1407     cbor_init ((CBOR *)SvPVX (pv));
1408     XPUSHs (sv_2mortal (sv_bless (
1409     newRV_noinc (pv),
1410     strEQ (klass, "CBOR::XS") ? CBOR_STASH : gv_stashpv (klass, 1)
1411     )));
1412     }
1413    
1414     void shrink (CBOR *self, int enable = 1)
1415     ALIAS:
1416     shrink = F_SHRINK
1417     allow_unknown = F_ALLOW_UNKNOWN
1418 root 1.18 allow_sharing = F_ALLOW_SHARING
1419 root 1.37 allow_cycles = F_ALLOW_CYCLES
1420 root 1.32 pack_strings = F_PACK_STRINGS
1421 root 1.51 utf8_strings = F_UTF8_STRINGS
1422 root 1.38 validate_utf8 = F_VALIDATE_UTF8
1423 root 1.1 PPCODE:
1424     {
1425     if (enable)
1426     self->flags |= ix;
1427     else
1428     self->flags &= ~ix;
1429    
1430     XPUSHs (ST (0));
1431     }
1432    
1433     void get_shrink (CBOR *self)
1434     ALIAS:
1435     get_shrink = F_SHRINK
1436     get_allow_unknown = F_ALLOW_UNKNOWN
1437 root 1.18 get_allow_sharing = F_ALLOW_SHARING
1438 root 1.37 get_allow_cycles = F_ALLOW_CYCLES
1439 root 1.32 get_pack_strings = F_PACK_STRINGS
1440 root 1.38 get_validate_utf8 = F_VALIDATE_UTF8
1441 root 1.1 PPCODE:
1442     XPUSHs (boolSV (self->flags & ix));
1443    
1444     void max_depth (CBOR *self, U32 max_depth = 0x80000000UL)
1445     PPCODE:
1446     self->max_depth = max_depth;
1447     XPUSHs (ST (0));
1448    
1449     U32 get_max_depth (CBOR *self)
1450     CODE:
1451     RETVAL = self->max_depth;
1452     OUTPUT:
1453     RETVAL
1454    
1455     void max_size (CBOR *self, U32 max_size = 0)
1456     PPCODE:
1457     self->max_size = max_size;
1458     XPUSHs (ST (0));
1459    
1460     int get_max_size (CBOR *self)
1461     CODE:
1462     RETVAL = self->max_size;
1463     OUTPUT:
1464     RETVAL
1465    
1466 root 1.27 void filter (CBOR *self, SV *filter = 0)
1467     PPCODE:
1468     SvREFCNT_dec (self->filter);
1469     self->filter = filter ? newSVsv (filter) : filter;
1470     XPUSHs (ST (0));
1471    
1472     SV *get_filter (CBOR *self)
1473     CODE:
1474     RETVAL = self->filter ? self->filter : NEWSV (0, 0);
1475     OUTPUT:
1476     RETVAL
1477    
1478 root 1.1 void encode (CBOR *self, SV *scalar)
1479     PPCODE:
1480     PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN;
1481     XPUSHs (scalar);
1482    
1483     void decode (CBOR *self, SV *cborstr)
1484     PPCODE:
1485     PUTBACK; cborstr = decode_cbor (cborstr, self, 0); SPAGAIN;
1486     XPUSHs (cborstr);
1487    
1488     void decode_prefix (CBOR *self, SV *cborstr)
1489     PPCODE:
1490     {
1491     SV *sv;
1492     char *offset;
1493     PUTBACK; sv = decode_cbor (cborstr, self, &offset); SPAGAIN;
1494     EXTEND (SP, 2);
1495     PUSHs (sv);
1496     PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr))));
1497     }
1498    
1499 root 1.41 void incr_parse (CBOR *self, SV *cborstr)
1500 root 1.42 ALIAS:
1501     incr_parse_multiple = 1
1502 root 1.40 PPCODE:
1503     {
1504     if (SvUTF8 (cborstr))
1505     sv_utf8_downgrade (cborstr, 0);
1506    
1507     if (!self->incr_count)
1508     {
1509     self->incr_count = newAV ();
1510     self->incr_pos = 0;
1511     self->incr_need = 1;
1512    
1513     av_push (self->incr_count, newSViv (1));
1514     }
1515    
1516 root 1.41 do
1517 root 1.40 {
1518     if (!incr_parse (self, cborstr))
1519     {
1520     if (self->incr_need > self->max_size && self->max_size)
1521     croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu",
1522     (unsigned long)self->incr_need, (unsigned long)self->max_size);
1523    
1524     break;
1525     }
1526    
1527 root 1.41 SV *sv;
1528     char *offset;
1529 root 1.40
1530 root 1.41 PUTBACK; sv = decode_cbor (cborstr, self, &offset); SPAGAIN;
1531     XPUSHs (sv);
1532 root 1.40
1533 root 1.41 sv_chop (cborstr, offset);
1534 root 1.40
1535 root 1.41 av_clear (self->incr_count);
1536     av_push (self->incr_count, newSViv (1));
1537 root 1.40
1538 root 1.41 self->incr_pos = 0;
1539     self->incr_need = self->incr_pos + 1;
1540 root 1.40 }
1541 root 1.42 while (ix);
1542 root 1.40 }
1543    
1544     void incr_reset (CBOR *self)
1545     CODE:
1546     {
1547     SvREFCNT_dec (self->incr_count);
1548     self->incr_count = 0;
1549     }
1550    
1551 root 1.27 void DESTROY (CBOR *self)
1552     PPCODE:
1553     cbor_free (self);
1554    
1555 root 1.1 PROTOTYPES: ENABLE
1556    
1557     void encode_cbor (SV *scalar)
1558 root 1.36 ALIAS:
1559     encode_cbor = 0
1560     encode_cbor_sharing = F_ALLOW_SHARING
1561 root 1.1 PPCODE:
1562     {
1563     CBOR cbor;
1564     cbor_init (&cbor);
1565 root 1.36 cbor.flags |= ix;
1566 root 1.1 PUTBACK; scalar = encode_cbor (scalar, &cbor); SPAGAIN;
1567     XPUSHs (scalar);
1568     }
1569    
1570     void decode_cbor (SV *cborstr)
1571     PPCODE:
1572     {
1573     CBOR cbor;
1574     cbor_init (&cbor);
1575     PUTBACK; cborstr = decode_cbor (cborstr, &cbor, 0); SPAGAIN;
1576     XPUSHs (cborstr);
1577     }
1578