--- CBOR-XS/XS.xs 2013/12/10 13:54:40 1.40 +++ CBOR-XS/XS.xs 2015/04/27 20:21:53 1.47 @@ -9,6 +9,7 @@ #include #include +#define ECB_NO_THREADS 1 #include "ecb.h" // compatibility with perl <5.18 @@ -325,11 +326,18 @@ encode_uint (enc, MAJOR_ARRAY, len + 1); - for (i = 0; i <= len; ++i) - { - SV **svp = av_fetch (av, i, 0); - encode_sv (enc, svp ? *svp : &PL_sv_undef); - } + if (SvMAGICAL (av)) + for (i = 0; i <= len; ++i) + { + SV **svp = av_fetch (av, i, 0); + encode_sv (enc, svp ? *svp : &PL_sv_undef); + } + else + for (i = 0; i <= len; ++i) + { + SV *sv = AvARRAY (av)[i]; + encode_sv (enc, sv ? sv : &PL_sv_undef); + } --enc->depth; } @@ -738,7 +746,7 @@ // byte or utf-8 strings as keys, but only when !stringref if (ecb_expect_true (!dec->stringref)) - if (ecb_expect_true ((*dec->cur - MAJOR_BYTES) <= LENGTH_EXT8)) + if (ecb_expect_true ((U8)(*dec->cur - MAJOR_BYTES) <= LENGTH_EXT8)) { I32 len = decode_uint (dec); char *key = (char *)dec->cur; @@ -749,7 +757,7 @@ return; } - else if (ecb_expect_true ((*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8)) + else if (ecb_expect_true ((U8)(*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8)) { I32 len = decode_uint (dec); char *key = (char *)dec->cur; @@ -1258,6 +1266,10 @@ switch (major) { + case MAJOR_TAG >> MAJOR_SHIFT: + ++count; // tags merely prefix another value + break; + case MAJOR_BYTES >> MAJOR_SHIFT: case MAJOR_TEXT >> MAJOR_SHIFT: case MAJOR_ARRAY >> MAJOR_SHIFT: @@ -1449,7 +1461,9 @@ PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); } -void incr_parse (CBOR *self, SV *cborstr, int chop = 0) +void incr_parse (CBOR *self, SV *cborstr) + ALIAS: + incr_parse_multiple = 1 PPCODE: { if (SvUTF8 (cborstr)) @@ -1464,7 +1478,7 @@ av_push (self->incr_count, newSViv (1)); } - for (;;) + do { if (!incr_parse (self, cborstr)) { @@ -1475,25 +1489,21 @@ break; } - SV *sv; - char *offset; + SV *sv; + char *offset; - PUTBACK; sv = decode_cbor (cborstr, self, &offset); SPAGAIN; - XPUSHs (sv); + PUTBACK; sv = decode_cbor (cborstr, self, &offset); SPAGAIN; + XPUSHs (sv); - av_clear (self->incr_count); - av_push (self->incr_count, newSViv (1)); + sv_chop (cborstr, offset); - if (chop) - { - self->incr_pos = 0; - sv_chop (cborstr, offset); - } - else - self->incr_pos = offset - SvPVX (cborstr); + av_clear (self->incr_count); + av_push (self->incr_count, newSViv (1)); - self->incr_need = self->incr_pos + 1; + self->incr_pos = 0; + self->incr_need = self->incr_pos + 1; } + while (ix); } void incr_reset (CBOR *self)