zlib / tests /tests_gzlib_gzseek64.c
AryaWu's picture
Upload folder using huggingface_hub
e996a55 verified
#include "unity/unity.h"
#include "zlib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Helper to create a temporary filename, optionally with a suffix (like ".gz"). */
static void make_temp_path(char *out, size_t outsz, const char *suffix) {
char base[L_tmpnam];
char *res = tmpnam(base);
if (res == NULL) {
/* Fallback */
#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);
}
}
/* Helpers to create files */
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;
}
/* Common test strings */
static const char *S_COMP = "hello world";
static const char *S_LONG = "0123456789ABCDEF"; /* 16 bytes */
static const char *S_RAW = "abcdef";
/* Unity hooks */
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
/* Tests */
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); /* invalid whence */
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);
/* Seek to position 6 ("hello " is 6 chars), expect 'w' next */
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);
/* Now at 7, seek forward by 1 to 8, expect 'o' (index 7 was 'w', 8 -> 'o' in "hello world") */
r = gzseek64(f, 1, SEEK_CUR);
TEST_ASSERT_EQUAL_INT64(9, (long long)r); /* After reading 'w', pos=7; +1 => 8; BUT gzgetc advanced to 8; seek +1 => 9 */
TEST_ASSERT_EQUAL_INT64(9, (long long)gztell64(f));
c = gzgetc(f); /* index 9 is 'l' in "hello world" (0-based) */
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);
/* Read 8 bytes: "hello wo" */
char buf[16];
int n = gzread(f, buf, 8);
TEST_ASSERT_EQUAL_INT(8, n);
/* Seek back to position 1 (from start), should succeed via rewind path */
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); /* second character of "hello world" */
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);
/* Read 2 bytes to set position to 2 */
char tmp[4];
int n = gzread(f, tmp, 2);
TEST_ASSERT_EQUAL_INT(2, n);
TEST_ASSERT_EQUAL_INT64(2, (long long)gztell64(f));
/* Attempt to seek -5 from current, which is before start -> fail */
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) {
/* Create a plain (non-gz) file and read via gzopen to force COPY (transparent) mode */
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);
/* Read one byte to force detection and enter COPY mode */
int c = gzgetc(f);
TEST_ASSERT_EQUAL_INT('a', c);
TEST_ASSERT_EQUAL_INT64(1, (long long)gztell64(f));
/* Seek forward by 3 relative to current: pos goes to 4; next char should be 'e' */
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);
/* Seek forward to 100 from start; nothing written yet, but pending skip */
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));
/* Write a single byte; this should realize the skip and then the byte */
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);
/* First, set a pending seek to position 5 */
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));
/* Now do a SEEK_CUR by 5; since seek is pending, this should add to pending skip */
r = gzseek64(f, 5, SEEK_CUR);
TEST_ASSERT_EQUAL_INT64(10, (long long)r);
TEST_ASSERT_EQUAL_INT64(10, (long long)gztell64(f));
/* Next character should be index 10 ('d') when we actually read */
int c = gzgetc(f);
TEST_ASSERT_EQUAL_INT('d', c);
gzclose(f);
remove(path);
}
/* Main */
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();
}