| #include "unity/unity.h" |
| #include "zlib.h" |
| #include <stdlib.h> |
| #include <string.h> |
| #include <stdint.h> |
|
|
| |
| |
| static uLong adler32_naive(uLong adler, const Bytef *buf, size_t len) { |
| const unsigned long BASE = 65521UL; |
| unsigned long sum1 = adler & 0xFFFFUL; |
| unsigned long sum2 = (adler >> 16) & 0xFFFFUL; |
|
|
| for (size_t i = 0; i < len; i++) { |
| sum1 += buf[i]; |
| if (sum1 >= BASE) sum1 -= BASE; |
| sum2 += sum1; |
| if (sum2 >= BASE) sum2 -= BASE; |
| } |
| return (uLong)(sum1 | (sum2 << 16)); |
| } |
|
|
| void setUp(void) { |
| |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
| void test_adler32_z_null_buf_len_nonzero_returns_one(void) { |
| uLong start = 0xDEADBEEFul; |
| uLong got = adler32_z(start, Z_NULL, (z_size_t)100); |
| TEST_ASSERT_EQUAL_HEX32(1UL, got); |
| } |
|
|
| void test_adler32_z_null_buf_len_zero_returns_one(void) { |
| uLong start = 0x12345678ul; |
| uLong got = adler32_z(start, Z_NULL, (z_size_t)0); |
| TEST_ASSERT_EQUAL_HEX32(1UL, got); |
| } |
|
|
| |
| void test_adler32_z_single_byte_from_initial(void) { |
| const unsigned char b = 'A'; |
| uLong got = adler32_z(1UL, (const Bytef *)&b, (z_size_t)1); |
| uLong exp = adler32_naive(1UL, (const Bytef *)&b, 1); |
| TEST_ASSERT_EQUAL_HEX32(exp, got); |
| } |
|
|
| |
| void test_adler32_z_single_byte_wrap_sum1(void) { |
| |
| uLong start = ((uLong)0 << 16) | 65520UL; |
| const unsigned char b = 10; |
| uLong got = adler32_z(start, (const Bytef *)&b, (z_size_t)1); |
| uLong exp = adler32_naive(start, (const Bytef *)&b, 1); |
| TEST_ASSERT_EQUAL_HEX32(exp, got); |
| } |
|
|
| |
| void test_adler32_z_small_string_lt_16(void) { |
| const char *msg = "Hello, world!"; |
| size_t len = strlen(msg); |
| uLong got = adler32_z(1UL, (const Bytef *)msg, (z_size_t)len); |
| uLong exp = adler32_naive(1UL, (const Bytef *)msg, len); |
| TEST_ASSERT_EQUAL_HEX32(exp, got); |
| } |
|
|
| |
| void test_adler32_z_small_len_wrap_sum1(void) { |
| unsigned char data[4] = {10, 20, 30, 40}; |
| |
| uLong start = ((uLong)1234 << 16) | 65520UL; |
| uLong got = adler32_z(start, (const Bytef *)data, (z_size_t)sizeof(data)); |
| uLong exp = adler32_naive(start, (const Bytef *)data, sizeof(data)); |
| TEST_ASSERT_EQUAL_HEX32(exp, got); |
| } |
|
|
| |
| void test_adler32_z_len_zero_normalizes_state(void) { |
| uLong start = 0xFFFFFFFFUL; |
| unsigned char dummy = 0; |
| uLong got = adler32_z(start, (const Bytef *)&dummy, (z_size_t)0); |
| |
| uLong exp = ((uLong)14 << 16) | 14; |
| TEST_ASSERT_EQUAL_HEX32(exp, got); |
| } |
|
|
| |
| void test_adler32_z_large_len_over_NMAX(void) { |
| const size_t len = 6000; |
| unsigned char *buf = (unsigned char *)malloc(len); |
| TEST_ASSERT_NOT_NULL(buf); |
| for (size_t i = 0; i < len; i++) { |
| buf[i] = (unsigned char)(i % 251); |
| } |
|
|
| uLong start = 1UL; |
| uLong got = adler32_z(start, (const Bytef *)buf, (z_size_t)len); |
| uLong exp = adler32_naive(start, (const Bytef *)buf, len); |
| free(buf); |
| TEST_ASSERT_EQUAL_HEX32(exp, got); |
| } |
|
|
| |
| void test_adler32_z_multiple_blocks_plus_remainder(void) { |
| const size_t NMAX_VAL = 5552; |
| const size_t len = NMAX_VAL * 2 + 123; |
| unsigned char *buf = (unsigned char *)malloc(len); |
| TEST_ASSERT_NOT_NULL(buf); |
| for (size_t i = 0; i < len; i++) { |
| buf[i] = (unsigned char)(i % 13); |
| } |
|
|
| uLong start = ((uLong)0x1357 << 16) | 0x2468; |
| uLong got = adler32_z(start, (const Bytef *)buf, (z_size_t)len); |
| uLong exp = adler32_naive(start, (const Bytef *)buf, len); |
| free(buf); |
| TEST_ASSERT_EQUAL_HEX32(exp, got); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_adler32_z_null_buf_len_nonzero_returns_one); |
| RUN_TEST(test_adler32_z_null_buf_len_zero_returns_one); |
| RUN_TEST(test_adler32_z_single_byte_from_initial); |
| RUN_TEST(test_adler32_z_single_byte_wrap_sum1); |
| RUN_TEST(test_adler32_z_small_string_lt_16); |
| RUN_TEST(test_adler32_z_small_len_wrap_sum1); |
| RUN_TEST(test_adler32_z_len_zero_normalizes_state); |
| RUN_TEST(test_adler32_z_large_len_over_NMAX); |
| RUN_TEST(test_adler32_z_multiple_blocks_plus_remainder); |
| return UNITY_END(); |
| } |