| #include "unity/unity.h" |
| #include "zlib.h" |
|
|
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
|
|
| |
| static void make_temp_path(char *out, size_t outsz, const char *suffix) { |
| char base[L_tmpnam]; |
| char *res = tmpnam(base); |
| if (res == NULL) { |
| |
| #if defined(_WIN32) |
| snprintf(out, outsz, "tmp_gzseek64_%lu%s", (unsigned long)GetTickCount(), suffix ? suffix : ""); |
| #else |
| snprintf(out, outsz, "tmp_gzseek64_%ld%s", (long)getpid(), suffix ? suffix : ""); |
| #endif |
| return; |
| } |
| if (suffix && *suffix) { |
| snprintf(out, outsz, "%s%s", base, suffix); |
| } else { |
| snprintf(out, outsz, "%s", base); |
| } |
| } |
|
|
| |
| static int create_plain_file_with_content(const char *path, const char *content) { |
| FILE *f = fopen(path, "wb"); |
| if (!f) return -1; |
| size_t len = strlen(content); |
| size_t wrote = fwrite(content, 1, len, f); |
| fclose(f); |
| return wrote == len ? 0 : -1; |
| } |
|
|
| static int create_gzip_file_with_content(const char *path, const char *content) { |
| gzFile gz = gzopen(path, "wb"); |
| if (gz == NULL) return -1; |
| int len = (int)strlen(content); |
| int wrote = gzwrite(gz, content, len); |
| int rc = gzclose(gz); |
| return (wrote == len && rc == Z_OK) ? 0 : -1; |
| } |
|
|
| |
| static const char *S_COMP = "hello world"; |
| static const char *S_LONG = "0123456789ABCDEF"; |
| static const char *S_RAW = "abcdef"; |
|
|
| |
| void setUp(void) { |
| |
| } |
| void tearDown(void) { |
| |
| } |
|
|
| |
|
|
| void test_gzseek64_null_file_returns_minus1(void) { |
| z_off64_t r = gzseek64(NULL, 0, SEEK_SET); |
| TEST_ASSERT_EQUAL_INT64(-1, (long long)r); |
| } |
|
|
| void test_gzseek64_invalid_whence_returns_minus1(void) { |
| char path[256]; |
| make_temp_path(path, sizeof(path), ".gz"); |
| TEST_ASSERT_EQUAL_INT(0, create_gzip_file_with_content(path, S_COMP)); |
| gzFile f = gzopen(path, "rb"); |
| TEST_ASSERT_NOT_NULL(f); |
|
|
| z_off64_t r = gzseek64(f, 0, 999); |
| TEST_ASSERT_EQUAL_INT64(-1, (long long)r); |
|
|
| gzclose(f); |
| remove(path); |
| } |
|
|
| void test_gzseek64_read_on_compressed_seek_set_and_read(void) { |
| char path[256]; |
| make_temp_path(path, sizeof(path), ".gz"); |
| TEST_ASSERT_EQUAL_INT(0, create_gzip_file_with_content(path, S_COMP)); |
|
|
| gzFile f = gzopen(path, "rb"); |
| TEST_ASSERT_NOT_NULL(f); |
|
|
| |
| z_off64_t r = gzseek64(f, 6, SEEK_SET); |
| TEST_ASSERT_EQUAL_INT64(6, (long long)r); |
| TEST_ASSERT_EQUAL_INT64(6, (long long)gztell64(f)); |
|
|
| int c = gzgetc(f); |
| TEST_ASSERT_EQUAL_INT('w', c); |
|
|
| |
| r = gzseek64(f, 1, SEEK_CUR); |
| TEST_ASSERT_EQUAL_INT64(9, (long long)r); |
| TEST_ASSERT_EQUAL_INT64(9, (long long)gztell64(f)); |
|
|
| c = gzgetc(f); |
| TEST_ASSERT_EQUAL_INT('l', c); |
|
|
| gzclose(f); |
| remove(path); |
| } |
|
|
| void test_gzseek64_read_backward_with_rewind(void) { |
| char path[256]; |
| make_temp_path(path, sizeof(path), ".gz"); |
| TEST_ASSERT_EQUAL_INT(0, create_gzip_file_with_content(path, S_COMP)); |
|
|
| gzFile f = gzopen(path, "rb"); |
| TEST_ASSERT_NOT_NULL(f); |
|
|
| |
| char buf[16]; |
| int n = gzread(f, buf, 8); |
| TEST_ASSERT_EQUAL_INT(8, n); |
|
|
| |
| z_off64_t r = gzseek64(f, 1, SEEK_SET); |
| TEST_ASSERT_EQUAL_INT64(1, (long long)r); |
| TEST_ASSERT_EQUAL_INT64(1, (long long)gztell64(f)); |
|
|
| int c = gzgetc(f); |
| TEST_ASSERT_EQUAL_INT('e', c); |
|
|
| gzclose(f); |
| remove(path); |
| } |
|
|
| void test_gzseek64_read_backward_before_start_fails(void) { |
| char path[256]; |
| make_temp_path(path, sizeof(path), ".gz"); |
| TEST_ASSERT_EQUAL_INT(0, create_gzip_file_with_content(path, S_LONG)); |
|
|
| gzFile f = gzopen(path, "rb"); |
| TEST_ASSERT_NOT_NULL(f); |
|
|
| |
| char tmp[4]; |
| int n = gzread(f, tmp, 2); |
| TEST_ASSERT_EQUAL_INT(2, n); |
| TEST_ASSERT_EQUAL_INT64(2, (long long)gztell64(f)); |
|
|
| |
| z_off64_t r = gzseek64(f, -5, SEEK_CUR); |
| TEST_ASSERT_EQUAL_INT64(-1, (long long)r); |
|
|
| gzclose(f); |
| remove(path); |
| } |
|
|
| void test_gzseek64_transparent_raw_file_lseek_branch(void) { |
| |
| char path[256]; |
| make_temp_path(path, sizeof(path), ".txt"); |
| TEST_ASSERT_EQUAL_INT(0, create_plain_file_with_content(path, S_RAW)); |
|
|
| gzFile f = gzopen(path, "rb"); |
| TEST_ASSERT_NOT_NULL(f); |
|
|
| |
| int c = gzgetc(f); |
| TEST_ASSERT_EQUAL_INT('a', c); |
| TEST_ASSERT_EQUAL_INT64(1, (long long)gztell64(f)); |
|
|
| |
| z_off64_t r = gzseek64(f, 3, SEEK_CUR); |
| TEST_ASSERT_EQUAL_INT64(4, (long long)r); |
| TEST_ASSERT_EQUAL_INT64(4, (long long)gztell64(f)); |
|
|
| c = gzgetc(f); |
| TEST_ASSERT_EQUAL_INT('e', c); |
|
|
| gzclose(f); |
| remove(path); |
| } |
|
|
| void test_gzseek64_write_mode_forward_and_tell_and_write(void) { |
| char path[256]; |
| make_temp_path(path, sizeof(path), ".gz"); |
|
|
| gzFile f = gzopen(path, "wb"); |
| TEST_ASSERT_NOT_NULL(f); |
|
|
| |
| z_off64_t r = gzseek64(f, 100, SEEK_SET); |
| TEST_ASSERT_EQUAL_INT64(100, (long long)r); |
| TEST_ASSERT_EQUAL_INT64(100, (long long)gztell64(f)); |
|
|
| |
| int put = gzputc(f, 'A'); |
| TEST_ASSERT_NOT_EQUAL(-1, put); |
| TEST_ASSERT_EQUAL_INT64(101, (long long)gztell64(f)); |
|
|
| gzclose(f); |
| remove(path); |
| } |
|
|
| void test_gzseek64_write_mode_negative_offset_fails(void) { |
| char path[256]; |
| make_temp_path(path, sizeof(path), ".gz"); |
|
|
| gzFile f = gzopen(path, "wb"); |
| TEST_ASSERT_NOT_NULL(f); |
|
|
| z_off64_t r = gzseek64(f, -1, SEEK_CUR); |
| TEST_ASSERT_EQUAL_INT64(-1, (long long)r); |
|
|
| gzclose(f); |
| remove(path); |
| } |
|
|
| void test_gzseek64_pending_seek_then_seek_cur_accumulates(void) { |
| char path[256]; |
| make_temp_path(path, sizeof(path), ".gz"); |
| TEST_ASSERT_EQUAL_INT(0, create_gzip_file_with_content(path, S_COMP)); |
|
|
| gzFile f = gzopen(path, "rb"); |
| TEST_ASSERT_NOT_NULL(f); |
|
|
| |
| z_off64_t r = gzseek64(f, 5, SEEK_SET); |
| TEST_ASSERT_EQUAL_INT64(5, (long long)r); |
| TEST_ASSERT_EQUAL_INT64(5, (long long)gztell64(f)); |
|
|
| |
| r = gzseek64(f, 5, SEEK_CUR); |
| TEST_ASSERT_EQUAL_INT64(10, (long long)r); |
| TEST_ASSERT_EQUAL_INT64(10, (long long)gztell64(f)); |
|
|
| |
| int c = gzgetc(f); |
| TEST_ASSERT_EQUAL_INT('d', c); |
|
|
| gzclose(f); |
| remove(path); |
| } |
|
|
| |
| int main(void) { |
| UNITY_BEGIN(); |
|
|
| RUN_TEST(test_gzseek64_null_file_returns_minus1); |
| RUN_TEST(test_gzseek64_invalid_whence_returns_minus1); |
| RUN_TEST(test_gzseek64_read_on_compressed_seek_set_and_read); |
| RUN_TEST(test_gzseek64_read_backward_with_rewind); |
| RUN_TEST(test_gzseek64_read_backward_before_start_fails); |
| RUN_TEST(test_gzseek64_transparent_raw_file_lseek_branch); |
| RUN_TEST(test_gzseek64_write_mode_forward_and_tell_and_write); |
| RUN_TEST(test_gzseek64_write_mode_negative_offset_fails); |
| RUN_TEST(test_gzseek64_pending_seek_then_seek_cur_accumulates); |
|
|
| return UNITY_END(); |
| } |