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.13 by root, Mon Oct 28 22:50:50 2013 UTC vs.
Revision 1.16 by root, Tue Oct 29 20:59:16 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
833static SV * 868static SV *
834decode_cbor (SV *string, CBOR *cbor, char **offset_return) 869decode_cbor (SV *string, CBOR *cbor, char **offset_return)
835{ 870{
836 dec_t dec; 871 dec_t dec;
837 SV *sv; 872 SV *sv;
873 STRLEN len;
874 char *data = SvPVbyte (string, len);
838 875
839 /* work around bugs in 5.10 where manipulating magic values
840 * makes perl ignore the magic in subsequent accesses.
841 * also make a copy of non-PV values, to get them into a clean
842 * state (SvPV should do that, but it's buggy, see below).
843 */
844 /*SvGETMAGIC (string);*/
845 if (SvMAGICAL (string) || !SvPOK (string))
846 string = sv_2mortal (newSVsv (string));
847
848 SvUPGRADE (string, SVt_PV);
849
850 /* work around a bug in perl 5.10, which causes SvCUR to fail an
851 * assertion with -DDEBUGGING, although SvCUR is documented to
852 * return the xpv_cur field which certainly exists after upgrading.
853 * according to nicholas clark, calling SvPOK fixes this.
854 * But it doesn't fix it, so try another workaround, call SvPV_nolen
855 * and hope for the best.
856 * Damnit, SvPV_nolen still trips over yet another assertion. This
857 * assertion business is seriously broken, try yet another workaround
858 * for the broken -DDEBUGGING.
859 */
860 {
861#ifdef DEBUGGING
862 STRLEN offset = SvOK (string) ? sv_len (string) : 0;
863#else
864 STRLEN offset = SvCUR (string);
865#endif
866
867 if (offset > cbor->max_size && cbor->max_size) 876 if (len > cbor->max_size && cbor->max_size)
868 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",
869 (unsigned long)SvCUR (string), (unsigned long)cbor->max_size); 878 (unsigned long)len, (unsigned long)cbor->max_size);
870 }
871
872 sv_utf8_downgrade (string, 0);
873 879
874 dec.cbor = *cbor; 880 dec.cbor = *cbor;
875 dec.cur = (U8 *)SvPVX (string); 881 dec.cur = (U8 *)data;
876 dec.end = (U8 *)SvEND (string); 882 dec.end = (U8 *)data + len;
877 dec.err = 0; 883 dec.err = 0;
878 dec.depth = 0; 884 dec.depth = 0;
879 885
880 sv = decode_sv (&dec); 886 sv = decode_sv (&dec);
881 887
887 dec.err = "garbage after CBOR object"; 893 dec.err = "garbage after CBOR object";
888 894
889 if (dec.err) 895 if (dec.err)
890 { 896 {
891 SvREFCNT_dec (sv); 897 SvREFCNT_dec (sv);
892 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);
893 } 899 }
894 900
895 sv = sv_2mortal (sv); 901 sv = sv_2mortal (sv);
896 902
897 return sv; 903 return sv;
980 CODE: 986 CODE:
981 RETVAL = self->max_size; 987 RETVAL = self->max_size;
982 OUTPUT: 988 OUTPUT:
983 RETVAL 989 RETVAL
984 990
985#if 0 //TODO
986
987void filter_cbor_object (CBOR *self, SV *cb = &PL_sv_undef)
988 PPCODE:
989{
990 SvREFCNT_dec (self->cb_object);
991 self->cb_object = SvOK (cb) ? newSVsv (cb) : 0;
992
993 XPUSHs (ST (0));
994}
995
996void filter_cbor_single_key_object (CBOR *self, SV *key, SV *cb = &PL_sv_undef)
997 PPCODE:
998{
999 if (!self->cb_sk_object)
1000 self->cb_sk_object = newHV ();
1001
1002 if (SvOK (cb))
1003 hv_store_ent (self->cb_sk_object, key, newSVsv (cb), 0);
1004 else
1005 {
1006 hv_delete_ent (self->cb_sk_object, key, G_DISCARD, 0);
1007
1008 if (!HvKEYS (self->cb_sk_object))
1009 {
1010 SvREFCNT_dec (self->cb_sk_object);
1011 self->cb_sk_object = 0;
1012 }
1013 }
1014
1015 XPUSHs (ST (0));
1016}
1017
1018#endif
1019
1020void encode (CBOR *self, SV *scalar) 991void encode (CBOR *self, SV *scalar)
1021 PPCODE: 992 PPCODE:
1022 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN; 993 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN;
1023 XPUSHs (scalar); 994 XPUSHs (scalar);
1024 995
1036 EXTEND (SP, 2); 1007 EXTEND (SP, 2);
1037 PUSHs (sv); 1008 PUSHs (sv);
1038 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); 1009 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr))));
1039} 1010}
1040 1011
1041#if 0
1042
1043void DESTROY (CBOR *self)
1044 CODE:
1045 SvREFCNT_dec (self->cb_sk_object);
1046 SvREFCNT_dec (self->cb_object);
1047
1048#endif
1049
1050PROTOTYPES: ENABLE 1012PROTOTYPES: ENABLE
1051 1013
1052void encode_cbor (SV *scalar) 1014void encode_cbor (SV *scalar)
1053 PPCODE: 1015 PPCODE:
1054{ 1016{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines