ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/CBOR-XS/XS.xs
Revision: 1.2
Committed: Sat Oct 26 10:41:12 2013 UTC (10 years, 6 months ago) by root
Branch: MAIN
Changes since 1.1: +17 -15 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     #include "ecb.h"
13    
14     #if defined(__BORLANDC__) || defined(_MSC_VER)
15     # define snprintf _snprintf // C compilers have this in stdio.h
16     #endif
17    
18     #define F_SHRINK 0x00000200UL
19     #define F_ALLOW_UNKNOWN 0x00002000UL
20    
21     #define INIT_SIZE 32 // initial scalar size to be allocated
22    
23     #define SB do {
24     #define SE } while (0)
25    
26     #if __GNUC__ >= 3
27     # define expect(expr,value) __builtin_expect ((expr), (value))
28     # define INLINE static inline
29     #else
30     # define expect(expr,value) (expr)
31     # define INLINE static
32     #endif
33    
34     #define expect_false(expr) expect ((expr) != 0, 0)
35     #define expect_true(expr) expect ((expr) != 0, 1)
36    
37     #define IN_RANGE_INC(type,val,beg,end) \
38     ((unsigned type)((unsigned type)(val) - (unsigned type)(beg)) \
39     <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg)))
40    
41     #define ERR_NESTING_EXCEEDED "cbor text or perl structure exceeds maximum nesting level (max_depth set too low?)"
42    
43     #ifdef USE_ITHREADS
44     # define CBOR_SLOW 1
45     # define CBOR_STASH (cbor_stash ? cbor_stash : gv_stashpv ("CBOR::XS", 1))
46     #else
47     # define CBOR_SLOW 0
48     # define CBOR_STASH cbor_stash
49     #endif
50    
51     static HV *cbor_stash, *cbor_boolean_stash; // CBOR::XS::
52     static SV *cbor_true, *cbor_false;
53    
54     typedef struct {
55     U32 flags;
56     U32 max_depth;
57     STRLEN max_size;
58    
59     SV *cb_object;
60     HV *cb_sk_object;
61     } CBOR;
62    
63     INLINE void
64     cbor_init (CBOR *cbor)
65     {
66     Zero (cbor, 1, CBOR);
67     cbor->max_depth = 512;
68     }
69    
70     /////////////////////////////////////////////////////////////////////////////
71     // utility functions
72    
73     INLINE SV *
74     get_bool (const char *name)
75     {
76     SV *sv = get_sv (name, 1);
77    
78     SvREADONLY_on (sv);
79     SvREADONLY_on (SvRV (sv));
80    
81     return sv;
82     }
83    
84     INLINE void
85     shrink (SV *sv)
86     {
87     sv_utf8_downgrade (sv, 1);
88    
89     if (SvLEN (sv) > SvCUR (sv) + 1)
90     {
91     #ifdef SvPV_shrink_to_cur
92     SvPV_shrink_to_cur (sv);
93     #elif defined (SvPV_renew)
94     SvPV_renew (sv, SvCUR (sv) + 1);
95     #endif
96     }
97     }
98    
99     /////////////////////////////////////////////////////////////////////////////
100     // fp hell
101    
102     //TODO
103    
104     /////////////////////////////////////////////////////////////////////////////
105     // encoder
106    
107     // structure used for encoding CBOR
108     typedef struct
109     {
110     char *cur; // SvPVX (sv) + current output position
111     char *end; // SvEND (sv)
112     SV *sv; // result scalar
113     CBOR cbor;
114     U32 depth; // recursion level
115     } enc_t;
116    
117     INLINE void
118     need (enc_t *enc, STRLEN len)
119     {
120     if (expect_false (enc->cur + len >= enc->end))
121     {
122     STRLEN cur = enc->cur - (char *)SvPVX (enc->sv);
123     SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1);
124     enc->cur = SvPVX (enc->sv) + cur;
125     enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1;
126     }
127     }
128    
129     INLINE void
130     encode_ch (enc_t *enc, char ch)
131     {
132     need (enc, 1);
133     *enc->cur++ = ch;
134     }
135    
136     static void
137     encode_uint (enc_t *enc, int major, UV len)
138     {
139     need (enc, 9);
140    
141     if (len < 24)
142     *enc->cur++ = major | len;
143     else if (len < 0x100)
144     {
145     *enc->cur++ = major | 24;
146     *enc->cur++ = len;
147     }
148     else if (len < 0x10000)
149     {
150     *enc->cur++ = major | 25;
151     *enc->cur++ = len >> 8;
152     *enc->cur++ = len;
153     }
154     else if (len < 0x100000000)
155     {
156     *enc->cur++ = major | 26;
157     *enc->cur++ = len >> 24;
158     *enc->cur++ = len >> 16;
159     *enc->cur++ = len >> 8;
160     *enc->cur++ = len;
161     }
162     else if (len)
163     {
164     *enc->cur++ = major | 27;
165     *enc->cur++ = len >> 56;
166     *enc->cur++ = len >> 48;
167     *enc->cur++ = len >> 40;
168     *enc->cur++ = len >> 32;
169     *enc->cur++ = len >> 24;
170     *enc->cur++ = len >> 16;
171     *enc->cur++ = len >> 8;
172     *enc->cur++ = len;
173     }
174     }
175    
176     static void
177     encode_str (enc_t *enc, int utf8, char *str, STRLEN len)
178     {
179     encode_uint (enc, utf8 ? 0x60 : 0x40, len);
180     need (enc, len);
181     memcpy (enc->cur, str, len);
182     enc->cur += len;
183     }
184    
185     static void encode_sv (enc_t *enc, SV *sv);
186    
187     static void
188     encode_av (enc_t *enc, AV *av)
189     {
190     int i, len = av_len (av);
191    
192     if (enc->depth >= enc->cbor.max_depth)
193     croak (ERR_NESTING_EXCEEDED);
194    
195     ++enc->depth;
196    
197     encode_uint (enc, 0x80, len + 1);
198    
199     for (i = 0; i <= len; ++i)
200     {
201     SV **svp = av_fetch (av, i, 0);
202     encode_sv (enc, svp ? *svp : &PL_sv_undef);
203     }
204    
205     --enc->depth;
206     }
207    
208     static void
209     encode_hv (enc_t *enc, HV *hv)
210     {
211     HE *he;
212    
213     if (enc->depth >= enc->cbor.max_depth)
214     croak (ERR_NESTING_EXCEEDED);
215    
216     ++enc->depth;
217    
218     int pairs = hv_iterinit (hv);
219     int mg = SvMAGICAL (hv);
220    
221     if (mg)
222     encode_ch (enc, 0xa0 | 31);
223     else
224     encode_uint (enc, 0xa0, pairs);
225    
226     while ((he = hv_iternext (hv)))
227     {
228     if (HeKLEN (he) == HEf_SVKEY)
229     encode_sv (enc, HeSVKEY (he));
230     else
231     encode_str (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he));
232    
233     encode_sv (enc, expect_false (mg) ? hv_iterval (hv, he) : HeVAL (he));
234     }
235    
236     if (mg)
237     encode_ch (enc, 0xe0 | 31);
238    
239     --enc->depth;
240     }
241    
242     // encode objects, arrays and special \0=false and \1=true values.
243     static void
244     encode_rv (enc_t *enc, SV *sv)
245     {
246     svtype svt;
247    
248     SvGETMAGIC (sv);
249     svt = SvTYPE (sv);
250    
251     if (expect_false (SvOBJECT (sv)))
252     {
253     HV *stash = !CBOR_SLOW || cbor_boolean_stash
254     ? cbor_boolean_stash
255     : gv_stashpv ("CBOR::XS::Boolean", 1);
256    
257     if (SvSTASH (sv) == stash)
258     encode_ch (enc, SvIV (sv) ? 0xe0 | 21 : 0xe0 | 20);
259     else
260     {
261     #if 0 //TODO
262     if (enc->cbor.flags & F_CONV_BLESSED)
263     {
264     // we re-bless the reference to get overload and other niceties right
265     GV *to_cbor = gv_fetchmethod_autoload (SvSTASH (sv), "TO_CBOR", 0);
266    
267     if (to_cbor)
268     {
269     dSP;
270    
271     ENTER; SAVETMPS; PUSHMARK (SP);
272     XPUSHs (sv_bless (sv_2mortal (newRV_inc (sv)), SvSTASH (sv)));
273    
274     // calling with G_SCALAR ensures that we always get a 1 return value
275     PUTBACK;
276     call_sv ((SV *)GvCV (to_cbor), G_SCALAR);
277     SPAGAIN;
278    
279     // catch this surprisingly common error
280     if (SvROK (TOPs) && SvRV (TOPs) == sv)
281     croak ("%s::TO_CBOR method returned same object as was passed instead of a new one", HvNAME (SvSTASH (sv)));
282    
283     sv = POPs;
284     PUTBACK;
285    
286     encode_sv (enc, sv);
287    
288     FREETMPS; LEAVE;
289     }
290     else if (enc->cbor.flags & F_ALLOW_BLESSED)
291     encode_str (enc, "null", 4, 0);
292     else
293     croak ("encountered object '%s', but neither allow_blessed enabled nor TO_CBOR method available on it",
294     SvPV_nolen (sv_2mortal (newRV_inc (sv))));
295     }
296     else if (enc->cbor.flags & F_ALLOW_BLESSED)
297     encode_str (enc, "null", 4, 0);
298     else
299     croak ("encountered object '%s', but neither allow_blessed nor convert_blessed settings are enabled",
300     SvPV_nolen (sv_2mortal (newRV_inc (sv))));
301     #endif
302     }
303     }
304     else if (svt == SVt_PVHV)
305     encode_hv (enc, (HV *)sv);
306     else if (svt == SVt_PVAV)
307     encode_av (enc, (AV *)sv);
308     else if (svt < SVt_PVAV)
309     {
310     STRLEN len = 0;
311     char *pv = svt ? SvPV (sv, len) : 0;
312    
313     if (len == 1 && *pv == '1')
314     encode_ch (enc, 0xe0 | 21);
315     else if (len == 1 && *pv == '0')
316     encode_ch (enc, 0xe0 | 20);
317     else if (enc->cbor.flags & F_ALLOW_UNKNOWN)
318     encode_ch (enc, 0xe0 | 23);
319     else
320     croak ("cannot encode reference to scalar '%s' unless the scalar is 0 or 1",
321     SvPV_nolen (sv_2mortal (newRV_inc (sv))));
322     }
323     else if (enc->cbor.flags & F_ALLOW_UNKNOWN)
324     encode_ch (enc, 0xe0 | 23);
325     else
326     croak ("encountered %s, but CBOR can only represent references to arrays or hashes",
327     SvPV_nolen (sv_2mortal (newRV_inc (sv))));
328     }
329    
330     static void
331     encode_nv (enc_t *enc, SV *sv)
332     {
333     double nv = SvNVX (sv);
334    
335     need (enc, 9);
336    
337     if (expect_false (nv == (U32)nv))
338     encode_uint (enc, 0x00, (U32)nv);
339     //TODO: maybe I32?
340     else if (expect_false (nv == (float)nv))
341     {
342     uint32_t fp = ecb_float_to_binary32 (nv);
343    
344     *enc->cur++ = 0xe0 | 26;
345    
346     if (!ecb_big_endian ())
347     fp = ecb_bswap32 (fp);
348    
349     memcpy (enc->cur, &fp, 4);
350     enc->cur += 4;
351     }
352     else
353     {
354     uint64_t fp = ecb_double_to_binary64 (nv);
355    
356     *enc->cur++ = 0xe0 | 27;
357    
358     if (!ecb_big_endian ())
359     fp = ecb_bswap64 (fp);
360    
361     memcpy (enc->cur, &fp, 8);
362     enc->cur += 8;
363     }
364     }
365    
366     static void
367     encode_sv (enc_t *enc, SV *sv)
368     {
369     SvGETMAGIC (sv);
370    
371     if (SvPOKp (sv))
372     {
373     STRLEN len;
374     char *str = SvPV (sv, len);
375     encode_str (enc, SvUTF8 (sv), str, len);
376     }
377     else if (SvNOKp (sv))
378     encode_nv (enc, sv);
379     else if (SvIOKp (sv))
380     {
381     if (SvIsUV (sv))
382     encode_uint (enc, 0x00, SvUVX (sv));
383     else if (SvIVX (sv) >= 0)
384     encode_uint (enc, 0x00, SvIVX (sv));
385     else
386     encode_uint (enc, 0x20, -(SvIVX (sv) + 1));
387     }
388     else if (SvROK (sv))
389     encode_rv (enc, SvRV (sv));
390     else if (!SvOK (sv))
391     encode_ch (enc, 0xe0 | 22);
392     else if (enc->cbor.flags & F_ALLOW_UNKNOWN)
393     encode_ch (enc, 0xe0 | 23);
394     else
395     croak ("encountered perl type (%s,0x%x) that CBOR cannot handle, check your input data",
396     SvPV_nolen (sv), (unsigned int)SvFLAGS (sv));
397     }
398    
399     static SV *
400     encode_cbor (SV *scalar, CBOR *cbor)
401     {
402     enc_t enc;
403    
404     enc.cbor = *cbor;
405     enc.sv = sv_2mortal (NEWSV (0, INIT_SIZE));
406     enc.cur = SvPVX (enc.sv);
407     enc.end = SvEND (enc.sv);
408     enc.depth = 0;
409    
410     SvPOK_only (enc.sv);
411     encode_sv (&enc, scalar);
412    
413     SvCUR_set (enc.sv, enc.cur - SvPVX (enc.sv));
414     *SvEND (enc.sv) = 0; // many xs functions expect a trailing 0 for text strings
415    
416     if (enc.cbor.flags & F_SHRINK)
417     shrink (enc.sv);
418    
419     return enc.sv;
420     }
421    
422     /////////////////////////////////////////////////////////////////////////////
423     // decoder
424    
425     // structure used for decoding CBOR
426     typedef struct
427     {
428     U8 *cur; // current parser pointer
429     U8 *end; // end of input string
430     const char *err; // parse error, if != 0
431     CBOR cbor;
432     U32 depth; // recursion depth
433     U32 maxdepth; // recursion depth limit
434     } dec_t;
435    
436     #define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE
437    
438     #define WANT(len) if (expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data");
439    
440     #define DEC_INC_DEPTH if (++dec->depth > dec->cbor.max_depth) ERR (ERR_NESTING_EXCEEDED)
441     #define DEC_DEC_DEPTH --dec->depth
442    
443     static UV
444     decode_uint (dec_t *dec)
445     {
446     switch (*dec->cur & 31)
447     {
448     case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
449     case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
450     case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
451     return *dec->cur++ & 31;
452    
453     case 24:
454     WANT (2);
455     dec->cur += 2;
456     return dec->cur[-1];
457    
458     case 25:
459     WANT (3);
460     dec->cur += 3;
461     return (((UV)dec->cur[-2]) << 8)
462     | ((UV)dec->cur[-1]);
463    
464     case 26:
465     WANT (5);
466     dec->cur += 5;
467     return (((UV)dec->cur[-4]) << 24)
468     | (((UV)dec->cur[-3]) << 16)
469     | (((UV)dec->cur[-2]) << 8)
470     | ((UV)dec->cur[-1]);
471    
472     case 27:
473     WANT (9);
474     dec->cur += 9;
475     return (((UV)dec->cur[-8]) << 56)
476     | (((UV)dec->cur[-7]) << 48)
477     | (((UV)dec->cur[-6]) << 40)
478     | (((UV)dec->cur[-5]) << 32)
479     | (((UV)dec->cur[-4]) << 24)
480     | (((UV)dec->cur[-3]) << 16)
481     | (((UV)dec->cur[-2]) << 8)
482     | ((UV)dec->cur[-1]);
483    
484     default:
485     ERR ("corrupted CBOR data (unsupported integer minor encoding)");
486     }
487    
488     fail:
489     return 0;
490     }
491    
492     static SV *decode_sv (dec_t *dec);
493    
494     static SV *
495     decode_av (dec_t *dec)
496     {
497     AV *av = newAV ();
498    
499     DEC_INC_DEPTH;
500    
501     if ((*dec->cur & 31) == 31)
502     {
503     ++dec->cur;
504    
505     for (;;)
506     {
507     WANT (1);
508    
509 root 1.2 if (*dec->cur == (0xe0 | 31))
510 root 1.1 {
511     ++dec->cur;
512     break;
513     }
514    
515     av_push (av, decode_sv (dec));
516     }
517     }
518     else
519     {
520     int i, len = decode_uint (dec);
521    
522     av_fill (av, len - 1);
523    
524     for (i = 0; i < len; ++i)
525     AvARRAY (av)[i] = decode_sv (dec);
526     }
527    
528     DEC_DEC_DEPTH;
529     return newRV_noinc ((SV *)av);
530    
531     fail:
532     SvREFCNT_dec (av);
533     DEC_DEC_DEPTH;
534     return &PL_sv_undef;
535     }
536    
537     static SV *
538     decode_hv (dec_t *dec)
539     {
540     HV *hv = newHV ();
541    
542     DEC_INC_DEPTH;
543    
544     if ((*dec->cur & 31) == 31)
545     {
546     ++dec->cur;
547    
548     for (;;)
549     {
550     WANT (1);
551    
552 root 1.2 if (*dec->cur == (0xe0 | 31))
553 root 1.1 {
554     ++dec->cur;
555     break;
556     }
557    
558     SV *k = decode_sv (dec);
559     SV *v = decode_sv (dec);
560    
561     hv_store_ent (hv, k, v, 0);
562     }
563     }
564     else
565     {
566     int len = decode_uint (dec);
567    
568     while (len--)
569     {
570     SV *k = decode_sv (dec);
571     SV *v = decode_sv (dec);
572    
573     hv_store_ent (hv, k, v, 0);
574     }
575     }
576    
577     DEC_DEC_DEPTH;
578     return newRV_noinc ((SV *)hv);
579    
580     #if 0
581     SV *sv;
582     HV *hv = newHV ();
583    
584     DEC_INC_DEPTH;
585     decode_ws (dec);
586    
587     for (;;)
588     {
589     // heuristic: assume that
590     // a) decode_str + hv_store_ent are abysmally slow.
591     // b) most hash keys are short, simple ascii text.
592     // => try to "fast-match" such strings to avoid
593     // the overhead of decode_str + hv_store_ent.
594     {
595     SV *value;
596     char *p = dec->cur;
597     char *e = p + 24; // only try up to 24 bytes
598    
599     for (;;)
600     {
601     // the >= 0x80 is false on most architectures
602     if (p == e || *p < 0x20 || *p >= 0x80 || *p == '\\')
603     {
604     // slow path, back up and use decode_str
605     SV *key = decode_str (dec);
606     if (!key)
607     goto fail;
608    
609     decode_ws (dec); EXPECT_CH (':');
610    
611     decode_ws (dec);
612     value = decode_sv (dec);
613     if (!value)
614     {
615     SvREFCNT_dec (key);
616     goto fail;
617     }
618    
619     hv_store_ent (hv, key, value, 0);
620     SvREFCNT_dec (key);
621    
622     break;
623     }
624     else if (*p == '"')
625     {
626     // fast path, got a simple key
627     char *key = dec->cur;
628     int len = p - key;
629     dec->cur = p + 1;
630    
631     decode_ws (dec); EXPECT_CH (':');
632    
633     decode_ws (dec);
634     value = decode_sv (dec);
635     if (!value)
636     goto fail;
637    
638     hv_store (hv, key, len, value, 0);
639    
640     break;
641     }
642    
643     ++p;
644     }
645     }
646    
647     decode_ws (dec);
648    
649     if (*dec->cur == '}')
650     {
651     ++dec->cur;
652     break;
653     }
654    
655     if (*dec->cur != ',')
656     ERR (", or } expected while parsing object/hash");
657    
658     ++dec->cur;
659    
660     decode_ws (dec);
661    
662     if (*dec->cur == '}' && dec->cbor.flags & F_RELAXED)
663     {
664     ++dec->cur;
665     break;
666     }
667     }
668    
669     DEC_DEC_DEPTH;
670     sv = newRV_noinc ((SV *)hv);
671    
672     // check filter callbacks
673     if (dec->cbor.flags & F_HOOK)
674     {
675     if (dec->cbor.cb_sk_object && HvKEYS (hv) == 1)
676     {
677     HE *cb, *he;
678    
679     hv_iterinit (hv);
680     he = hv_iternext (hv);
681     hv_iterinit (hv);
682    
683     // the next line creates a mortal sv each time its called.
684     // might want to optimise this for common cases.
685     cb = hv_fetch_ent (dec->cbor.cb_sk_object, hv_iterkeysv (he), 0, 0);
686    
687     if (cb)
688     {
689     dSP;
690     int count;
691    
692     ENTER; SAVETMPS; PUSHMARK (SP);
693     XPUSHs (HeVAL (he));
694     sv_2mortal (sv);
695    
696     PUTBACK; count = call_sv (HeVAL (cb), G_ARRAY); SPAGAIN;
697    
698     if (count == 1)
699     {
700     sv = newSVsv (POPs);
701     FREETMPS; LEAVE;
702     return sv;
703     }
704    
705     SvREFCNT_inc (sv);
706     FREETMPS; LEAVE;
707     }
708     }
709    
710     if (dec->cbor.cb_object)
711     {
712     dSP;
713     int count;
714    
715     ENTER; SAVETMPS; PUSHMARK (SP);
716     XPUSHs (sv_2mortal (sv));
717    
718     PUTBACK; count = call_sv (dec->cbor.cb_object, G_ARRAY); SPAGAIN;
719    
720     if (count == 1)
721     {
722     sv = newSVsv (POPs);
723     FREETMPS; LEAVE;
724     return sv;
725     }
726    
727     SvREFCNT_inc (sv);
728     FREETMPS; LEAVE;
729     }
730     }
731    
732     return sv;
733     #endif
734    
735     fail:
736     SvREFCNT_dec (hv);
737     DEC_DEC_DEPTH;
738     return &PL_sv_undef;
739     }
740    
741     static SV *
742     decode_str (dec_t *dec, int utf8)
743     {
744     SV *sv;
745    
746     if ((*dec->cur & 31) == 31)
747     {
748     ++dec->cur;
749    
750     sv = newSVpvn ("", 0);
751    
752     // not very fast, and certainly not robust against illegal input
753     for (;;)
754     {
755     WANT (1);
756    
757 root 1.2 if (*dec->cur == (0xe0 | 31))
758 root 1.1 {
759     ++dec->cur;
760     break;
761     }
762    
763     SV *sv2 = decode_sv (dec);
764     sv_catsv (sv, sv2);
765     }
766     }
767     else
768     {
769     STRLEN len = decode_uint (dec);
770    
771     WANT (len);
772     sv = newSVpvn (dec->cur, len);
773     dec->cur += len;
774     }
775    
776     if (utf8)
777     SvUTF8_on (sv);
778    
779     return sv;
780    
781     fail:
782     return &PL_sv_undef;
783     }
784    
785     static SV *
786     decode_sv (dec_t *dec)
787     {
788     WANT (1);
789    
790     switch (*dec->cur >> 5)
791     {
792     case 0: // unsigned int
793     //TODO: 64 bit values on 3 2bit perls
794     return newSVuv (decode_uint (dec));
795     case 1: // negative int
796     return newSViv (-1 - (IV)decode_uint (dec));
797     case 2: // octet string
798     return decode_str (dec, 0);
799     case 3: // utf-8 string
800     return decode_str (dec, 1);
801     case 4: // array
802     return decode_av (dec);
803     case 5: // map
804     return decode_hv (dec);
805     case 6: // tag
806     abort ();
807     break;
808     case 7: // misc
809     switch (*dec->cur++ & 31)
810     {
811     case 20:
812     #if CBOR_SLOW
813     cbor_false = get_bool ("CBOR::XS::false");
814     #endif
815     return newSVsv (cbor_false);
816     case 21:
817     #if CBOR_SLOW
818     cbor_true = get_bool ("CBOR::XS::true");
819     #endif
820     return newSVsv (cbor_true);
821     case 22:
822     return newSVsv (&PL_sv_undef);
823    
824     case 25:
825 root 1.2 {
826     WANT (2);
827    
828     uint16_t fp = (dec->cur[0] << 8) | dec->cur[1];
829     dec->cur += 2;
830    
831     return newSVnv (ecb_binary16_to_float (fp));
832     }
833 root 1.1
834     case 26:
835     {
836     uint32_t fp;
837     WANT (4);
838     memcpy (&fp, dec->cur, 4);
839     dec->cur += 4;
840    
841     if (!ecb_big_endian ())
842     fp = ecb_bswap32 (fp);
843    
844     return newSVnv (ecb_binary32_to_float (fp));
845     }
846    
847     case 27:
848     {
849     uint64_t fp;
850     WANT (8);
851     memcpy (&fp, dec->cur, 8);
852     dec->cur += 8;
853    
854     if (!ecb_big_endian ())
855     fp = ecb_bswap64 (fp);
856    
857     return newSVnv (ecb_binary64_to_double (fp));
858     }
859    
860     // 0..19 unassigned
861     // 24 reserved + unassigned (reserved values are not encodable)
862     default:
863     ERR ("corrupted CBOR data (reserved/unassigned major 7 value)");
864     }
865    
866     break;
867     }
868     #if 0
869     switch (*dec->cur)
870     {
871     //case '"': ++dec->cur; return decode_str (dec);
872     case '[': ++dec->cur; return decode_av (dec);
873     case '{': ++dec->cur; return decode_hv (dec);
874    
875     case '-':
876     case '0': case '1': case '2': case '3': case '4':
877     case '5': case '6': case '7': case '8': case '9':
878     //TODO return decode_num (dec);
879    
880     case 't':
881     if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "true", 4))
882     {
883     dec->cur += 4;
884     #if CBOR_SLOW
885     cbor_true = get_bool ("CBOR::XS::true");
886     #endif
887     return newSVsv (cbor_true);
888     }
889     else
890     ERR ("'true' expected");
891    
892     break;
893    
894     case 'f':
895     if (dec->end - dec->cur >= 5 && !memcmp (dec->cur, "false", 5))
896     {
897     dec->cur += 5;
898     #if CBOR_SLOW
899     cbor_false = get_bool ("CBOR::XS::false");
900     #endif
901     return newSVsv (cbor_false);
902     }
903     else
904     ERR ("'false' expected");
905    
906     break;
907    
908     case 'n':
909     if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "null", 4))
910     {
911     dec->cur += 4;
912     return newSVsv (&PL_sv_undef);
913     }
914     else
915     ERR ("'null' expected");
916    
917     break;
918    
919     default:
920     ERR ("malformed CBOR string, neither array, object, number, string or atom");
921     break;
922     }
923     #endif
924    
925     fail:
926     return &PL_sv_undef;
927     }
928    
929     static SV *
930     decode_cbor (SV *string, CBOR *cbor, char **offset_return)
931     {
932     dec_t dec;
933     SV *sv;
934    
935     /* work around bugs in 5.10 where manipulating magic values
936     * makes perl ignore the magic in subsequent accesses.
937     * also make a copy of non-PV values, to get them into a clean
938     * state (SvPV should do that, but it's buggy, see below).
939     */
940     /*SvGETMAGIC (string);*/
941     if (SvMAGICAL (string) || !SvPOK (string))
942     string = sv_2mortal (newSVsv (string));
943    
944     SvUPGRADE (string, SVt_PV);
945    
946     /* work around a bug in perl 5.10, which causes SvCUR to fail an
947     * assertion with -DDEBUGGING, although SvCUR is documented to
948     * return the xpv_cur field which certainly exists after upgrading.
949     * according to nicholas clark, calling SvPOK fixes this.
950     * But it doesn't fix it, so try another workaround, call SvPV_nolen
951     * and hope for the best.
952     * Damnit, SvPV_nolen still trips over yet another assertion. This
953     * assertion business is seriously broken, try yet another workaround
954     * for the broken -DDEBUGGING.
955     */
956     {
957     #ifdef DEBUGGING
958     STRLEN offset = SvOK (string) ? sv_len (string) : 0;
959     #else
960     STRLEN offset = SvCUR (string);
961     #endif
962    
963     if (offset > cbor->max_size && cbor->max_size)
964     croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu",
965     (unsigned long)SvCUR (string), (unsigned long)cbor->max_size);
966     }
967    
968     sv_utf8_downgrade (string, 0);
969    
970     dec.cbor = *cbor;
971     dec.cur = (U8 *)SvPVX (string);
972     dec.end = (U8 *)SvEND (string);
973     dec.err = 0;
974     dec.depth = 0;
975    
976     if (dec.cbor.cb_object || dec.cbor.cb_sk_object)
977     ;//TODO dec.cbor.flags |= F_HOOK;
978    
979     sv = decode_sv (&dec);
980    
981     if (offset_return)
982     *offset_return = dec.cur;
983    
984     if (!(offset_return || !sv))
985 root 1.2 if (dec.cur != dec.end && !dec.err)
986     dec.err = "garbage after CBOR object";
987    
988     if (dec.err)
989 root 1.1 {
990 root 1.2 SvREFCNT_dec (sv);
991     croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)SvPVX (string), (int)(uint8_t)*dec.cur);
992 root 1.1 }
993    
994     sv = sv_2mortal (sv);
995    
996     return sv;
997     }
998    
999     /////////////////////////////////////////////////////////////////////////////
1000     // XS interface functions
1001    
1002     MODULE = CBOR::XS PACKAGE = CBOR::XS
1003    
1004     BOOT:
1005     {
1006     cbor_stash = gv_stashpv ("CBOR::XS" , 1);
1007     cbor_boolean_stash = gv_stashpv ("CBOR::XS::Boolean", 1);
1008    
1009     cbor_true = get_bool ("CBOR::XS::true");
1010     cbor_false = get_bool ("CBOR::XS::false");
1011     }
1012    
1013     PROTOTYPES: DISABLE
1014    
1015     void CLONE (...)
1016     CODE:
1017     cbor_stash = 0;
1018     cbor_boolean_stash = 0;
1019    
1020     void new (char *klass)
1021     PPCODE:
1022     {
1023     SV *pv = NEWSV (0, sizeof (CBOR));
1024     SvPOK_only (pv);
1025     cbor_init ((CBOR *)SvPVX (pv));
1026     XPUSHs (sv_2mortal (sv_bless (
1027     newRV_noinc (pv),
1028     strEQ (klass, "CBOR::XS") ? CBOR_STASH : gv_stashpv (klass, 1)
1029     )));
1030     }
1031    
1032     void shrink (CBOR *self, int enable = 1)
1033     ALIAS:
1034     shrink = F_SHRINK
1035     allow_unknown = F_ALLOW_UNKNOWN
1036     PPCODE:
1037     {
1038     if (enable)
1039     self->flags |= ix;
1040     else
1041     self->flags &= ~ix;
1042    
1043     XPUSHs (ST (0));
1044     }
1045    
1046     void get_shrink (CBOR *self)
1047     ALIAS:
1048     get_shrink = F_SHRINK
1049     get_allow_unknown = F_ALLOW_UNKNOWN
1050     PPCODE:
1051     XPUSHs (boolSV (self->flags & ix));
1052    
1053     void max_depth (CBOR *self, U32 max_depth = 0x80000000UL)
1054     PPCODE:
1055     self->max_depth = max_depth;
1056     XPUSHs (ST (0));
1057    
1058     U32 get_max_depth (CBOR *self)
1059     CODE:
1060     RETVAL = self->max_depth;
1061     OUTPUT:
1062     RETVAL
1063    
1064     void max_size (CBOR *self, U32 max_size = 0)
1065     PPCODE:
1066     self->max_size = max_size;
1067     XPUSHs (ST (0));
1068    
1069     int get_max_size (CBOR *self)
1070     CODE:
1071     RETVAL = self->max_size;
1072     OUTPUT:
1073     RETVAL
1074    
1075     #if 0 //TODO
1076    
1077     void filter_cbor_object (CBOR *self, SV *cb = &PL_sv_undef)
1078     PPCODE:
1079     {
1080     SvREFCNT_dec (self->cb_object);
1081     self->cb_object = SvOK (cb) ? newSVsv (cb) : 0;
1082    
1083     XPUSHs (ST (0));
1084     }
1085    
1086     void filter_cbor_single_key_object (CBOR *self, SV *key, SV *cb = &PL_sv_undef)
1087     PPCODE:
1088     {
1089     if (!self->cb_sk_object)
1090     self->cb_sk_object = newHV ();
1091    
1092     if (SvOK (cb))
1093     hv_store_ent (self->cb_sk_object, key, newSVsv (cb), 0);
1094     else
1095     {
1096     hv_delete_ent (self->cb_sk_object, key, G_DISCARD, 0);
1097    
1098     if (!HvKEYS (self->cb_sk_object))
1099     {
1100     SvREFCNT_dec (self->cb_sk_object);
1101     self->cb_sk_object = 0;
1102     }
1103     }
1104    
1105     XPUSHs (ST (0));
1106     }
1107    
1108     #endif
1109    
1110     void encode (CBOR *self, SV *scalar)
1111     PPCODE:
1112     PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN;
1113     XPUSHs (scalar);
1114    
1115     void decode (CBOR *self, SV *cborstr)
1116     PPCODE:
1117     PUTBACK; cborstr = decode_cbor (cborstr, self, 0); SPAGAIN;
1118     XPUSHs (cborstr);
1119    
1120     void decode_prefix (CBOR *self, SV *cborstr)
1121     PPCODE:
1122     {
1123     SV *sv;
1124     char *offset;
1125     PUTBACK; sv = decode_cbor (cborstr, self, &offset); SPAGAIN;
1126     EXTEND (SP, 2);
1127     PUSHs (sv);
1128     PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr))));
1129     }
1130    
1131     void DESTROY (CBOR *self)
1132     CODE:
1133     SvREFCNT_dec (self->cb_sk_object);
1134     SvREFCNT_dec (self->cb_object);
1135    
1136     PROTOTYPES: ENABLE
1137    
1138     void encode_cbor (SV *scalar)
1139     PPCODE:
1140     {
1141     CBOR cbor;
1142     cbor_init (&cbor);
1143     PUTBACK; scalar = encode_cbor (scalar, &cbor); SPAGAIN;
1144     XPUSHs (scalar);
1145     }
1146    
1147     void decode_cbor (SV *cborstr)
1148     PPCODE:
1149     {
1150     CBOR cbor;
1151     cbor_init (&cbor);
1152     PUTBACK; cborstr = decode_cbor (cborstr, &cbor, 0); SPAGAIN;
1153     XPUSHs (cborstr);
1154     }
1155