1 /* test_gzio.cc - Test read/write of .gz files */
2
3 #include "zbuild.h"
4 #ifdef ZLIB_COMPAT
5 # include "zlib.h"
6 #else
7 # include "zlib-ng.h"
8 #endif
9
10 #include <stdio.h>
11 #include <stdint.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include "test_shared.h"
16
17 #include <gtest/gtest.h>
18
19 #define TESTFILE "foo.gz"
20
TEST(gzip,readwrite)21 TEST(gzip, readwrite) {
22 #ifdef NO_GZCOMPRESS
23 fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
24 GTEST_SKIP();
25 #else
26 uint8_t compr[128], uncompr[128];
27 uint32_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
28 size_t read;
29 int64_t pos;
30 gzFile file;
31 int err;
32
33 /* Write gz file with test data */
34 file = PREFIX(gzopen)(TESTFILE, "wb");
35 ASSERT_TRUE(file != NULL);
36 /* Write hello, hello! using gzputs and gzprintf */
37 PREFIX(gzputc)(file, 'h');
38 EXPECT_EQ(PREFIX(gzputs)(file, "ello"), 4);
39 EXPECT_EQ(PREFIX(gzprintf)(file, ", %s!", "hello"), 8);
40 /* Write string null-teriminator using gzseek */
41 EXPECT_GE(PREFIX(gzseek)(file, 1L, SEEK_CUR), 0);
42 /* Write hello, hello! using gzfwrite using best compression level */
43 EXPECT_EQ(PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY), Z_OK);
44 EXPECT_NE(PREFIX(gzfwrite)(hello, hello_len, 1, file), 0);
45 /* Flush compressed bytes to file */
46 EXPECT_EQ(PREFIX(gzflush)(file, Z_SYNC_FLUSH), Z_OK);
47 compr_len = (uint32_t)PREFIX(gzoffset)(file);
48 EXPECT_GE(compr_len, 0UL);
49 PREFIX(gzclose)(file);
50
51 /* Open gz file we previously wrote */
52 file = PREFIX(gzopen)(TESTFILE, "rb");
53 ASSERT_TRUE(file != NULL);
54
55 /* Read uncompressed data - hello, hello! string twice */
56 strcpy((char*)uncompr, "garbages");
57 EXPECT_EQ(PREFIX(gzread)(file, uncompr, (unsigned)uncompr_len), (int)(hello_len + hello_len));
58 EXPECT_STREQ((char*)uncompr, hello);
59
60 /* Check position at the end of the gz file */
61 EXPECT_EQ(PREFIX(gzeof)(file), 1);
62
63 /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */
64 pos = PREFIX(gzseek)(file, -22L, SEEK_CUR);
65 EXPECT_EQ(pos, 6);
66 EXPECT_EQ(PREFIX(gztell)(file), pos);
67 EXPECT_EQ(PREFIX(gzgetc)(file), ' ');
68 EXPECT_EQ(PREFIX(gzungetc)(' ', file), ' ');
69 /* Read first hello, hello! string with gzgets */
70 strcpy((char*)uncompr, "garbages");
71 PREFIX(gzgets)(file, (char*)uncompr, (int)uncompr_len);
72 EXPECT_EQ(strlen((char*)uncompr), 7); /* " hello!" */
73 EXPECT_STREQ((char*)uncompr, hello + 6);
74
75 /* Seek to second hello, hello! string */
76 pos = PREFIX(gzseek)(file, 14L, SEEK_SET);
77 EXPECT_EQ(pos, 14);
78 EXPECT_EQ(PREFIX(gztell)(file), pos);
79
80 /* Check position not at end of file */
81 EXPECT_EQ(PREFIX(gzeof)(file), 0);
82 /* Read first hello, hello! string with gzfread */
83 strcpy((char*)uncompr, "garbages");
84 read = PREFIX(gzfread)(uncompr, uncompr_len, 1, file);
85 EXPECT_STREQ((const char *)uncompr, hello);
86
87 pos = PREFIX(gzoffset)(file);
88 EXPECT_GE(pos, 0);
89 EXPECT_EQ(pos, (compr_len + 10));
90
91 /* Trigger an error and clear it with gzclearerr */
92 PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file);
93 PREFIX(gzerror)(file, &err);
94 EXPECT_NE(err, 0);
95
96 PREFIX(gzclearerr)(file);
97 PREFIX(gzerror)(file, &err);
98 EXPECT_EQ(err, 0);
99
100 PREFIX(gzclose)(file);
101
102 EXPECT_EQ(PREFIX(gzclose)(NULL), Z_STREAM_ERROR);
103 Z_UNUSED(read);
104 #endif
105 }
106