ray 0.0.0.pre1 → 0.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. data/.gitignore +15 -0
  2. data/.gitmodules +3 -0
  3. data/Rakefile +148 -5
  4. data/VERSION +1 -1
  5. data/ext/event.c +535 -0
  6. data/ext/extconf.rb +7 -1
  7. data/ext/image.c +110 -18
  8. data/ext/joystick.c +145 -0
  9. data/ext/ray.c +288 -35
  10. data/ext/ray.h +54 -2
  11. data/lib/ray/config.rb +84 -0
  12. data/lib/ray/dsl.rb +19 -0
  13. data/lib/ray/dsl/converter.rb +65 -0
  14. data/lib/ray/dsl/event.rb +52 -0
  15. data/lib/ray/dsl/event_raiser.rb +21 -0
  16. data/lib/ray/dsl/event_runner.rb +39 -0
  17. data/lib/ray/dsl/event_translator.rb +38 -0
  18. data/lib/ray/dsl/handler.rb +71 -0
  19. data/lib/ray/dsl/listener.rb +30 -0
  20. data/lib/ray/dsl/matcher.rb +60 -0
  21. data/lib/ray/dsl/type.rb +58 -0
  22. data/lib/ray/game.rb +107 -0
  23. data/lib/ray/helper.rb +17 -0
  24. data/lib/ray/image.rb +11 -0
  25. data/lib/ray/ray.rb +8 -0
  26. data/lib/ray/scene.rb +102 -0
  27. data/psp/SDL_psp_main.c +84 -0
  28. data/psp/bigdecimal/README +60 -0
  29. data/psp/bigdecimal/bigdecimal.c +4697 -0
  30. data/psp/bigdecimal/bigdecimal.h +216 -0
  31. data/psp/bigdecimal/lib/bigdecimal/jacobian.rb +85 -0
  32. data/psp/bigdecimal/lib/bigdecimal/ludcmp.rb +84 -0
  33. data/psp/bigdecimal/lib/bigdecimal/math.rb +235 -0
  34. data/psp/bigdecimal/lib/bigdecimal/newton.rb +77 -0
  35. data/psp/bigdecimal/lib/bigdecimal/util.rb +65 -0
  36. data/psp/digest/bubblebabble/bubblebabble.c +142 -0
  37. data/psp/digest/defs.h +20 -0
  38. data/psp/digest/digest.c +643 -0
  39. data/psp/digest/digest.h +32 -0
  40. data/psp/digest/lib/digest.rb +50 -0
  41. data/psp/digest/lib/md5.rb +27 -0
  42. data/psp/digest/lib/sha1.rb +27 -0
  43. data/psp/digest/md5/md5.c +420 -0
  44. data/psp/digest/md5/md5.h +80 -0
  45. data/psp/digest/md5/md5init.c +40 -0
  46. data/psp/digest/rmd160/rmd160.c +457 -0
  47. data/psp/digest/rmd160/rmd160.h +56 -0
  48. data/psp/digest/rmd160/rmd160init.c +40 -0
  49. data/psp/digest/sha1/sha1.c +269 -0
  50. data/psp/digest/sha1/sha1.h +39 -0
  51. data/psp/digest/sha1/sha1init.c +40 -0
  52. data/psp/digest/sha2/lib/sha2.rb +73 -0
  53. data/psp/digest/sha2/sha2.c +919 -0
  54. data/psp/digest/sha2/sha2.h +109 -0
  55. data/psp/digest/sha2/sha2init.c +52 -0
  56. data/psp/enumerator/enumerator.c +298 -0
  57. data/psp/etc/etc.c +559 -0
  58. data/psp/ext.c +285 -0
  59. data/psp/fcntl/fcntl.c +187 -0
  60. data/psp/lib/rbconfig.rb +178 -0
  61. data/psp/nkf/lib/kconv.rb +367 -0
  62. data/psp/nkf/nkf-utf8/config.h +88 -0
  63. data/psp/nkf/nkf-utf8/nkf.c +6040 -0
  64. data/psp/nkf/nkf-utf8/utf8tbl.c +8500 -0
  65. data/psp/nkf/nkf-utf8/utf8tbl.h +34 -0
  66. data/psp/nkf/nkf.c +654 -0
  67. data/psp/socket/addrinfo.h +173 -0
  68. data/psp/socket/getaddrinfo.c +676 -0
  69. data/psp/socket/getnameinfo.c +270 -0
  70. data/psp/socket/pspsocket.c +71 -0
  71. data/psp/socket/pspsocket.h +28 -0
  72. data/psp/socket/socket.c +4662 -0
  73. data/psp/socket/sockport.h +76 -0
  74. data/psp/stringio/stringio.c +1306 -0
  75. data/psp/strscan/strscan.c +1320 -0
  76. data/psp/syck/bytecode.c +1166 -0
  77. data/psp/syck/emitter.c +1242 -0
  78. data/psp/syck/gram.c +1894 -0
  79. data/psp/syck/gram.h +79 -0
  80. data/psp/syck/handler.c +174 -0
  81. data/psp/syck/implicit.c +2990 -0
  82. data/psp/syck/node.c +408 -0
  83. data/psp/syck/rubyext.c +2367 -0
  84. data/psp/syck/syck.c +504 -0
  85. data/psp/syck/syck.h +456 -0
  86. data/psp/syck/token.c +2725 -0
  87. data/psp/syck/yaml2byte.c +257 -0
  88. data/psp/syck/yamlbyte.h +170 -0
  89. data/psp/thread/thread.c +1175 -0
  90. data/psp/zlib/zlib.c +3547 -0
  91. data/script.rb +10 -0
  92. data/spec/ray/config_spec.rb +90 -0
  93. data/spec/ray/conversion_spec.rb +43 -0
  94. data/spec/ray/event_spec.rb +191 -0
  95. data/spec/ray/image_spec.rb +43 -1
  96. data/spec/ray/joystick_spec.rb +17 -0
  97. data/spec/ray/matcher_spec.rb +73 -0
  98. data/spec/ray/ray_spec.rb +72 -1
  99. data/spec/ray/type_spec.rb +17 -0
  100. data/spec/res/aqua.bmp +0 -0
  101. data/spec/res/aqua.png +0 -0
  102. data/spec/res/not_a_jpeg.jpeg +0 -0
  103. data/spec_runner.rb +4 -0
  104. metadata +101 -9
  105. data/ext/Makefile +0 -189
  106. data/ext/ray +0 -0
  107. data/ext/ray.bundle +0 -0
  108. data/ext/ray_ext.bundle +0 -0
  109. data/ext/ray_ext.so +0 -0
  110. data/ext/test.rb +0 -21
