void srl_iterator_next_until_depth_and_idx(pTHX_ srl_iterator_t *iter, UV expected_depth, U32 expected_idx) { U32 current_idx; srl_stack_t *stack = iter->stack; IV current_depth = SRL_STACK_DEPTH(stack); DEBUG_ASSERT_RDR_SANE(iter->pbuf); SRL_ITER_TRACE("expected_depth=%"UVuf" expected_idx=%u", expected_depth, expected_idx); SRL_ITER_ASSERT_STACK(iter); if (expect_false((IV) expected_depth > current_depth)) { SRL_ITER_ERRORf2("srl_iterator_next_until_depth() can only go forward, " "so expected_depth=%"UVuf" should not be greater then current_depth=%"IVdf, expected_depth, current_depth); } current_idx = stack->ptr->idx; if (expect_false((IV) expected_depth == current_depth && expected_idx == current_idx)) return; while (expect_true(!srl_stack_empty(stack))) { srl_iterator_wrap_stack(aTHX_ iter, expected_depth); current_depth = SRL_STACK_DEPTH(stack); if (expect_false(srl_stack_empty(stack))) break; current_idx = stack->ptr->idx; if (current_depth == (IV) expected_depth && current_idx == expected_idx) break; if (expect_false(current_depth == (IV) expected_depth && expected_idx > current_idx)) { SRL_ITER_ERRORf2("srl_iterator_next_until_depth() can only go forward, " "so expected_idx=%d should not be greater then current_idx=%d", expected_idx, current_idx); } srl_iterator_step_internal(aTHX_ iter); } if (expect_false(current_depth != (IV) expected_depth)) { SRL_ITER_ERRORf2("func led to wrong stack depth, expected=%"IVdf", actual=%"IVdf, expected_depth, current_depth); } if (expect_false(current_idx != expected_idx)) { SRL_ITER_ERRORf2("func led to wrong stack index, expected=%u, actual=%u", expected_idx, current_idx); } SRL_ITER_TRACE("Reached expected stack depth: %"UVuf " and idx: %u", expected_depth, expected_idx); DEBUG_ASSERT_RDR_SANE(iter->pbuf); }
void srl_iterator_next_until_depth_and_idx(pTHX_ srl_iterator_t *iter, UV expected_depth, U32 expected_idx) { IV current_depth = iter->stack.depth; srl_iterator_stack_ptr stack_ptr = iter->stack.ptr; DEBUG_ASSERT_RDR_SANE(iter->pbuf); SRL_ITER_ASSERT_STACK(iter); SRL_ITER_TRACE("expected_depth=%"UVuf" expected_idx=%u", expected_depth, expected_idx); SRL_ITER_REPORT_STACK_STATE(iter); if (expect_false((IV) expected_depth == current_depth && (IV) expected_idx == stack_ptr->idx)) return; if (expect_false((IV) expected_depth > current_depth)) { SRL_ITER_ERRORf2("srl_iterator_next_until_depth() can only go forward, " "so expected_depth=%"UVuf" should not be greater then current_depth=%"IVdf, expected_depth, current_depth); } stack_ptr = iter->stack.begin + expected_depth; if (expect_false((IV) expected_idx > stack_ptr->idx)) { SRL_ITER_ERRORf3("srl_iterator_next_until_depth() can only go forward, " "so expected_idx=%u should not be greater then current " "index (%u) at expected_depth=%"IVdf, expected_idx, stack_ptr->idx, expected_depth); } stack_ptr = iter->stack.ptr; while (1) { srl_iterator_wrap_stack(iter, expected_depth, stack_ptr); if (iter->stack.depth == (IV) expected_depth) { if (stack_ptr->idx == (IV) expected_idx) break; assert(((IV) expected_idx > stack_ptr->idx) == 0); } srl_iterator_step_internal(iter, stack_ptr); } assert(stack_ptr->idx == (IV) expected_idx); assert(iter->stack.depth == (IV) expected_depth); SRL_ITER_TRACE("Reached expected stack depth: %"UVuf " and idx: %u", expected_depth, expected_idx); DEBUG_ASSERT_RDR_SANE(iter->pbuf); }
void srl_iterator_step_in(pTHX_ srl_iterator_t *iter, UV n) { srl_iterator_stack_ptr stack_ptr = iter->stack.ptr; DEBUG_ASSERT_RDR_SANE(iter->pbuf); SRL_ITER_ASSERT_STACK(iter); SRL_ITER_TRACE("n=%"UVuf, n); SRL_ITER_REPORT_STACK_STATE(iter); while (n--) { srl_iterator_wrap_stack(iter, -1, stack_ptr); srl_iterator_step_internal(iter, stack_ptr); } SRL_ITER_TRACE("Completed expected number of steps"); DEBUG_ASSERT_RDR_SANE(iter->pbuf); }
void srl_iterator_next(pTHX_ srl_iterator_t *iter, UV n) { IV expected_depth = iter->stack.depth; srl_iterator_stack_ptr stack_ptr = iter->stack.ptr; DEBUG_ASSERT_RDR_SANE(iter->pbuf); SRL_ITER_ASSERT_STACK(iter); SRL_ITER_TRACE("n=%"UVuf, n); SRL_ITER_REPORT_STACK_STATE(iter); if (expect_false(n == 0)) return; while (1) { srl_iterator_wrap_stack(iter, expected_depth, stack_ptr); if (iter->stack.depth == expected_depth) { if (n == 0) break; else n--; } srl_iterator_step_internal(iter, stack_ptr); } if (expect_false(n != 0)) { SRL_ITER_ERRORf1("Failed to do %"UVuf" next steps. Likely EOF was reached", n); } if (expect_false(iter->stack.depth != expected_depth)) { SRL_ITER_ERRORf2("next() led to wrong stack depth, expected=%"IVdf", actual=%"IVdf, expected_depth, iter->stack.depth); } SRL_ITER_TRACE("Did expected number of steps at depth %"IVdf, expected_depth); DEBUG_ASSERT_RDR_SANE(iter->pbuf); }
void srl_iterator_next(pTHX_ srl_iterator_t *iter, UV n) { srl_stack_t *stack = iter->stack; IV expected_depth = SRL_STACK_DEPTH(stack); DEBUG_ASSERT_RDR_SANE(iter->pbuf); SRL_ITER_TRACE("n=%"UVuf, n); SRL_ITER_ASSERT_STACK(iter); if (expect_false(n == 0)) return; if (expect_false(stack->ptr->idx == 0)) SRL_ITER_ERROR("Nothing to parse at this depth"); while (expect_true(!srl_stack_empty(stack))) { if (SRL_STACK_DEPTH(stack) == expected_depth) { if (n == 0) break; else n--; } srl_iterator_step_internal(aTHX_ iter); srl_iterator_wrap_stack(aTHX_ iter, expected_depth); } if (expect_false(n != 0)) { SRL_ITER_ERRORf1("Failed to do %"UVuf" next steps. Likely EOF was reached", n); } if (expect_false(SRL_STACK_DEPTH(stack) != expected_depth)) { SRL_ITER_ERRORf2("next() led to wrong stack depth, expected=%"IVdf", actual=%"IVdf, expected_depth, SRL_STACK_DEPTH(stack)); } SRL_ITER_TRACE("Did expected number of steps at depth %"IVdf, expected_depth); DEBUG_ASSERT_RDR_SANE(iter->pbuf); }
/* Main routine. Caller must ensure that EOF is NOT reached */ SRL_STATIC_INLINE void srl_iterator_step_internal(pTHX_ srl_iterator_t *iter) { U8 tag; UV length; srl_stack_t *stack = iter->stack; DEBUG_ASSERT_RDR_SANE(iter->pbuf); srl_iterator_wrap_stack(aTHX_ iter, -1); if (srl_stack_empty(stack)) return; SRL_ITER_ASSERT_STACK(iter); stack->ptr->idx--; SRL_ITER_TRACE("stack->ptr: idx=%d depth=%d", stack->ptr->idx, (int) SRL_STACK_DEPTH(stack)); SRL_ITER_ASSERT_STACK(iter); read_again: tag = *iter->buf.pos & ~SRL_HDR_TRACK_FLAG; SRL_ITER_REPORT_TAG(iter, tag); iter->buf.pos++; /* No code which decrease step, next or stack's counters should be added here. * Otherwise the counters will be decreased twicer for tags like REFN, ALIAS, etc. */ switch (tag) { CASE_SRL_HDR_SHORT_BINARY: iter->buf.pos += SRL_HDR_SHORT_BINARY_LEN_FROM_TAG(tag); break; case SRL_HDR_HASH: length = srl_read_varint_uv_count(aTHX_ iter->pbuf, " while reading HASH"); if (length > 0) srl_stack_push_and_set(iter, tag, length * 2); break; case SRL_HDR_ARRAY: length = srl_read_varint_uv_count(aTHX_ iter->pbuf, " while reading ARRAY"); if (length > 0) srl_stack_push_and_set(iter, tag, length); break; CASE_SRL_HDR_HASHREF: length = SRL_HDR_HASHREF_LEN_FROM_TAG(tag); if (length > 0) srl_stack_push_and_set(iter, tag, length * 2); break; CASE_SRL_HDR_ARRAYREF: length = SRL_HDR_ARRAYREF_LEN_FROM_TAG(tag); if (length > 0) srl_stack_push_and_set(iter, tag, length); break; CASE_SRL_HDR_POS: CASE_SRL_HDR_NEG: break; case SRL_HDR_VARINT: case SRL_HDR_ZIGZAG: srl_skip_varint(aTHX_ iter->pbuf); break; case SRL_HDR_FLOAT: iter->buf.pos += 4; break; case SRL_HDR_DOUBLE: iter->buf.pos += 8; break; case SRL_HDR_LONG_DOUBLE: iter->buf.pos += 16; break; case SRL_HDR_TRUE: case SRL_HDR_FALSE: case SRL_HDR_UNDEF: case SRL_HDR_CANONICAL_UNDEF: break; case SRL_HDR_REFN: case SRL_HDR_ALIAS: case SRL_HDR_WEAKEN: goto read_again; case SRL_HDR_PAD: while (SRL_RDR_NOT_DONE(iter->pbuf) && *iter->buf.pos++ == SRL_HDR_PAD) {}; goto read_again; case SRL_HDR_BINARY: case SRL_HDR_STR_UTF8: length = srl_read_varint_uv_length(aTHX_ iter->pbuf, " while reading BINARY or STR_UTF8"); iter->buf.pos += length; break; case SRL_HDR_COPY: case SRL_HDR_REFP: srl_skip_varint(aTHX_ iter->pbuf); break; /* case SRL_HDR_OBJECTV: */ /* case SRL_HDR_OBJECTV_FREEZE: */ /* case SRL_HDR_REGEXP: */ /* case SRL_HDR_OBJECT: */ /* case SRL_HDR_OBJECT_FREEZE: */ default: SRL_RDR_ERROR_UNIMPLEMENTED(iter->pbuf, tag, ""); break; } DEBUG_ASSERT_RDR_SANE(iter->pbuf); }