chd 0.1.1

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