… | |
… | |
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 |
15 | enum cbor_tag |
26 | enum 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 | |
|
|
589 | static void |
|
|
590 | decode_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 | |
578 | static SV * |
623 | static SV * |
579 | decode_hv (dec_t *dec) |
624 | decode_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; |
|
|
749 | |
|
|
750 | if (SvTRUE (ERRSV)) |
|
|
751 | { |
|
|
752 | FREETMPS; LEAVE; |
|
|
753 | ERR (SvPVutf8_nolen (sv_2mortal (SvREFCNT_inc (ERRSV)))); |
|
|
754 | } |
714 | |
755 | |
715 | SvREFCNT_dec (sv); |
756 | SvREFCNT_dec (sv); |
716 | sv = SvREFCNT_inc (POPs); |
757 | sv = SvREFCNT_inc (POPs); |
717 | |
758 | |
718 | PUTBACK; |
759 | PUTBACK; |
… | |
… | |
833 | static SV * |
874 | static SV * |
834 | decode_cbor (SV *string, CBOR *cbor, char **offset_return) |
875 | decode_cbor (SV *string, CBOR *cbor, char **offset_return) |
835 | { |
876 | { |
836 | dec_t dec; |
877 | dec_t dec; |
837 | SV *sv; |
878 | SV *sv; |
|
|
879 | STRLEN len; |
|
|
880 | char *data = SvPVbyte (string, len); |
838 | |
881 | |
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) |
882 | 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", |
883 | 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); |
884 | (unsigned long)len, (unsigned long)cbor->max_size); |
870 | } |
|
|
871 | |
|
|
872 | sv_utf8_downgrade (string, 0); |
|
|
873 | |
885 | |
874 | dec.cbor = *cbor; |
886 | dec.cbor = *cbor; |
875 | dec.cur = (U8 *)SvPVX (string); |
887 | dec.cur = (U8 *)data; |
876 | dec.end = (U8 *)SvEND (string); |
888 | dec.end = (U8 *)data + len; |
877 | dec.err = 0; |
889 | dec.err = 0; |
878 | dec.depth = 0; |
890 | dec.depth = 0; |
879 | |
891 | |
880 | sv = decode_sv (&dec); |
892 | sv = decode_sv (&dec); |
881 | |
893 | |
… | |
… | |
887 | dec.err = "garbage after CBOR object"; |
899 | dec.err = "garbage after CBOR object"; |
888 | |
900 | |
889 | if (dec.err) |
901 | if (dec.err) |
890 | { |
902 | { |
891 | SvREFCNT_dec (sv); |
903 | SvREFCNT_dec (sv); |
892 | 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); |
893 | } |
905 | } |
894 | |
906 | |
895 | sv = sv_2mortal (sv); |
907 | sv = sv_2mortal (sv); |
896 | |
908 | |
897 | return sv; |
909 | return sv; |
… | |
… | |
980 | CODE: |
992 | CODE: |
981 | RETVAL = self->max_size; |
993 | RETVAL = self->max_size; |
982 | OUTPUT: |
994 | OUTPUT: |
983 | RETVAL |
995 | RETVAL |
984 | |
996 | |
985 | #if 0 //TODO |
|
|
986 | |
|
|
987 | void 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 | |
|
|
996 | void 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 | |
|
|
1020 | void encode (CBOR *self, SV *scalar) |
997 | void encode (CBOR *self, SV *scalar) |
1021 | PPCODE: |
998 | PPCODE: |
1022 | PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN; |
999 | PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN; |
1023 | XPUSHs (scalar); |
1000 | XPUSHs (scalar); |
1024 | |
1001 | |
… | |
… | |
1036 | EXTEND (SP, 2); |
1013 | EXTEND (SP, 2); |
1037 | PUSHs (sv); |
1014 | PUSHs (sv); |
1038 | PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); |
1015 | PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); |
1039 | } |
1016 | } |
1040 | |
1017 | |
1041 | #if 0 |
|
|
1042 | |
|
|
1043 | void DESTROY (CBOR *self) |
|
|
1044 | CODE: |
|
|
1045 | SvREFCNT_dec (self->cb_sk_object); |
|
|
1046 | SvREFCNT_dec (self->cb_object); |
|
|
1047 | |
|
|
1048 | #endif |
|
|
1049 | |
|
|
1050 | PROTOTYPES: ENABLE |
1018 | PROTOTYPES: ENABLE |
1051 | |
1019 | |
1052 | void encode_cbor (SV *scalar) |
1020 | void encode_cbor (SV *scalar) |
1053 | PPCODE: |
1021 | PPCODE: |
1054 | { |
1022 | { |