blob: 59e46f520a5cb54be6e620c129f97775f2ad6779 [file] [log] [blame]
/* test_gzio.cc - Test read/write of .gz files */
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
#else
# include "zlib-ng.h"
#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "test_shared.h"
#include <gtest/gtest.h>
#define TESTFILE "foo.gz"
TEST(gzip, readwrite) {
#ifdef NO_GZCOMPRESS
fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
GTEST_SKIP();
#else
uint8_t compr[128], uncompr[128];
uint32_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
size_t read;
int64_t pos;
gzFile file;
int err;
/* Write gz file with test data */
file = PREFIX(gzopen)(TESTFILE, "wb");
ASSERT_TRUE(file != NULL);
/* Write hello, hello! using gzputs and gzprintf */
PREFIX(gzputc)(file, 'h');
EXPECT_EQ(PREFIX(gzputs)(file, "ello"), 4);
EXPECT_EQ(PREFIX(gzprintf)(file, ", %s!", "hello"), 8);
/* Write string null-teriminator using gzseek */
EXPECT_GE(PREFIX(gzseek)(file, 1L, SEEK_CUR), 0);
/* Write hello, hello! using gzfwrite using best compression level */
EXPECT_EQ(PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY), Z_OK);
EXPECT_NE(PREFIX(gzfwrite)(hello, hello_len, 1, file), 0UL);
/* Flush compressed bytes to file */
EXPECT_EQ(PREFIX(gzflush)(file, Z_SYNC_FLUSH), Z_OK);
compr_len = (uint32_t)PREFIX(gzoffset)(file);
EXPECT_GE(compr_len, 0UL);
PREFIX(gzclose)(file);
/* Open gz file we previously wrote */
file = PREFIX(gzopen)(TESTFILE, "rb");
ASSERT_TRUE(file != NULL);
/* Read uncompressed data - hello, hello! string twice */
strcpy((char*)uncompr, "garbages");
EXPECT_EQ(PREFIX(gzread)(file, uncompr, (unsigned)uncompr_len), (int)(hello_len + hello_len));
EXPECT_STREQ((char*)uncompr, hello);
/* Check position at the end of the gz file */
EXPECT_EQ(PREFIX(gzeof)(file), 1);
/* Seek backwards mid-string and check char reading with gzgetc and gzungetc */
pos = PREFIX(gzseek)(file, -22L, SEEK_CUR);
EXPECT_EQ(pos, 6);
EXPECT_EQ(PREFIX(gztell)(file), pos);
EXPECT_EQ(PREFIX(gzgetc)(file), ' ');
EXPECT_EQ(PREFIX(gzungetc)(' ', file), ' ');
/* Read first hello, hello! string with gzgets */
strcpy((char*)uncompr, "garbages");
PREFIX(gzgets)(file, (char*)uncompr, (int)uncompr_len);
EXPECT_EQ(strlen((char*)uncompr), 7UL); /* " hello!" */
EXPECT_STREQ((char*)uncompr, hello + 6);
/* Seek to second hello, hello! string */
pos = PREFIX(gzseek)(file, 14L, SEEK_SET);
EXPECT_EQ(pos, 14);
EXPECT_EQ(PREFIX(gztell)(file), pos);
/* Check position not at end of file */
EXPECT_EQ(PREFIX(gzeof)(file), 0);
/* Read first hello, hello! string with gzfread */
strcpy((char*)uncompr, "garbages");
read = PREFIX(gzfread)(uncompr, uncompr_len, 1, file);
EXPECT_STREQ((const char *)uncompr, hello);
pos = PREFIX(gzoffset)(file);
EXPECT_GE(pos, 0);
EXPECT_EQ(pos, (compr_len + 10));
/* Trigger an error and clear it with gzclearerr */
PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file);
PREFIX(gzerror)(file, &err);
EXPECT_NE(err, 0);
PREFIX(gzclearerr)(file);
PREFIX(gzerror)(file, &err);
EXPECT_EQ(err, 0);
PREFIX(gzclose)(file);
EXPECT_EQ(PREFIX(gzclose)(NULL), Z_STREAM_ERROR);
Z_UNUSED(read);
#endif
}