HSE_sink_res heatshrink_encoder_sink(heatshrink_encoder *hse, uint8_t *in_buf, size_t size, size_t *input_size) { if ((hse == NULL) || (in_buf == NULL) || (input_size == NULL)) { return HSER_SINK_ERROR_NULL; } /* Sinking more content after saying the content is done, tsk tsk */ if (is_finishing(hse)) { return HSER_SINK_ERROR_MISUSE; } /* Sinking more content before processing is done */ if (hse->state != HSES_NOT_FULL) { return HSER_SINK_ERROR_MISUSE; } uint16_t write_offset = get_input_offset(hse) + hse->input_size; uint16_t ibs = get_input_buffer_size(hse); uint16_t rem = ibs - hse->input_size; uint16_t cp_sz = rem < size ? rem : size; memcpy(&hse->buffer[write_offset], in_buf, cp_sz); *input_size = cp_sz; hse->input_size += cp_sz; LOG("-- sunk %u bytes (of %zu) into encoder at %d, input buffer now has %u\n", cp_sz, size, write_offset, hse->input_size); if (cp_sz == rem) { LOG("-- internal buffer is now full\n"); hse->state = HSES_FILLED; } return HSER_SINK_OK; }
static HSE_state ICACHE_FLASH_ATTR st_step_search(heatshrink_encoder *hse) { uint16_t window_length = get_input_buffer_size(hse); uint16_t lookahead_sz = get_lookahead_size(hse); uint16_t msi = hse->match_scan_index; LOG("## step_search, scan @ +%d (%d/%d), input size %d\n", msi, hse->input_size + msi, 2*window_length, hse->input_size); bool fin = is_finishing(hse); if (msi >= hse->input_size - (fin ? 0 : lookahead_sz)) { /* Current search buffer is exhausted, copy it into the * backlog and await more input. */ LOG("-- end of search @ %d, saving backlog\n", msi); return HSES_SAVE_BACKLOG; } uint16_t input_offset = get_input_offset(hse); uint16_t end = input_offset + msi; uint16_t start = 0; if (backlog_is_filled(hse)) { /* last WINDOW_LENGTH bytes */ start = end - window_length + 1; } else if (backlog_is_partial(hse)) { /* clamp to available data */ start = end - window_length + 1; if (start < lookahead_sz) { start = lookahead_sz; } } else { /* only scan available input */ start = input_offset; } uint16_t max_possible = lookahead_sz; if (hse->input_size - msi < lookahead_sz) { max_possible = hse->input_size - msi; } uint16_t match_length = 0; uint16_t match_pos = find_longest_match(hse, start, end, max_possible, &match_length); if (match_pos == MATCH_NOT_FOUND) { LOG("ss Match not found\n"); hse->match_scan_index++; hse->flags |= FLAG_HAS_LITERAL; hse->match_length = 0; return HSES_YIELD_TAG_BIT; } else { LOG("ss Found match of %d bytes at %d\n", match_length, match_pos); hse->match_pos = match_pos; hse->match_length = match_length; ASSERT(match_pos < 1 << hse->window_sz2 /*window_length*/); return HSES_YIELD_TAG_BIT; } }
static HSE_state ICACHE_FLASH_ATTR st_save_backlog(heatshrink_encoder *hse) { if (is_finishing(hse)) { /* copy remaining literal (if necessary) */ if (has_literal(hse)) { hse->flags |= FLAG_ON_FINAL_LITERAL; return HSES_YIELD_TAG_BIT; } else { return HSES_FLUSH_BITS; } } else { LOG("-- saving backlog\n"); save_backlog(hse); return HSES_NOT_FULL; } }
static HSE_state st_step_search(heatshrink_encoder *hse) { uint16_t window_length = get_input_buffer_size(hse); uint16_t lookahead_sz = get_lookahead_size(hse); uint16_t msi = hse->match_scan_index; LOG("## step_search, scan @ +%d (%d/%d), input size %d\n", msi, hse->input_size + msi, 2*window_length, hse->input_size); bool fin = is_finishing(hse); if (msi > hse->input_size - (fin ? 1 : lookahead_sz)) { /* Current search buffer is exhausted, copy it into the * backlog and await more input. */ LOG("-- end of search @ %d\n", msi); return fin ? HSES_FLUSH_BITS : HSES_SAVE_BACKLOG; } uint16_t input_offset = get_input_offset(hse); uint16_t end = input_offset + msi; uint16_t start = end - window_length; uint16_t max_possible = lookahead_sz; if (hse->input_size - msi < lookahead_sz) { max_possible = hse->input_size - msi; } uint16_t match_length = 0; uint16_t match_pos = find_longest_match(hse, start, end, max_possible, &match_length); if (match_pos == MATCH_NOT_FOUND) { LOG("ss Match not found\n"); hse->match_scan_index++; hse->match_length = 0; return HSES_YIELD_TAG_BIT; } else { LOG("ss Found match of %d bytes at %d\n", match_length, match_pos); hse->match_pos = match_pos; hse->match_length = match_length; ASSERT(match_pos < 1 << HEATSHRINK_ENCODER_WINDOW_BITS(hse) /*window_length*/); return HSES_YIELD_TAG_BIT; } }