zstdlib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES.md +9 -0
  3. data/Gemfile +3 -0
  4. data/README.md +96 -0
  5. data/Rakefile +29 -0
  6. data/ext/zstdlib/extconf.rb +53 -0
  7. data/ext/zstdlib/ruby/zlib-2.2/zlib.c +4659 -0
  8. data/ext/zstdlib/ruby/zlib-2.3/zlib.c +4686 -0
  9. data/ext/zstdlib/ruby/zlib-2.4/zlib.c +4843 -0
  10. data/ext/zstdlib/ruby/zlib-2.5/zlib.c +4848 -0
  11. data/ext/zstdlib/ruby/zlib-2.6/zlib.c +4890 -0
  12. data/ext/zstdlib/zlib-1.2.11/adler32.c +186 -0
  13. data/ext/zstdlib/zlib-1.2.11/compress.c +86 -0
  14. data/ext/zstdlib/zlib-1.2.11/crc32.c +442 -0
  15. data/ext/zstdlib/zlib-1.2.11/crc32.h +441 -0
  16. data/ext/zstdlib/zlib-1.2.11/deflate.c +2163 -0
  17. data/ext/zstdlib/zlib-1.2.11/deflate.h +349 -0
  18. data/ext/zstdlib/zlib-1.2.11/gzclose.c +25 -0
  19. data/ext/zstdlib/zlib-1.2.11/gzguts.h +218 -0
  20. data/ext/zstdlib/zlib-1.2.11/gzlib.c +637 -0
  21. data/ext/zstdlib/zlib-1.2.11/gzread.c +654 -0
  22. data/ext/zstdlib/zlib-1.2.11/gzwrite.c +665 -0
  23. data/ext/zstdlib/zlib-1.2.11/infback.c +640 -0
  24. data/ext/zstdlib/zlib-1.2.11/inffast.c +323 -0
  25. data/ext/zstdlib/zlib-1.2.11/inffast.h +11 -0
  26. data/ext/zstdlib/zlib-1.2.11/inffixed.h +94 -0
  27. data/ext/zstdlib/zlib-1.2.11/inflate.c +1561 -0
  28. data/ext/zstdlib/zlib-1.2.11/inflate.h +125 -0
  29. data/ext/zstdlib/zlib-1.2.11/inftrees.c +304 -0
  30. data/ext/zstdlib/zlib-1.2.11/inftrees.h +62 -0
  31. data/ext/zstdlib/zlib-1.2.11/trees.c +1203 -0
  32. data/ext/zstdlib/zlib-1.2.11/trees.h +128 -0
  33. data/ext/zstdlib/zlib-1.2.11/uncompr.c +93 -0
  34. data/ext/zstdlib/zlib-1.2.11/zconf.h +534 -0
  35. data/ext/zstdlib/zlib-1.2.11/zlib.h +1912 -0
  36. data/ext/zstdlib/zlib-1.2.11/zutil.c +325 -0
  37. data/ext/zstdlib/zlib-1.2.11/zutil.h +271 -0
  38. data/ext/zstdlib/zlib.mk +14 -0
  39. data/ext/zstdlib/zlibwrapper/zlibwrapper.c +14 -0
  40. data/ext/zstdlib/zlibwrapper.mk +14 -0
  41. data/ext/zstdlib/zstd-1.3.8/lib/common/bitstream.h +455 -0
  42. data/ext/zstdlib/zstd-1.3.8/lib/common/compiler.h +140 -0
  43. data/ext/zstdlib/zstd-1.3.8/lib/common/cpu.h +215 -0
  44. data/ext/zstdlib/zstd-1.3.8/lib/common/debug.c +44 -0
  45. data/ext/zstdlib/zstd-1.3.8/lib/common/debug.h +134 -0
  46. data/ext/zstdlib/zstd-1.3.8/lib/common/entropy_common.c +236 -0
  47. data/ext/zstdlib/zstd-1.3.8/lib/common/error_private.c +54 -0
  48. data/ext/zstdlib/zstd-1.3.8/lib/common/error_private.h +76 -0
  49. data/ext/zstdlib/zstd-1.3.8/lib/common/fse.h +708 -0
  50. data/ext/zstdlib/zstd-1.3.8/lib/common/fse_decompress.c +309 -0
  51. data/ext/zstdlib/zstd-1.3.8/lib/common/huf.h +358 -0
  52. data/ext/zstdlib/zstd-1.3.8/lib/common/mem.h +380 -0
  53. data/ext/zstdlib/zstd-1.3.8/lib/common/pool.c +340 -0
  54. data/ext/zstdlib/zstd-1.3.8/lib/common/pool.h +84 -0
  55. data/ext/zstdlib/zstd-1.3.8/lib/common/threading.c +75 -0
  56. data/ext/zstdlib/zstd-1.3.8/lib/common/threading.h +123 -0
  57. data/ext/zstdlib/zstd-1.3.8/lib/common/xxhash.c +876 -0
  58. data/ext/zstdlib/zstd-1.3.8/lib/common/xxhash.h +305 -0
  59. data/ext/zstdlib/zstd-1.3.8/lib/common/zstd_common.c +83 -0
  60. data/ext/zstdlib/zstd-1.3.8/lib/common/zstd_errors.h +93 -0
  61. data/ext/zstdlib/zstd-1.3.8/lib/common/zstd_internal.h +266 -0
  62. data/ext/zstdlib/zstd-1.3.8/lib/compress/fse_compress.c +721 -0
  63. data/ext/zstdlib/zstd-1.3.8/lib/compress/hist.c +203 -0
  64. data/ext/zstdlib/zstd-1.3.8/lib/compress/hist.h +95 -0
  65. data/ext/zstdlib/zstd-1.3.8/lib/compress/huf_compress.c +798 -0
  66. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_compress.c +4290 -0
  67. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_compress_internal.h +860 -0
  68. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_double_fast.c +499 -0
  69. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_double_fast.h +38 -0
  70. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_fast.c +391 -0
  71. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_fast.h +37 -0
  72. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_lazy.c +1106 -0
  73. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_lazy.h +67 -0
  74. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_ldm.c +597 -0
  75. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_ldm.h +105 -0
  76. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_opt.c +1217 -0
  77. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_opt.h +56 -0
  78. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstdmt_compress.c +2107 -0
  79. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstdmt_compress.h +174 -0
  80. data/ext/zstdlib/zstd-1.3.8/lib/decompress/huf_decompress.c +1232 -0
  81. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_ddict.c +240 -0
  82. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_ddict.h +44 -0
  83. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_decompress.c +1672 -0
  84. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_decompress_block.c +1307 -0
  85. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_decompress_block.h +59 -0
  86. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_decompress_internal.h +168 -0
  87. data/ext/zstdlib/zstd-1.3.8/lib/zstd.h +1766 -0
  88. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzclose.c +28 -0
  89. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzcompatibility.h +68 -0
  90. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzguts.h +227 -0
  91. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzlib.c +640 -0
  92. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzread.c +670 -0
  93. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzwrite.c +671 -0
  94. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/zstd_zlibwrapper.c +1105 -0
  95. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/zstd_zlibwrapper.h +88 -0
  96. data/ext/zstdlib/zstd.mk +14 -0
  97. data/lib/zstdlib.rb +6 -0
  98. data/test/zstdlib_test.rb +21 -0
  99. metadata +198 -0
