… | |
… | |
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 | #if defined(__BORLANDC__) || defined(_MSC_VER) |
|
|
15 | # define snprintf _snprintf // C compilers have this in stdio.h |
|
|
16 | #endif |
|
|
17 | |
13 | |
18 | #define F_SHRINK 0x00000200UL |
14 | #define F_SHRINK 0x00000200UL |
19 | #define F_ALLOW_UNKNOWN 0x00002000UL |
15 | #define F_ALLOW_UNKNOWN 0x00002000UL |
20 | |
16 | |
21 | #define INIT_SIZE 32 // initial scalar size to be allocated |
17 | #define INIT_SIZE 32 // initial scalar size to be allocated |
… | |
… | |
138 | { |
134 | { |
139 | need (enc, 9); |
135 | need (enc, 9); |
140 | |
136 | |
141 | if (len < 24) |
137 | if (len < 24) |
142 | *enc->cur++ = major | len; |
138 | *enc->cur++ = major | len; |
143 | else if (len < 0x100) |
139 | else if (len <= 0xff) |
144 | { |
140 | { |
145 | *enc->cur++ = major | 24; |
141 | *enc->cur++ = major | 24; |
146 | *enc->cur++ = len; |
142 | *enc->cur++ = len; |
147 | } |
143 | } |
148 | else if (len < 0x10000) |
144 | else if (len <= 0xffff) |
149 | { |
145 | { |
150 | *enc->cur++ = major | 25; |
146 | *enc->cur++ = major | 25; |
151 | *enc->cur++ = len >> 8; |
147 | *enc->cur++ = len >> 8; |
152 | *enc->cur++ = len; |
148 | *enc->cur++ = len; |
153 | } |
149 | } |
154 | else if (len < 0x100000000) |
150 | else if (len <= 0xffffffff) |
155 | { |
151 | { |
156 | *enc->cur++ = major | 26; |
152 | *enc->cur++ = major | 26; |
157 | *enc->cur++ = len >> 24; |
153 | *enc->cur++ = len >> 24; |
158 | *enc->cur++ = len >> 16; |
154 | *enc->cur++ = len >> 16; |
159 | *enc->cur++ = len >> 8; |
155 | *enc->cur++ = len >> 8; |
160 | *enc->cur++ = len; |
156 | *enc->cur++ = len; |
161 | } |
157 | } |
162 | else if (len) |
158 | else |
163 | { |
159 | { |
164 | *enc->cur++ = major | 27; |
160 | *enc->cur++ = major | 27; |
165 | *enc->cur++ = len >> 56; |
161 | *enc->cur++ = len >> 56; |
166 | *enc->cur++ = len >> 48; |
162 | *enc->cur++ = len >> 48; |
167 | *enc->cur++ = len >> 40; |
163 | *enc->cur++ = len >> 40; |
… | |
… | |
504 | |
500 | |
505 | for (;;) |
501 | for (;;) |
506 | { |
502 | { |
507 | WANT (1); |
503 | WANT (1); |
508 | |
504 | |
509 | if (*dec->cur == 0xe0 | 31) |
505 | if (*dec->cur == (0xe0 | 31)) |
510 | { |
506 | { |
511 | ++dec->cur; |
507 | ++dec->cur; |
512 | break; |
508 | break; |
513 | } |
509 | } |
514 | |
510 | |
… | |
… | |
547 | |
543 | |
548 | for (;;) |
544 | for (;;) |
549 | { |
545 | { |
550 | WANT (1); |
546 | WANT (1); |
551 | |
547 | |
552 | if (*dec->cur == 0xe0 | 31) |
548 | if (*dec->cur == (0xe0 | 31)) |
553 | { |
549 | { |
554 | ++dec->cur; |
550 | ++dec->cur; |
555 | break; |
551 | break; |
556 | } |
552 | } |
557 | |
553 | |
… | |
… | |
752 | // not very fast, and certainly not robust against illegal input |
748 | // not very fast, and certainly not robust against illegal input |
753 | for (;;) |
749 | for (;;) |
754 | { |
750 | { |
755 | WANT (1); |
751 | WANT (1); |
756 | |
752 | |
757 | if (*dec->cur == 0xe0 | 31) |
753 | if (*dec->cur == (0xe0 | 31)) |
758 | { |
754 | { |
759 | ++dec->cur; |
755 | ++dec->cur; |
760 | break; |
756 | break; |
761 | } |
757 | } |
762 | |
758 | |
… | |
… | |
778 | |
774 | |
779 | return sv; |
775 | return sv; |
780 | |
776 | |
781 | fail: |
777 | fail: |
782 | return &PL_sv_undef; |
778 | return &PL_sv_undef; |
|
|
779 | } |
|
|
780 | |
|
|
781 | static SV * |
|
|
782 | decode_tagged (dec_t *dec) |
|
|
783 | { |
|
|
784 | UV tag = decode_uint (dec); |
|
|
785 | SV *sv = decode_sv (dec); |
|
|
786 | |
|
|
787 | if (tag == 55799) // 2.4.5 Self-Describe CBOR |
|
|
788 | return sv; |
|
|
789 | |
|
|
790 | AV *av = newAV (); |
|
|
791 | av_push (av, newSVuv (tag)); |
|
|
792 | av_push (av, sv); |
|
|
793 | return newRV_noinc ((SV *)av); |
783 | } |
794 | } |
784 | |
795 | |
785 | static SV * |
796 | static SV * |
786 | decode_sv (dec_t *dec) |
797 | decode_sv (dec_t *dec) |
787 | { |
798 | { |
… | |
… | |
801 | case 4: // array |
812 | case 4: // array |
802 | return decode_av (dec); |
813 | return decode_av (dec); |
803 | case 5: // map |
814 | case 5: // map |
804 | return decode_hv (dec); |
815 | return decode_hv (dec); |
805 | case 6: // tag |
816 | case 6: // tag |
806 | abort (); |
817 | return decode_tagged (dec); |
807 | break; |
|
|
808 | case 7: // misc |
818 | case 7: // misc |
809 | switch (*dec->cur++ & 31) |
819 | switch (*dec->cur++ & 31) |
810 | { |
820 | { |
811 | case 20: |
821 | case 20: |
812 | #if CBOR_SLOW |
822 | #if CBOR_SLOW |
… | |
… | |
820 | return newSVsv (cbor_true); |
830 | return newSVsv (cbor_true); |
821 | case 22: |
831 | case 22: |
822 | return newSVsv (&PL_sv_undef); |
832 | return newSVsv (&PL_sv_undef); |
823 | |
833 | |
824 | case 25: |
834 | case 25: |
825 | // half float |
|
|
826 | abort (); |
|
|
827 | break; |
835 | { |
|
|
836 | WANT (2); |
|
|
837 | |
|
|
838 | uint16_t fp = (dec->cur[0] << 8) | dec->cur[1]; |
|
|
839 | dec->cur += 2; |
|
|
840 | |
|
|
841 | return newSVnv (ecb_binary16_to_float (fp)); |
|
|
842 | } |
828 | |
843 | |
829 | case 26: |
844 | case 26: |
830 | { |
845 | { |
831 | uint32_t fp; |
846 | uint32_t fp; |
832 | WANT (4); |
847 | WANT (4); |
… | |
… | |
975 | |
990 | |
976 | if (offset_return) |
991 | if (offset_return) |
977 | *offset_return = dec.cur; |
992 | *offset_return = dec.cur; |
978 | |
993 | |
979 | if (!(offset_return || !sv)) |
994 | if (!(offset_return || !sv)) |
980 | { |
|
|
981 | if (*dec.cur && !dec.err) |
995 | if (dec.cur != dec.end && !dec.err) |
982 | { |
|
|
983 | dec.err = "garbage after CBOR object"; |
996 | dec.err = "garbage after CBOR object"; |
|
|
997 | |
|
|
998 | if (dec.err) |
|
|
999 | { |
984 | SvREFCNT_dec (sv); |
1000 | SvREFCNT_dec (sv); |
985 | sv = 0; |
|
|
986 | } |
|
|
987 | } |
|
|
988 | |
|
|
989 | if (!sv) |
|
|
990 | croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)SvPVX (string), (int)(uint8_t)*dec.cur); |
1001 | croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)SvPVX (string), (int)(uint8_t)*dec.cur); |
|
|
1002 | } |
991 | |
1003 | |
992 | sv = sv_2mortal (sv); |
1004 | sv = sv_2mortal (sv); |
993 | |
1005 | |
994 | return sv; |
1006 | return sv; |
995 | } |
1007 | } |