static HSD_state st_yield_backref(heatshrink_decoder *hsd, output_info *oi) { size_t count = oi->buf_size - *oi->output_size; if (count > 0) { size_t i = 0; if (hsd->output_count < count) count = hsd->output_count; uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)]; uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1; uint16_t neg_offset = hsd->output_index; LOG("-- emitting %zu bytes from -%u bytes back\n", count, neg_offset); ASSERT(neg_offset <= mask + 1); ASSERT(count <= (size_t)(1 << BACKREF_COUNT_BITS(hsd))); for (i=0; i<count; i++) { uint8_t c = buf[(hsd->head_index - neg_offset) & mask]; push_byte(hsd, oi, c); buf[hsd->head_index & mask] = c; hsd->head_index++; LOG(" -- ++ 0x%02x\n", c); } hsd->output_count -= count; if (hsd->output_count == 0) { return HSDS_TAG_BIT; } } return HSDS_YIELD_BACKREF; }
static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd) { uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); uint32_t bits = get_bits(hsd, br_bit_ct < 8 ? br_bit_ct : 8); LOG("-- backref count (lsb), got 0x%04x (+1)\n", bits); if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_LSB; } hsd->output_count |= bits; hsd->output_count++; return HSDS_YIELD_BACKREF; }
static HSD_state st_backref_count_msb(heatshrink_decoder *hsd) { uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); ASSERT(br_bit_ct > 8); uint32_t bits = get_bits(hsd, br_bit_ct - 8); LOG("-- backref count (msb), got 0x%04x (+1)\n", bits); if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_MSB; } hsd->output_count = bits << 8; return HSDS_BACKREF_COUNT_LSB; }
static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd) { uint8_t bit_ct = BACKREF_INDEX_BITS(hsd); uint32_t bits = get_bits(hsd, bit_ct < 8 ? bit_ct : 8); LOG("-- backref index (lsb), got 0x%04x (+1)\n", bits); if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_LSB; } hsd->output_index |= bits; hsd->output_index++; uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); hsd->output_count = 0; return (br_bit_ct > 8) ? HSDS_BACKREF_COUNT_MSB : HSDS_BACKREF_COUNT_LSB; }