~ubuntu-branches/ubuntu/hardy/ruby1.8/hardy-updates

« back to all changes in this revision

Viewing changes to ext/zlib/zlib.c

  • Committer: Bazaar Package Importer
  • Author(s): akira yamada
  • Date: 2007-03-13 22:11:58 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070313221158-h3oql37brlaf2go2
Tags: 1.8.6-1
* new upstream version, 1.8.6.
* libruby1.8 conflicts with libopenssl-ruby1.8 (< 1.8.6) (closes: #410018)
* changed packaging style to cdbs from dbs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.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