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