| #include "unity/unity.h" |
| #include "zlib.h" |
| #include "deflate.h" |
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdint.h> |
|
|
| |
| void test_fill_window(deflate_state *s); |
|
|
| static void init_deflater(z_stream *strm) { |
| memset(strm, 0, sizeof(*strm)); |
| int ret = deflateInit(strm, Z_DEFAULT_COMPRESSION); |
| TEST_ASSERT_EQUAL_INT(Z_OK, ret); |
| } |
|
|
| static void cleanup_deflater(z_stream *strm) { |
| int ret = deflateEnd(strm); |
| TEST_ASSERT(ret == Z_OK || ret == Z_DATA_ERROR); |
| } |
|
|
| void setUp(void) { |
| |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
| |
| |
| |
| void test_fill_window_reads_data_and_updates_adler_and_window(void) { |
| z_stream strm; |
| init_deflater(&strm); |
|
|
| deflate_state *s = (deflate_state *)strm.state; |
| TEST_ASSERT_NOT_NULL(s); |
|
|
| |
| const size_t in_len = 100; |
| unsigned char inbuf[in_len]; |
| for (size_t i = 0; i < in_len; i++) inbuf[i] = (unsigned char)(i ^ 0x5A); |
|
|
| strm.next_in = inbuf; |
| strm.avail_in = (uInt)in_len; |
|
|
| |
| TEST_ASSERT_TRUE(s->lookahead < MIN_LOOKAHEAD); |
|
|
| |
| uLong expected_adler = adler32(strm.adler, inbuf, (uInt)in_len); |
|
|
| test_fill_window(s); |
|
|
| |
| TEST_ASSERT_EQUAL_UINT32_MESSAGE(in_len, strm.total_in, "total_in should equal input length"); |
| TEST_ASSERT_EQUAL_UINT_MESSAGE(0, strm.avail_in, "avail_in should be zero after read"); |
|
|
| |
| TEST_ASSERT_TRUE_MESSAGE(s->lookahead == in_len, "lookahead should equal input length when input is exhausted"); |
| TEST_ASSERT_EQUAL_INT(0, memcmp(s->window + s->strstart, inbuf, in_len)); |
|
|
| |
| TEST_ASSERT_EQUAL_UINT32(expected_adler, strm.adler); |
|
|
| |
| TEST_ASSERT_TRUE(s->high_water >= (ulg)(s->strstart + s->lookahead)); |
|
|
| cleanup_deflater(&strm); |
| } |
|
|
| |
| |
| |
| |
| void test_fill_window_no_input_no_change(void) { |
| z_stream strm; |
| init_deflater(&strm); |
|
|
| deflate_state *s = (deflate_state *)strm.state; |
| TEST_ASSERT_NOT_NULL(s); |
|
|
| |
| strm.next_in = Z_NULL; |
| strm.avail_in = 0; |
|
|
| |
| uInt initial_lookahead = s->lookahead; |
| uLong initial_total_in = strm.total_in; |
|
|
| |
| TEST_ASSERT_TRUE(s->lookahead < MIN_LOOKAHEAD); |
|
|
| test_fill_window(s); |
|
|
| TEST_ASSERT_EQUAL_UINT(initial_lookahead, s->lookahead); |
| TEST_ASSERT_EQUAL_UINT32(initial_total_in, strm.total_in); |
|
|
| cleanup_deflater(&strm); |
| } |
|
|
| |
| |
| |
| |
| void test_fill_window_zeroes_high_water_region(void) { |
| z_stream strm; |
| init_deflater(&strm); |
|
|
| deflate_state *s = (deflate_state *)strm.state; |
| TEST_ASSERT_NOT_NULL(s); |
|
|
| |
| memset(s->window, 0xA5, (size_t)s->w_size * 2); |
| s->high_water = 0; |
|
|
| |
| const uInt in_len = 16; |
| unsigned char inbuf[in_len]; |
| for (uInt i = 0; i < in_len; i++) inbuf[i] = (unsigned char)(0xC3 ^ i); |
|
|
| strm.next_in = inbuf; |
| strm.avail_in = in_len; |
|
|
| |
| TEST_ASSERT_TRUE(s->lookahead < MIN_LOOKAHEAD); |
|
|
| test_fill_window(s); |
|
|
| |
| ulg curr = s->strstart + (ulg)s->lookahead; |
| TEST_ASSERT_EQUAL_UINT(in_len, curr); |
|
|
| |
| ulg expected_zero = s->window_size - curr; |
| if (expected_zero > WIN_INIT) expected_zero = WIN_INIT; |
|
|
| |
| for (ulg i = 0; i < expected_zero; i++) { |
| TEST_ASSERT_EQUAL_UINT8_MESSAGE(0, s->window[curr + i], "high-water region should be zeroed"); |
| } |
|
|
| |
| TEST_ASSERT_TRUE(s->high_water >= curr); |
|
|
| cleanup_deflater(&strm); |
| } |
|
|
| |
| |
| |
| |
| void test_fill_window_triggers_slide_and_adjusts_pointers(void) { |
| z_stream strm; |
| init_deflater(&strm); |
|
|
| deflate_state *s = (deflate_state *)strm.state; |
| TEST_ASSERT_NOT_NULL(s); |
|
|
| uInt wsize = s->w_size; |
| ulg win_size = s->window_size; |
|
|
| |
| uInt more = MIN_LOOKAHEAD; |
| uInt copy_len = wsize - more; |
| memset(s->window, 0x00, (size_t)wsize * 2); |
| memset(s->window + wsize, 0x5B, copy_len); |
|
|
| |
| |
| s->strstart = (uInt)(win_size - MIN_LOOKAHEAD); |
| s->lookahead = 0; |
| s->block_start = 0; |
| s->insert = 0; |
| s->match_start = wsize + 5; |
|
|
| |
| unsigned char inbyte = 0xAA; |
| strm.next_in = &inbyte; |
| strm.avail_in = 1; |
|
|
| test_fill_window(s); |
|
|
| |
| for (uInt i = 0; i < copy_len; i++) { |
| TEST_ASSERT_EQUAL_UINT8(0x5B, s->window[i]); |
| } |
|
|
| |
| TEST_ASSERT_EQUAL_UINT((uInt)5, s->match_start); |
|
|
| cleanup_deflater(&strm); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_fill_window_reads_data_and_updates_adler_and_window); |
| RUN_TEST(test_fill_window_no_input_no_change); |
| RUN_TEST(test_fill_window_zeroes_high_water_region); |
| RUN_TEST(test_fill_window_triggers_slide_and_adjusts_pointers); |
| return UNITY_END(); |
| } |