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

Comparing CBOR-XS/XS.xs (file contents):
Revision 1.15 by root, Tue Oct 29 18:37:31 2013 UTC vs.
Revision 1.16 by root, Tue Oct 29 20:59:16 2013 UTC

584 SvREFCNT_dec (av); 584 SvREFCNT_dec (av);
585 DEC_DEC_DEPTH; 585 DEC_DEC_DEPTH;
586 return &PL_sv_undef; 586 return &PL_sv_undef;
587} 587}
588 588
589static void
590decode_he (dec_t *dec, HV *hv)
591{
592 // for speed reasons, we specialcase single-string
593 // byte or utf-8 strings as keys.
594
595 if (*dec->cur >= 0x40 && *dec->cur <= 0x40 + 27)
596 {
597 I32 len = decode_uint (dec);
598 char *key = (char *)dec->cur;
599
600 dec->cur += len;
601
602 hv_store (hv, key, len, decode_sv (dec), 0);
603 }
604 else if (*dec->cur >= 0x60 && *dec->cur <= 0x60 + 27)
605 {
606 I32 len = decode_uint (dec);
607 char *key = (char *)dec->cur;
608
609 dec->cur += len;
610
611 hv_store (hv, key, -len, decode_sv (dec), 0);
612 }
613 else
614 {
615 SV *k = decode_sv (dec);
616 SV *v = decode_sv (dec);
617
618 hv_store_ent (hv, k, v, 0);
619 SvREFCNT_dec (k);
620 }
621}
622
589static SV * 623static SV *
590decode_hv (dec_t *dec) 624decode_hv (dec_t *dec)
591{ 625{
592 HV *hv = newHV (); 626 HV *hv = newHV ();
593 627
605 { 639 {
606 ++dec->cur; 640 ++dec->cur;
607 break; 641 break;
608 } 642 }
609 643
610 SV *k = decode_sv (dec); 644 decode_he (dec, hv);
611 SV *v = decode_sv (dec);
612
613 hv_store_ent (hv, k, v, 0);
614 SvREFCNT_dec (k);
615 } 645 }
616 } 646 }
617 else 647 else
618 { 648 {
619 int len = decode_uint (dec); 649 int pairs = decode_uint (dec);
620 650
621 while (len--) 651 while (pairs--)
622 { 652 decode_he (dec, hv);
623 SV *k = decode_sv (dec);
624 SV *v = decode_sv (dec);
625
626 hv_store_ent (hv, k, v, 0);
627 SvREFCNT_dec (k);
628 }
629 } 653 }
630 654
631 DEC_DEC_DEPTH; 655 DEC_DEC_DEPTH;
632 return newRV_noinc ((SV *)hv); 656 return newRV_noinc ((SV *)hv);
633 657
844static SV * 868static SV *
845decode_cbor (SV *string, CBOR *cbor, char **offset_return) 869decode_cbor (SV *string, CBOR *cbor, char **offset_return)
846{ 870{
847 dec_t dec; 871 dec_t dec;
848 SV *sv; 872 SV *sv;
873 STRLEN len;
874 char *data = SvPVbyte (string, len);
849 875
850 /* work around bugs in 5.10 where manipulating magic values
851 * makes perl ignore the magic in subsequent accesses.
852 * also make a copy of non-PV values, to get them into a clean
853 * state (SvPV should do that, but it's buggy, see below).
854 */
855 /*SvGETMAGIC (string);*/
856 if (SvMAGICAL (string) || !SvPOK (string))
857 string = sv_2mortal (newSVsv (string));
858
859 SvUPGRADE (string, SVt_PV);
860
861 /* work around a bug in perl 5.10, which causes SvCUR to fail an
862 * assertion with -DDEBUGGING, although SvCUR is documented to
863 * return the xpv_cur field which certainly exists after upgrading.
864 * according to nicholas clark, calling SvPOK fixes this.
865 * But it doesn't fix it, so try another workaround, call SvPV_nolen
866 * and hope for the best.
867 * Damnit, SvPV_nolen still trips over yet another assertion. This
868 * assertion business is seriously broken, try yet another workaround
869 * for the broken -DDEBUGGING.
870 */
871 {
872#ifdef DEBUGGING
873 STRLEN offset = SvOK (string) ? sv_len (string) : 0;
874#else
875 STRLEN offset = SvCUR (string);
876#endif
877
878 if (offset > cbor->max_size && cbor->max_size) 876 if (len > cbor->max_size && cbor->max_size)
879 croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu", 877 croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu",
880 (unsigned long)SvCUR (string), (unsigned long)cbor->max_size); 878 (unsigned long)len, (unsigned long)cbor->max_size);
881 }
882
883 sv_utf8_downgrade (string, 0);
884 879
885 dec.cbor = *cbor; 880 dec.cbor = *cbor;
886 dec.cur = (U8 *)SvPVX (string); 881 dec.cur = (U8 *)data;
887 dec.end = (U8 *)SvEND (string); 882 dec.end = (U8 *)data + len;
888 dec.err = 0; 883 dec.err = 0;
889 dec.depth = 0; 884 dec.depth = 0;
890 885
891 sv = decode_sv (&dec); 886 sv = decode_sv (&dec);
892 887
898 dec.err = "garbage after CBOR object"; 893 dec.err = "garbage after CBOR object";
899 894
900 if (dec.err) 895 if (dec.err)
901 { 896 {
902 SvREFCNT_dec (sv); 897 SvREFCNT_dec (sv);
903 croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)SvPVX (string), (int)(uint8_t)*dec.cur); 898 croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)data, (int)(uint8_t)*dec.cur);
904 } 899 }
905 900
906 sv = sv_2mortal (sv); 901 sv = sv_2mortal (sv);
907 902
908 return sv; 903 return sv;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines