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.12 by root, Mon Oct 28 19:06:45 2013 UTC vs.
Revision 1.17 by root, Tue Oct 29 22:04:52 2013 UTC

8#include <stdio.h> 8#include <stdio.h>
9#include <limits.h> 9#include <limits.h>
10#include <float.h> 10#include <float.h>
11 11
12#include "ecb.h" 12#include "ecb.h"
13
14// compatibility with perl <5.18
15#ifndef HvNAMELEN_get
16# define HvNAMELEN_get(hv) strlen (HvNAME (hv))
17#endif
18#ifndef HvNAMELEN
19# define HvNAMELEN(hv) HvNAMELEN_get (hv)
20#endif
21#ifndef HvNAMEUTF8
22# define HvNAMEUTF8(hv) 0
23#endif
13 24
14// known tags 25// known tags
15enum cbor_tag 26enum cbor_tag
16{ 27{
17 // inofficial extensions (pending iana registration) 28 // inofficial extensions (pending iana registration)
573 SvREFCNT_dec (av); 584 SvREFCNT_dec (av);
574 DEC_DEC_DEPTH; 585 DEC_DEC_DEPTH;
575 return &PL_sv_undef; 586 return &PL_sv_undef;
576} 587}
577 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
578static SV * 623static SV *
579decode_hv (dec_t *dec) 624decode_hv (dec_t *dec)
580{ 625{
581 HV *hv = newHV (); 626 HV *hv = newHV ();
582 627
594 { 639 {
595 ++dec->cur; 640 ++dec->cur;
596 break; 641 break;
597 } 642 }
598 643
599 SV *k = decode_sv (dec); 644 decode_he (dec, hv);
600 SV *v = decode_sv (dec);
601
602 hv_store_ent (hv, k, v, 0);
603 SvREFCNT_dec (k);
604 } 645 }
605 } 646 }
606 else 647 else
607 { 648 {
608 int len = decode_uint (dec); 649 int pairs = decode_uint (dec);
609 650
610 while (len--) 651 while (pairs--)
611 { 652 decode_he (dec, hv);
612 SV *k = decode_sv (dec);
613 SV *v = decode_sv (dec);
614
615 hv_store_ent (hv, k, v, 0);
616 SvREFCNT_dec (k);
617 }
618 } 653 }
619 654
620 DEC_DEC_DEPTH; 655 DEC_DEC_DEPTH;
621 return newRV_noinc ((SV *)hv); 656 return newRV_noinc ((SV *)hv);
622 657
707 742
708 for (i = 1; i < len; ++i) 743 for (i = 1; i < len; ++i)
709 PUSHs (*av_fetch (av, i, 1)); 744 PUSHs (*av_fetch (av, i, 1));
710 745
711 PUTBACK; 746 PUTBACK;
712 call_sv ((SV *)GvCV (method), G_SCALAR); 747 call_sv ((SV *)GvCV (method), G_SCALAR | G_EVAL);
713 SPAGAIN; 748 SPAGAIN;
714 749
750 if (SvTRUE (ERRSV))
751 {
752 FREETMPS; LEAVE;
753 ERR (SvPVutf8_nolen (sv_2mortal (SvREFCNT_inc (ERRSV))));
754 }
755
756 SvREFCNT_dec (sv);
715 sv = SvREFCNT_inc (POPs); 757 sv = SvREFCNT_inc (POPs);
716 758
717 PUTBACK; 759 PUTBACK;
718 760
719 FREETMPS; LEAVE; 761 FREETMPS; LEAVE;
832static SV * 874static SV *
833decode_cbor (SV *string, CBOR *cbor, char **offset_return) 875decode_cbor (SV *string, CBOR *cbor, char **offset_return)
834{ 876{
835 dec_t dec; 877 dec_t dec;
836 SV *sv; 878 SV *sv;
879 STRLEN len;
880 char *data = SvPVbyte (string, len);
837 881
838 /* work around bugs in 5.10 where manipulating magic values
839 * makes perl ignore the magic in subsequent accesses.
840 * also make a copy of non-PV values, to get them into a clean
841 * state (SvPV should do that, but it's buggy, see below).
842 */
843 /*SvGETMAGIC (string);*/
844 if (SvMAGICAL (string) || !SvPOK (string))
845 string = sv_2mortal (newSVsv (string));
846
847 SvUPGRADE (string, SVt_PV);
848
849 /* work around a bug in perl 5.10, which causes SvCUR to fail an
850 * assertion with -DDEBUGGING, although SvCUR is documented to
851 * return the xpv_cur field which certainly exists after upgrading.
852 * according to nicholas clark, calling SvPOK fixes this.
853 * But it doesn't fix it, so try another workaround, call SvPV_nolen
854 * and hope for the best.
855 * Damnit, SvPV_nolen still trips over yet another assertion. This
856 * assertion business is seriously broken, try yet another workaround
857 * for the broken -DDEBUGGING.
858 */
859 {
860#ifdef DEBUGGING
861 STRLEN offset = SvOK (string) ? sv_len (string) : 0;
862#else
863 STRLEN offset = SvCUR (string);
864#endif
865
866 if (offset > cbor->max_size && cbor->max_size) 882 if (len > cbor->max_size && cbor->max_size)
867 croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu", 883 croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu",
868 (unsigned long)SvCUR (string), (unsigned long)cbor->max_size); 884 (unsigned long)len, (unsigned long)cbor->max_size);
869 }
870
871 sv_utf8_downgrade (string, 0);
872 885
873 dec.cbor = *cbor; 886 dec.cbor = *cbor;
874 dec.cur = (U8 *)SvPVX (string); 887 dec.cur = (U8 *)data;
875 dec.end = (U8 *)SvEND (string); 888 dec.end = (U8 *)data + len;
876 dec.err = 0; 889 dec.err = 0;
877 dec.depth = 0; 890 dec.depth = 0;
878 891
879 sv = decode_sv (&dec); 892 sv = decode_sv (&dec);
880 893
886 dec.err = "garbage after CBOR object"; 899 dec.err = "garbage after CBOR object";
887 900
888 if (dec.err) 901 if (dec.err)
889 { 902 {
890 SvREFCNT_dec (sv); 903 SvREFCNT_dec (sv);
891 croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)SvPVX (string), (int)(uint8_t)*dec.cur); 904 croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)data, (int)(uint8_t)*dec.cur);
892 } 905 }
893 906
894 sv = sv_2mortal (sv); 907 sv = sv_2mortal (sv);
895 908
896 return sv; 909 return sv;
979 CODE: 992 CODE:
980 RETVAL = self->max_size; 993 RETVAL = self->max_size;
981 OUTPUT: 994 OUTPUT:
982 RETVAL 995 RETVAL
983 996
984#if 0 //TODO
985
986void filter_cbor_object (CBOR *self, SV *cb = &PL_sv_undef)
987 PPCODE:
988{
989 SvREFCNT_dec (self->cb_object);
990 self->cb_object = SvOK (cb) ? newSVsv (cb) : 0;
991
992 XPUSHs (ST (0));
993}
994
995void filter_cbor_single_key_object (CBOR *self, SV *key, SV *cb = &PL_sv_undef)
996 PPCODE:
997{
998 if (!self->cb_sk_object)
999 self->cb_sk_object = newHV ();
1000
1001 if (SvOK (cb))
1002 hv_store_ent (self->cb_sk_object, key, newSVsv (cb), 0);
1003 else
1004 {
1005 hv_delete_ent (self->cb_sk_object, key, G_DISCARD, 0);
1006
1007 if (!HvKEYS (self->cb_sk_object))
1008 {
1009 SvREFCNT_dec (self->cb_sk_object);
1010 self->cb_sk_object = 0;
1011 }
1012 }
1013
1014 XPUSHs (ST (0));
1015}
1016
1017#endif
1018
1019void encode (CBOR *self, SV *scalar) 997void encode (CBOR *self, SV *scalar)
1020 PPCODE: 998 PPCODE:
1021 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN; 999 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN;
1022 XPUSHs (scalar); 1000 XPUSHs (scalar);
1023 1001
1035 EXTEND (SP, 2); 1013 EXTEND (SP, 2);
1036 PUSHs (sv); 1014 PUSHs (sv);
1037 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); 1015 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr))));
1038} 1016}
1039 1017
1040#if 0
1041
1042void DESTROY (CBOR *self)
1043 CODE:
1044 SvREFCNT_dec (self->cb_sk_object);
1045 SvREFCNT_dec (self->cb_object);
1046
1047#endif
1048
1049PROTOTYPES: ENABLE 1018PROTOTYPES: ENABLE
1050 1019
1051void encode_cbor (SV *scalar) 1020void encode_cbor (SV *scalar)
1052 PPCODE: 1021 PPCODE:
1053{ 1022{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines