… | |
… | |
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; |
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; |
… | |
… | |
832 | static SV * |
874 | static SV * |
833 | decode_cbor (SV *string, CBOR *cbor, char **offset_return) |
875 | decode_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 | |
|
|
986 | void 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 | |
|
|
995 | void 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 | |
|
|
1019 | void encode (CBOR *self, SV *scalar) |
997 | void 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 | |
|
|
1042 | void DESTROY (CBOR *self) |
|
|
1043 | CODE: |
|
|
1044 | SvREFCNT_dec (self->cb_sk_object); |
|
|
1045 | SvREFCNT_dec (self->cb_object); |
|
|
1046 | |
|
|
1047 | #endif |
|
|
1048 | |
|
|
1049 | PROTOTYPES: ENABLE |
1018 | PROTOTYPES: ENABLE |
1050 | |
1019 | |
1051 | void encode_cbor (SV *scalar) |
1020 | void encode_cbor (SV *scalar) |
1052 | PPCODE: |
1021 | PPCODE: |
1053 | { |
1022 | { |