SRL_STATIC_INLINE srl_merger_t * srl_empty_merger_struct(pTHX) { srl_merger_t *mrg = NULL; Newx(mrg, 1, srl_merger_t); if (mrg == NULL) croak("Out of memory"); /* Init buffer struct */ if (expect_false(srl_buf_init_buffer(aTHX_ &mrg->obuf, INITIALIZATION_SIZE) != 0)) { Safefree(mrg); croak("Out of memory"); } SRL_RDR_CLEAR(&mrg->ibuf); mrg->pibuf = &mrg->ibuf; mrg->recursion_depth = 0; mrg->max_recursion_depth = DEFAULT_MAX_RECUR_DEPTH; /* Zero fields */ mrg->cnt_of_merged_elements = 0; mrg->obuf_padding_bytes_offset = 0; mrg->obuf_last_successfull_offset = 0; mrg->protocol_version = SRL_PROTOCOL_VERSION; mrg->classname_deduper_tbl = NULL; mrg->string_deduper_tbl = NULL; mrg->tracked_offsets_tbl = NULL; mrg->tracked_offsets = NULL; mrg->snappy_workmem = NULL; mrg->flags = 0; return mrg; }
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); }
srl_iterator_t * srl_build_iterator_struct(pTHX_ HV *opt) { srl_stack_t *stack = NULL; srl_iterator_t *iter = NULL; Newx(iter, 1, srl_iterator_t); if (iter == NULL) croak("Out of memory"); Newx(stack, 1, srl_stack_t); if (stack == NULL) { Safefree(iter); croak("Out of memory"); } // TODO inline stack // TODO keep fixed stack size ??? if (expect_false(srl_stack_init(aTHX_ stack, 1024) != 0)) { Safefree(iter); Safefree(stack); croak("Out of memory"); } SRL_RDR_CLEAR(&iter->buf); iter->pbuf = &iter->buf; iter->stack = stack; iter->document = NULL; iter->tmp_buf_owner = NULL; iter->first_tag_offset = 0; iter->dec = NULL; /* load options */ if (opt != NULL) { /* svp = hv_fetchs(opt, "dedupe_strings", 0); if (svp && SvTRUE(*svp)) SRL_iter_SET_OPTION(iter, SRL_F_DEDUPE_STRINGS); */ } return iter; }
void srl_init_iterator(pTHX_ srl_iterator_t *iter, HV *opt) { assert(iter != NULL); if (expect_false(srl_stack_init(aTHX_ &iter->stack, 32) != 0)) { Safefree(iter); croak("Out of memory"); } SRL_RDR_CLEAR(&iter->buf); iter->pbuf = &iter->buf; iter->pstack = &iter->stack; iter->document = NULL; iter->dec = NULL; /* load options */ if (opt != NULL) { /* svp = hv_fetchs(opt, "dedupe_strings", 0); if (svp && SvTRUE(*svp)) SRL_iter_SET_OPTION(iter, SRL_F_DEDUPE_STRINGS); */ } }