… | |
… | |
584 | SvREFCNT_dec (av); |
584 | SvREFCNT_dec (av); |
585 | DEC_DEC_DEPTH; |
585 | DEC_DEC_DEPTH; |
586 | return &PL_sv_undef; |
586 | return &PL_sv_undef; |
587 | } |
587 | } |
588 | |
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 | |
589 | static SV * |
623 | static SV * |
590 | decode_hv (dec_t *dec) |
624 | decode_hv (dec_t *dec) |
591 | { |
625 | { |
592 | HV *hv = newHV (); |
626 | HV *hv = newHV (); |
593 | |
627 | |
… | |
… | |
605 | { |
639 | { |
606 | ++dec->cur; |
640 | ++dec->cur; |
607 | break; |
641 | break; |
608 | } |
642 | } |
609 | |
643 | |
610 | SV *k = decode_sv (dec); |
644 | decode_he (dec, hv); |
611 | SV *v = decode_sv (dec); |
|
|
612 | |
|
|
613 | hv_store_ent (hv, k, v, 0); |
|
|
614 | SvREFCNT_dec (k); |
|
|
615 | } |
645 | } |
616 | } |
646 | } |
617 | else |
647 | else |
618 | { |
648 | { |
619 | int len = decode_uint (dec); |
649 | int pairs = decode_uint (dec); |
620 | |
650 | |
621 | while (len--) |
651 | while (pairs--) |
622 | { |
652 | decode_he (dec, hv); |
623 | SV *k = decode_sv (dec); |
|
|
624 | SV *v = decode_sv (dec); |
|
|
625 | |
|
|
626 | hv_store_ent (hv, k, v, 0); |
|
|
627 | SvREFCNT_dec (k); |
|
|
628 | } |
|
|
629 | } |
653 | } |
630 | |
654 | |
631 | DEC_DEC_DEPTH; |
655 | DEC_DEC_DEPTH; |
632 | return newRV_noinc ((SV *)hv); |
656 | return newRV_noinc ((SV *)hv); |
633 | |
657 | |
… | |
… | |
844 | static SV * |
868 | static SV * |
845 | decode_cbor (SV *string, CBOR *cbor, char **offset_return) |
869 | decode_cbor (SV *string, CBOR *cbor, char **offset_return) |
846 | { |
870 | { |
847 | dec_t dec; |
871 | dec_t dec; |
848 | SV *sv; |
872 | SV *sv; |
|
|
873 | STRLEN len; |
|
|
874 | char *data = SvPVbyte (string, len); |
849 | |
875 | |
850 | /* work around bugs in 5.10 where manipulating magic values |
|
|
851 | * makes perl ignore the magic in subsequent accesses. |
|
|
852 | * also make a copy of non-PV values, to get them into a clean |
|
|
853 | * state (SvPV should do that, but it's buggy, see below). |
|
|
854 | */ |
|
|
855 | /*SvGETMAGIC (string);*/ |
|
|
856 | if (SvMAGICAL (string) || !SvPOK (string)) |
|
|
857 | string = sv_2mortal (newSVsv (string)); |
|
|
858 | |
|
|
859 | SvUPGRADE (string, SVt_PV); |
|
|
860 | |
|
|
861 | /* work around a bug in perl 5.10, which causes SvCUR to fail an |
|
|
862 | * assertion with -DDEBUGGING, although SvCUR is documented to |
|
|
863 | * return the xpv_cur field which certainly exists after upgrading. |
|
|
864 | * according to nicholas clark, calling SvPOK fixes this. |
|
|
865 | * But it doesn't fix it, so try another workaround, call SvPV_nolen |
|
|
866 | * and hope for the best. |
|
|
867 | * Damnit, SvPV_nolen still trips over yet another assertion. This |
|
|
868 | * assertion business is seriously broken, try yet another workaround |
|
|
869 | * for the broken -DDEBUGGING. |
|
|
870 | */ |
|
|
871 | { |
|
|
872 | #ifdef DEBUGGING |
|
|
873 | STRLEN offset = SvOK (string) ? sv_len (string) : 0; |
|
|
874 | #else |
|
|
875 | STRLEN offset = SvCUR (string); |
|
|
876 | #endif |
|
|
877 | |
|
|
878 | if (offset > cbor->max_size && cbor->max_size) |
876 | if (len > cbor->max_size && cbor->max_size) |
879 | 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", |
880 | (unsigned long)SvCUR (string), (unsigned long)cbor->max_size); |
878 | (unsigned long)len, (unsigned long)cbor->max_size); |
881 | } |
|
|
882 | |
|
|
883 | sv_utf8_downgrade (string, 0); |
|
|
884 | |
879 | |
885 | dec.cbor = *cbor; |
880 | dec.cbor = *cbor; |
886 | dec.cur = (U8 *)SvPVX (string); |
881 | dec.cur = (U8 *)data; |
887 | dec.end = (U8 *)SvEND (string); |
882 | dec.end = (U8 *)data + len; |
888 | dec.err = 0; |
883 | dec.err = 0; |
889 | dec.depth = 0; |
884 | dec.depth = 0; |
890 | |
885 | |
891 | sv = decode_sv (&dec); |
886 | sv = decode_sv (&dec); |
892 | |
887 | |
… | |
… | |
898 | dec.err = "garbage after CBOR object"; |
893 | dec.err = "garbage after CBOR object"; |
899 | |
894 | |
900 | if (dec.err) |
895 | if (dec.err) |
901 | { |
896 | { |
902 | SvREFCNT_dec (sv); |
897 | SvREFCNT_dec (sv); |
903 | 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); |
904 | } |
899 | } |
905 | |
900 | |
906 | sv = sv_2mortal (sv); |
901 | sv = sv_2mortal (sv); |
907 | |
902 | |
908 | return sv; |
903 | return sv; |
… | |
… | |
991 | CODE: |
986 | CODE: |
992 | RETVAL = self->max_size; |
987 | RETVAL = self->max_size; |
993 | OUTPUT: |
988 | OUTPUT: |
994 | RETVAL |
989 | RETVAL |
995 | |
990 | |
996 | #if 0 //TODO |
|
|
997 | |
|
|
998 | void filter_cbor_object (CBOR *self, SV *cb = &PL_sv_undef) |
|
|
999 | PPCODE: |
|
|
1000 | { |
|
|
1001 | SvREFCNT_dec (self->cb_object); |
|
|
1002 | self->cb_object = SvOK (cb) ? newSVsv (cb) : 0; |
|
|
1003 | |
|
|
1004 | XPUSHs (ST (0)); |
|
|
1005 | } |
|
|
1006 | |
|
|
1007 | void filter_cbor_single_key_object (CBOR *self, SV *key, SV *cb = &PL_sv_undef) |
|
|
1008 | PPCODE: |
|
|
1009 | { |
|
|
1010 | if (!self->cb_sk_object) |
|
|
1011 | self->cb_sk_object = newHV (); |
|
|
1012 | |
|
|
1013 | if (SvOK (cb)) |
|
|
1014 | hv_store_ent (self->cb_sk_object, key, newSVsv (cb), 0); |
|
|
1015 | else |
|
|
1016 | { |
|
|
1017 | hv_delete_ent (self->cb_sk_object, key, G_DISCARD, 0); |
|
|
1018 | |
|
|
1019 | if (!HvKEYS (self->cb_sk_object)) |
|
|
1020 | { |
|
|
1021 | SvREFCNT_dec (self->cb_sk_object); |
|
|
1022 | self->cb_sk_object = 0; |
|
|
1023 | } |
|
|
1024 | } |
|
|
1025 | |
|
|
1026 | XPUSHs (ST (0)); |
|
|
1027 | } |
|
|
1028 | |
|
|
1029 | #endif |
|
|
1030 | |
|
|
1031 | void encode (CBOR *self, SV *scalar) |
991 | void encode (CBOR *self, SV *scalar) |
1032 | PPCODE: |
992 | PPCODE: |
1033 | PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN; |
993 | PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN; |
1034 | XPUSHs (scalar); |
994 | XPUSHs (scalar); |
1035 | |
995 | |
… | |
… | |
1047 | EXTEND (SP, 2); |
1007 | EXTEND (SP, 2); |
1048 | PUSHs (sv); |
1008 | PUSHs (sv); |
1049 | PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); |
1009 | PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); |
1050 | } |
1010 | } |
1051 | |
1011 | |
1052 | #if 0 |
|
|
1053 | |
|
|
1054 | void DESTROY (CBOR *self) |
|
|
1055 | CODE: |
|
|
1056 | SvREFCNT_dec (self->cb_sk_object); |
|
|
1057 | SvREFCNT_dec (self->cb_object); |
|
|
1058 | |
|
|
1059 | #endif |
|
|
1060 | |
|
|
1061 | PROTOTYPES: ENABLE |
1012 | PROTOTYPES: ENABLE |
1062 | |
1013 | |
1063 | void encode_cbor (SV *scalar) |
1014 | void encode_cbor (SV *scalar) |
1064 | PPCODE: |
1015 | PPCODE: |
1065 | { |
1016 | { |