data/psp/zlib/zlib.c ADDED
@@ -0,0 +1,3547 @@
1
+ /*
2
+ * zlib.c - An interface for zlib.
3
+ *
4
+ * Copyright (C) UENO Katsuhiro 2000-2003
5
+ *
6
+ * $Id: zlib.c 11708 2007-02-12 23:01:19Z shyouhei $
7
+ */
8
+
9
+ #include <ruby/ruby.h>
10
+ #include <zlib.h>
11
+ #include <time.h>
12
+
13
+ #define RUBY_ZLIB_VERSION "0.6.0"
14
+
15
+
16
+ #define OBJ_IS_FREED(val) (RBASIC(val)->flags == 0)
17
+
18
+ #ifndef GZIP_SUPPORT
19
+ #define GZIP_SUPPORT 1
20
+ #endif
21
+
22
+ /* from zutil.h */
23
+ #ifndef DEF_MEM_LEVEL
24
+ #if MAX_MEM_LEVEL >= 8
25
+ #define DEF_MEM_LEVEL 8
26
+ #else
27
+ #define DEF_MEM_LEVEL MAX_MEM_LEVEL
28
+ #endif
29
+ #endif
30
+
31
+
32
+ /*--------- Prototypes --------*/
33
+
34
+ static NORETURN(void raise_zlib_error _((int, const char *)));
35
+ static VALUE rb_zlib_version _((VALUE));
36
+ static VALUE do_checksum _((int, VALUE*, uLong (*) _((uLong, const Bytef*, uInt))));
37
+ static VALUE rb_zlib_adler32 _((int, VALUE*, VALUE));
38
+ static VALUE rb_zlib_crc32 _((int, VALUE*, VALUE));
39
+ static VALUE rb_zlib_crc_table _((VALUE));
40
+ static voidpf zlib_mem_alloc _((voidpf, uInt, uInt));
41
+ static void zlib_mem_free _((voidpf, voidpf));
42
+ static void finalizer_warn _((const char*));
43
+
44
+ struct zstream;
45
+ struct zstream_funcs;
46
+ static void zstream_init _((struct zstream*, const struct zstream_funcs *));
47
+ static void zstream_expand_buffer _((struct zstream*));
48
+ static void zstream_expand_buffer_into _((struct zstream*, int));
49
+ static void zstream_append_buffer _((struct zstream*, const char*, int));
50
+ static VALUE zstream_detach_buffer _((struct zstream*));
51
+ static VALUE zstream_shift_buffer _((struct zstream*, int));
52
+ static void zstream_buffer_ungetc _((struct zstream*, int));
53
+ static void zstream_append_input _((struct zstream*, const char*, unsigned int));
54
+ static void zstream_discard_input _((struct zstream*, unsigned int));
55
+ static void zstream_reset_input _((struct zstream*));
56
+ static void zstream_passthrough_input _((struct zstream*));
57
+ static VALUE zstream_detach_input _((struct zstream*));
58
+ static void zstream_reset _((struct zstream*));
59
+ static VALUE zstream_end _((struct zstream*));
60
+ static void zstream_run _((struct zstream*, Bytef*, uInt, int));
61
+ static VALUE zstream_sync _((struct zstream*, Bytef*, uInt));
62
+ static void zstream_mark _((struct zstream*));
63
+ static void zstream_free _((struct zstream*));
64
+ static VALUE zstream_new _((VALUE, const struct zstream_funcs*));
65
+ static struct zstream *get_zstream _((VALUE));
66
+ static void zstream_finalize _((struct zstream*));
67
+
68
+ static VALUE rb_zstream_end _((VALUE));
69
+ static VALUE rb_zstream_reset _((VALUE));
70
+ static VALUE rb_zstream_finish _((VALUE));
71
+ static VALUE rb_zstream_flush_next_in _((VALUE));
72
+ static VALUE rb_zstream_flush_next_out _((VALUE));
73
+ static VALUE rb_zstream_avail_out _((VALUE));
74
+ static VALUE rb_zstream_set_avail_out _((VALUE, VALUE));
75
+ static VALUE rb_zstream_avail_in _((VALUE));
76
+ static VALUE rb_zstream_total_in _((VALUE));
77
+ static VALUE rb_zstream_total_out _((VALUE));
78
+ static VALUE rb_zstream_data_type _((VALUE));
79
+ static VALUE rb_zstream_adler _((VALUE));
80
+ static VALUE rb_zstream_finished_p _((VALUE));
81
+ static VALUE rb_zstream_closed_p _((VALUE));
82
+
83
+ static VALUE rb_deflate_s_allocate _((VALUE));
84
+ static VALUE rb_deflate_initialize _((int, VALUE*, VALUE));
85
+ static VALUE rb_deflate_init_copy _((VALUE, VALUE));
86
+ static VALUE deflate_run _((VALUE));
87
+ static VALUE rb_deflate_s_deflate _((int, VALUE*, VALUE));
88
+ static void do_deflate _((struct zstream*, VALUE, int));
89
+ static VALUE rb_deflate_deflate _((int, VALUE*, VALUE));
90
+ static VALUE rb_deflate_addstr _((VALUE, VALUE));
91
+ static VALUE rb_deflate_flush _((int, VALUE*, VALUE));
92
+ static VALUE rb_deflate_params _((VALUE, VALUE, VALUE));
93
+ static VALUE rb_deflate_set_dictionary _((VALUE, VALUE));
94
+
95
+ static VALUE inflate_run _((VALUE));
96
+ static VALUE rb_inflate_s_allocate _((VALUE));
97
+ static VALUE rb_inflate_initialize _((int, VALUE*, VALUE));
98
+ static VALUE rb_inflate_s_inflate _((VALUE, VALUE));
99
+ static void do_inflate _((struct zstream*, VALUE));
100
+ static VALUE rb_inflate_inflate _((VALUE, VALUE));
101
+ static VALUE rb_inflate_addstr _((VALUE, VALUE));
102
+ static VALUE rb_inflate_sync _((VALUE, VALUE));
103
+ static VALUE rb_inflate_sync_point_p _((VALUE));
104
+ static VALUE rb_inflate_set_dictionary _((VALUE, VALUE));
105
+
106
+ #if GZIP_SUPPORT
107
+ struct gzfile;
108
+ static void gzfile_mark _((struct gzfile*));
109
+ static void gzfile_free _((struct gzfile*));
110
+ static VALUE gzfile_new _((VALUE, const struct zstream_funcs*, void (*) _((struct gzfile*))));
111
+ static void gzfile_reset _((struct gzfile*));
112
+ static void gzfile_close _((struct gzfile*, int));
113
+ static void gzfile_write_raw _((struct gzfile*));
114
+ static VALUE gzfile_read_raw _((struct gzfile*));
115
+ static int gzfile_read_raw_ensure _((struct gzfile*, int));
116
+ static char *gzfile_read_raw_until_zero _((struct gzfile*, long));
117
+ static unsigned int gzfile_get16 _((const unsigned char*));
118
+ static unsigned long gzfile_get32 _((const unsigned char*));
119
+ static void gzfile_set32 _((unsigned long n, unsigned char*));
120
+ static void gzfile_make_header _((struct gzfile*));
121
+ static void gzfile_make_footer _((struct gzfile*));
122
+ static void gzfile_read_header _((struct gzfile*));
123
+ static void gzfile_check_footer _((struct gzfile*));
124
+ static void gzfile_write _((struct gzfile*, Bytef*, uInt));
125
+ static long gzfile_read_more _((struct gzfile*));
126
+ static void gzfile_calc_crc _((struct gzfile*, VALUE));
127
+ static VALUE gzfile_read _((struct gzfile*, int));
128
+ static VALUE gzfile_read_all _((struct gzfile*));
129
+ static void gzfile_ungetc _((struct gzfile*, int));
130
+ static VALUE gzfile_writer_end_run _((VALUE));
131
+ static void gzfile_writer_end _((struct gzfile*));
132
+ static VALUE gzfile_reader_end_run _((VALUE));
133
+ static void gzfile_reader_end _((struct gzfile*));
134
+ static void gzfile_reader_rewind _((struct gzfile*));
135
+ static VALUE gzfile_reader_get_unused _((struct gzfile*));
136
+ static struct gzfile *get_gzfile _((VALUE));
137
+ static VALUE gzfile_ensure_close _((VALUE));
138
+ static VALUE rb_gzfile_s_wrap _((int, VALUE*, VALUE));
139
+ static VALUE gzfile_s_open _((int, VALUE*, VALUE, const char*));
140
+
141
+ static VALUE rb_gzfile_to_io _((VALUE));
142
+ static VALUE rb_gzfile_crc _((VALUE));
143
+ static VALUE rb_gzfile_mtime _((VALUE));
144
+ static VALUE rb_gzfile_level _((VALUE));
145
+ static VALUE rb_gzfile_os_code _((VALUE));
146
+ static VALUE rb_gzfile_orig_name _((VALUE));
147
+ static VALUE rb_gzfile_comment _((VALUE));
148
+ static VALUE rb_gzfile_lineno _((VALUE));
149
+ static VALUE rb_gzfile_set_lineno _((VALUE, VALUE));
150
+ static VALUE rb_gzfile_set_mtime _((VALUE, VALUE));
151
+ static VALUE rb_gzfile_set_orig_name _((VALUE, VALUE));
152
+ static VALUE rb_gzfile_set_comment _((VALUE, VALUE));
153
+ static VALUE rb_gzfile_close _((VALUE));
154
+ static VALUE rb_gzfile_finish _((VALUE));
155
+ static VALUE rb_gzfile_closed_p _((VALUE));
156
+ static VALUE rb_gzfile_eof_p _((VALUE));
157
+ static VALUE rb_gzfile_sync _((VALUE));
158
+ static VALUE rb_gzfile_set_sync _((VALUE, VALUE));
159
+ static VALUE rb_gzfile_total_in _((VALUE));
160
+ static VALUE rb_gzfile_total_out _((VALUE));
161
+
162
+ static VALUE rb_gzwriter_s_allocate _((VALUE));
163
+ static VALUE rb_gzwriter_s_open _((int, VALUE*, VALUE));
164
+ static VALUE rb_gzwriter_initialize _((int, VALUE*, VALUE));
165
+ static VALUE rb_gzwriter_flush _((int, VALUE*, VALUE));
166
+ static VALUE rb_gzwriter_write _((VALUE, VALUE));
167
+ static VALUE rb_gzwriter_putc _((VALUE, VALUE));
168
+
169
+ static VALUE rb_gzreader_s_allocate _((VALUE));
170
+ static VALUE rb_gzreader_s_open _((int, VALUE*, VALUE));
171
+ static VALUE rb_gzreader_initialize _((VALUE, VALUE));
172
+ static VALUE rb_gzreader_rewind _((VALUE));
173
+ static VALUE rb_gzreader_unused _((VALUE));
174
+ static VALUE rb_gzreader_read _((int, VALUE*, VALUE));
175
+ static VALUE rb_gzreader_getc _((VALUE));
176
+ static VALUE rb_gzreader_readchar _((VALUE));
177
+ static VALUE rb_gzreader_each_byte _((VALUE));
178
+ static VALUE rb_gzreader_ungetc _((VALUE, VALUE));
179
+ static void gzreader_skip_linebreaks _((struct gzfile*));
180
+ static VALUE gzreader_gets _((int, VALUE*, VALUE));
181
+ static VALUE rb_gzreader_gets _((int, VALUE*, VALUE));
182
+ static VALUE rb_gzreader_readline _((int, VALUE*, VALUE));
183
+ static VALUE rb_gzreader_each _((int, VALUE*, VALUE));
184
+ static VALUE rb_gzreader_readlines _((int, VALUE*, VALUE));
185
+ #endif /* GZIP_SUPPORT */
186
+
187
+
188
+ void Init_zlib _((void));
189
+
190
+
191
+
192
+ /*--------- Exceptions --------*/
193
+
194
+ static VALUE cZError, cStreamEnd, cNeedDict;
195
+ static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError;
196
+
197
+ static void
198
+ raise_zlib_error(err, msg)
199
+ int err;
200
+ const char *msg;
201
+ {
202
+ VALUE exc;
203
+
204
+ if (!msg) {
205
+ msg = zError(err);
206
+ }
207
+
208
+ switch(err) {
209
+ case Z_STREAM_END:
210
+ exc = rb_exc_new2(cStreamEnd, msg);
211
+ break;
212
+ case Z_NEED_DICT:
213
+ exc = rb_exc_new2(cNeedDict, msg);
214
+ break;
215
+ case Z_STREAM_ERROR:
216
+ exc = rb_exc_new2(cStreamError, msg);
217
+ break;
218
+ case Z_DATA_ERROR:
219
+ exc = rb_exc_new2(cDataError, msg);
220
+ break;
221
+ case Z_BUF_ERROR:
222
+ exc = rb_exc_new2(cBufError, msg);
223
+ break;
224
+ case Z_VERSION_ERROR:
225
+ exc = rb_exc_new2(cVersionError, msg);
226
+ break;
227
+ case Z_MEM_ERROR:
228
+ exc = rb_exc_new2(cMemError, msg);
229
+ break;
230
+ case Z_ERRNO:
231
+ rb_sys_fail(msg);
232
+ /* no return */
233
+ default:
234
+ {
235
+ char buf[BUFSIZ];
236
+ snprintf(buf, BUFSIZ, "unknown zlib error %d: %s", err, msg);
237
+ exc = rb_exc_new2(cZError, buf);
238
+ }
239
+ }
240
+
241
+ rb_exc_raise(exc);
242
+ }
243
+
244
+
245
+ /*--- Warning (in finalizer) ---*/
246
+
247
+ static void
248
+ finalizer_warn(msg)
249
+ const char *msg;
250
+ {
251
+ fprintf(stderr, "zlib(finalizer): %s\n", msg);
252
+ }
253
+
254
+
255
+ /*-------- module Zlib --------*/
256
+
257
+ /*
258
+ * Returns the string which represents the version of zlib library.
259
+ */
260
+ static VALUE
261
+ rb_zlib_version(klass)
262
+ VALUE klass;
263
+ {
264
+ VALUE str;
265
+
266
+ str = rb_str_new2(zlibVersion());
267
+ OBJ_TAINT(str); /* for safe */
268
+ return str;
269
+ }
270
+
271
+ static VALUE
272
+ do_checksum(argc, argv, func)
273
+ int argc;
274
+ VALUE *argv;
275
+ uLong (*func) _((uLong, const Bytef *, uInt));
276
+ {
277
+ VALUE str, vsum;
278
+ unsigned long sum;
279
+
280
+ rb_scan_args(argc, argv, "02", &str, &vsum);
281
+
282
+ if (!NIL_P(vsum)) {
283
+ sum = NUM2ULONG(vsum);
284
+ }
285
+ else if (NIL_P(str)) {
286
+ sum = 0;
287
+ }
288
+ else {
289
+ sum = func(0, Z_NULL, 0);
290
+ }
291
+
292
+ if (NIL_P(str)) {
293
+ sum = func(sum, Z_NULL, 0);
294
+ }
295
+ else {
296
+ StringValue(str);
297
+ sum = func(sum, RSTRING(str)->ptr, RSTRING(str)->len);
298
+ }
299
+ return rb_uint2inum(sum);
300
+ }
301
+
302
+ /*
303
+ * call-seq: Zlib.adler32(string, adler)
304
+ *
305
+ * Calculates Alder-32 checksum for +string+, and returns updated value of
306
+ * +adler+. If +string+ is omitted, it returns the Adler-32 initial value. If
307
+ * +adler+ is omitted, it assumes that the initial value is given to +adler+.
308
+ *
309
+ * FIXME: expression.
310
+ */
311
+ static VALUE
312
+ rb_zlib_adler32(argc, argv, klass)
313
+ int argc;
314
+ VALUE *argv;
315
+ VALUE klass;
316
+ {
317
+ return do_checksum(argc, argv, adler32);
318
+ }
319
+
320
+ /*
321
+ * call-seq: Zlib.crc32(string, adler)
322
+ *
323
+ * Calculates CRC checksum for +string+, and returns updated value of +crc+. If
324
+ * +string+ is omitted, it returns the CRC initial value. If +crc+ is omitted, it
325
+ * assumes that the initial value is given to +crc+.
326
+ *
327
+ * FIXME: expression.
328
+ */
329
+ static VALUE
330
+ rb_zlib_crc32(argc, argv, klass)
331
+ int argc;
332
+ VALUE *argv;
333
+ VALUE klass;
334
+ {
335
+ return do_checksum(argc, argv, crc32);
336
+ }
337
+
338
+ /*
339
+ * Returns the table for calculating CRC checksum as an array.
340
+ */
341
+ static VALUE
342
+ rb_zlib_crc_table(obj)
343
+ VALUE obj;
344
+ {
345
+ const unsigned long *crctbl;
346
+ VALUE dst;
347
+ int i;
348
+
349
+ crctbl = get_crc_table();
350
+ dst = rb_ary_new2(256);
351
+
352
+ for (i = 0; i < 256; i++) {
353
+ rb_ary_push(dst, rb_uint2inum(crctbl[i]));
354
+ }
355
+ return dst;
356
+ }
357
+
358
+
359
+
360
+ /*-------- zstream - internal APIs --------*/
361
+
362
+ struct zstream {
363
+ unsigned long flags;
364
+ VALUE buf;
365
+ long buf_filled;
366
+ VALUE input;
367
+ z_stream stream;
368
+ const struct zstream_funcs {
369
+ int (*reset) _((z_streamp));
370
+ int (*end) _((z_streamp));
371
+ int (*run) _((z_streamp, int));
372
+ } *func;
373
+ };
374
+
375
+ #define ZSTREAM_FLAG_READY 0x1
376
+ #define ZSTREAM_FLAG_IN_STREAM 0x2
377
+ #define ZSTREAM_FLAG_FINISHED 0x4
378
+ #define ZSTREAM_FLAG_CLOSING 0x8
379
+ #define ZSTREAM_FLAG_UNUSED 0x10
380
+
381
+ #define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
382
+ #define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
383
+ #define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)
384
+ #define ZSTREAM_IS_CLOSING(z) ((z)->flags & ZSTREAM_FLAG_CLOSING)
385
+
386
+ /* I think that more better value should be found,
387
+ but I gave up finding it. B) */
388
+ #define ZSTREAM_INITIAL_BUFSIZE 1024
389
+ #define ZSTREAM_AVAIL_OUT_STEP_MAX 16384
390
+ #define ZSTREAM_AVAIL_OUT_STEP_MIN 2048
391
+
392
+ static const struct zstream_funcs deflate_funcs = {
393
+ deflateReset, deflateEnd, deflate,
394
+ };
395
+
396
+ static const struct zstream_funcs inflate_funcs = {
397
+ inflateReset, inflateEnd, inflate,
398
+ };
399
+
400
+
401
+ static voidpf
402
+ zlib_mem_alloc(opaque, items, size)
403
+ voidpf opaque;
404
+ uInt items, size;
405
+ {
406
+ return xmalloc(items * size);
407
+ }
408
+
409
+ static void
410
+ zlib_mem_free(opaque, address)
411
+ voidpf opaque, address;
412
+ {
413
+ free(address);
414
+ }
415
+
416
+ static void
417
+ zstream_init(z, func)
418
+ struct zstream *z;
419
+ const struct zstream_funcs *func;
420
+ {
421
+ z->flags = 0;
422
+ z->buf = Qnil;
423
+ z->buf_filled = 0;
424
+ z->input = Qnil;
425
+ z->stream.zalloc = zlib_mem_alloc;
426
+ z->stream.zfree = zlib_mem_free;
427
+ z->stream.opaque = Z_NULL;
428
+ z->stream.msg = Z_NULL;
429
+ z->stream.next_in = Z_NULL;
430
+ z->stream.avail_in = 0;
431
+ z->stream.next_out = Z_NULL;
432
+ z->stream.avail_out = 0;
433
+ z->func = func;
434
+ }
435
+
436
+ #define zstream_init_deflate(z) zstream_init((z), &deflate_funcs)
437
+ #define zstream_init_inflate(z) zstream_init((z), &inflate_funcs)
438
+
439
+ static void
440
+ zstream_expand_buffer(z)
441
+ struct zstream *z;
442
+ {
443
+ long inc;
444
+
445
+ if (NIL_P(z->buf)) {
446
+ /* I uses rb_str_new here not rb_str_buf_new because
447
+ rb_str_buf_new makes a zero-length string. */
448
+ z->buf = rb_str_new(0, ZSTREAM_INITIAL_BUFSIZE);
449
+ z->buf_filled = 0;
450
+ z->stream.next_out = RSTRING(z->buf)->ptr;
451
+ z->stream.avail_out = ZSTREAM_INITIAL_BUFSIZE;
452
+ RBASIC(z->buf)->klass = 0;
453
+ return;
454
+ }
455
+
456
+ if (RSTRING(z->buf)->len - z->buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
457
+ /* to keep other threads from freezing */
458
+ z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
459
+ }
460
+ else {
461
+ inc = z->buf_filled / 2;
462
+ if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
463
+ inc = ZSTREAM_AVAIL_OUT_STEP_MIN;
464
+ }
465
+ rb_str_resize(z->buf, z->buf_filled + inc);
466
+ z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
467
+ inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
468
+ }
469
+ z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;
470
+ }
471
+
472
+ static void
473
+ zstream_expand_buffer_into(z, size)
474
+ struct zstream *z;
475
+ int size;
476
+ {
477
+ if (NIL_P(z->buf)) {
478
+ /* I uses rb_str_new here not rb_str_buf_new because
479
+ rb_str_buf_new makes a zero-length string. */
480
+ z->buf = rb_str_new(0, size);
481
+ z->buf_filled = 0;
482
+ z->stream.next_out = RSTRING(z->buf)->ptr;
483
+ z->stream.avail_out = size;
484
+ RBASIC(z->buf)->klass = 0;
485
+ }
486
+ else if (z->stream.avail_out != size) {
487
+ rb_str_resize(z->buf, z->buf_filled + size);
488
+ z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;
489
+ z->stream.avail_out = size;
490
+ }
491
+ }
492
+
493
+ static void
494
+ zstream_append_buffer(z, src, len)
495
+ struct zstream *z;
496
+ const char *src;
497
+ int len;
498
+ {
499
+ if (NIL_P(z->buf)) {
500
+ z->buf = rb_str_buf_new(len);
501
+ rb_str_buf_cat(z->buf, src, len);
502
+ z->buf_filled = len;
503
+ z->stream.next_out = RSTRING(z->buf)->ptr;
504
+ z->stream.avail_out = 0;
505
+ RBASIC(z->buf)->klass = 0;
506
+ return;
507
+ }
508
+
509
+ if (RSTRING(z->buf)->len < z->buf_filled + len) {
510
+ rb_str_resize(z->buf, z->buf_filled + len);
511
+ z->stream.avail_out = 0;
512
+ }
513
+ else {
514
+ if (z->stream.avail_out >= len) {
515
+ z->stream.avail_out -= len;
516
+ }
517
+ else {
518
+ z->stream.avail_out = 0;
519
+ }
520
+ }
521
+ memcpy(RSTRING(z->buf)->ptr + z->buf_filled, src, len);
522
+ z->buf_filled += len;
523
+ z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;
524
+ }
525
+
526
+ #define zstream_append_buffer2(z,v) \
527
+ zstream_append_buffer((z),RSTRING(v)->ptr,RSTRING(v)->len)
528
+
529
+ static VALUE
530
+ zstream_detach_buffer(z)
531
+ struct zstream *z;
532
+ {
533
+ VALUE dst;
534
+
535
+ if (NIL_P(z->buf)) {
536
+ dst = rb_str_new(0, 0);
537
+ }
538
+ else {
539
+ dst = z->buf;
540
+ rb_str_resize(dst, z->buf_filled);
541
+ RBASIC(dst)->klass = rb_cString;
542
+ }
543
+
544
+ z->buf = Qnil;
545
+ z->buf_filled = 0;
546
+ z->stream.next_out = 0;
547
+ z->stream.avail_out = 0;
548
+ return dst;
549
+ }
550
+
551
+ static VALUE
552
+ zstream_shift_buffer(z, len)
553
+ struct zstream *z;
554
+ int len;
555
+ {
556
+ VALUE dst;
557
+
558
+ if (z->buf_filled <= len) {
559
+ return zstream_detach_buffer(z);
560
+ }
561
+
562
+ dst = rb_str_substr(z->buf, 0, len);
563
+ RBASIC(dst)->klass = rb_cString;
564
+ z->buf_filled -= len;
565
+ memmove(RSTRING(z->buf)->ptr, RSTRING(z->buf)->ptr + len,
566
+ z->buf_filled);
567
+ z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;
568
+ z->stream.avail_out = RSTRING(z->buf)->len - z->buf_filled;
569
+ if (z->stream.avail_out > ZSTREAM_AVAIL_OUT_STEP_MAX) {
570
+ z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
571
+ }
572
+
573
+ return dst;
574
+ }
575
+
576
+ static void
577
+ zstream_buffer_ungetc(z, c)
578
+ struct zstream *z;
579
+ int c;
580
+ {
581
+ if (NIL_P(z->buf) || RSTRING(z->buf)->len - z->buf_filled == 0) {
582
+ zstream_expand_buffer(z);
583
+ }
584
+
585
+ memmove(RSTRING(z->buf)->ptr + 1, RSTRING(z->buf)->ptr, z->buf_filled);
586
+ RSTRING(z->buf)->ptr[0] = (char)c;
587
+ z->buf_filled++;
588
+ if (z->stream.avail_out > 0) {
589
+ z->stream.next_out++;
590
+ z->stream.avail_out--;
591
+ }
592
+ }
593
+
594
+ static void
595
+ zstream_append_input(z, src, len)
596
+ struct zstream *z;
597
+ const char *src;
598
+ unsigned int len;
599
+ {
600
+ if (len <= 0) return;
601
+
602
+ if (NIL_P(z->input)) {
603
+ z->input = rb_str_buf_new(len);
604
+ rb_str_buf_cat(z->input, src, len);
605
+ RBASIC(z->input)->klass = 0;
606
+ }
607
+ else {
608
+ rb_str_buf_cat(z->input, src, len);
609
+ }
610
+ }
611
+
612
+ #define zstream_append_input2(z,v)\
613
+ zstream_append_input((z), RSTRING(v)->ptr, RSTRING(v)->len)
614
+
615
+ static void
616
+ zstream_discard_input(z, len)
617
+ struct zstream *z;
618
+ unsigned int len;
619
+ {
620
+ if (NIL_P(z->input) || RSTRING(z->input)->len <= len) {
621
+ z->input = Qnil;
622
+ }
623
+ else {
624
+ memmove(RSTRING(z->input)->ptr, RSTRING(z->input)->ptr + len,
625
+ RSTRING(z->input)->len - len);
626
+ rb_str_resize(z->input, RSTRING(z->input)->len - len);
627
+ }
628
+ }
629
+
630
+ static void
631
+ zstream_reset_input(z)
632
+ struct zstream *z;
633
+ {
634
+ z->input = Qnil;
635
+ }
636
+
637
+ static void
638
+ zstream_passthrough_input(z)
639
+ struct zstream *z;
640
+ {
641
+ if (!NIL_P(z->input)) {
642
+ zstream_append_buffer2(z, z->input);
643
+ z->input = Qnil;
644
+ }
645
+ }
646
+
647
+ static VALUE
648
+ zstream_detach_input(z)
649
+ struct zstream *z;
650
+ {
651
+ VALUE dst;
652
+
653
+ if (NIL_P(z->input)) {
654
+ dst = rb_str_new(0, 0);
655
+ }
656
+ else {
657
+ dst = z->input;
658
+ RBASIC(dst)->klass = rb_cString;
659
+ }
660
+ z->input = Qnil;
661
+ return dst;
662
+ }
663
+
664
+ static void
665
+ zstream_reset(z)
666
+ struct zstream *z;
667
+ {
668
+ int err;
669
+
670
+ err = z->func->reset(&z->stream);
671
+ if (err != Z_OK) {
672
+ raise_zlib_error(err, z->stream.msg);
673
+ }
674
+ z->flags = ZSTREAM_FLAG_READY;
675
+ z->buf = Qnil;
676
+ z->buf_filled = 0;
677
+ z->stream.next_out = 0;
678
+ z->stream.avail_out = 0;
679
+ zstream_reset_input(z);
680
+ }
681
+
682
+ static VALUE
683
+ zstream_end(z)
684
+ struct zstream *z;
685
+ {
686
+ int err;
687
+
688
+ if (!ZSTREAM_IS_READY(z)) {
689
+ rb_warning("attempt to close uninitialized zstream; ignored.");
690
+ return Qnil;
691
+ }
692
+ if (z->flags & ZSTREAM_FLAG_IN_STREAM) {
693
+ rb_warning("attempt to close unfinished zstream; reset forced.");
694
+ zstream_reset(z);
695
+ }
696
+
697
+ zstream_reset_input(z);
698
+ err = z->func->end(&z->stream);
699
+ if (err != Z_OK) {
700
+ raise_zlib_error(err, z->stream.msg);
701
+ }
702
+ z->flags = 0;
703
+ return Qnil;
704
+ }
705
+
706
+ static void
707
+ zstream_run(z, src, len, flush)
708
+ struct zstream *z;
709
+ Bytef *src;
710
+ uInt len;
711
+ int flush;
712
+ {
713
+ uInt n;
714
+ int err;
715
+ volatile VALUE guard;
716
+
717
+ if (NIL_P(z->input) && len == 0) {
718
+ z->stream.next_in = "";
719
+ z->stream.avail_in = 0;
720
+ }
721
+ else {
722
+ zstream_append_input(z, src, len);
723
+ z->stream.next_in = RSTRING(z->input)->ptr;
724
+ z->stream.avail_in = RSTRING(z->input)->len;
725
+ /* keep reference to `z->input' so as not to be garbage collected
726
+ after zstream_reset_input() and prevent `z->stream.next_in'
727
+ from dangling. */
728
+ guard = z->input;
729
+ }
730
+
731
+ if (z->stream.avail_out == 0) {
732
+ zstream_expand_buffer(z);
733
+ }
734
+
735
+ for (;;) {
736
+ n = z->stream.avail_out;
737
+ err = z->func->run(&z->stream, flush);
738
+ z->buf_filled += n - z->stream.avail_out;
739
+ rb_thread_schedule();
740
+
741
+ if (err == Z_STREAM_END) {
742
+ z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
743
+ z->flags |= ZSTREAM_FLAG_FINISHED;
744
+ break;
745
+ }
746
+ if (err != Z_OK) {
747
+ if (flush != Z_FINISH && err == Z_BUF_ERROR
748
+ && z->stream.avail_out > 0) {
749
+ z->flags |= ZSTREAM_FLAG_IN_STREAM;
750
+ break;
751
+ }
752
+ zstream_reset_input(z);
753
+ if (z->stream.avail_in > 0) {
754
+ zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
755
+ }
756
+ raise_zlib_error(err, z->stream.msg);
757
+ }
758
+ if (z->stream.avail_out > 0) {
759
+ z->flags |= ZSTREAM_FLAG_IN_STREAM;
760
+ break;
761
+ }
762
+ zstream_expand_buffer(z);
763
+ }
764
+
765
+ zstream_reset_input(z);
766
+ if (z->stream.avail_in > 0) {
767
+ zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
768
+ guard = Qnil; /* prevent tail call to make guard effective */
769
+ }
770
+ }
771
+
772
+ static VALUE
773
+ zstream_sync(z, src, len)
774
+ struct zstream *z;
775
+ Bytef *src;
776
+ uInt len;
777
+ {
778
+ VALUE rest;
779
+ int err;
780
+
781
+ if (!NIL_P(z->input)) {
782
+ z->stream.next_in = RSTRING(z->input)->ptr;
783
+ z->stream.avail_in = RSTRING(z->input)->len;
784
+ err = inflateSync(&z->stream);
785
+ if (err == Z_OK) {
786
+ zstream_discard_input(z,
787
+ RSTRING(z->input)->len - z->stream.avail_in);
788
+ zstream_append_input(z, src, len);
789
+ return Qtrue;
790
+ }
791
+ zstream_reset_input(z);
792
+ if (err != Z_DATA_ERROR) {
793
+ rest = rb_str_new(z->stream.next_in, z->stream.avail_in);
794
+ raise_zlib_error(err, z->stream.msg);
795
+ }
796
+ }
797
+
798
+ if (len <= 0) return Qfalse;
799
+
800
+ z->stream.next_in = src;
801
+ z->stream.avail_in = len;
802
+ err = inflateSync(&z->stream);
803
+ if (err == Z_OK) {
804
+ zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
805
+ return Qtrue;
806
+ }
807
+ if (err != Z_DATA_ERROR) {
808
+ rest = rb_str_new(z->stream.next_in, z->stream.avail_in);
809
+ raise_zlib_error(err, z->stream.msg);
810
+ }
811
+ return Qfalse;
812
+ }
813
+
814
+ static void
815
+ zstream_mark(z)
816
+ struct zstream *z;
817
+ {
818
+ rb_gc_mark(z->buf);
819
+ rb_gc_mark(z->input);
820
+ }
821
+
822
+ static void
823
+ zstream_finalize(z)
824
+ struct zstream *z;
825
+ {
826
+ int err = z->func->end(&z->stream);
827
+ if (err == Z_STREAM_ERROR)
828
+ finalizer_warn("the stream state was inconsistent.");
829
+ if (err == Z_DATA_ERROR)
830
+ finalizer_warn("the stream was freed prematurely.");
831
+ }
832
+
833
+ static void
834
+ zstream_free(z)
835
+ struct zstream *z;
836
+ {
837
+ if (ZSTREAM_IS_READY(z)) {
838
+ zstream_finalize(z);
839
+ }
840
+ free(z);
841
+ }
842
+
843
+ static VALUE
844
+ zstream_new(klass, funcs)
845
+ VALUE klass;
846
+ const struct zstream_funcs *funcs;
847
+ {
848
+ VALUE obj;
849
+ struct zstream *z;
850
+
851
+ obj = Data_Make_Struct(klass, struct zstream,
852
+ zstream_mark, zstream_free, z);
853
+ zstream_init(z, funcs);
854
+ return obj;
855
+ }
856
+
857
+ #define zstream_deflate_new(klass) zstream_new((klass), &deflate_funcs)
858
+ #define zstream_inflate_new(klass) zstream_new((klass), &inflate_funcs)
859
+
860
+ static struct zstream *
861
+ get_zstream(obj)
862
+ VALUE obj;
863
+ {
864
+ struct zstream *z;
865
+
866
+ Data_Get_Struct(obj, struct zstream, z);
867
+ if (!ZSTREAM_IS_READY(z)) {
868
+ rb_raise(cZError, "stream is not ready");
869
+ }
870
+ return z;
871
+ }
872
+
873
+
874
+ /* ------------------------------------------------------------------------- */
875
+
876
+ /*
877
+ * Document-class: Zlib::ZStream
878
+ *
879
+ * Zlib::ZStream is the abstract class for the stream which handles the
880
+ * compressed data. The operations are defined in the subclasses:
881
+ * Zlib::Deflate for compression, and Zlib::Inflate for decompression.
882
+ *
883
+ * An instance of Zlib::ZStream has one stream (struct zstream in the source)
884
+ * and two variable-length buffers which associated to the input (next_in) of
885
+ * the stream and the output (next_out) of the stream. In this document,
886
+ * "input buffer" means the buffer for input, and "output buffer" means the
887
+ * buffer for output.
888
+ *
889
+ * Data input into an instance of Zlib::ZStream are temporally stored into
890
+ * the end of input buffer, and then data in input buffer are processed from
891
+ * the beginning of the buffer until no more output from the stream is
892
+ * produced (i.e. until avail_out > 0 after processing). During processing,
893
+ * output buffer is allocated and expanded automatically to hold all output
894
+ * data.
895
+ *
896
+ * Some particular instance methods consume the data in output buffer and
897
+ * return them as a String.
898
+ *
899
+ * Here is an ascii art for describing above:
900
+ *
901
+ * +================ an instance of Zlib::ZStream ================+
902
+ * || ||
903
+ * || +--------+ +-------+ +--------+ ||
904
+ * || +--| output |<---------|zstream|<---------| input |<--+ ||
905
+ * || | | buffer | next_out+-------+next_in | buffer | | ||
906
+ * || | +--------+ +--------+ | ||
907
+ * || | | ||
908
+ * +===|======================================================|===+
909
+ * | |
910
+ * v |
911
+ * "output data" "input data"
912
+ *
913
+ * If an error occurs during processing input buffer, an exception which is a
914
+ * subclass of Zlib::Error is raised. At that time, both input and output
915
+ * buffer keep their conditions at the time when the error occurs.
916
+ *
917
+ * == Method Catalogue
918
+ *
919
+ * Many of the methods in this class are fairly low-level and unlikely to be
920
+ * of interest to users. In fact, users are unlikely to use this class
921
+ * directly; rather they will be interested in Zlib::Inflate and
922
+ * Zlib::Deflate.
923
+ *
924
+ * The higher level methods are listed below.
925
+ *
926
+ * - #total_in
927
+ * - #total_out
928
+ * - #data_type
929
+ * - #adler
930
+ * - #reset
931
+ * - #finish
932
+ * - #finished?
933
+ * - #close
934
+ * - #closed?
935
+ */
936
+
937
+ /*
938
+ * Closes the stream. All operations on the closed stream will raise an
939
+ * exception.
940
+ */
941
+ static VALUE
942
+ rb_zstream_end(obj)
943
+ VALUE obj;
944
+ {
945
+ zstream_end(get_zstream(obj));
946
+ return Qnil;
947
+ }
948
+
949
+ /*
950
+ * Resets and initializes the stream. All data in both input and output buffer
951
+ * are discarded.
952
+ */
953
+ static VALUE
954
+ rb_zstream_reset(obj)
955
+ VALUE obj;
956
+ {
957
+ zstream_reset(get_zstream(obj));
958
+ return Qnil;
959
+ }
960
+
961
+ /*
962
+ * Finishes the stream and flushes output buffer. See Zlib::Deflate#finish and
963
+ * Zlib::Inflate#finish for details of this behavior.
964
+ */
965
+ static VALUE
966
+ rb_zstream_finish(obj)
967
+ VALUE obj;
968
+ {
969
+ struct zstream *z = get_zstream(obj);
970
+ VALUE dst;
971
+
972
+ zstream_run(z, "", 0, Z_FINISH);
973
+ dst = zstream_detach_buffer(z);
974
+
975
+ OBJ_INFECT(dst, obj);
976
+ return dst;
977
+ }
978
+
979
+ /*
980
+ * Flushes input buffer and returns all data in that buffer.
981
+ */
982
+ static VALUE
983
+ rb_zstream_flush_next_in(obj)
984
+ VALUE obj;
985
+ {
986
+ struct zstream *z;
987
+ VALUE dst;
988
+
989
+ Data_Get_Struct(obj, struct zstream, z);
990
+ dst = zstream_detach_input(z);
991
+ OBJ_INFECT(dst, obj);
992
+ return dst;
993
+ }
994
+
995
+ /*
996
+ * Flushes output buffer and returns all data in that buffer.
997
+ */
998
+ static VALUE
999
+ rb_zstream_flush_next_out(obj)
1000
+ VALUE obj;
1001
+ {
1002
+ struct zstream *z;
1003
+ VALUE dst;
1004
+
1005
+ Data_Get_Struct(obj, struct zstream, z);
1006
+ dst = zstream_detach_buffer(z);
1007
+ OBJ_INFECT(dst, obj);
1008
+ return dst;
1009
+ }
1010
+
1011
+ /*
1012
+ * Returns number of bytes of free spaces in output buffer. Because the free
1013
+ * space is allocated automatically, this method returns 0 normally.
1014
+ */
1015
+ static VALUE
1016
+ rb_zstream_avail_out(obj)
1017
+ VALUE obj;
1018
+ {
1019
+ struct zstream *z;
1020
+ Data_Get_Struct(obj, struct zstream, z);
1021
+ return rb_uint2inum(z->stream.avail_out);
1022
+ }
1023
+
1024
+ /*
1025
+ * Allocates +size+ bytes of free space in the output buffer. If there are more
1026
+ * than +size+ bytes already in the buffer, the buffer is truncated. Because
1027
+ * free space is allocated automatically, you usually don't need to use this
1028
+ * method.
1029
+ */
1030
+ static VALUE
1031
+ rb_zstream_set_avail_out(obj, size)
1032
+ VALUE obj, size;
1033
+ {
1034
+ struct zstream *z = get_zstream(obj);
1035
+
1036
+ Check_Type(size, T_FIXNUM);
1037
+ zstream_expand_buffer_into(z, FIX2INT(size));
1038
+ return size;
1039
+ }
1040
+
1041
+ /*
1042
+ * Returns bytes of data in the input buffer. Normally, returns 0.
1043
+ */
1044
+ static VALUE
1045
+ rb_zstream_avail_in(obj)
1046
+ VALUE obj;
1047
+ {
1048
+ struct zstream *z;
1049
+ Data_Get_Struct(obj, struct zstream, z);
1050
+ return INT2FIX(NIL_P(z->input) ? 0 : (int)(RSTRING(z->input)->len));
1051
+ }
1052
+
1053
+ /*
1054
+ * Returns the total bytes of the input data to the stream. FIXME
1055
+ */
1056
+ static VALUE
1057
+ rb_zstream_total_in(obj)
1058
+ VALUE obj;
1059
+ {
1060
+ return rb_uint2inum(get_zstream(obj)->stream.total_in);
1061
+ }
1062
+
1063
+ /*
1064
+ * Returns the total bytes of the output data from the stream. FIXME
1065
+ */
1066
+ static VALUE
1067
+ rb_zstream_total_out(obj)
1068
+ VALUE obj;
1069
+ {
1070
+ return rb_uint2inum(get_zstream(obj)->stream.total_out);
1071
+ }
1072
+
1073
+ /*
1074
+ * Guesses the type of the data which have been inputed into the stream. The
1075
+ * returned value is either <tt>Zlib::BINARY</tt>, <tt>Zlib::ASCII</tt>, or
1076
+ * <tt>Zlib::UNKNOWN</tt>.
1077
+ */
1078
+ static VALUE
1079
+ rb_zstream_data_type(obj)
1080
+ VALUE obj;
1081
+ {
1082
+ return INT2FIX(get_zstream(obj)->stream.data_type);
1083
+ }
1084
+
1085
+ /*
1086
+ * Returns the adler-32 checksum.
1087
+ */
1088
+ static VALUE
1089
+ rb_zstream_adler(obj)
1090
+ VALUE obj;
1091
+ {
1092
+ return rb_uint2inum(get_zstream(obj)->stream.adler);
1093
+ }
1094
+
1095
+ /*
1096
+ * Returns true if the stream is finished.
1097
+ */
1098
+ static VALUE
1099
+ rb_zstream_finished_p(obj)
1100
+ VALUE obj;
1101
+ {
1102
+ return ZSTREAM_IS_FINISHED(get_zstream(obj)) ? Qtrue : Qfalse;
1103
+ }
1104
+
1105
+ /*
1106
+ * Returns true if the stream is closed.
1107
+ */
1108
+ static VALUE
1109
+ rb_zstream_closed_p(obj)
1110
+ VALUE obj;
1111
+ {
1112
+ struct zstream *z;
1113
+ Data_Get_Struct(obj, struct zstream, z);
1114
+ return ZSTREAM_IS_READY(z) ? Qfalse : Qtrue;
1115
+ }
1116
+
1117
+
1118
+ /* ------------------------------------------------------------------------- */
1119
+
1120
+ /*
1121
+ * Document-class: Zlib::Deflate
1122
+ *
1123
+ * Zlib::Deflate is the class for compressing data. See Zlib::Stream for more
1124
+ * information.
1125
+ */
1126
+
1127
+ #define FIXNUMARG(val, ifnil) \
1128
+ (NIL_P((val)) ? (ifnil) \
1129
+ : ((void)Check_Type((val), T_FIXNUM), FIX2INT((val))))
1130
+
1131
+ #define ARG_LEVEL(val) FIXNUMARG((val), Z_DEFAULT_COMPRESSION)
1132
+ #define ARG_WBITS(val) FIXNUMARG((val), MAX_WBITS)
1133
+ #define ARG_MEMLEVEL(val) FIXNUMARG((val), DEF_MEM_LEVEL)
1134
+ #define ARG_STRATEGY(val) FIXNUMARG((val), Z_DEFAULT_STRATEGY)
1135
+ #define ARG_FLUSH(val) FIXNUMARG((val), Z_NO_FLUSH)
1136
+
1137
+
1138
+ static VALUE
1139
+ rb_deflate_s_allocate(klass)
1140
+ VALUE klass;
1141
+ {
1142
+ return zstream_deflate_new(klass);
1143
+ }
1144
+
1145
+ /*
1146
+ * call-seq: Zlib::Deflate.new(level=nil, windowBits=nil, memlevel=nil, strategy=nil)
1147
+ *
1148
+ * Creates a new deflate stream for compression. See zlib.h for details of
1149
+ * each argument. If an argument is nil, the default value of that argument is
1150
+ * used.
1151
+ *
1152
+ * TODO: document better!
1153
+ */
1154
+ static VALUE
1155
+ rb_deflate_initialize(argc, argv, obj)
1156
+ int argc;
1157
+ VALUE *argv;
1158
+ VALUE obj;
1159
+ {
1160
+ struct zstream *z;
1161
+ VALUE level, wbits, memlevel, strategy;
1162
+ int err;
1163
+
1164
+ rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy);
1165
+ Data_Get_Struct(obj, struct zstream, z);
1166
+
1167
+ err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
1168
+ ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
1169
+ ARG_STRATEGY(strategy));
1170
+ if (err != Z_OK) {
1171
+ raise_zlib_error(err, z->stream.msg);
1172
+ }
1173
+ ZSTREAM_READY(z);
1174
+
1175
+ return obj;
1176
+ }
1177
+
1178
+ /*
1179
+ * Duplicates the deflate stream.
1180
+ */
1181
+ static VALUE
1182
+ rb_deflate_init_copy(self, orig)
1183
+ VALUE self, orig;
1184
+ {
1185
+ struct zstream *z1 = get_zstream(self);
1186
+ struct zstream *z2 = get_zstream(orig);
1187
+ int err;
1188
+
1189
+ err = deflateCopy(&z1->stream, &z2->stream);
1190
+ if (err != Z_OK) {
1191
+ raise_zlib_error(err, 0);
1192
+ }
1193
+ z1->flags = z2->flags;
1194
+
1195
+ return self;
1196
+ }
1197
+
1198
+ static VALUE
1199
+ deflate_run(args)
1200
+ VALUE args;
1201
+ {
1202
+ struct zstream *z = (struct zstream *)((VALUE *)args)[0];
1203
+ VALUE src = ((VALUE *)args)[1];
1204
+
1205
+ zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_FINISH);
1206
+ return zstream_detach_buffer(z);
1207
+ }
1208
+
1209
+ /*
1210
+ * call-seq: Zlib::Deflate.deflate(string[, level])
1211
+ *
1212
+ * Compresses the given +string+. Valid values of level are
1213
+ * <tt>Zlib::NO_COMPRESSION</tt>, <tt>Zlib::BEST_SPEED</tt>,
1214
+ * <tt>Zlib::BEST_COMPRESSION</tt>, <tt>Zlib::DEFAULT_COMPRESSION</tt>, and an
1215
+ * integer from 0 to 9.
1216
+ *
1217
+ * This method is almost equivalent to the following code:
1218
+ *
1219
+ * def deflate(string, level)
1220
+ * z = Zlib::Deflate.new(level)
1221
+ * dst = z.deflate(string, Zlib::FINISH)
1222
+ * z.close
1223
+ * dst
1224
+ * end
1225
+ *
1226
+ * TODO: what's default value of +level+?
1227
+ *
1228
+ */
1229
+ static VALUE
1230
+ rb_deflate_s_deflate(argc, argv, klass)
1231
+ int argc;
1232
+ VALUE *argv;
1233
+ VALUE klass;
1234
+ {
1235
+ struct zstream z;
1236
+ VALUE src, level, dst, args[2];
1237
+ int err, lev;
1238
+
1239
+ rb_scan_args(argc, argv, "11", &src, &level);
1240
+
1241
+ lev = ARG_LEVEL(level);
1242
+ StringValue(src);
1243
+ zstream_init_deflate(&z);
1244
+ err = deflateInit(&z.stream, lev);
1245
+ if (err != Z_OK) {
1246
+ raise_zlib_error(err, z.stream.msg);
1247
+ }
1248
+ ZSTREAM_READY(&z);
1249
+
1250
+ args[0] = (VALUE)&z;
1251
+ args[1] = src;
1252
+ dst = rb_ensure(deflate_run, (VALUE)args, zstream_end, (VALUE)&z);
1253
+
1254
+ OBJ_INFECT(dst, src);
1255
+ return dst;
1256
+ }
1257
+
1258
+ static void
1259
+ do_deflate(z, src, flush)
1260
+ struct zstream *z;
1261
+ VALUE src;
1262
+ int flush;
1263
+ {
1264
+ if (NIL_P(src)) {
1265
+ zstream_run(z, "", 0, Z_FINISH);
1266
+ return;
1267
+ }
1268
+ StringValue(src);
1269
+ if (flush != Z_NO_FLUSH || RSTRING(src)->len > 0) { /* prevent BUF_ERROR */
1270
+ zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, flush);
1271
+ }
1272
+ }
1273
+
1274
+ /*
1275
+ * call-seq: deflate(string[, flush])
1276
+ *
1277
+ * Inputs +string+ into the deflate stream and returns the output from the
1278
+ * stream. On calling this method, both the input and the output buffers of
1279
+ * the stream are flushed. If +string+ is nil, this method finishes the
1280
+ * stream, just like Zlib::ZStream#finish.
1281
+ *
1282
+ * The value of +flush+ should be either <tt>Zlib::NO_FLUSH</tt>,
1283
+ * <tt>Zlib::SYNC_FLUSH</tt>, <tt>Zlib::FULL_FLUSH</tt>, or
1284
+ * <tt>Zlib::FINISH</tt>. See zlib.h for details.
1285
+ *
1286
+ * TODO: document better!
1287
+ */
1288
+ static VALUE
1289
+ rb_deflate_deflate(argc, argv, obj)
1290
+ int argc;
1291
+ VALUE *argv;
1292
+ VALUE obj;
1293
+ {
1294
+ struct zstream *z = get_zstream(obj);
1295
+ VALUE src, flush, dst;
1296
+
1297
+ rb_scan_args(argc, argv, "11", &src, &flush);
1298
+ OBJ_INFECT(obj, src);
1299
+ do_deflate(z, src, ARG_FLUSH(flush));
1300
+ dst = zstream_detach_buffer(z);
1301
+
1302
+ OBJ_INFECT(dst, obj);
1303
+ return dst;
1304
+ }
1305
+
1306
+ /*
1307
+ * call-seq: << string
1308
+ *
1309
+ * Inputs +string+ into the deflate stream just like Zlib::Deflate#deflate, but
1310
+ * returns the Zlib::Deflate object itself. The output from the stream is
1311
+ * preserved in output buffer.
1312
+ */
1313
+ static VALUE
1314
+ rb_deflate_addstr(obj, src)
1315
+ VALUE obj, src;
1316
+ {
1317
+ OBJ_INFECT(obj, src);
1318
+ do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
1319
+ return obj;
1320
+ }
1321
+
1322
+ /*
1323
+ * call-seq: flush(flush)
1324
+ *
1325
+ * This method is equivalent to <tt>deflate('', flush)</tt>. If flush is omitted,
1326
+ * <tt>Zlib::SYNC_FLUSH</tt> is used as flush. This method is just provided
1327
+ * to improve the readability of your Ruby program.
1328
+ *
1329
+ * TODO: document better!
1330
+ */
1331
+ static VALUE
1332
+ rb_deflate_flush(argc, argv, obj)
1333
+ int argc;
1334
+ VALUE *argv;
1335
+ VALUE obj;
1336
+ {
1337
+ struct zstream *z = get_zstream(obj);
1338
+ VALUE v_flush, dst;
1339
+ int flush;
1340
+
1341
+ rb_scan_args(argc, argv, "01", &v_flush);
1342
+ flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
1343
+ if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
1344
+ zstream_run(z, "", 0, flush);
1345
+ }
1346
+ dst = zstream_detach_buffer(z);
1347
+
1348
+ OBJ_INFECT(dst, obj);
1349
+ return dst;
1350
+ }
1351
+
1352
+ /*
1353
+ * call-seq: params(level, strategy)
1354
+ *
1355
+ * Changes the parameters of the deflate stream. See zlib.h for details. The
1356
+ * output from the stream by changing the params is preserved in output
1357
+ * buffer.
1358
+ *
1359
+ * TODO: document better!
1360
+ */
1361
+ static VALUE
1362
+ rb_deflate_params(obj, v_level, v_strategy)
1363
+ VALUE obj, v_level, v_strategy;
1364
+ {
1365
+ struct zstream *z = get_zstream(obj);
1366
+ int level, strategy;
1367
+ int err;
1368
+
1369
+ level = ARG_LEVEL(v_level);
1370
+ strategy = ARG_STRATEGY(v_strategy);
1371
+
1372
+ err = deflateParams(&z->stream, level, strategy);
1373
+ while (err == Z_BUF_ERROR) {
1374
+ rb_warning("deflateParams() returned Z_BUF_ERROR");
1375
+ zstream_expand_buffer(z);
1376
+ err = deflateParams(&z->stream, level, strategy);
1377
+ }
1378
+ if (err != Z_OK) {
1379
+ raise_zlib_error(err, z->stream.msg);
1380
+ }
1381
+
1382
+ return Qnil;
1383
+ }
1384
+
1385
+ /*
1386
+ * call-seq: set_dictionary(string)
1387
+ *
1388
+ * Sets the preset dictionary and returns +string+. This method is available
1389
+ * just only after Zlib::Deflate.new or Zlib::ZStream#reset method was called.
1390
+ * See zlib.h for details.
1391
+ *
1392
+ * TODO: document better!
1393
+ */
1394
+ static VALUE
1395
+ rb_deflate_set_dictionary(obj, dic)
1396
+ VALUE obj, dic;
1397
+ {
1398
+ struct zstream *z = get_zstream(obj);
1399
+ VALUE src = dic;
1400
+ int err;
1401
+
1402
+ OBJ_INFECT(obj, dic);
1403
+ StringValue(src);
1404
+ err = deflateSetDictionary(&z->stream,
1405
+ RSTRING(src)->ptr, RSTRING(src)->len);
1406
+ if (err != Z_OK) {
1407
+ raise_zlib_error(err, z->stream.msg);
1408
+ }
1409
+
1410
+ return dic;
1411
+ }
1412
+
1413
+
1414
+ /* ------------------------------------------------------------------------- */
1415
+
1416
+ /*
1417
+ * Document-class: Zlib::Inflate
1418
+ *
1419
+ * Zlib:Inflate is the class for decompressing compressed data. Unlike
1420
+ * Zlib::Deflate, an instance of this class is not able to duplicate (clone,
1421
+ * dup) itself.
1422
+ */
1423
+
1424
+
1425
+
1426
+ static VALUE
1427
+ rb_inflate_s_allocate(klass)
1428
+ VALUE klass;
1429
+ {
1430
+ return zstream_inflate_new(klass);
1431
+ }
1432
+
1433
+ /*
1434
+ * call-seq: Zlib::Inflate.new(window_bits)
1435
+ *
1436
+ * Creates a new inflate stream for decompression. See zlib.h for details
1437
+ * of the argument. If +window_bits+ is +nil+, the default value is used.
1438
+ *
1439
+ * TODO: document better!
1440
+ */
1441
+ static VALUE
1442
+ rb_inflate_initialize(argc, argv, obj)
1443
+ int argc;
1444
+ VALUE *argv;
1445
+ VALUE obj;
1446
+ {
1447
+ struct zstream *z;
1448
+ VALUE wbits;
1449
+ int err;
1450
+
1451
+ rb_scan_args(argc, argv, "01", &wbits);
1452
+ Data_Get_Struct(obj, struct zstream, z);
1453
+
1454
+ err = inflateInit2(&z->stream, ARG_WBITS(wbits));
1455
+ if (err != Z_OK) {
1456
+ raise_zlib_error(err, z->stream.msg);
1457
+ }
1458
+ ZSTREAM_READY(z);
1459
+
1460
+ return obj;
1461
+ }
1462
+
1463
+ static VALUE
1464
+ inflate_run(args)
1465
+ VALUE args;
1466
+ {
1467
+ struct zstream *z = (struct zstream *)((VALUE *)args)[0];
1468
+ VALUE src = ((VALUE *)args)[1];
1469
+
1470
+ zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_SYNC_FLUSH);
1471
+ zstream_run(z, "", 0, Z_FINISH); /* for checking errors */
1472
+ return zstream_detach_buffer(z);
1473
+ }
1474
+
1475
+ /*
1476
+ * call-seq: Zlib::Inflate.inflate(string)
1477
+ *
1478
+ * Decompresses +string+. Raises a Zlib::NeedDict exception if a preset
1479
+ * dictionary is needed for decompression.
1480
+ *
1481
+ * This method is almost equivalent to the following code:
1482
+ *
1483
+ * def inflate(string)
1484
+ * zstream = Zlib::Inflate.new
1485
+ * buf = zstream.inflate(string)
1486
+ * zstream.finish
1487
+ * zstream.close
1488
+ * buf
1489
+ * end
1490
+ *
1491
+ */
1492
+ static VALUE
1493
+ rb_inflate_s_inflate(obj, src)
1494
+ VALUE obj, src;
1495
+ {
1496
+ struct zstream z;
1497
+ VALUE dst, args[2];
1498
+ int err;
1499
+
1500
+ StringValue(src);
1501
+ zstream_init_inflate(&z);
1502
+ err = inflateInit(&z.stream);
1503
+ if (err != Z_OK) {
1504
+ raise_zlib_error(err, z.stream.msg);
1505
+ }
1506
+ ZSTREAM_READY(&z);
1507
+
1508
+ args[0] = (VALUE)&z;
1509
+ args[1] = src;
1510
+ dst = rb_ensure(inflate_run, (VALUE)args, zstream_end, (VALUE)&z);
1511
+
1512
+ OBJ_INFECT(dst, src);
1513
+ return dst;
1514
+ }
1515
+
1516
+ static void
1517
+ do_inflate(z, src)
1518
+ struct zstream *z;
1519
+ VALUE src;
1520
+ {
1521
+ if (NIL_P(src)) {
1522
+ zstream_run(z, "", 0, Z_FINISH);
1523
+ return;
1524
+ }
1525
+ StringValue(src);
1526
+ if (RSTRING(src)->len > 0) { /* prevent Z_BUF_ERROR */
1527
+ zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_SYNC_FLUSH);
1528
+ }
1529
+ }
1530
+
1531
+ /*
1532
+ * call-seq: inflate(string)
1533
+ *
1534
+ * Inputs +string+ into the inflate stream and returns the output from the
1535
+ * stream. Calling this method, both the input and the output buffer of the
1536
+ * stream are flushed. If string is +nil+, this method finishes the stream,
1537
+ * just like Zlib::ZStream#finish.
1538
+ *
1539
+ * Raises a Zlib::NeedDict exception if a preset dictionary is needed to
1540
+ * decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
1541
+ * call this method again with an empty string. (<i>???</i>)
1542
+ *
1543
+ * TODO: document better!
1544
+ */
1545
+ static VALUE
1546
+ rb_inflate_inflate(obj, src)
1547
+ VALUE obj, src;
1548
+ {
1549
+ struct zstream *z = get_zstream(obj);
1550
+ VALUE dst;
1551
+
1552
+ OBJ_INFECT(obj, src);
1553
+
1554
+ if (ZSTREAM_IS_FINISHED(z)) {
1555
+ if (NIL_P(src)) {
1556
+ dst = zstream_detach_buffer(z);
1557
+ }
1558
+ else {
1559
+ StringValue(src);
1560
+ zstream_append_buffer2(z, src);
1561
+ dst = rb_str_new(0, 0);
1562
+ }
1563
+ }
1564
+ else {
1565
+ do_inflate(z, src);
1566
+ dst = zstream_detach_buffer(z);
1567
+ if (ZSTREAM_IS_FINISHED(z)) {
1568
+ zstream_passthrough_input(z);
1569
+ }
1570
+ }
1571
+
1572
+ OBJ_INFECT(dst, obj);
1573
+ return dst;
1574
+ }
1575
+
1576
+ /*
1577
+ * call-seq: << string
1578
+ *
1579
+ * Inputs +string+ into the inflate stream just like Zlib::Inflate#inflate, but
1580
+ * returns the Zlib::Inflate object itself. The output from the stream is
1581
+ * preserved in output buffer.
1582
+ */
1583
+ static VALUE
1584
+ rb_inflate_addstr(obj, src)
1585
+ VALUE obj, src;
1586
+ {
1587
+ struct zstream *z = get_zstream(obj);
1588
+
1589
+ OBJ_INFECT(obj, src);
1590
+
1591
+ if (ZSTREAM_IS_FINISHED(z)) {
1592
+ if (!NIL_P(src)) {
1593
+ StringValue(src);
1594
+ zstream_append_buffer2(z, src);
1595
+ }
1596
+ }
1597
+ else {
1598
+ do_inflate(z, src);
1599
+ if (ZSTREAM_IS_FINISHED(z)) {
1600
+ zstream_passthrough_input(z);
1601
+ }
1602
+ }
1603
+
1604
+ return obj;
1605
+ }
1606
+
1607
+ /*
1608
+ * call-seq: sync(string)
1609
+ *
1610
+ * Inputs +string+ into the end of input buffer and skips data until a full
1611
+ * flush point can be found. If the point is found in the buffer, this method
1612
+ * flushes the buffer and returns false. Otherwise it returns +true+ and the
1613
+ * following data of full flush point is preserved in the buffer.
1614
+ */
1615
+ static VALUE
1616
+ rb_inflate_sync(obj, src)
1617
+ VALUE obj, src;
1618
+ {
1619
+ struct zstream *z = get_zstream(obj);
1620
+
1621
+ OBJ_INFECT(obj, src);
1622
+ StringValue(src);
1623
+ return zstream_sync(z, RSTRING(src)->ptr, RSTRING(src)->len);
1624
+ }
1625
+
1626
+ /*
1627
+ * Quoted verbatim from original documentation:
1628
+ *
1629
+ * What is this?
1630
+ *
1631
+ * <tt>:)</tt>
1632
+ */
1633
+ static VALUE
1634
+ rb_inflate_sync_point_p(obj)
1635
+ VALUE obj;
1636
+ {
1637
+ struct zstream *z = get_zstream(obj);
1638
+ int err;
1639
+
1640
+ err = inflateSyncPoint(&z->stream);
1641
+ if (err == 1) {
1642
+ return Qtrue;
1643
+ }
1644
+ if (err != Z_OK) {
1645
+ raise_zlib_error(err, z->stream.msg);
1646
+ }
1647
+ return Qfalse;
1648
+ }
1649
+
1650
+ /*
1651
+ * Sets the preset dictionary and returns +string+. This method is available just
1652
+ * only after a Zlib::NeedDict exception was raised. See zlib.h for details.
1653
+ *
1654
+ * TODO: document better!
1655
+ */
1656
+ static VALUE
1657
+ rb_inflate_set_dictionary(obj, dic)
1658
+ VALUE obj, dic;
1659
+ {
1660
+ struct zstream *z = get_zstream(obj);
1661
+ VALUE src = dic;
1662
+ int err;
1663
+
1664
+ OBJ_INFECT(obj, dic);
1665
+ StringValue(src);
1666
+ err = inflateSetDictionary(&z->stream,
1667
+ RSTRING(src)->ptr, RSTRING(src)->len);
1668
+ if (err != Z_OK) {
1669
+ raise_zlib_error(err, z->stream.msg);
1670
+ }
1671
+
1672
+ return dic;
1673
+ }
1674
+
1675
+
1676
+
1677
+ #if GZIP_SUPPORT
1678
+
1679
+ /* NOTE: Features for gzip files of Ruby/zlib are written from scratch
1680
+ * and using undocumented feature of zlib, negative wbits.
1681
+ * I don't think gzFile APIs of zlib are good for Ruby.
1682
+ */
1683
+
1684
+ /*------- .gz file header --------*/
1685
+
1686
+ #define GZ_MAGIC1 0x1f
1687
+ #define GZ_MAGIC2 0x8b
1688
+ #define GZ_METHOD_DEFLATE 8
1689
+ #define GZ_FLAG_MULTIPART 0x2
1690
+ #define GZ_FLAG_EXTRA 0x4
1691
+ #define GZ_FLAG_ORIG_NAME 0x8
1692
+ #define GZ_FLAG_COMMENT 0x10
1693
+ #define GZ_FLAG_ENCRYPT 0x20
1694
+ #define GZ_FLAG_UNKNOWN_MASK 0xc0
1695
+
1696
+ #define GZ_EXTRAFLAG_FAST 0x4
1697
+ #define GZ_EXTRAFLAG_SLOW 0x2
1698
+
1699
+ /* from zutil.h */
1700
+ #define OS_MSDOS 0x00
1701
+ #define OS_AMIGA 0x01
1702
+ #define OS_VMS 0x02
1703
+ #define OS_UNIX 0x03
1704
+ #define OS_ATARI 0x05
1705
+ #define OS_OS2 0x06
1706
+ #define OS_MACOS 0x07
1707
+ #define OS_TOPS20 0x0a
1708
+ #define OS_WIN32 0x0b
1709
+
1710
+ #define OS_VMCMS 0x04
1711
+ #define OS_ZSYSTEM 0x08
1712
+ #define OS_CPM 0x09
1713
+ #define OS_QDOS 0x0c
1714
+ #define OS_RISCOS 0x0d
1715
+ #define OS_UNKNOWN 0xff
1716
+
1717
+ #ifndef OS_CODE
1718
+ #define OS_CODE OS_UNIX
1719
+ #endif
1720
+
1721
+ static ID id_write, id_read, id_flush, id_seek, id_close;
1722
+ static VALUE cGzError, cNoFooter, cCRCError, cLengthError;
1723
+
1724
+
1725
+
1726
+ /*-------- gzfile internal APIs --------*/
1727
+
1728
+ struct gzfile {
1729
+ struct zstream z;
1730
+ VALUE io;
1731
+ int level;
1732
+ time_t mtime; /* for header */
1733
+ int os_code; /* for header */
1734
+ VALUE orig_name; /* for header; must be a String */
1735
+ VALUE comment; /* for header; must be a String */
1736
+ unsigned long crc;
1737
+ int lineno;
1738
+ int ungetc;
1739
+ void (*end)(struct gzfile *);
1740
+ };
1741
+
1742
+ #define GZFILE_FLAG_SYNC ZSTREAM_FLAG_UNUSED
1743
+ #define GZFILE_FLAG_HEADER_FINISHED (ZSTREAM_FLAG_UNUSED << 1)
1744
+ #define GZFILE_FLAG_FOOTER_FINISHED (ZSTREAM_FLAG_UNUSED << 2)
1745
+
1746
+ #define GZFILE_IS_FINISHED(gz) \
1747
+ (ZSTREAM_IS_FINISHED(&gz->z) && (gz)->z.buf_filled == 0)
1748
+
1749
+ #define GZFILE_READ_SIZE 2048
1750
+
1751
+
1752
+ static void
1753
+ gzfile_mark(gz)
1754
+ struct gzfile *gz;
1755
+ {
1756
+ rb_gc_mark(gz->io);
1757
+ rb_gc_mark(gz->orig_name);
1758
+ rb_gc_mark(gz->comment);
1759
+ zstream_mark(&gz->z);
1760
+ }
1761
+
1762
+ static void
1763
+ gzfile_free(gz)
1764
+ struct gzfile *gz;
1765
+ {
1766
+ struct zstream *z = &gz->z;
1767
+
1768
+ if (ZSTREAM_IS_READY(z)) {
1769
+ if (z->func == &deflate_funcs) {
1770
+ finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
1771
+ }
1772
+ zstream_finalize(z);
1773
+ }
1774
+ free(gz);
1775
+ }
1776
+
1777
+ static VALUE
1778
+ gzfile_new(klass, funcs, endfunc)
1779
+ VALUE klass;
1780
+ const struct zstream_funcs *funcs;
1781
+ void (*endfunc) _((struct gzfile *));
1782
+ {
1783
+ VALUE obj;
1784
+ struct gzfile *gz;
1785
+
1786
+ obj = Data_Make_Struct(klass, struct gzfile, gzfile_mark, gzfile_free, gz);
1787
+ zstream_init(&gz->z, funcs);
1788
+ gz->io = Qnil;
1789
+ gz->level = 0;
1790
+ gz->mtime = 0;
1791
+ gz->os_code = OS_CODE;
1792
+ gz->orig_name = Qnil;
1793
+ gz->comment = Qnil;
1794
+ gz->crc = crc32(0, Z_NULL, 0);
1795
+ gz->lineno = 0;
1796
+ gz->ungetc = 0;
1797
+ gz->end = endfunc;
1798
+
1799
+ return obj;
1800
+ }
1801
+
1802
+ #define gzfile_writer_new(gz) gzfile_new((gz),&deflate_funcs,gzfile_writer_end)
1803
+ #define gzfile_reader_new(gz) gzfile_new((gz),&inflate_funcs,gzfile_reader_end)
1804
+
1805
+ static void
1806
+ gzfile_reset(gz)
1807
+ struct gzfile *gz;
1808
+ {
1809
+ zstream_reset(&gz->z);
1810
+ gz->crc = crc32(0, Z_NULL, 0);
1811
+ gz->lineno = 0;
1812
+ gz->ungetc = 0;
1813
+ }
1814
+
1815
+ static void
1816
+ gzfile_close(gz, closeflag)
1817
+ struct gzfile *gz;
1818
+ int closeflag;
1819
+ {
1820
+ VALUE io = gz->io;
1821
+
1822
+ gz->end(gz);
1823
+ gz->io = Qnil;
1824
+ gz->orig_name = Qnil;
1825
+ gz->comment = Qnil;
1826
+ if (closeflag && rb_respond_to(io, id_close)) {
1827
+ rb_funcall(io, id_close, 0);
1828
+ }
1829
+ }
1830
+
1831
+ static void
1832
+ gzfile_write_raw(gz)
1833
+ struct gzfile *gz;
1834
+ {
1835
+ VALUE str;
1836
+
1837
+ if (gz->z.buf_filled > 0) {
1838
+ str = zstream_detach_buffer(&gz->z);
1839
+ OBJ_TAINT(str); /* for safe */
1840
+ rb_funcall(gz->io, id_write, 1, str);
1841
+ if ((gz->z.flags & GZFILE_FLAG_SYNC)
1842
+ && rb_respond_to(gz->io, id_flush))
1843
+ rb_funcall(gz->io, id_flush, 0);
1844
+ }
1845
+ }
1846
+
1847
+ static VALUE
1848
+ gzfile_read_raw(gz)
1849
+ struct gzfile *gz;
1850
+ {
1851
+ VALUE str;
1852
+
1853
+ str = rb_funcall(gz->io, id_read, 1, INT2FIX(GZFILE_READ_SIZE));
1854
+ if (!NIL_P(str)) {
1855
+ Check_Type(str, T_STRING);
1856
+ }
1857
+ return str;
1858
+ }
1859
+
1860
+ static int
1861
+ gzfile_read_raw_ensure(gz, size)
1862
+ struct gzfile *gz;
1863
+ int size;
1864
+ {
1865
+ VALUE str;
1866
+
1867
+ while (NIL_P(gz->z.input) || RSTRING(gz->z.input)->len < size) {
1868
+ str = gzfile_read_raw(gz);
1869
+ if (NIL_P(str)) return Qfalse;
1870
+ zstream_append_input2(&gz->z, str);
1871
+ }
1872
+ return Qtrue;
1873
+ }
1874
+
1875
+ static char *
1876
+ gzfile_read_raw_until_zero(gz, offset)
1877
+ struct gzfile *gz;
1878
+ long offset;
1879
+ {
1880
+ VALUE str;
1881
+ char *p;
1882
+
1883
+ for (;;) {
1884
+ p = memchr(RSTRING(gz->z.input)->ptr + offset, '\0',
1885
+ RSTRING(gz->z.input)->len - offset);
1886
+ if (p) break;
1887
+ str = gzfile_read_raw(gz);
1888
+ if (NIL_P(str)) {
1889
+ rb_raise(cGzError, "unexpected end of file");
1890
+ }
1891
+ offset = RSTRING(gz->z.input)->len;
1892
+ zstream_append_input2(&gz->z, str);
1893
+ }
1894
+ return p;
1895
+ }
1896
+
1897
+ static unsigned int
1898
+ gzfile_get16(src)
1899
+ const unsigned char *src;
1900
+ {
1901
+ unsigned int n;
1902
+ n = *(src++) & 0xff;
1903
+ n |= (*(src++) & 0xff) << 8;
1904
+ return n;
1905
+ }
1906
+
1907
+ static unsigned long
1908
+ gzfile_get32(src)
1909
+ const unsigned char *src;
1910
+ {
1911
+ unsigned long n;
1912
+ n = *(src++) & 0xff;
1913
+ n |= (*(src++) & 0xff) << 8;
1914
+ n |= (*(src++) & 0xff) << 16;
1915
+ n |= (*(src++) & 0xffU) << 24;
1916
+ return n;
1917
+ }
1918
+
1919
+ static void
1920
+ gzfile_set32(n, dst)
1921
+ unsigned long n;
1922
+ unsigned char *dst;
1923
+ {
1924
+ *(dst++) = n & 0xff;
1925
+ *(dst++) = (n >> 8) & 0xff;
1926
+ *(dst++) = (n >> 16) & 0xff;
1927
+ *dst = (n >> 24) & 0xff;
1928
+ }
1929
+
1930
+ static void
1931
+ gzfile_make_header(gz)
1932
+ struct gzfile *gz;
1933
+ {
1934
+ unsigned char buf[10]; /* the size of gzip header */
1935
+ unsigned char flags = 0, extraflags = 0;
1936
+
1937
+ if (!NIL_P(gz->orig_name)) {
1938
+ flags |= GZ_FLAG_ORIG_NAME;
1939
+ }
1940
+ if (!NIL_P(gz->comment)) {
1941
+ flags |= GZ_FLAG_COMMENT;
1942
+ }
1943
+ if (gz->mtime == 0) {
1944
+ gz->mtime = time(0);
1945
+ }
1946
+
1947
+ if (gz->level == Z_BEST_SPEED) {
1948
+ extraflags |= GZ_EXTRAFLAG_FAST;
1949
+ }
1950
+ else if (gz->level == Z_BEST_COMPRESSION) {
1951
+ extraflags |= GZ_EXTRAFLAG_SLOW;
1952
+ }
1953
+
1954
+ buf[0] = GZ_MAGIC1;
1955
+ buf[1] = GZ_MAGIC2;
1956
+ buf[2] = GZ_METHOD_DEFLATE;
1957
+ buf[3] = flags;
1958
+ gzfile_set32(gz->mtime, &buf[4]);
1959
+ buf[8] = extraflags;
1960
+ buf[9] = gz->os_code;
1961
+ zstream_append_buffer(&gz->z, buf, sizeof(buf));
1962
+
1963
+ if (!NIL_P(gz->orig_name)) {
1964
+ zstream_append_buffer2(&gz->z, gz->orig_name);
1965
+ zstream_append_buffer(&gz->z, "\0", 1);
1966
+ }
1967
+ if (!NIL_P(gz->comment)) {
1968
+ zstream_append_buffer2(&gz->z, gz->comment);
1969
+ zstream_append_buffer(&gz->z, "\0", 1);
1970
+ }
1971
+
1972
+ gz->z.flags |= GZFILE_FLAG_HEADER_FINISHED;
1973
+ }
1974
+
1975
+ static void
1976
+ gzfile_make_footer(gz)
1977
+ struct gzfile *gz;
1978
+ {
1979
+ unsigned char buf[8]; /* 8 is the size of gzip footer */
1980
+
1981
+ gzfile_set32(gz->crc, buf);
1982
+ gzfile_set32(gz->z.stream.total_in, &buf[4]);
1983
+ zstream_append_buffer(&gz->z, buf, sizeof(buf));
1984
+ gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
1985
+ }
1986
+
1987
+ static void
1988
+ gzfile_read_header(gz)
1989
+ struct gzfile *gz;
1990
+ {
1991
+ const unsigned char *head;
1992
+ long len;
1993
+ char flags, *p;
1994
+
1995
+ if (!gzfile_read_raw_ensure(gz, 10)) { /* 10 is the size of gzip header */
1996
+ rb_raise(cGzError, "not in gzip format");
1997
+ }
1998
+
1999
+ head = RSTRING(gz->z.input)->ptr;
2000
+
2001
+ if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {
2002
+ rb_raise(cGzError, "not in gzip format");
2003
+ }
2004
+ if (head[2] != GZ_METHOD_DEFLATE) {
2005
+ rb_raise(cGzError, "unsupported compression method %d", head[2]);
2006
+ }
2007
+
2008
+ flags = head[3];
2009
+ if (flags & GZ_FLAG_MULTIPART) {
2010
+ rb_raise(cGzError, "multi-part gzip file is not supported");
2011
+ }
2012
+ else if (flags & GZ_FLAG_ENCRYPT) {
2013
+ rb_raise(cGzError, "encrypted gzip file is not supported");
2014
+ }
2015
+ else if (flags & GZ_FLAG_UNKNOWN_MASK) {
2016
+ rb_raise(cGzError, "unknown flags 0x%02x", flags);
2017
+ }
2018
+
2019
+ if (head[8] & GZ_EXTRAFLAG_FAST) {
2020
+ gz->level = Z_BEST_SPEED;
2021
+ }
2022
+ else if (head[8] & GZ_EXTRAFLAG_SLOW) {
2023
+ gz->level = Z_BEST_COMPRESSION;
2024
+ }
2025
+ else {
2026
+ gz->level = Z_DEFAULT_COMPRESSION;
2027
+ }
2028
+
2029
+ gz->mtime = gzfile_get32(&head[4]);
2030
+ gz->os_code = head[9];
2031
+ zstream_discard_input(&gz->z, 10);
2032
+
2033
+ if (flags & GZ_FLAG_EXTRA) {
2034
+ if (!gzfile_read_raw_ensure(gz, 2)) {
2035
+ rb_raise(cGzError, "unexpected end of file");
2036
+ }
2037
+ len = gzfile_get16(RSTRING(gz->z.input)->ptr);
2038
+ if (!gzfile_read_raw_ensure(gz, 2 + len)) {
2039
+ rb_raise(cGzError, "unexpected end of file");
2040
+ }
2041
+ zstream_discard_input(&gz->z, 2 + len);
2042
+ }
2043
+ if (flags & GZ_FLAG_ORIG_NAME) {
2044
+ p = gzfile_read_raw_until_zero(gz, 0);
2045
+ len = p - RSTRING(gz->z.input)->ptr;
2046
+ gz->orig_name = rb_str_new(RSTRING(gz->z.input)->ptr, len);
2047
+ OBJ_TAINT(gz->orig_name); /* for safe */
2048
+ zstream_discard_input(&gz->z, len + 1);
2049
+ }
2050
+ if (flags & GZ_FLAG_COMMENT) {
2051
+ p = gzfile_read_raw_until_zero(gz, 0);
2052
+ len = p - RSTRING(gz->z.input)->ptr;
2053
+ gz->comment = rb_str_new(RSTRING(gz->z.input)->ptr, len);
2054
+ OBJ_TAINT(gz->comment); /* for safe */
2055
+ zstream_discard_input(&gz->z, len + 1);
2056
+ }
2057
+
2058
+ if (gz->z.input != Qnil && RSTRING(gz->z.input)->len > 0) {
2059
+ zstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);
2060
+ }
2061
+ }
2062
+
2063
+ static void
2064
+ gzfile_check_footer(gz)
2065
+ struct gzfile *gz;
2066
+ {
2067
+ unsigned long crc, length;
2068
+
2069
+ gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
2070
+
2071
+ if (!gzfile_read_raw_ensure(gz, 8)) { /* 8 is the size of gzip footer */
2072
+ rb_raise(cNoFooter, "footer is not found");
2073
+ }
2074
+
2075
+ crc = gzfile_get32(RSTRING(gz->z.input)->ptr);
2076
+ length = gzfile_get32(RSTRING(gz->z.input)->ptr + 4);
2077
+
2078
+ gz->z.stream.total_in += 8; /* to rewind correctly */
2079
+ zstream_discard_input(&gz->z, 8);
2080
+
2081
+ if (gz->crc != crc) {
2082
+ rb_raise(cCRCError, "invalid compressed data -- crc error");
2083
+ }
2084
+ if (gz->z.stream.total_out != length) {
2085
+ rb_raise(cLengthError, "invalid compressed data -- length error");
2086
+ }
2087
+ }
2088
+
2089
+ static void
2090
+ gzfile_write(gz, str, len)
2091
+ struct gzfile *gz;
2092
+ Bytef *str;
2093
+ uInt len;
2094
+ {
2095
+ if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2096
+ gzfile_make_header(gz);
2097
+ }
2098
+
2099
+ if (len > 0 || (gz->z.flags & GZFILE_FLAG_SYNC)) {
2100
+ gz->crc = crc32(gz->crc, str, len);
2101
+ zstream_run(&gz->z, str, len, (gz->z.flags & GZFILE_FLAG_SYNC)
2102
+ ? Z_SYNC_FLUSH : Z_NO_FLUSH);
2103
+ }
2104
+ gzfile_write_raw(gz);
2105
+ }
2106
+
2107
+ static long
2108
+ gzfile_read_more(gz)
2109
+ struct gzfile *gz;
2110
+ {
2111
+ volatile VALUE str;
2112
+
2113
+ while (!ZSTREAM_IS_FINISHED(&gz->z)) {
2114
+ str = gzfile_read_raw(gz);
2115
+ if (NIL_P(str)) {
2116
+ if (!ZSTREAM_IS_FINISHED(&gz->z)) {
2117
+ rb_raise(cGzError, "unexpected end of file");
2118
+ }
2119
+ break;
2120
+ }
2121
+ if (RSTRING(str)->len > 0) { /* prevent Z_BUF_ERROR */
2122
+ zstream_run(&gz->z, RSTRING(str)->ptr, RSTRING(str)->len,
2123
+ Z_SYNC_FLUSH);
2124
+ }
2125
+ if (gz->z.buf_filled > 0) break;
2126
+ }
2127
+ return gz->z.buf_filled;
2128
+ }
2129
+
2130
+ static void
2131
+ gzfile_calc_crc(gz, str)
2132
+ struct gzfile *gz;
2133
+ VALUE str;
2134
+ {
2135
+ if (RSTRING(str)->len <= gz->ungetc) {
2136
+ gz->ungetc -= RSTRING(str)->len;
2137
+ }
2138
+ else {
2139
+ gz->crc = crc32(gz->crc, RSTRING(str)->ptr + gz->ungetc,
2140
+ RSTRING(str)->len - gz->ungetc);
2141
+ gz->ungetc = 0;
2142
+ }
2143
+ }
2144
+
2145
+ static VALUE
2146
+ gzfile_read(gz, len)
2147
+ struct gzfile *gz;
2148
+ int len;
2149
+ {
2150
+ VALUE dst;
2151
+
2152
+ if (len < 0)
2153
+ rb_raise(rb_eArgError, "negative length %d given", len);
2154
+ if (len == 0)
2155
+ return rb_str_new(0, 0);
2156
+ while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
2157
+ gzfile_read_more(gz);
2158
+ }
2159
+ if (GZFILE_IS_FINISHED(gz)) {
2160
+ if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2161
+ gzfile_check_footer(gz);
2162
+ }
2163
+ return Qnil;
2164
+ }
2165
+
2166
+ dst = zstream_shift_buffer(&gz->z, len);
2167
+ gzfile_calc_crc(gz, dst);
2168
+
2169
+ OBJ_TAINT(dst); /* for safe */
2170
+ return dst;
2171
+ }
2172
+
2173
+ static VALUE
2174
+ gzfile_read_all(gz)
2175
+ struct gzfile *gz;
2176
+ {
2177
+ VALUE dst;
2178
+
2179
+ while (!ZSTREAM_IS_FINISHED(&gz->z)) {
2180
+ gzfile_read_more(gz);
2181
+ }
2182
+ if (GZFILE_IS_FINISHED(gz)) {
2183
+ if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2184
+ gzfile_check_footer(gz);
2185
+ }
2186
+ return rb_str_new(0, 0);
2187
+ }
2188
+
2189
+ dst = zstream_detach_buffer(&gz->z);
2190
+ gzfile_calc_crc(gz, dst);
2191
+
2192
+ OBJ_TAINT(dst); /* for safe */
2193
+ return dst;
2194
+ }
2195
+
2196
+ static void
2197
+ gzfile_ungetc(gz, c)
2198
+ struct gzfile *gz;
2199
+ int c;
2200
+ {
2201
+ zstream_buffer_ungetc(&gz->z, c);
2202
+ gz->ungetc++;
2203
+ }
2204
+
2205
+ static VALUE
2206
+ gzfile_writer_end_run(arg)
2207
+ VALUE arg;
2208
+ {
2209
+ struct gzfile *gz = (struct gzfile *)arg;
2210
+
2211
+ if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2212
+ gzfile_make_header(gz);
2213
+ }
2214
+
2215
+ zstream_run(&gz->z, "", 0, Z_FINISH);
2216
+ gzfile_make_footer(gz);
2217
+ gzfile_write_raw(gz);
2218
+
2219
+ return Qnil;
2220
+ }
2221
+
2222
+ static void
2223
+ gzfile_writer_end(gz)
2224
+ struct gzfile *gz;
2225
+ {
2226
+ if (ZSTREAM_IS_CLOSING(&gz->z)) return;
2227
+ gz->z.flags |= ZSTREAM_FLAG_CLOSING;
2228
+
2229
+ rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
2230
+ }
2231
+
2232
+ static VALUE
2233
+ gzfile_reader_end_run(arg)
2234
+ VALUE arg;
2235
+ {
2236
+ struct gzfile *gz = (struct gzfile *)arg;
2237
+
2238
+ if (GZFILE_IS_FINISHED(gz)
2239
+ && !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2240
+ gzfile_check_footer(gz);
2241
+ }
2242
+
2243
+ return Qnil;
2244
+ }
2245
+
2246
+ static void
2247
+ gzfile_reader_end(gz)
2248
+ struct gzfile *gz;
2249
+ {
2250
+ if (ZSTREAM_IS_CLOSING(&gz->z)) return;
2251
+ gz->z.flags |= ZSTREAM_FLAG_CLOSING;
2252
+
2253
+ rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
2254
+ }
2255
+
2256
+ static void
2257
+ gzfile_reader_rewind(gz)
2258
+ struct gzfile *gz;
2259
+ {
2260
+ long n;
2261
+
2262
+ n = gz->z.stream.total_in;
2263
+ if (!NIL_P(gz->z.input)) {
2264
+ n += RSTRING(gz->z.input)->len;
2265
+ }
2266
+
2267
+ rb_funcall(gz->io, id_seek, 2, rb_int2inum(-n), INT2FIX(1));
2268
+ gzfile_reset(gz);
2269
+ }
2270
+
2271
+ static VALUE
2272
+ gzfile_reader_get_unused(gz)
2273
+ struct gzfile *gz;
2274
+ {
2275
+ VALUE str;
2276
+
2277
+ if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;
2278
+ if (!GZFILE_IS_FINISHED(gz)) return Qnil;
2279
+ if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2280
+ gzfile_check_footer(gz);
2281
+ }
2282
+ if (NIL_P(gz->z.input)) return Qnil;
2283
+
2284
+ str = rb_str_dup(gz->z.input);
2285
+ OBJ_TAINT(str); /* for safe */
2286
+ return str;
2287
+ }
2288
+
2289
+ static struct gzfile *
2290
+ get_gzfile(obj)
2291
+ VALUE obj;
2292
+ {
2293
+ struct gzfile *gz;
2294
+
2295
+ Data_Get_Struct(obj, struct gzfile, gz);
2296
+ if (!ZSTREAM_IS_READY(&gz->z)) {
2297
+ rb_raise(cGzError, "closed gzip stream");
2298
+ }
2299
+ return gz;
2300
+ }
2301
+
2302
+
2303
+ /* ------------------------------------------------------------------------- */
2304
+
2305
+ /*
2306
+ * Document-class: Zlib::GzipFile
2307
+ *
2308
+ * Zlib::GzipFile is an abstract class for handling a gzip formatted
2309
+ * compressed file. The operations are defined in the subclasses,
2310
+ * Zlib::GzipReader for reading, and Zlib::GzipWriter for writing.
2311
+ *
2312
+ * GzipReader should be used by associating an IO, or IO-like, object.
2313
+ */
2314
+
2315
+
2316
+ static VALUE
2317
+ gzfile_ensure_close(obj)
2318
+ VALUE obj;
2319
+ {
2320
+ struct gzfile *gz;
2321
+
2322
+ Data_Get_Struct(obj, struct gzfile, gz);
2323
+ if (ZSTREAM_IS_READY(&gz->z)) {
2324
+ gzfile_close(gz, 1);
2325
+ }
2326
+ return Qnil;
2327
+ }
2328
+
2329
+ /*
2330
+ * See Zlib::GzipReader#wrap and Zlib::GzipWriter#wrap.
2331
+ */
2332
+ static VALUE
2333
+ rb_gzfile_s_wrap(argc, argv, klass)
2334
+ int argc;
2335
+ VALUE *argv;
2336
+ VALUE klass;
2337
+ {
2338
+ VALUE obj = rb_class_new_instance(argc, argv, klass);
2339
+
2340
+ if (rb_block_given_p()) {
2341
+ return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);
2342
+ }
2343
+ else {
2344
+ return obj;
2345
+ }
2346
+ }
2347
+
2348
+ /*
2349
+ * See Zlib::GzipReader#open and Zlib::GzipWriter#open.
2350
+ */
2351
+ static VALUE
2352
+ gzfile_s_open(argc, argv, klass, mode)
2353
+ int argc;
2354
+ VALUE *argv;
2355
+ VALUE klass;
2356
+ const char *mode;
2357
+ {
2358
+ VALUE io, filename;
2359
+
2360
+ if (argc < 1) {
2361
+ rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
2362
+ }
2363
+ filename = argv[0];
2364
+ SafeStringValue(filename);
2365
+ io = rb_file_open(RSTRING(filename)->ptr, mode);
2366
+
2367
+ argv[0] = io;
2368
+ return rb_gzfile_s_wrap(argc, argv, klass);
2369
+ }
2370
+
2371
+ /*
2372
+ * Same as IO.
2373
+ */
2374
+ static VALUE
2375
+ rb_gzfile_to_io(obj)
2376
+ VALUE obj;
2377
+ {
2378
+ return get_gzfile(obj)->io;
2379
+ }
2380
+
2381
+ /*
2382
+ * Returns CRC value of the uncompressed data.
2383
+ */
2384
+ static VALUE
2385
+ rb_gzfile_crc(obj)
2386
+ VALUE obj;
2387
+ {
2388
+ return rb_uint2inum(get_gzfile(obj)->crc);
2389
+ }
2390
+
2391
+ /*
2392
+ * Returns last modification time recorded in the gzip file header.
2393
+ */
2394
+ static VALUE
2395
+ rb_gzfile_mtime(obj)
2396
+ VALUE obj;
2397
+ {
2398
+ return rb_time_new(get_gzfile(obj)->mtime, (time_t)0);
2399
+ }
2400
+
2401
+ /*
2402
+ * Returns compression level.
2403
+ */
2404
+ static VALUE
2405
+ rb_gzfile_level(obj)
2406
+ VALUE obj;
2407
+ {
2408
+ return INT2FIX(get_gzfile(obj)->level);
2409
+ }
2410
+
2411
+ /*
2412
+ * Returns OS code number recorded in the gzip file header.
2413
+ */
2414
+ static VALUE
2415
+ rb_gzfile_os_code(obj)
2416
+ VALUE obj;
2417
+ {
2418
+ return INT2FIX(get_gzfile(obj)->os_code);
2419
+ }
2420
+
2421
+ /*
2422
+ * Returns original filename recorded in the gzip file header, or +nil+ if
2423
+ * original filename is not present.
2424
+ */
2425
+ static VALUE
2426
+ rb_gzfile_orig_name(obj)
2427
+ VALUE obj;
2428
+ {
2429
+ VALUE str = get_gzfile(obj)->orig_name;
2430
+ if (!NIL_P(str)) {
2431
+ str = rb_str_dup(str);
2432
+ }
2433
+ OBJ_TAINT(str); /* for safe */
2434
+ return str;
2435
+ }
2436
+
2437
+ /*
2438
+ * Returns comments recorded in the gzip file header, or nil if the comments
2439
+ * is not present.
2440
+ */
2441
+ static VALUE
2442
+ rb_gzfile_comment(obj)
2443
+ VALUE obj;
2444
+ {
2445
+ VALUE str = get_gzfile(obj)->comment;
2446
+ if (!NIL_P(str)) {
2447
+ str = rb_str_dup(str);
2448
+ }
2449
+ OBJ_TAINT(str); /* for safe */
2450
+ return str;
2451
+ }
2452
+
2453
+ /*
2454
+ * ???
2455
+ */
2456
+ static VALUE
2457
+ rb_gzfile_lineno(obj)
2458
+ VALUE obj;
2459
+ {
2460
+ return INT2NUM(get_gzfile(obj)->lineno);
2461
+ }
2462
+
2463
+ /*
2464
+ * ???
2465
+ */
2466
+ static VALUE
2467
+ rb_gzfile_set_lineno(obj, lineno)
2468
+ VALUE obj, lineno;
2469
+ {
2470
+ struct gzfile *gz = get_gzfile(obj);
2471
+ gz->lineno = NUM2INT(lineno);
2472
+ return lineno;
2473
+ }
2474
+
2475
+ /*
2476
+ * ???
2477
+ */
2478
+ static VALUE
2479
+ rb_gzfile_set_mtime(obj, mtime)
2480
+ VALUE obj, mtime;
2481
+ {
2482
+ struct gzfile *gz = get_gzfile(obj);
2483
+ VALUE val;
2484
+
2485
+ if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
2486
+ rb_raise(cGzError, "header is already written");
2487
+ }
2488
+
2489
+ if (FIXNUM_P(time)) {
2490
+ gz->mtime = FIX2INT(mtime);
2491
+ }
2492
+ else {
2493
+ val = rb_Integer(mtime);
2494
+ gz->mtime = FIXNUM_P(val) ? FIX2INT(val) : rb_big2ulong(val);
2495
+ }
2496
+ return mtime;
2497
+ }
2498
+
2499
+ /*
2500
+ * ???
2501
+ */
2502
+ static VALUE
2503
+ rb_gzfile_set_orig_name(obj, str)
2504
+ VALUE obj, str;
2505
+ {
2506
+ struct gzfile *gz = get_gzfile(obj);
2507
+ VALUE s;
2508
+ char *p;
2509
+
2510
+ if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
2511
+ rb_raise(cGzError, "header is already written");
2512
+ }
2513
+ s = rb_str_dup(rb_str_to_str(str));
2514
+ p = memchr(RSTRING(s)->ptr, '\0', RSTRING(s)->len);
2515
+ if (p) {
2516
+ rb_str_resize(s, p - RSTRING(s)->ptr);
2517
+ }
2518
+ gz->orig_name = s;
2519
+ return str;
2520
+ }
2521
+
2522
+ /*
2523
+ * ???
2524
+ */
2525
+ static VALUE
2526
+ rb_gzfile_set_comment(obj, str)
2527
+ VALUE obj, str;
2528
+ {
2529
+ struct gzfile *gz = get_gzfile(obj);
2530
+ VALUE s;
2531
+ char *p;
2532
+
2533
+ if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
2534
+ rb_raise(cGzError, "header is already written");
2535
+ }
2536
+ s = rb_str_dup(rb_str_to_str(str));
2537
+ p = memchr(RSTRING(s)->ptr, '\0', RSTRING(s)->len);
2538
+ if (p) {
2539
+ rb_str_resize(s, p - RSTRING(s)->ptr);
2540
+ }
2541
+ gz->comment = s;
2542
+ return str;
2543
+ }
2544
+
2545
+ /*
2546
+ * Closes the GzipFile object. This method calls close method of the
2547
+ * associated IO object. Returns the associated IO object.
2548
+ */
2549
+ static VALUE
2550
+ rb_gzfile_close(obj)
2551
+ VALUE obj;
2552
+ {
2553
+ struct gzfile *gz = get_gzfile(obj);
2554
+ VALUE io;
2555
+
2556
+ io = gz->io;
2557
+ gzfile_close(gz, 1);
2558
+ return io;
2559
+ }
2560
+
2561
+ /*
2562
+ * Closes the GzipFile object. Unlike Zlib::GzipFile#close, this method never
2563
+ * calls the close method of the associated IO object. Returns the associated IO
2564
+ * object.
2565
+ */
2566
+ static VALUE
2567
+ rb_gzfile_finish(obj)
2568
+ VALUE obj;
2569
+ {
2570
+ struct gzfile *gz = get_gzfile(obj);
2571
+ VALUE io;
2572
+
2573
+ io = gz->io;
2574
+ gzfile_close(gz, 0);
2575
+ return io;
2576
+ }
2577
+
2578
+ /*
2579
+ * Same as IO.
2580
+ */
2581
+ static VALUE
2582
+ rb_gzfile_closed_p(obj)
2583
+ VALUE obj;
2584
+ {
2585
+ struct gzfile *gz;
2586
+ Data_Get_Struct(obj, struct gzfile, gz);
2587
+ return NIL_P(gz->io) ? Qtrue : Qfalse;
2588
+ }
2589
+
2590
+ /*
2591
+ * ???
2592
+ */
2593
+ static VALUE
2594
+ rb_gzfile_eof_p(obj)
2595
+ VALUE obj;
2596
+ {
2597
+ struct gzfile *gz = get_gzfile(obj);
2598
+ return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
2599
+ }
2600
+
2601
+ /*
2602
+ * Same as IO.
2603
+ */
2604
+ static VALUE
2605
+ rb_gzfile_sync(obj)
2606
+ VALUE obj;
2607
+ {
2608
+ return (get_gzfile(obj)->z.flags & GZFILE_FLAG_SYNC) ? Qtrue : Qfalse;
2609
+ }
2610
+
2611
+ /*
2612
+ * call-seq: sync = flag
2613
+ *
2614
+ * Same as IO. If flag is +true+, the associated IO object must respond to the
2615
+ * +flush+ method. While +sync+ mode is +true+, the compression ratio
2616
+ * decreases sharply.
2617
+ */
2618
+ static VALUE
2619
+ rb_gzfile_set_sync(obj, mode)
2620
+ VALUE obj, mode;
2621
+ {
2622
+ struct gzfile *gz = get_gzfile(obj);
2623
+
2624
+ if (RTEST(mode)) {
2625
+ gz->z.flags |= GZFILE_FLAG_SYNC;
2626
+ }
2627
+ else {
2628
+ gz->z.flags &= ~GZFILE_FLAG_SYNC;
2629
+ }
2630
+ return mode;
2631
+ }
2632
+
2633
+ /*
2634
+ * ???
2635
+ */
2636
+ static VALUE
2637
+ rb_gzfile_total_in(obj)
2638
+ VALUE obj;
2639
+ {
2640
+ return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
2641
+ }
2642
+
2643
+ /*
2644
+ * ???
2645
+ */
2646
+ static VALUE
2647
+ rb_gzfile_total_out(obj)
2648
+ VALUE obj;
2649
+ {
2650
+ struct gzfile *gz = get_gzfile(obj);
2651
+ return rb_uint2inum(gz->z.stream.total_out - gz->z.buf_filled);
2652
+ }
2653
+
2654
+
2655
+ /* ------------------------------------------------------------------------- */
2656
+
2657
+ /*
2658
+ * Document-class: Zlib::GzipWriter
2659
+ *
2660
+ * Zlib::GzipWriter is a class for writing gzipped files. GzipWriter should
2661
+ * be used with an instance of IO, or IO-like, object.
2662
+ *
2663
+ * For example:
2664
+ *
2665
+ * Zlib::GzipWriter.open('hoge.gz') do |gz|
2666
+ * gz.write 'jugemu jugemu gokou no surikire...'
2667
+ * end
2668
+ *
2669
+ * File.open('hoge.gz', 'w') do |f|
2670
+ * gz = Zlib::GzipWriter.new(f)
2671
+ * gz.write 'jugemu jugemu gokou no surikire...'
2672
+ * gz.close
2673
+ * end
2674
+ *
2675
+ * # TODO: test these. Are they equivalent? Can GzipWriter.new take a
2676
+ * # block?
2677
+ *
2678
+ * NOTE: Due to the limitation of Ruby's finalizer, you must explicitly close
2679
+ * GzipWriter objects by Zlib::GzipWriter#close etc. Otherwise, GzipWriter
2680
+ * will be not able to write the gzip footer and will generate a broken gzip
2681
+ * file.
2682
+ */
2683
+
2684
+ static VALUE
2685
+ rb_gzwriter_s_allocate(klass)
2686
+ VALUE klass;
2687
+ {
2688
+ return gzfile_writer_new(klass);
2689
+ }
2690
+
2691
+ /*
2692
+ * call-seq: Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... }
2693
+ *
2694
+ * Opens a file specified by +filename+ for writing gzip compressed data, and
2695
+ * returns a GzipWriter object associated with that file. Further details of
2696
+ * this method are found in Zlib::GzipWriter.new and Zlib::GzipWriter#wrap.
2697
+ */
2698
+ static VALUE
2699
+ rb_gzwriter_s_open(argc, argv, klass)
2700
+ int argc;
2701
+ VALUE *argv;
2702
+ VALUE klass;
2703
+ {
2704
+ return gzfile_s_open(argc, argv, klass, "wb");
2705
+ }
2706
+
2707
+ /*
2708
+ * call-seq: Zlib::GzipWriter.new(io, level, strategy)
2709
+ *
2710
+ * Creates a GzipWriter object associated with +io+. +level+ and +strategy+
2711
+ * should be the same as the arguments of Zlib::Deflate.new. The GzipWriter
2712
+ * object writes gzipped data to +io+. At least, +io+ must respond to the
2713
+ * +write+ method that behaves same as write method in IO class.
2714
+ */
2715
+ static VALUE
2716
+ rb_gzwriter_initialize(argc, argv, obj)
2717
+ int argc;
2718
+ VALUE *argv;
2719
+ VALUE obj;
2720
+ {
2721
+ struct gzfile *gz;
2722
+ VALUE io, level, strategy;
2723
+ int err;
2724
+
2725
+ rb_scan_args(argc, argv, "12", &io, &level, &strategy);
2726
+ Data_Get_Struct(obj, struct gzfile, gz);
2727
+
2728
+ /* this is undocumented feature of zlib */
2729
+ gz->level = ARG_LEVEL(level);
2730
+ err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
2731
+ -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
2732
+ if (err != Z_OK) {
2733
+ raise_zlib_error(err, gz->z.stream.msg);
2734
+ }
2735
+ gz->io = io;
2736
+ ZSTREAM_READY(&gz->z);
2737
+
2738
+ return obj;
2739
+ }
2740
+
2741
+ /*
2742
+ * call-seq: flush(flush=nil)
2743
+ *
2744
+ * Flushes all the internal buffers of the GzipWriter object. The meaning of
2745
+ * +flush+ is same as in Zlib::Deflate#deflate. <tt>Zlib::SYNC_FLUSH</tt> is used if
2746
+ * +flush+ is omitted. It is no use giving flush <tt>Zlib::NO_FLUSH</tt>.
2747
+ */
2748
+ static VALUE
2749
+ rb_gzwriter_flush(argc, argv, obj)
2750
+ int argc;
2751
+ VALUE *argv;
2752
+ VALUE obj;
2753
+ {
2754
+ struct gzfile *gz = get_gzfile(obj);
2755
+ VALUE v_flush;
2756
+ int flush;
2757
+
2758
+ rb_scan_args(argc, argv, "01", &v_flush);
2759
+
2760
+ flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
2761
+ if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
2762
+ zstream_run(&gz->z, "", 0, flush);
2763
+ }
2764
+
2765
+ gzfile_write_raw(gz);
2766
+ if (rb_respond_to(gz->io, id_flush)) {
2767
+ rb_funcall(gz->io, id_flush, 0);
2768
+ }
2769
+ return obj;
2770
+ }
2771
+
2772
+ /*
2773
+ * Same as IO.
2774
+ */
2775
+ static VALUE
2776
+ rb_gzwriter_write(obj, str)
2777
+ VALUE obj, str;
2778
+ {
2779
+ struct gzfile *gz = get_gzfile(obj);
2780
+
2781
+ if (TYPE(str) != T_STRING) {
2782
+ str = rb_obj_as_string(str);
2783
+ }
2784
+ gzfile_write(gz, RSTRING(str)->ptr, RSTRING(str)->len);
2785
+ return INT2FIX(RSTRING(str)->len);
2786
+ }
2787
+
2788
+ /*
2789
+ * Same as IO.
2790
+ */
2791
+ static VALUE
2792
+ rb_gzwriter_putc(obj, ch)
2793
+ VALUE obj, ch;
2794
+ {
2795
+ struct gzfile *gz = get_gzfile(obj);
2796
+ char c = NUM2CHR(ch);
2797
+
2798
+ gzfile_write(gz, &c, 1);
2799
+ return ch;
2800
+ }
2801
+
2802
+
2803
+
2804
+ /*
2805
+ * Document-method: <<
2806
+ * Same as IO.
2807
+ */
2808
+ #define rb_gzwriter_addstr rb_io_addstr
2809
+ /*
2810
+ * Document-method: printf
2811
+ * Same as IO.
2812
+ */
2813
+ #define rb_gzwriter_printf rb_io_printf
2814
+ /*
2815
+ * Document-method: print
2816
+ * Same as IO.
2817
+ */
2818
+ #define rb_gzwriter_print rb_io_print
2819
+ /*
2820
+ * Document-method: puts
2821
+ * Same as IO.
2822
+ */
2823
+ #define rb_gzwriter_puts rb_io_puts
2824
+
2825
+
2826
+ /* ------------------------------------------------------------------------- */
2827
+
2828
+ /*
2829
+ * Document-class: Zlib::GzipReader
2830
+ *
2831
+ * Zlib::GzipReader is the class for reading a gzipped file. GzipReader should
2832
+ * be used an IO, or -IO-lie, object.
2833
+ *
2834
+ * Zlib::GzipReader.open('hoge.gz') {|gz|
2835
+ * print gz.read
2836
+ * }
2837
+ *
2838
+ * File.open('hoge.gz') do |f|
2839
+ * gz = Zlib::GzipReader.new(f)
2840
+ * print gz.read
2841
+ * gz.close
2842
+ * end
2843
+ *
2844
+ * # TODO: test these. Are they equivalent? Can GzipReader.new take a
2845
+ * # block?
2846
+ *
2847
+ * == Method Catalogue
2848
+ *
2849
+ * The following methods in Zlib::GzipReader are just like their counterparts
2850
+ * in IO, but they raise Zlib::Error or Zlib::GzipFile::Error exception if an
2851
+ * error was found in the gzip file.
2852
+ * - #each
2853
+ * - #each_line
2854
+ * - #each_byte
2855
+ * - #gets
2856
+ * - #getc
2857
+ * - #lineno
2858
+ * - #lineno=
2859
+ * - #read
2860
+ * - #readchar
2861
+ * - #readline
2862
+ * - #readlines
2863
+ * - #ungetc
2864
+ *
2865
+ * Be careful of the footer of the gzip file. A gzip file has the checksum of
2866
+ * pre-compressed data in its footer. GzipReader checks all uncompressed data
2867
+ * against that checksum at the following cases, and if it fails, raises
2868
+ * <tt>Zlib::GzipFile::NoFooter</tt>, <tt>Zlib::GzipFile::CRCError</tt>, or
2869
+ * <tt>Zlib::GzipFile::LengthError</tt> exception.
2870
+ *
2871
+ * - When an reading request is received beyond the end of file (the end of
2872
+ * compressed data). That is, when Zlib::GzipReader#read,
2873
+ * Zlib::GzipReader#gets, or some other methods for reading returns nil.
2874
+ * - When Zlib::GzipFile#close method is called after the object reaches the
2875
+ * end of file.
2876
+ * - When Zlib::GzipReader#unused method is called after the object reaches
2877
+ * the end of file.
2878
+ *
2879
+ * The rest of the methods are adequately described in their own
2880
+ * documentation.
2881
+ */
2882
+
2883
+ static VALUE
2884
+ rb_gzreader_s_allocate(klass)
2885
+ VALUE klass;
2886
+ {
2887
+ return gzfile_reader_new(klass);
2888
+ }
2889
+
2890
+ /*
2891
+ * call-seq: Zlib::GzipReader.open(filename) {|gz| ... }
2892
+ *
2893
+ * Opens a file specified by +filename+ as a gzipped file, and returns a
2894
+ * GzipReader object associated with that file. Further details of this method
2895
+ * are in Zlib::GzipReader.new and ZLib::GzipReader.wrap.
2896
+ */
2897
+ static VALUE
2898
+ rb_gzreader_s_open(argc, argv, klass)
2899
+ int argc;
2900
+ VALUE *argv;
2901
+ VALUE klass;
2902
+ {
2903
+ return gzfile_s_open(argc, argv, klass, "rb");
2904
+ }
2905
+
2906
+ /*
2907
+ * call-seq: Zlib::GzipReader.new(io)
2908
+ *
2909
+ * Creates a GzipReader object associated with +io+. The GzipReader object reads
2910
+ * gzipped data from +io+, and parses/decompresses them. At least, +io+ must have
2911
+ * a +read+ method that behaves same as the +read+ method in IO class.
2912
+ *
2913
+ * If the gzip file header is incorrect, raises an Zlib::GzipFile::Error
2914
+ * exception.
2915
+ */
2916
+ static VALUE
2917
+ rb_gzreader_initialize(obj, io)
2918
+ VALUE obj, io;
2919
+ {
2920
+ struct gzfile *gz;
2921
+ int err;
2922
+
2923
+ Data_Get_Struct(obj, struct gzfile, gz);
2924
+
2925
+ /* this is undocumented feature of zlib */
2926
+ err = inflateInit2(&gz->z.stream, -MAX_WBITS);
2927
+ if (err != Z_OK) {
2928
+ raise_zlib_error(err, gz->z.stream.msg);
2929
+ }
2930
+ gz->io = io;
2931
+ ZSTREAM_READY(&gz->z);
2932
+ gzfile_read_header(gz);
2933
+
2934
+ return obj;
2935
+ }
2936
+
2937
+ /*
2938
+ * Resets the position of the file pointer to the point created the GzipReader
2939
+ * object. The associated IO object needs to respond to the +seek+ method.
2940
+ */
2941
+ static VALUE
2942
+ rb_gzreader_rewind(obj)
2943
+ VALUE obj;
2944
+ {
2945
+ struct gzfile *gz = get_gzfile(obj);
2946
+ gzfile_reader_rewind(gz);
2947
+ return INT2FIX(0);
2948
+ }
2949
+
2950
+ /*
2951
+ * Returns the rest of the data which had read for parsing gzip format, or
2952
+ * +nil+ if the whole gzip file is not parsed yet.
2953
+ */
2954
+ static VALUE
2955
+ rb_gzreader_unused(obj)
2956
+ VALUE obj;
2957
+ {
2958
+ struct gzfile *gz;
2959
+ Data_Get_Struct(obj, struct gzfile, gz);
2960
+ return gzfile_reader_get_unused(gz);
2961
+ }
2962
+
2963
+ /*
2964
+ * See Zlib::GzipReader documentation for a description.
2965
+ */
2966
+ static VALUE
2967
+ rb_gzreader_read(argc, argv, obj)
2968
+ int argc;
2969
+ VALUE *argv;
2970
+ VALUE obj;
2971
+ {
2972
+ struct gzfile *gz = get_gzfile(obj);
2973
+ VALUE vlen;
2974
+ int len;
2975
+
2976
+ rb_scan_args(argc, argv, "01", &vlen);
2977
+ if (NIL_P(vlen)) {
2978
+ return gzfile_read_all(gz);
2979
+ }
2980
+
2981
+ len = NUM2INT(vlen);
2982
+ if (len < 0) {
2983
+ rb_raise(rb_eArgError, "negative length %d given", len);
2984
+ }
2985
+ return gzfile_read(gz, len);
2986
+ }
2987
+
2988
+ /*
2989
+ * See Zlib::GzipReader documentation for a description.
2990
+ */
2991
+ static VALUE
2992
+ rb_gzreader_getc(obj)
2993
+ VALUE obj;
2994
+ {
2995
+ struct gzfile *gz = get_gzfile(obj);
2996
+ VALUE dst;
2997
+
2998
+ dst = gzfile_read(gz, 1);
2999
+ if (!NIL_P(dst)) {
3000
+ dst = INT2FIX((unsigned int)(RSTRING(dst)->ptr[0]) & 0xff);
3001
+ }
3002
+ return dst;
3003
+ }
3004
+
3005
+ /*
3006
+ * See Zlib::GzipReader documentation for a description.
3007
+ */
3008
+ static VALUE
3009
+ rb_gzreader_readchar(obj)
3010
+ VALUE obj;
3011
+ {
3012
+ VALUE dst;
3013
+ dst = rb_gzreader_getc(obj);
3014
+ if (NIL_P(dst)) {
3015
+ rb_raise(rb_eEOFError, "end of file reached");
3016
+ }
3017
+ return dst;
3018
+ }
3019
+
3020
+ /*
3021
+ * See Zlib::GzipReader documentation for a description.
3022
+ */
3023
+ static VALUE
3024
+ rb_gzreader_each_byte(obj)
3025
+ VALUE obj;
3026
+ {
3027
+ VALUE c;
3028
+ while (!NIL_P(c = rb_gzreader_getc(obj))) {
3029
+ rb_yield(c);
3030
+ }
3031
+ return Qnil;
3032
+ }
3033
+
3034
+ /*
3035
+ * See Zlib::GzipReader documentation for a description.
3036
+ */
3037
+ static VALUE
3038
+ rb_gzreader_ungetc(obj, ch)
3039
+ VALUE obj, ch;
3040
+ {
3041
+ struct gzfile *gz = get_gzfile(obj);
3042
+ gzfile_ungetc(gz, NUM2CHR(ch));
3043
+ return Qnil;
3044
+ }
3045
+
3046
+ static void
3047
+ gzreader_skip_linebreaks(gz)
3048
+ struct gzfile *gz;
3049
+ {
3050
+ VALUE str;
3051
+ char *p;
3052
+ int n;
3053
+
3054
+ while (gz->z.buf_filled == 0) {
3055
+ if (GZFILE_IS_FINISHED(gz)) return;
3056
+ gzfile_read_more(gz);
3057
+ }
3058
+ n = 0;
3059
+ p = RSTRING(gz->z.buf)->ptr;
3060
+
3061
+ while (n++, *(p++) == '\n') {
3062
+ if (n >= gz->z.buf_filled) {
3063
+ str = zstream_detach_buffer(&gz->z);
3064
+ gzfile_calc_crc(gz, str);
3065
+ while (gz->z.buf_filled == 0) {
3066
+ if (GZFILE_IS_FINISHED(gz)) return;
3067
+ gzfile_read_more(gz);
3068
+ }
3069
+ n = 0;
3070
+ p = RSTRING(gz->z.buf)->ptr;
3071
+ }
3072
+ }
3073
+
3074
+ str = zstream_shift_buffer(&gz->z, n - 1);
3075
+ gzfile_calc_crc(gz, str);
3076
+ }
3077
+
3078
+ static void
3079
+ rscheck(rsptr, rslen, rs)
3080
+ char *rsptr;
3081
+ long rslen;
3082
+ VALUE rs;
3083
+ {
3084
+ if (RSTRING(rs)->ptr != rsptr && RSTRING(rs)->len != rslen)
3085
+ rb_raise(rb_eRuntimeError, "rs modified");
3086
+ }
3087
+
3088
+ static VALUE
3089
+ gzreader_gets(argc, argv, obj)
3090
+ int argc;
3091
+ VALUE *argv;
3092
+ VALUE obj;
3093
+ {
3094
+ struct gzfile *gz = get_gzfile(obj);
3095
+ volatile VALUE rs;
3096
+ VALUE dst;
3097
+ char *rsptr, *p, *res;
3098
+ long rslen, n;
3099
+ int rspara;
3100
+
3101
+ if (argc == 0) {
3102
+ rs = rb_rs;
3103
+ }
3104
+ else {
3105
+ rb_scan_args(argc, argv, "1", &rs);
3106
+ if (!NIL_P(rs)) {
3107
+ Check_Type(rs, T_STRING);
3108
+ }
3109
+ }
3110
+
3111
+ if (NIL_P(rs)) {
3112
+ dst = gzfile_read_all(gz);
3113
+ if (RSTRING(dst)->len != 0) gz->lineno++;
3114
+ return dst;
3115
+ }
3116
+
3117
+ if (RSTRING(rs)->len == 0) {
3118
+ rsptr = "\n\n";
3119
+ rslen = 2;
3120
+ rspara = 1;
3121
+ } else {
3122
+ rsptr = RSTRING(rs)->ptr;
3123
+ rslen = RSTRING(rs)->len;
3124
+ rspara = 0;
3125
+ }
3126
+
3127
+ if (rspara) {
3128
+ gzreader_skip_linebreaks(gz);
3129
+ }
3130
+
3131
+ while (gz->z.buf_filled < rslen) {
3132
+ if (ZSTREAM_IS_FINISHED(&gz->z)) {
3133
+ if (gz->z.buf_filled > 0) gz->lineno++;
3134
+ return gzfile_read(gz, rslen);
3135
+ }
3136
+ gzfile_read_more(gz);
3137
+ }
3138
+
3139
+ p = RSTRING(gz->z.buf)->ptr;
3140
+ n = rslen;
3141
+ for (;;) {
3142
+ if (n > gz->z.buf_filled) {
3143
+ if (ZSTREAM_IS_FINISHED(&gz->z)) break;
3144
+ gzfile_read_more(gz);
3145
+ p = RSTRING(gz->z.buf)->ptr + n - rslen;
3146
+ }
3147
+ if (!rspara) rscheck(rsptr, rslen, rs);
3148
+ res = memchr(p, rsptr[0], (gz->z.buf_filled - n + 1));
3149
+ if (!res) {
3150
+ n = gz->z.buf_filled + 1;
3151
+ } else {
3152
+ n += (long)(res - p);
3153
+ p = res;
3154
+ if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
3155
+ p++, n++;
3156
+ }
3157
+ }
3158
+
3159
+ gz->lineno++;
3160
+ dst = gzfile_read(gz, n);
3161
+ if (rspara) {
3162
+ gzreader_skip_linebreaks(gz);
3163
+ }
3164
+
3165
+ return dst;
3166
+ }
3167
+
3168
+ /*
3169
+ * See Zlib::GzipReader documentation for a description.
3170
+ */
3171
+ static VALUE
3172
+ rb_gzreader_gets(argc, argv, obj)
3173
+ int argc;
3174
+ VALUE *argv;
3175
+ VALUE obj;
3176
+ {
3177
+ VALUE dst;
3178
+ dst = gzreader_gets(argc, argv, obj);
3179
+ if (!NIL_P(dst)) {
3180
+ rb_lastline_set(dst);
3181
+ }
3182
+ return dst;
3183
+ }
3184
+
3185
+ /*
3186
+ * See Zlib::GzipReader documentation for a description.
3187
+ */
3188
+ static VALUE
3189
+ rb_gzreader_readline(argc, argv, obj)
3190
+ int argc;
3191
+ VALUE *argv;
3192
+ VALUE obj;
3193
+ {
3194
+ VALUE dst;
3195
+ dst = rb_gzreader_gets(argc, argv, obj);
3196
+ if (NIL_P(dst)) {
3197
+ rb_raise(rb_eEOFError, "end of file reached");
3198
+ }
3199
+ return dst;
3200
+ }
3201
+
3202
+ /*
3203
+ * See Zlib::GzipReader documentation for a description.
3204
+ */
3205
+ static VALUE
3206
+ rb_gzreader_each(argc, argv, obj)
3207
+ int argc;
3208
+ VALUE *argv;
3209
+ VALUE obj;
3210
+ {
3211
+ VALUE str;
3212
+ while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
3213
+ rb_yield(str);
3214
+ }
3215
+ return obj;
3216
+ }
3217
+
3218
+ /*
3219
+ * See Zlib::GzipReader documentation for a description.
3220
+ */
3221
+ static VALUE
3222
+ rb_gzreader_readlines(argc, argv, obj)
3223
+ int argc;
3224
+ VALUE *argv;
3225
+ VALUE obj;
3226
+ {
3227
+ VALUE str, dst;
3228
+ dst = rb_ary_new();
3229
+ while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
3230
+ rb_ary_push(dst, str);
3231
+ }
3232
+ return dst;
3233
+ }
3234
+
3235
+ #endif /* GZIP_SUPPORT */
3236
+
3237
+
3238
+
3239
+ /*
3240
+ * The Zlib module contains several classes for compressing and decompressing
3241
+ * streams, and for working with "gzip" files.
3242
+ *
3243
+ * == Classes
3244
+ *
3245
+ * Following are the classes that are most likely to be of interest to the
3246
+ * user:
3247
+ * Zlib::Inflate
3248
+ * Zlib::Deflate
3249
+ * Zlib::GzipReader
3250
+ * Zlib::GzipWriter
3251
+ *
3252
+ * There are two important base classes for the classes above: Zlib::ZStream
3253
+ * and Zlib::GzipFile. Everything else is an error class.
3254
+ *
3255
+ * == Constants
3256
+ *
3257
+ * Here's a list.
3258
+ *
3259
+ * Zlib::VERSION
3260
+ * The Ruby/zlib version string.
3261
+ *
3262
+ * Zlib::ZLIB_VERSION
3263
+ * The string which represents the version of zlib.h.
3264
+ *
3265
+ * Zlib::BINARY
3266
+ * Zlib::ASCII
3267
+ * Zlib::UNKNOWN
3268
+ * The integers representing data types which Zlib::ZStream#data_type
3269
+ * method returns.
3270
+ *
3271
+ * Zlib::NO_COMPRESSION
3272
+ * Zlib::BEST_SPEED
3273
+ * Zlib::BEST_COMPRESSION
3274
+ * Zlib::DEFAULT_COMPRESSION
3275
+ * The integers representing compression levels which are an argument
3276
+ * for Zlib::Deflate.new, Zlib::Deflate#deflate, and so on.
3277
+ *
3278
+ * Zlib::FILTERED
3279
+ * Zlib::HUFFMAN_ONLY
3280
+ * Zlib::DEFAULT_STRATEGY
3281
+ * The integers representing compression methods which are an argument
3282
+ * for Zlib::Deflate.new and Zlib::Deflate#params.
3283
+ *
3284
+ * Zlib::DEF_MEM_LEVEL
3285
+ * Zlib::MAX_MEM_LEVEL
3286
+ * The integers representing memory levels which are an argument for
3287
+ * Zlib::Deflate.new, Zlib::Deflate#params, and so on.
3288
+ *
3289
+ * Zlib::MAX_WBITS
3290
+ * The default value of windowBits which is an argument for
3291
+ * Zlib::Deflate.new and Zlib::Inflate.new.
3292
+ *
3293
+ * Zlib::NO_FLUSH
3294
+ * Zlib::SYNC_FLUSH
3295
+ * Zlib::FULL_FLUSH
3296
+ * Zlib::FINISH
3297
+ * The integers to control the output of the deflate stream, which are
3298
+ * an argument for Zlib::Deflate#deflate and so on.
3299
+ *
3300
+ * Zlib::OS_CODE
3301
+ * Zlib::OS_MSDOS
3302
+ * Zlib::OS_AMIGA
3303
+ * Zlib::OS_VMS
3304
+ * Zlib::OS_UNIX
3305
+ * Zlib::OS_VMCMS
3306
+ * Zlib::OS_ATARI
3307
+ * Zlib::OS_OS2
3308
+ * Zlib::OS_MACOS
3309
+ * Zlib::OS_ZSYSTEM
3310
+ * Zlib::OS_CPM
3311
+ * Zlib::OS_TOPS20
3312
+ * Zlib::OS_WIN32
3313
+ * Zlib::OS_QDOS
3314
+ * Zlib::OS_RISCOS
3315
+ * Zlib::OS_UNKNOWN
3316
+ * The return values of Zlib::GzipFile#os_code method.
3317
+ */
3318
+ void Init_zlib()
3319
+ {
3320
+ VALUE mZlib, cZStream, cDeflate, cInflate;
3321
+ #if GZIP_SUPPORT
3322
+ VALUE cGzipFile, cGzipWriter, cGzipReader;
3323
+ #endif
3324
+
3325
+ mZlib = rb_define_module("Zlib");
3326
+
3327
+ cZError = rb_define_class_under(mZlib, "Error", rb_eStandardError);
3328
+ cStreamEnd = rb_define_class_under(mZlib, "StreamEnd", cZError);
3329
+ cNeedDict = rb_define_class_under(mZlib, "NeedDict", cZError);
3330
+ cDataError = rb_define_class_under(mZlib, "DataError", cZError);
3331
+ cStreamError = rb_define_class_under(mZlib, "StreamError", cZError);
3332
+ cMemError = rb_define_class_under(mZlib, "MemError", cZError);
3333
+ cBufError = rb_define_class_under(mZlib, "BufError", cZError);
3334
+ cVersionError = rb_define_class_under(mZlib, "VersionError", cZError);
3335
+
3336
+ rb_define_module_function(mZlib, "zlib_version", rb_zlib_version, 0);
3337
+ rb_define_module_function(mZlib, "adler32", rb_zlib_adler32, -1);
3338
+ rb_define_module_function(mZlib, "crc32", rb_zlib_crc32, -1);
3339
+ rb_define_module_function(mZlib, "crc_table", rb_zlib_crc_table, 0);
3340
+
3341
+ rb_define_const(mZlib, "VERSION", rb_str_new2(RUBY_ZLIB_VERSION));
3342
+ rb_define_const(mZlib, "ZLIB_VERSION", rb_str_new2(ZLIB_VERSION));
3343
+
3344
+ cZStream = rb_define_class_under(mZlib, "ZStream", rb_cObject);
3345
+ rb_undef_alloc_func(cZStream);
3346
+ rb_define_method(cZStream, "avail_out", rb_zstream_avail_out, 0);
3347
+ rb_define_method(cZStream, "avail_out=", rb_zstream_set_avail_out, 1);
3348
+ rb_define_method(cZStream, "avail_in", rb_zstream_avail_in, 0);
3349
+ rb_define_method(cZStream, "total_in", rb_zstream_total_in, 0);
3350
+ rb_define_method(cZStream, "total_out", rb_zstream_total_out, 0);
3351
+ rb_define_method(cZStream, "data_type", rb_zstream_data_type, 0);
3352
+ rb_define_method(cZStream, "adler", rb_zstream_adler, 0);
3353
+ rb_define_method(cZStream, "finished?", rb_zstream_finished_p, 0);
3354
+ rb_define_method(cZStream, "stream_end?", rb_zstream_finished_p, 0);
3355
+ rb_define_method(cZStream, "closed?", rb_zstream_closed_p, 0);
3356
+ rb_define_method(cZStream, "ended?", rb_zstream_closed_p, 0);
3357
+ rb_define_method(cZStream, "close", rb_zstream_end, 0);
3358
+ rb_define_method(cZStream, "end", rb_zstream_end, 0);
3359
+ rb_define_method(cZStream, "reset", rb_zstream_reset, 0);
3360
+ rb_define_method(cZStream, "finish", rb_zstream_finish, 0);
3361
+ rb_define_method(cZStream, "flush_next_in", rb_zstream_flush_next_in, 0);
3362
+ rb_define_method(cZStream, "flush_next_out", rb_zstream_flush_next_out, 0);
3363
+
3364
+ rb_define_const(mZlib, "BINARY", INT2FIX(Z_BINARY));
3365
+ rb_define_const(mZlib, "ASCII", INT2FIX(Z_ASCII));
3366
+ rb_define_const(mZlib, "UNKNOWN", INT2FIX(Z_UNKNOWN));
3367
+
3368
+ cDeflate = rb_define_class_under(mZlib, "Deflate", cZStream);
3369
+ rb_define_singleton_method(cDeflate, "deflate", rb_deflate_s_deflate, -1);
3370
+ rb_define_alloc_func(cDeflate, rb_deflate_s_allocate);
3371
+ rb_define_method(cDeflate, "initialize", rb_deflate_initialize, -1);
3372
+ rb_define_method(cDeflate, "initialize_copy", rb_deflate_init_copy, 0);
3373
+ rb_define_method(cDeflate, "deflate", rb_deflate_deflate, -1);
3374
+ rb_define_method(cDeflate, "<<", rb_deflate_addstr, 1);
3375
+ rb_define_method(cDeflate, "flush", rb_deflate_flush, -1);
3376
+ rb_define_method(cDeflate, "params", rb_deflate_params, 2);
3377
+ rb_define_method(cDeflate, "set_dictionary", rb_deflate_set_dictionary, 1);
3378
+
3379
+ cInflate = rb_define_class_under(mZlib, "Inflate", cZStream);
3380
+ rb_define_singleton_method(cInflate, "inflate", rb_inflate_s_inflate, 1);
3381
+ rb_define_alloc_func(cInflate, rb_inflate_s_allocate);
3382
+ rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1);
3383
+ rb_define_method(cInflate, "inflate", rb_inflate_inflate, 1);
3384
+ rb_define_method(cInflate, "<<", rb_inflate_addstr, 1);
3385
+ rb_define_method(cInflate, "sync", rb_inflate_sync, 1);
3386
+ rb_define_method(cInflate, "sync_point?", rb_inflate_sync_point_p, 0);
3387
+ rb_define_method(cInflate, "set_dictionary", rb_inflate_set_dictionary, 1);
3388
+
3389
+ rb_define_const(mZlib, "NO_COMPRESSION", INT2FIX(Z_NO_COMPRESSION));
3390
+ rb_define_const(mZlib, "BEST_SPEED", INT2FIX(Z_BEST_SPEED));
3391
+ rb_define_const(mZlib, "BEST_COMPRESSION", INT2FIX(Z_BEST_COMPRESSION));
3392
+ rb_define_const(mZlib, "DEFAULT_COMPRESSION",
3393
+ INT2FIX(Z_DEFAULT_COMPRESSION));
3394
+
3395
+ rb_define_const(mZlib, "FILTERED", INT2FIX(Z_FILTERED));
3396
+ rb_define_const(mZlib, "HUFFMAN_ONLY", INT2FIX(Z_HUFFMAN_ONLY));
3397
+ rb_define_const(mZlib, "DEFAULT_STRATEGY", INT2FIX(Z_DEFAULT_STRATEGY));
3398
+
3399
+ rb_define_const(mZlib, "MAX_WBITS", INT2FIX(MAX_WBITS));
3400
+ rb_define_const(mZlib, "DEF_MEM_LEVEL", INT2FIX(DEF_MEM_LEVEL));
3401
+ rb_define_const(mZlib, "MAX_MEM_LEVEL", INT2FIX(MAX_MEM_LEVEL));
3402
+
3403
+ rb_define_const(mZlib, "NO_FLUSH", INT2FIX(Z_NO_FLUSH));
3404
+ rb_define_const(mZlib, "SYNC_FLUSH", INT2FIX(Z_SYNC_FLUSH));
3405
+ rb_define_const(mZlib, "FULL_FLUSH", INT2FIX(Z_FULL_FLUSH));
3406
+ rb_define_const(mZlib, "FINISH", INT2FIX(Z_FINISH));
3407
+
3408
+ #if GZIP_SUPPORT
3409
+ id_write = rb_intern("write");
3410
+ id_read = rb_intern("read");
3411
+ id_flush = rb_intern("flush");
3412
+ id_seek = rb_intern("seek");
3413
+ id_close = rb_intern("close");
3414
+
3415
+ cGzipFile = rb_define_class_under(mZlib, "GzipFile", rb_cObject);
3416
+ cGzError = rb_define_class_under(cGzipFile, "Error", cZError);
3417
+
3418
+ cNoFooter = rb_define_class_under(cGzipFile, "NoFooter", cGzError);
3419
+ cCRCError = rb_define_class_under(cGzipFile, "CRCError", cGzError);
3420
+ cLengthError = rb_define_class_under(cGzipFile,"LengthError",cGzError);
3421
+
3422
+ cGzipWriter = rb_define_class_under(mZlib, "GzipWriter", cGzipFile);
3423
+ cGzipReader = rb_define_class_under(mZlib, "GzipReader", cGzipFile);
3424
+ rb_include_module(cGzipReader, rb_mEnumerable);
3425
+
3426
+ rb_define_singleton_method(cGzipFile, "wrap", rb_gzfile_s_wrap, -1);
3427
+ rb_undef_alloc_func(cGzipFile);
3428
+ rb_define_method(cGzipFile, "to_io", rb_gzfile_to_io, 0);
3429
+ rb_define_method(cGzipFile, "crc", rb_gzfile_crc, 0);
3430
+ rb_define_method(cGzipFile, "mtime", rb_gzfile_mtime, 0);
3431
+ rb_define_method(cGzipFile, "level", rb_gzfile_level, 0);
3432
+ rb_define_method(cGzipFile, "os_code", rb_gzfile_os_code, 0);
3433
+ rb_define_method(cGzipFile, "orig_name", rb_gzfile_orig_name, 0);
3434
+ rb_define_method(cGzipFile, "comment", rb_gzfile_comment, 0);
3435
+ rb_define_method(cGzipReader, "lineno", rb_gzfile_lineno, 0);
3436
+ rb_define_method(cGzipReader, "lineno=", rb_gzfile_set_lineno, 1);
3437
+ rb_define_method(cGzipWriter, "mtime=", rb_gzfile_set_mtime, 1);
3438
+ rb_define_method(cGzipWriter, "orig_name=", rb_gzfile_set_orig_name,1);
3439
+ rb_define_method(cGzipWriter, "comment=", rb_gzfile_set_comment, 1);
3440
+ rb_define_method(cGzipFile, "close", rb_gzfile_close, 0);
3441
+ rb_define_method(cGzipFile, "finish", rb_gzfile_finish, 0);
3442
+ rb_define_method(cGzipFile, "closed?", rb_gzfile_closed_p, 0);
3443
+ rb_define_method(cGzipReader, "eof", rb_gzfile_eof_p, 0);
3444
+ rb_define_method(cGzipReader, "eof?", rb_gzfile_eof_p, 0);
3445
+ rb_define_method(cGzipFile, "sync", rb_gzfile_sync, 0);
3446
+ rb_define_method(cGzipFile, "sync=", rb_gzfile_set_sync, 1);
3447
+ rb_define_method(cGzipReader, "pos", rb_gzfile_total_out, 0);
3448
+ rb_define_method(cGzipWriter, "pos", rb_gzfile_total_in, 0);
3449
+ rb_define_method(cGzipReader, "tell", rb_gzfile_total_out, 0);
3450
+ rb_define_method(cGzipWriter, "tell", rb_gzfile_total_in, 0);
3451
+
3452
+ rb_define_singleton_method(cGzipWriter, "open", rb_gzwriter_s_open,-1);
3453
+ rb_define_alloc_func(cGzipWriter, rb_gzwriter_s_allocate);
3454
+ rb_define_method(cGzipWriter, "initialize", rb_gzwriter_initialize,-1);
3455
+ rb_define_method(cGzipWriter, "flush", rb_gzwriter_flush, -1);
3456
+ rb_define_method(cGzipWriter, "write", rb_gzwriter_write, 1);
3457
+ rb_define_method(cGzipWriter, "putc", rb_gzwriter_putc, 1);
3458
+ rb_define_method(cGzipWriter, "<<", rb_gzwriter_addstr, 1);
3459
+ rb_define_method(cGzipWriter, "printf", rb_gzwriter_printf, -1);
3460
+ rb_define_method(cGzipWriter, "print", rb_gzwriter_print, -1);
3461
+ rb_define_method(cGzipWriter, "puts", rb_gzwriter_puts, -1);
3462
+
3463
+ rb_define_singleton_method(cGzipReader, "open", rb_gzreader_s_open,-1);
3464
+ rb_define_alloc_func(cGzipReader, rb_gzreader_s_allocate);
3465
+ rb_define_method(cGzipReader, "initialize", rb_gzreader_initialize, 1);
3466
+ rb_define_method(cGzipReader, "rewind", rb_gzreader_rewind, 0);
3467
+ rb_define_method(cGzipReader, "unused", rb_gzreader_unused, 0);
3468
+ rb_define_method(cGzipReader, "read", rb_gzreader_read, -1);
3469
+ rb_define_method(cGzipReader, "getc", rb_gzreader_getc, 0);
3470
+ rb_define_method(cGzipReader, "readchar", rb_gzreader_readchar, 0);
3471
+ rb_define_method(cGzipReader, "each_byte", rb_gzreader_each_byte, 0);
3472
+ rb_define_method(cGzipReader, "ungetc", rb_gzreader_ungetc, 1);
3473
+ rb_define_method(cGzipReader, "gets", rb_gzreader_gets, -1);
3474
+ rb_define_method(cGzipReader, "readline", rb_gzreader_readline, -1);
3475
+ rb_define_method(cGzipReader, "each", rb_gzreader_each, -1);
3476
+ rb_define_method(cGzipReader, "each_line", rb_gzreader_each, -1);
3477
+ rb_define_method(cGzipReader, "readlines", rb_gzreader_readlines, -1);
3478
+
3479
+ rb_define_const(mZlib, "OS_CODE", INT2FIX(OS_CODE));
3480
+ rb_define_const(mZlib, "OS_MSDOS", INT2FIX(OS_MSDOS));
3481
+ rb_define_const(mZlib, "OS_AMIGA", INT2FIX(OS_AMIGA));
3482
+ rb_define_const(mZlib, "OS_VMS", INT2FIX(OS_VMS));
3483
+ rb_define_const(mZlib, "OS_UNIX", INT2FIX(OS_UNIX));
3484
+ rb_define_const(mZlib, "OS_ATARI", INT2FIX(OS_ATARI));
3485
+ rb_define_const(mZlib, "OS_OS2", INT2FIX(OS_OS2));
3486
+ rb_define_const(mZlib, "OS_MACOS", INT2FIX(OS_MACOS));
3487
+ rb_define_const(mZlib, "OS_TOPS20", INT2FIX(OS_TOPS20));
3488
+ rb_define_const(mZlib, "OS_WIN32", INT2FIX(OS_WIN32));
3489
+
3490
+ rb_define_const(mZlib, "OS_VMCMS", INT2FIX(OS_VMCMS));
3491
+ rb_define_const(mZlib, "OS_ZSYSTEM", INT2FIX(OS_ZSYSTEM));
3492
+ rb_define_const(mZlib, "OS_CPM", INT2FIX(OS_CPM));
3493
+ rb_define_const(mZlib, "OS_QDOS", INT2FIX(OS_QDOS));
3494
+ rb_define_const(mZlib, "OS_RISCOS", INT2FIX(OS_RISCOS));
3495
+ rb_define_const(mZlib, "OS_UNKNOWN", INT2FIX(OS_UNKNOWN));
3496
+
3497
+ #endif /* GZIP_SUPPORT */
3498
+ }
3499
+
3500
+ /* Document error classes. */
3501
+
3502
+ /*
3503
+ * Document-class: Zlib::Error
3504
+ *
3505
+ * The superclass for all exceptions raised by Ruby/zlib.
3506
+ *
3507
+ * The following exceptions are defined as subclasses of Zlib::Error. These
3508
+ * exceptions are raised when zlib library functions return with an error
3509
+ * status.
3510
+ *
3511
+ * - Zlib::StreamEnd
3512
+ * - Zlib::NeedDict
3513
+ * - Zlib::DataError
3514
+ * - Zlib::StreamError
3515
+ * - Zlib::MemError
3516
+ * - Zlib::BufError
3517
+ * - Zlib::VersionError
3518
+ *
3519
+ */
3520
+
3521
+ /*
3522
+ * Document-class: Zlib::GzipFile::Error
3523
+ *
3524
+ * Base class of errors that occur when processing GZIP files.
3525
+ */
3526
+
3527
+ /*
3528
+ * Document-class: Zlib::GzipFile::NoFooter
3529
+ *
3530
+ * Raised when gzip file footer is not found.
3531
+ */
3532
+
3533
+ /*
3534
+ * Document-class: Zlib::GzipFile::CRCError
3535
+ *
3536
+ * Raised when the CRC checksum recorded in gzip file footer is not equivalent
3537
+ * to the CRC checksum of the actual uncompressed data.
3538
+ */
3539
+
3540
+ /*
3541
+ * Document-class: Zlib::GzipFile::LengthError
3542
+ *
3543
+ * Raised when the data length recorded in the gzip file footer is not equivalent
3544
+ * to the length of the actual uncompressed data.
3545
+ */
3546
+
3547
+