#include "unity/unity.h" #include "zlib.h" #include #include #include /* Unity required functions */ void setUp(void) { /* Setup code here, or leave empty */ } void tearDown(void) { /* Cleanup code here, or leave empty */ } /* Helper to fill a buffer with a deterministic pattern */ static void fill_pattern(unsigned char *buf, size_t len) { for (size_t i = 0; i < len; i++) { buf[i] = (unsigned char)((i * 3u + 7u) & 0xFFu); } } /* Tests */ void test_crc32_z_null_buf_returns_zero(void) { unsigned long r1 = crc32_z(1234UL, NULL, 0); TEST_ASSERT_EQUAL_UINT32(0u, (uint32_t)r1); unsigned long r2 = crc32_z(0UL, NULL, 5); TEST_ASSERT_EQUAL_UINT32(0u, (uint32_t)r2); unsigned long r3 = crc32_z(0xFFFFFFFFUL, NULL, 1000); TEST_ASSERT_EQUAL_UINT32(0u, (uint32_t)r3); } void test_crc32_z_empty_input_returns_initial(void) { const unsigned char dummy = 0xAA; /* not used, just to have a pointer if needed */ (void)dummy; unsigned long seeds[] = {0UL, 1UL, 0xFFFFFFFFUL, 0xDEADBEEFUL}; for (size_t i = 0; i < sizeof(seeds)/sizeof(seeds[0]); i++) { unsigned long init = seeds[i]; unsigned long r = crc32_z(init, (const unsigned char *)"", 0); TEST_ASSERT_EQUAL_UINT32((uint32_t)init, (uint32_t)r); } } void test_crc32_z_known_vector_123456789(void) { const unsigned char *msg = (const unsigned char *)"123456789"; unsigned long r = crc32_z(0UL, msg, 9); TEST_ASSERT_EQUAL_HEX32(0xCBF43926u, (uint32_t)r); } void test_crc32_z_known_vector_quick_brown(void) { const char *s = "The quick brown fox jumps over the lazy dog"; unsigned long r = crc32_z(0UL, (const unsigned char *)s, (z_size_t)strlen(s)); TEST_ASSERT_EQUAL_HEX32(0x414FA339u, (uint32_t)r); } void test_crc32_z_incremental_vs_one_shot_large(void) { const size_t total = 1000; unsigned char *buf = (unsigned char *)malloc(total); TEST_ASSERT_NOT_NULL(buf); fill_pattern(buf, total); /* One-shot */ unsigned long one = crc32_z(0UL, buf, (z_size_t)total); /* Incremental: split into uneven segments */ unsigned long inc = 0UL; inc = crc32_z(inc, buf, 13); inc = crc32_z(inc, buf + 13, 257); inc = crc32_z(inc, buf + 270, 3); inc = crc32_z(inc, buf + 273, (z_size_t)(total - 273)); TEST_ASSERT_EQUAL_UINT32((uint32_t)one, (uint32_t)inc); free(buf); } void test_crc32_z_nonzero_initial_seed_incremental(void) { const size_t total = 250; unsigned char *buf = (unsigned char *)malloc(total); TEST_ASSERT_NOT_NULL(buf); fill_pattern(buf, total); unsigned long init = 0xA5A5A5A5UL; /* One-shot with non-zero initial seed */ unsigned long one = crc32_z(init, buf, (z_size_t)total); /* Incremental, small chunks */ unsigned long inc = init; size_t pos = 0; while (pos < total) { size_t chunk = 7; if (chunk > total - pos) chunk = total - pos; inc = crc32_z(inc, buf + pos, (z_size_t)chunk); pos += chunk; } TEST_ASSERT_EQUAL_UINT32((uint32_t)one, (uint32_t)inc); free(buf); } void test_crc32_z_input_buffer_unchanged(void) { const size_t len = 128; unsigned char *buf = (unsigned char *)malloc(len); unsigned char *copy = (unsigned char *)malloc(len); TEST_ASSERT_NOT_NULL(buf); TEST_ASSERT_NOT_NULL(copy); fill_pattern(buf, len); memcpy(copy, buf, len); (void)crc32_z(0UL, buf, (z_size_t)len); TEST_ASSERT_EQUAL_UINT8_ARRAY(copy, buf, len); free(copy); free(buf); } void test_crc32_z_unaligned_buffer(void) { /* Create a buffer with an extra headroom to allow unaligned starts */ const size_t total = 260; unsigned char *raw = (unsigned char *)malloc(total + 8); TEST_ASSERT_NOT_NULL(raw); unsigned char *buf = raw + 3; /* create an unaligned pointer intentionally */ fill_pattern(buf, total); /* Compute CRC on slice [1 .. 200] from unaligned base */ const size_t offset = 1; const size_t len = 200; unsigned long r_unaligned = crc32_z(0UL, buf + offset, (z_size_t)len); /* Copy the same slice to a separate, aligned buffer and compute CRC */ unsigned char *copy = (unsigned char *)malloc(len); TEST_ASSERT_NOT_NULL(copy); memcpy(copy, buf + offset, len); unsigned long r_aligned = crc32_z(0UL, copy, (z_size_t)len); TEST_ASSERT_EQUAL_UINT32((uint32_t)r_aligned, (uint32_t)r_unaligned); free(copy); free(raw); } /* main */ int main(void) { UNITY_BEGIN(); RUN_TEST(test_crc32_z_null_buf_returns_zero); RUN_TEST(test_crc32_z_empty_input_returns_initial); RUN_TEST(test_crc32_z_known_vector_123456789); RUN_TEST(test_crc32_z_known_vector_quick_brown); RUN_TEST(test_crc32_z_incremental_vs_one_shot_large); RUN_TEST(test_crc32_z_nonzero_initial_seed_incremental); RUN_TEST(test_crc32_z_input_buffer_unchanged); RUN_TEST(test_crc32_z_unaligned_buffer); return UNITY_END(); }