SRL_STATIC_INLINE void srl_set_input_buffer(pTHX_ srl_merger_t *mrg, SV *src) { STRLEN len; UV header_len; U8 encoding_flags; U8 protocol_version; srl_buffer_char *tmp; IV proto_version_and_encoding_flags_int; SRL_RDR_CLEAR(&mrg->ibuf); tmp = (srl_buffer_char*) SvPV(src, len); mrg->ibuf.start = mrg->ibuf.pos = tmp; mrg->ibuf.end = mrg->ibuf.start + len; proto_version_and_encoding_flags_int = srl_validate_header_version(aTHX_ (srl_reader_char_ptr) mrg->ibuf.start, len); if (proto_version_and_encoding_flags_int < 1) { if (proto_version_and_encoding_flags_int == 0) SRL_RDR_ERROR(mrg->pibuf, "Bad Sereal header: It seems your document was accidentally UTF-8 encoded"); else SRL_RDR_ERROR(mrg->pibuf, "Bad Sereal header: Not a valid Sereal document."); } mrg->ibuf.pos += 5; encoding_flags = (U8) (proto_version_and_encoding_flags_int & SRL_PROTOCOL_ENCODING_MASK); protocol_version = (U8) (proto_version_and_encoding_flags_int & SRL_PROTOCOL_VERSION_MASK); if (expect_false(protocol_version > 3 || protocol_version < 1)) { SRL_RDR_ERRORf1(mrg->pibuf, "Unsupported Sereal protocol version %u", (unsigned int) protocol_version); } // skip header in any case header_len = srl_read_varint_uv_length(aTHX_ mrg->pibuf, " while reading header"); mrg->ibuf.pos += header_len; if (encoding_flags == SRL_PROTOCOL_ENCODING_RAW) { /* no op */ } else if ( encoding_flags == SRL_PROTOCOL_ENCODING_SNAPPY || encoding_flags == SRL_PROTOCOL_ENCODING_SNAPPY_INCREMENTAL) { srl_decompress_body_snappy(aTHX_ mrg->pibuf, encoding_flags, NULL); } else if (encoding_flags == SRL_PROTOCOL_ENCODING_ZLIB) { srl_decompress_body_zlib(aTHX_ mrg->pibuf, NULL); } else { SRL_RDR_ERROR(mrg->pibuf, "Sereal document encoded in an unknown format"); } /* this functions *MUST* be called after srl_decompress_body* */ SRL_RDR_UPDATE_BODY_POS(mrg->pibuf, protocol_version); DEBUG_ASSERT_RDR_SANE(mrg->pibuf); }
void srl_iterator_set(pTHX_ srl_iterator_t *iter, SV *src) { SV *sv; STRLEN len; UV header_len; U8 encoding_flags; U8 protocol_version; srl_reader_char_ptr tmp; IV proto_version_and_encoding_flags_int; srl_iterator_stack_ptr stack_ptr = NULL; if (iter->document) { SvREFCNT_dec(iter->document); iter->document = NULL; } iter->document = src; SvREFCNT_inc(iter->document); tmp = (srl_reader_char_ptr) SvPV(src, len); iter->buf.start = iter->buf.pos = tmp; iter->buf.end = iter->buf.start + len; proto_version_and_encoding_flags_int = srl_validate_header_version(aTHX_ iter->buf.start, len); if (proto_version_and_encoding_flags_int < 1) { if (proto_version_and_encoding_flags_int == 0) SRL_RDR_ERROR(iter->pbuf, "Bad Sereal header: It seems your document was accidentally UTF-8 encoded"); else SRL_RDR_ERROR(iter->pbuf, "Bad Sereal header: Not a valid Sereal document."); } iter->buf.pos += 5; encoding_flags = (U8) (proto_version_and_encoding_flags_int & SRL_PROTOCOL_ENCODING_MASK); protocol_version = (U8) (proto_version_and_encoding_flags_int & SRL_PROTOCOL_VERSION_MASK); if (expect_false(protocol_version > 3 || protocol_version < 1)) { SRL_RDR_ERRORf1(iter->pbuf, "Unsupported Sereal protocol version %u", (unsigned int) protocol_version); } // skip header in any case header_len = srl_read_varint_uv_length(aTHX_ iter->pbuf, " while reading header"); iter->buf.pos += header_len; if (encoding_flags == SRL_PROTOCOL_ENCODING_RAW) { /* no op */ } else if ( encoding_flags == SRL_PROTOCOL_ENCODING_SNAPPY || encoding_flags == SRL_PROTOCOL_ENCODING_SNAPPY_INCREMENTAL) { srl_decompress_body_snappy(aTHX_ iter->pbuf, encoding_flags, &sv); SvREFCNT_dec(iter->document); SvREFCNT_inc(sv); iter->document = sv; } else if (encoding_flags == SRL_PROTOCOL_ENCODING_ZLIB) { srl_decompress_body_zlib(aTHX_ iter->pbuf, &sv); SvREFCNT_dec(iter->document); SvREFCNT_inc(sv); iter->document = sv; } else { SRL_RDR_ERROR(iter->pbuf, "Sereal document encoded in an unknown format"); } /* this function *MUST* be called after calling srl_decompress_body* */ SRL_RDR_UPDATE_BODY_POS(iter->pbuf, protocol_version); DEBUG_ASSERT_RDR_SANE(iter->pbuf); srl_stack_push_and_set(iter, SRL_ITER_STACK_ROOT_TAG, 1, stack_ptr); srl_iterator_reset(aTHX_ iter); }