@@ -0,0 +1,670 @@
1
+ /* gzread.c contains minimal changes required to be compiled with zlibWrapper:
2
+ * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */
3
+
4
+ /* gzread.c -- zlib functions for reading gzip files
5
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
6
+ * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html
7
+ */
8
+
9
+ #include "gzguts.h"
10
+
11
+ /* Local functions */
12
+ local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
13
+ local int gz_avail OF((gz_statep));
14
+ local int gz_look OF((gz_statep));
15
+ local int gz_decomp OF((gz_statep));
16
+ local int gz_fetch OF((gz_statep));
17
+ local int gz_skip OF((gz_statep, z_off64_t));
18
+ local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
19
+
20
+ /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
21
+ state.state->fd, and update state.state->eof, state.state->err, and state.state->msg as appropriate.
22
+ This function needs to loop on read(), since read() is not guaranteed to
23
+ read the number of bytes requested, depending on the type of descriptor. */
24
+ local int gz_load(state, buf, len, have)
25
+ gz_statep state;
26
+ unsigned char *buf;
27
+ unsigned len;
28
+ unsigned *have;
29
+ {
30
+ ssize_t ret;
31
+ unsigned get, max = ((unsigned)-1 >> 2) + 1;
32
+
33
+ *have = 0;
34
+ do {
35
+ get = len - *have;
36
+ if (get > max)
37
+ get = max;
38
+ ret = read(state.state->fd, buf + *have, get);
39
+ if (ret <= 0)
40
+ break;
41
+ *have += (unsigned)ret;
42
+ } while (*have < len);
43
+ if (ret < 0) {
44
+ gz_error(state, Z_ERRNO, zstrerror());
45
+ return -1;
46
+ }
47
+ if (ret == 0)
48
+ state.state->eof = 1;
49
+ return 0;
50
+ }
51
+
52
+ /* Load up input buffer and set eof flag if last data loaded -- return -1 on
53
+ error, 0 otherwise. Note that the eof flag is set when the end of the input
54
+ file is reached, even though there may be unused data in the buffer. Once
55
+ that data has been used, no more attempts will be made to read the file.
56
+ If strm->avail_in != 0, then the current data is moved to the beginning of
57
+ the input buffer, and then the remainder of the buffer is loaded with the
58
+ available data from the input file. */
59
+ local int gz_avail(state)
60
+ gz_statep state;
61
+ {
62
+ unsigned got;
63
+ z_streamp strm = &(state.state->strm);
64
+
65
+ if (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)
66
+ return -1;
67
+ if (state.state->eof == 0) {
68
+ if (strm->avail_in) { /* copy what's there to the start */
69
+ unsigned char *p = state.state->in;
70
+ unsigned const char *q = strm->next_in;
71
+ unsigned n = strm->avail_in;
72
+ do {
73
+ *p++ = *q++;
74
+ } while (--n);
75
+ }
76
+ if (gz_load(state, state.state->in + strm->avail_in,
77
+ state.state->size - strm->avail_in, &got) == -1)
78
+ return -1;
79
+ strm->avail_in += got;
80
+ strm->next_in = state.state->in;
81
+ }
82
+ return 0;
83
+ }
84
+
85
+ /* Look for gzip header, set up for inflate or copy. state.state->x.have must be 0.
86
+ If this is the first time in, allocate required memory. state.state->how will be
87
+ left unchanged if there is no more input data available, will be set to COPY
88
+ if there is no gzip header and direct copying will be performed, or it will
89
+ be set to GZIP for decompression. If direct copying, then leftover input
90
+ data from the input buffer will be copied to the output buffer. In that
91
+ case, all further file reads will be directly to either the output buffer or
92
+ a user buffer. If decompressing, the inflate state will be initialized.
93
+ gz_look() will return 0 on success or -1 on failure. */
94
+ local int gz_look(state)
95
+ gz_statep state;
96
+ {
97
+ z_streamp strm = &(state.state->strm);
98
+
99
+ /* allocate read buffers and inflate memory */
100
+ if (state.state->size == 0) {
101
+ /* allocate buffers */
102
+ state.state->in = (unsigned char *)malloc(state.state->want);
103
+ state.state->out = (unsigned char *)malloc(state.state->want << 1);
104
+ if (state.state->in == NULL || state.state->out == NULL) {
105
+ free(state.state->out);
106
+ free(state.state->in);
107
+ gz_error(state, Z_MEM_ERROR, "out of memory");
108
+ return -1;
109
+ }
110
+ state.state->size = state.state->want;
111
+
112
+ /* allocate inflate memory */
113
+ state.state->strm.zalloc = Z_NULL;
114
+ state.state->strm.zfree = Z_NULL;
115
+ state.state->strm.opaque = Z_NULL;
116
+ state.state->strm.avail_in = 0;
117
+ state.state->strm.next_in = Z_NULL;
118
+ if (inflateInit2(&(state.state->strm), 15 + 16) != Z_OK) { /* gunzip */
119
+ free(state.state->out);
120
+ free(state.state->in);
121
+ state.state->size = 0;
122
+ gz_error(state, Z_MEM_ERROR, "out of memory");
123
+ return -1;
124
+ }
125
+ }
126
+
127
+ /* get at least the magic bytes in the input buffer */
128
+ if (strm->avail_in < 2) {
129
+ if (gz_avail(state) == -1)
130
+ return -1;
131
+ if (strm->avail_in == 0)
132
+ return 0;
133
+ }
134
+
135
+ /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
136
+ a logical dilemma here when considering the case of a partially written
137
+ gzip file, to wit, if a single 31 byte is written, then we cannot tell
138
+ whether this is a single-byte file, or just a partially written gzip
139
+ file -- for here we assume that if a gzip file is being written, then
140
+ the header will be written in a single operation, so that reading a
141
+ single byte is sufficient indication that it is not a gzip file) */
142
+ if (strm->avail_in > 1 &&
143
+ ((strm->next_in[0] == 31 && strm->next_in[1] == 139) /* gz header */
144
+ || (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { /* zstd header */
145
+ inflateReset(strm);
146
+ state.state->how = GZIP;
147
+ state.state->direct = 0;
148
+ return 0;
149
+ }
150
+
151
+ /* no gzip header -- if we were decoding gzip before, then this is trailing
152
+ garbage. Ignore the trailing garbage and finish. */
153
+ if (state.state->direct == 0) {
154
+ strm->avail_in = 0;
155
+ state.state->eof = 1;
156
+ state.state->x.have = 0;
157
+ return 0;
158
+ }
159
+
160
+ /* doing raw i/o, copy any leftover input to output -- this assumes that
161
+ the output buffer is larger than the input buffer, which also assures
162
+ space for gzungetc() */
163
+ state.state->x.next = state.state->out;
164
+ if (strm->avail_in) {
165
+ memcpy(state.state->x.next, strm->next_in, strm->avail_in);
166
+ state.state->x.have = strm->avail_in;
167
+ strm->avail_in = 0;
168
+ }
169
+ state.state->how = COPY;
170
+ state.state->direct = 1;
171
+ return 0;
172
+ }
173
+
174
+ /* Decompress from input to the provided next_out and avail_out in the state.
175
+ On return, state.state->x.have and state.state->x.next point to the just decompressed
176
+ data. If the gzip stream completes, state.state->how is reset to LOOK to look for
177
+ the next gzip stream or raw data, once state.state->x.have is depleted. Returns 0
178
+ on success, -1 on failure. */
179
+ local int gz_decomp(state)
180
+ gz_statep state;
181
+ {
182
+ int ret = Z_OK;
183
+ unsigned had;
184
+ z_streamp strm = &(state.state->strm);
185
+
186
+ /* fill output buffer up to end of deflate stream */
187
+ had = strm->avail_out;
188
+ do {
189
+ /* get more input for inflate() */
190
+ if (strm->avail_in == 0 && gz_avail(state) == -1)
191
+ return -1;
192
+ if (strm->avail_in == 0) {
193
+ gz_error(state, Z_BUF_ERROR, "unexpected end of file");
194
+ break;
195
+ }
196
+
197
+ /* decompress and handle errors */
198
+ ret = inflate(strm, Z_NO_FLUSH);
199
+ if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
200
+ gz_error(state, Z_STREAM_ERROR,
201
+ "internal error: inflate stream corrupt");
202
+ return -1;
203
+ }
204
+ if (ret == Z_MEM_ERROR) {
205
+ gz_error(state, Z_MEM_ERROR, "out of memory");
206
+ return -1;
207
+ }
208
+ if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
209
+ gz_error(state, Z_DATA_ERROR,
210
+ strm->msg == NULL ? "compressed data error" : strm->msg);
211
+ return -1;
212
+ }
213
+ } while (strm->avail_out && ret != Z_STREAM_END);
214
+
215
+ /* update available output */
216
+ state.state->x.have = had - strm->avail_out;
217
+ state.state->x.next = strm->next_out - state.state->x.have;
218
+
219
+ /* if the gzip stream completed successfully, look for another */
220
+ if (ret == Z_STREAM_END)
221
+ state.state->how = LOOK;
222
+
223
+ /* good decompression */
224
+ return 0;
225
+ }
226
+
227
+ /* Fetch data and put it in the output buffer. Assumes state.state->x.have is 0.
228
+ Data is either copied from the input file or decompressed from the input
229
+ file depending on state.state->how. If state.state->how is LOOK, then a gzip header is
230
+ looked for to determine whether to copy or decompress. Returns -1 on error,
231
+ otherwise 0. gz_fetch() will leave state.state->how as COPY or GZIP unless the
232
+ end of the input file has been reached and all data has been processed. */
233
+ local int gz_fetch(state)
234
+ gz_statep state;
235
+ {
236
+ z_streamp strm = &(state.state->strm);
237
+
238
+ do {
239
+ switch(state.state->how) {
240
+ case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
241
+ if (gz_look(state) == -1)
242
+ return -1;
243
+ if (state.state->how == LOOK)
244
+ return 0;
245
+ break;
246
+ case COPY: /* -> COPY */
247
+ if (gz_load(state, state.state->out, state.state->size << 1, &(state.state->x.have))
248
+ == -1)
249
+ return -1;
250
+ state.state->x.next = state.state->out;
251
+ return 0;
252
+ case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
253
+ strm->avail_out = state.state->size << 1;
254
+ strm->next_out = state.state->out;
255
+ if (gz_decomp(state) == -1)
256
+ return -1;
257
+ }
258
+ } while (state.state->x.have == 0 && (!state.state->eof || strm->avail_in));
259
+ return 0;
260
+ }
261
+
262
+ /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
263
+ local int gz_skip(state, len)
264
+ gz_statep state;
265
+ z_off64_t len;
266
+ {
267
+ unsigned n;
268
+
269
+ /* skip over len bytes or reach end-of-file, whichever comes first */
270
+ while (len)
271
+ /* skip over whatever is in output buffer */
272
+ if (state.state->x.have) {
273
+ n = GT_OFF(state.state->x.have) || (z_off64_t)state.state->x.have > len ?
274
+ (unsigned)len : state.state->x.have;
275
+ state.state->x.have -= n;
276
+ state.state->x.next += n;
277
+ state.state->x.pos += n;
278
+ len -= n;
279
+ }
280
+
281
+ /* output buffer empty -- return if we're at the end of the input */
282
+ else if (state.state->eof && state.state->strm.avail_in == 0)
283
+ break;
284
+
285
+ /* need more data to skip -- load up output buffer */
286
+ else {
287
+ /* get more output, looking for header if required */
288
+ if (gz_fetch(state) == -1)
289
+ return -1;
290
+ }
291
+ return 0;
292
+ }
293
+
294
+ /* Read len bytes into buf from file, or less than len up to the end of the
295
+ input. Return the number of bytes read. If zero is returned, either the
296
+ end of file was reached, or there was an error. state.state->err must be
297
+ consulted in that case to determine which. */
298
+ local z_size_t gz_read(state, buf, len)
299
+ gz_statep state;
300
+ voidp buf;
301
+ z_size_t len;
302
+ {
303
+ z_size_t got;
304
+ unsigned n;
305
+
306
+ /* if len is zero, avoid unnecessary operations */
307
+ if (len == 0)
308
+ return 0;
309
+
310
+ /* process a skip request */
311
+ if (state.state->seek) {
312
+ state.state->seek = 0;
313
+ if (gz_skip(state, state.state->skip) == -1)
314
+ return 0;
315
+ }
316
+
317
+ /* get len bytes to buf, or less than len if at the end */
318
+ got = 0;
319
+ do {
320
+ /* set n to the maximum amount of len that fits in an unsigned int */
321
+ n = -1;
322
+ if (n > len)
323
+ n = (unsigned)len;
324
+
325
+ /* first just try copying data from the output buffer */
326
+ if (state.state->x.have) {
327
+ if (state.state->x.have < n)
328
+ n = state.state->x.have;
329
+ memcpy(buf, state.state->x.next, n);
330
+ state.state->x.next += n;
331
+ state.state->x.have -= n;
332
+ }
333
+
334
+ /* output buffer empty -- return if we're at the end of the input */
335
+ else if (state.state->eof && state.state->strm.avail_in == 0) {
336
+ state.state->past = 1; /* tried to read past end */
337
+ break;
338
+ }
339
+
340
+ /* need output data -- for small len or new stream load up our output
341
+ buffer */
342
+ else if (state.state->how == LOOK || n < (state.state->size << 1)) {
343
+ /* get more output, looking for header if required */
344
+ if (gz_fetch(state) == -1)
345
+ return 0;
346
+ continue; /* no progress yet -- go back to copy above */
347
+ /* the copy above assures that we will leave with space in the
348
+ output buffer, allowing at least one gzungetc() to succeed */
349
+ }
350
+
351
+ /* large len -- read directly into user buffer */
352
+ else if (state.state->how == COPY) { /* read directly */
353
+ if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
354
+ return 0;
355
+ }
356
+
357
+ /* large len -- decompress directly into user buffer */
358
+ else { /* state.state->how == GZIP */
359
+ state.state->strm.avail_out = n;
360
+ state.state->strm.next_out = (unsigned char *)buf;
361
+ if (gz_decomp(state) == -1)
362
+ return 0;
363
+ n = state.state->x.have;
364
+ state.state->x.have = 0;
365
+ }
366
+
367
+ /* update progress */
368
+ len -= n;
369
+ buf = (char *)buf + n;
370
+ got += n;
371
+ state.state->x.pos += n;
372
+ } while (len);
373
+
374
+ /* return number of bytes read into user buffer */
375
+ return got;
376
+ }
377
+
378
+ /* -- see zlib.h -- */
379
+ int ZEXPORT gzread(file, buf, len)
380
+ gzFile file;
381
+ voidp buf;
382
+ unsigned len;
383
+ {
384
+ gz_statep state;
385
+
386
+ /* get internal structure */
387
+ if (file == NULL)
388
+ return -1;
389
+ state = (gz_statep)file;
390
+
391
+ /* check that we're reading and that there's no (serious) error */
392
+ if (state.state->mode != GZ_READ ||
393
+ (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
394
+ return -1;
395
+
396
+ /* since an int is returned, make sure len fits in one, otherwise return
397
+ with an error (this avoids a flaw in the interface) */
398
+ if ((int)len < 0) {
399
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
400
+ return -1;
401
+ }
402
+
403
+ /* read len or fewer bytes to buf */
404
+ len = (unsigned)gz_read(state, buf, len);
405
+
406
+ /* check for an error */
407
+ if (len == 0 && state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)
408
+ return -1;
409
+
410
+ /* return the number of bytes read (this is assured to fit in an int) */
411
+ return (int)len;
412
+ }
413
+
414
+ /* -- see zlib.h -- */
415
+ z_size_t ZEXPORT gzfread(buf, size, nitems, file)
416
+ voidp buf;
417
+ z_size_t size;
418
+ z_size_t nitems;
419
+ gzFile file;
420
+ {
421
+ z_size_t len;
422
+ gz_statep state;
423
+
424
+ /* get internal structure */
425
+ if (file == NULL)
426
+ return 0;
427
+ state = (gz_statep)file;
428
+
429
+ /* check that we're reading and that there's no (serious) error */
430
+ if (state.state->mode != GZ_READ ||
431
+ (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
432
+ return 0;
433
+
434
+ /* compute bytes to read -- error on overflow */
435
+ len = nitems * size;
436
+ if (size && len / size != nitems) {
437
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
438
+ return 0;
439
+ }
440
+
441
+ /* read len or fewer bytes to buf, return the number of full items read */
442
+ return len ? gz_read(state, buf, len) / size : 0;
443
+ }
444
+
445
+ /* -- see zlib.h -- */
446
+ #if ZLIB_VERNUM >= 0x1261
447
+ #ifdef Z_PREFIX_SET
448
+ # undef z_gzgetc
449
+ #else
450
+ # undef gzgetc
451
+ #endif
452
+ #endif
453
+
454
+ #if ZLIB_VERNUM == 0x1260
455
+ # undef gzgetc
456
+ #endif
457
+
458
+ #if ZLIB_VERNUM <= 0x1250
459
+ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
460
+ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));
461
+ #endif
462
+
463
+ int ZEXPORT gzgetc(file)
464
+ gzFile file;
465
+ {
466
+ int ret;
467
+ unsigned char buf[1];
468
+ gz_statep state;
469
+
470
+ /* get internal structure */
471
+ if (file == NULL)
472
+ return -1;
473
+ state = (gz_statep)file;
474
+
475
+ /* check that we're reading and that there's no (serious) error */
476
+ if (state.state->mode != GZ_READ ||
477
+ (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
478
+ return -1;
479
+
480
+ /* try output buffer (no need to check for skip request) */
481
+ if (state.state->x.have) {
482
+ state.state->x.have--;
483
+ state.state->x.pos++;
484
+ return *(state.state->x.next)++;
485
+ }
486
+
487
+ /* nothing there -- try gz_read() */
488
+ ret = (unsigned)gz_read(state, buf, 1);
489
+ return ret < 1 ? -1 : buf[0];
490
+ }
491
+
492
+ int ZEXPORT gzgetc_(file)
493
+ gzFile file;
494
+ {
495
+ return gzgetc(file);
496
+ }
497
+
498
+ /* -- see zlib.h -- */
499
+ int ZEXPORT gzungetc(c, file)
500
+ int c;
501
+ gzFile file;
502
+ {
503
+ gz_statep state;
504
+
505
+ /* get internal structure */
506
+ if (file == NULL)
507
+ return -1;
508
+ state = (gz_statep)file;
509
+
510
+ /* check that we're reading and that there's no (serious) error */
511
+ if (state.state->mode != GZ_READ ||
512
+ (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
513
+ return -1;
514
+
515
+ /* process a skip request */
516
+ if (state.state->seek) {
517
+ state.state->seek = 0;
518
+ if (gz_skip(state, state.state->skip) == -1)
519
+ return -1;
520
+ }
521
+
522
+ /* can't push EOF */
523
+ if (c < 0)
524
+ return -1;
525
+
526
+ /* if output buffer empty, put byte at end (allows more pushing) */
527
+ if (state.state->x.have == 0) {
528
+ state.state->x.have = 1;
529
+ state.state->x.next = state.state->out + (state.state->size << 1) - 1;
530
+ state.state->x.next[0] = (unsigned char)c;
531
+ state.state->x.pos--;
532
+ state.state->past = 0;
533
+ return c;
534
+ }
535
+
536
+ /* if no room, give up (must have already done a gzungetc()) */
537
+ if (state.state->x.have == (state.state->size << 1)) {
538
+ gz_error(state, Z_DATA_ERROR, "out of room to push characters");
539
+ return -1;
540
+ }
541
+
542
+ /* slide output data if needed and insert byte before existing data */
543
+ if (state.state->x.next == state.state->out) {
544
+ unsigned char *src = state.state->out + state.state->x.have;
545
+ unsigned char *dest = state.state->out + (state.state->size << 1);
546
+ while (src > state.state->out)
547
+ *--dest = *--src;
548
+ state.state->x.next = dest;
549
+ }
550
+ state.state->x.have++;
551
+ state.state->x.next--;
552
+ state.state->x.next[0] = (unsigned char)c;
553
+ state.state->x.pos--;
554
+ state.state->past = 0;
555
+ return c;
556
+ }
557
+
558
+ /* -- see zlib.h -- */
559
+ char * ZEXPORT gzgets(file, buf, len)
560
+ gzFile file;
561
+ char *buf;
562
+ int len;
563
+ {
564
+ unsigned left, n;
565
+ char *str;
566
+ unsigned char *eol;
567
+ gz_statep state;
568
+
569
+ /* check parameters and get internal structure */
570
+ if (file == NULL || buf == NULL || len < 1)
571
+ return NULL;
572
+ state = (gz_statep)file;
573
+
574
+ /* check that we're reading and that there's no (serious) error */
575
+ if (state.state->mode != GZ_READ ||
576
+ (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
577
+ return NULL;
578
+
579
+ /* process a skip request */
580
+ if (state.state->seek) {
581
+ state.state->seek = 0;
582
+ if (gz_skip(state, state.state->skip) == -1)
583
+ return NULL;
584
+ }
585
+
586
+ /* copy output bytes up to new line or len - 1, whichever comes first --
587
+ append a terminating zero to the string (we don't check for a zero in
588
+ the contents, let the user worry about that) */
589
+ str = buf;
590
+ left = (unsigned)len - 1;
591
+ if (left) do {
592
+ /* assure that something is in the output buffer */
593
+ if (state.state->x.have == 0 && gz_fetch(state) == -1)
594
+ return NULL; /* error */
595
+ if (state.state->x.have == 0) { /* end of file */
596
+ state.state->past = 1; /* read past end */
597
+ break; /* return what we have */
598
+ }
599
+
600
+ /* look for end-of-line in current output buffer */
601
+ n = state.state->x.have > left ? left : state.state->x.have;
602
+ eol = (unsigned char *)memchr(state.state->x.next, '\n', n);
603
+ if (eol != NULL)
604
+ n = (unsigned)(eol - state.state->x.next) + 1;
605
+
606
+ /* copy through end-of-line, or remainder if not found */
607
+ memcpy(buf, state.state->x.next, n);
608
+ state.state->x.have -= n;
609
+ state.state->x.next += n;
610
+ state.state->x.pos += n;
611
+ left -= n;
612
+ buf += n;
613
+ } while (left && eol == NULL);
614
+
615
+ /* return terminated string, or if nothing, end of file */
616
+ if (buf == str)
617
+ return NULL;
618
+ buf[0] = 0;
619
+ return str;
620
+ }
621
+
622
+ /* -- see zlib.h -- */
623
+ int ZEXPORT gzdirect(file)
624
+ gzFile file;
625
+ {
626
+ gz_statep state;
627
+
628
+ /* get internal structure */
629
+ if (file == NULL)
630
+ return 0;
631
+ state = (gz_statep)file;
632
+
633
+ /* if the state is not known, but we can find out, then do so (this is
634
+ mainly for right after a gzopen() or gzdopen()) */
635
+ if (state.state->mode == GZ_READ && state.state->how == LOOK && state.state->x.have == 0)
636
+ (void)gz_look(state);
637
+
638
+ /* return 1 if transparent, 0 if processing a gzip stream */
639
+ return state.state->direct;
640
+ }
641
+
642
+ /* -- see zlib.h -- */
643
+ int ZEXPORT gzclose_r(file)
644
+ gzFile file;
645
+ {
646
+ int ret, err;
647
+ gz_statep state;
648
+
649
+ /* get internal structure */
650
+ if (file == NULL)
651
+ return Z_STREAM_ERROR;
652
+ state = (gz_statep)file;
653
+
654
+ /* check that we're reading */
655
+ if (state.state->mode != GZ_READ)
656
+ return Z_STREAM_ERROR;
657
+
658
+ /* free memory and close file */
659
+ if (state.state->size) {
660
+ inflateEnd(&(state.state->strm));
661
+ free(state.state->out);
662
+ free(state.state->in);
663
+ }
664
+ err = state.state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
665
+ gz_error(state, Z_OK, NULL);
666
+ free(state.state->path);
667
+ ret = close(state.state->fd);
668
+ free(state.state);
669
+ return ret ? Z_ERRNO : err;
670
+ }