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