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.11 by root, Sun Oct 27 22:35:15 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 } 645 }
604 } 646 }
605 else 647 else
606 { 648 {
607 int len = decode_uint (dec); 649 int pairs = decode_uint (dec);
608 650
609 while (len--) 651 while (pairs--)
610 { 652 decode_he (dec, hv);
611 SV *k = decode_sv (dec);
612 SV *v = decode_sv (dec);
613
614 hv_store_ent (hv, k, v, 0);
615 }
616 } 653 }
617 654
618 DEC_DEC_DEPTH; 655 DEC_DEC_DEPTH;
619 return newRV_noinc ((SV *)hv); 656 return newRV_noinc ((SV *)hv);
620 657
705 742
706 for (i = 1; i < len; ++i) 743 for (i = 1; i < len; ++i)
707 PUSHs (*av_fetch (av, i, 1)); 744 PUSHs (*av_fetch (av, i, 1));
708 745
709 PUTBACK; 746 PUTBACK;
710 call_sv ((SV *)GvCV (method), G_SCALAR); 747 call_sv ((SV *)GvCV (method), G_SCALAR | G_EVAL);
711 SPAGAIN; 748 SPAGAIN;
712 749
750 if (SvTRUE (ERRSV))
751 {
752 FREETMPS; LEAVE;
753 ERR (SvPVutf8_nolen (sv_2mortal (SvREFCNT_inc (ERRSV))));
754 }
755
756 SvREFCNT_dec (sv);
713 sv = SvREFCNT_inc (POPs); 757 sv = SvREFCNT_inc (POPs);
714 758
715 PUTBACK; 759 PUTBACK;
716 760
717 FREETMPS; LEAVE; 761 FREETMPS; LEAVE;
830static SV * 874static SV *
831decode_cbor (SV *string, CBOR *cbor, char **offset_return) 875decode_cbor (SV *string, CBOR *cbor, char **offset_return)
832{ 876{
833 dec_t dec; 877 dec_t dec;
834 SV *sv; 878 SV *sv;
879 STRLEN len;
880 char *data = SvPVbyte (string, len);
835 881
836 /* work around bugs in 5.10 where manipulating magic values
837 * makes perl ignore the magic in subsequent accesses.
838 * also make a copy of non-PV values, to get them into a clean
839 * state (SvPV should do that, but it's buggy, see below).
840 */
841 /*SvGETMAGIC (string);*/
842 if (SvMAGICAL (string) || !SvPOK (string))
843 string = sv_2mortal (newSVsv (string));
844
845 SvUPGRADE (string, SVt_PV);
846
847 /* work around a bug in perl 5.10, which causes SvCUR to fail an
848 * assertion with -DDEBUGGING, although SvCUR is documented to
849 * return the xpv_cur field which certainly exists after upgrading.
850 * according to nicholas clark, calling SvPOK fixes this.
851 * But it doesn't fix it, so try another workaround, call SvPV_nolen
852 * and hope for the best.
853 * Damnit, SvPV_nolen still trips over yet another assertion. This
854 * assertion business is seriously broken, try yet another workaround
855 * for the broken -DDEBUGGING.
856 */
857 {
858#ifdef DEBUGGING
859 STRLEN offset = SvOK (string) ? sv_len (string) : 0;
860#else
861 STRLEN offset = SvCUR (string);
862#endif
863
864 if (offset > cbor->max_size && cbor->max_size) 882 if (len > cbor->max_size && cbor->max_size)
865 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",
866 (unsigned long)SvCUR (string), (unsigned long)cbor->max_size); 884 (unsigned long)len, (unsigned long)cbor->max_size);
867 }
868
869 sv_utf8_downgrade (string, 0);
870 885
871 dec.cbor = *cbor; 886 dec.cbor = *cbor;
872 dec.cur = (U8 *)SvPVX (string); 887 dec.cur = (U8 *)data;
873 dec.end = (U8 *)SvEND (string); 888 dec.end = (U8 *)data + len;
874 dec.err = 0; 889 dec.err = 0;
875 dec.depth = 0; 890 dec.depth = 0;
876 891
877 sv = decode_sv (&dec); 892 sv = decode_sv (&dec);
878 893
884 dec.err = "garbage after CBOR object"; 899 dec.err = "garbage after CBOR object";
885 900
886 if (dec.err) 901 if (dec.err)
887 { 902 {
888 SvREFCNT_dec (sv); 903 SvREFCNT_dec (sv);
889 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);
890 } 905 }
891 906
892 sv = sv_2mortal (sv); 907 sv = sv_2mortal (sv);
893 908
894 return sv; 909 return sv;
977 CODE: 992 CODE:
978 RETVAL = self->max_size; 993 RETVAL = self->max_size;
979 OUTPUT: 994 OUTPUT:
980 RETVAL 995 RETVAL
981 996
982#if 0 //TODO
983
984void filter_cbor_object (CBOR *self, SV *cb = &PL_sv_undef)
985 PPCODE:
986{
987 SvREFCNT_dec (self->cb_object);
988 self->cb_object = SvOK (cb) ? newSVsv (cb) : 0;
989
990 XPUSHs (ST (0));
991}
992
993void filter_cbor_single_key_object (CBOR *self, SV *key, SV *cb = &PL_sv_undef)
994 PPCODE:
995{
996 if (!self->cb_sk_object)
997 self->cb_sk_object = newHV ();
998
999 if (SvOK (cb))
1000 hv_store_ent (self->cb_sk_object, key, newSVsv (cb), 0);
1001 else
1002 {
1003 hv_delete_ent (self->cb_sk_object, key, G_DISCARD, 0);
1004
1005 if (!HvKEYS (self->cb_sk_object))
1006 {
1007 SvREFCNT_dec (self->cb_sk_object);
1008 self->cb_sk_object = 0;
1009 }
1010 }
1011
1012 XPUSHs (ST (0));
1013}
1014
1015#endif
1016
1017void encode (CBOR *self, SV *scalar) 997void encode (CBOR *self, SV *scalar)
1018 PPCODE: 998 PPCODE:
1019 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN; 999 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN;
1020 XPUSHs (scalar); 1000 XPUSHs (scalar);
1021 1001
1033 EXTEND (SP, 2); 1013 EXTEND (SP, 2);
1034 PUSHs (sv); 1014 PUSHs (sv);
1035 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); 1015 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr))));
1036} 1016}
1037 1017
1038#if 0
1039
1040void DESTROY (CBOR *self)
1041 CODE:
1042 SvREFCNT_dec (self->cb_sk_object);
1043 SvREFCNT_dec (self->cb_object);
1044
1045#endif
1046
1047PROTOTYPES: ENABLE 1018PROTOTYPES: ENABLE
1048 1019
1049void encode_cbor (SV *scalar) 1020void encode_cbor (SV *scalar)
1050 PPCODE: 1021 PPCODE:
1051{ 1022{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines