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