2
* zlib.c - An interface for zlib.
4
* Copyright (C) UENO Katsuhiro 2000-2003
6
* $Id: zlib.c 11708 2007-02-12 23:01:19Z shyouhei $
13
#define RUBY_ZLIB_VERSION "0.6.0"
16
#define OBJ_IS_FREED(val) (RBASIC(val)->flags == 0)
19
#define GZIP_SUPPORT 1
24
#if MAX_MEM_LEVEL >= 8
25
#define DEF_MEM_LEVEL 8
27
#define DEF_MEM_LEVEL MAX_MEM_LEVEL
32
/*--------- Prototypes --------*/
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*));
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*));
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));
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));
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));
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*));
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));
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));
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 */
188
void Init_zlib _((void));
192
/*--------- Exceptions --------*/
194
static VALUE cZError, cStreamEnd, cNeedDict;
195
static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError;
198
raise_zlib_error(err, msg)
210
exc = rb_exc_new2(cStreamEnd, msg);
213
exc = rb_exc_new2(cNeedDict, msg);
216
exc = rb_exc_new2(cStreamError, msg);
219
exc = rb_exc_new2(cDataError, msg);
222
exc = rb_exc_new2(cBufError, msg);
224
case Z_VERSION_ERROR:
225
exc = rb_exc_new2(cVersionError, msg);
228
exc = rb_exc_new2(cMemError, msg);
236
snprintf(buf, BUFSIZ, "unknown zlib error %d: %s", err, msg);
237
exc = rb_exc_new2(cZError, buf);
245
/*--- Warning (in finalizer) ---*/
251
fprintf(stderr, "zlib(finalizer): %s\n", msg);
255
/*-------- module Zlib --------*/
258
* Returns the string which represents the version of zlib library.
261
rb_zlib_version(klass)
266
str = rb_str_new2(zlibVersion());
267
OBJ_TAINT(str); /* for safe */
272
do_checksum(argc, argv, func)
275
uLong (*func) _((uLong, const Bytef *, uInt));
280
rb_scan_args(argc, argv, "02", &str, &vsum);
283
sum = NUM2ULONG(vsum);
285
else if (NIL_P(str)) {
289
sum = func(0, Z_NULL, 0);
293
sum = func(sum, Z_NULL, 0);
297
sum = func(sum, RSTRING(str)->ptr, RSTRING(str)->len);
299
return rb_uint2inum(sum);
303
* call-seq: Zlib.adler32(string, adler)
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+.
312
rb_zlib_adler32(argc, argv, klass)
317
return do_checksum(argc, argv, adler32);
321
* call-seq: Zlib.crc32(string, adler)
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+.
330
rb_zlib_crc32(argc, argv, klass)
335
return do_checksum(argc, argv, crc32);
339
* Returns the table for calculating CRC checksum as an array.
342
rb_zlib_crc_table(obj)
345
const unsigned long *crctbl;
349
crctbl = get_crc_table();
350
dst = rb_ary_new2(256);
352
for (i = 0; i < 256; i++) {
353
rb_ary_push(dst, rb_uint2inum(crctbl[i]));
360
/*-------- zstream - internal APIs --------*/
368
const struct zstream_funcs {
369
int (*reset) _((z_streamp));
370
int (*end) _((z_streamp));
371
int (*run) _((z_streamp, int));
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
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)
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
392
static const struct zstream_funcs deflate_funcs = {
393
deflateReset, deflateEnd, deflate,
396
static const struct zstream_funcs inflate_funcs = {
397
inflateReset, inflateEnd, inflate,
402
zlib_mem_alloc(opaque, items, size)
406
return xmalloc(items * size);
410
zlib_mem_free(opaque, address)
411
voidpf opaque, address;
417
zstream_init(z, func)
419
const struct zstream_funcs *func;
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;
436
#define zstream_init_deflate(z) zstream_init((z), &deflate_funcs)
437
#define zstream_init_inflate(z) zstream_init((z), &inflate_funcs)
440
zstream_expand_buffer(z)
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);
450
z->stream.next_out = RSTRING(z->buf)->ptr;
451
z->stream.avail_out = ZSTREAM_INITIAL_BUFSIZE;
452
RBASIC(z->buf)->klass = 0;
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;
461
inc = z->buf_filled / 2;
462
if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
463
inc = ZSTREAM_AVAIL_OUT_STEP_MIN;
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;
469
z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;
473
zstream_expand_buffer_into(z, size)
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);
482
z->stream.next_out = RSTRING(z->buf)->ptr;
483
z->stream.avail_out = size;
484
RBASIC(z->buf)->klass = 0;
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;
494
zstream_append_buffer(z, src, len)
500
z->buf = rb_str_buf_new(len);
501
rb_str_buf_cat(z->buf, src, len);
503
z->stream.next_out = RSTRING(z->buf)->ptr;
504
z->stream.avail_out = 0;
505
RBASIC(z->buf)->klass = 0;
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;
514
if (z->stream.avail_out >= len) {
515
z->stream.avail_out -= len;
518
z->stream.avail_out = 0;
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;
526
#define zstream_append_buffer2(z,v) \
527
zstream_append_buffer((z),RSTRING(v)->ptr,RSTRING(v)->len)
530
zstream_detach_buffer(z)
536
dst = rb_str_new(0, 0);
540
rb_str_resize(dst, z->buf_filled);
541
RBASIC(dst)->klass = rb_cString;
546
z->stream.next_out = 0;
547
z->stream.avail_out = 0;
552
zstream_shift_buffer(z, len)
558
if (z->buf_filled <= len) {
559
return zstream_detach_buffer(z);
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,
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;
577
zstream_buffer_ungetc(z, c)
581
if (NIL_P(z->buf) || RSTRING(z->buf)->len - z->buf_filled == 0) {
582
zstream_expand_buffer(z);
585
memmove(RSTRING(z->buf)->ptr + 1, RSTRING(z->buf)->ptr, z->buf_filled);
586
RSTRING(z->buf)->ptr[0] = (char)c;
588
if (z->stream.avail_out > 0) {
589
z->stream.next_out++;
590
z->stream.avail_out--;
595
zstream_append_input(z, src, len)
600
if (len <= 0) return;
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;
608
rb_str_buf_cat(z->input, src, len);
612
#define zstream_append_input2(z,v)\
613
zstream_append_input((z), RSTRING(v)->ptr, RSTRING(v)->len)
616
zstream_discard_input(z, len)
620
if (NIL_P(z->input) || RSTRING(z->input)->len <= len) {
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);
631
zstream_reset_input(z)
638
zstream_passthrough_input(z)
641
if (!NIL_P(z->input)) {
642
zstream_append_buffer2(z, z->input);
648
zstream_detach_input(z)
653
if (NIL_P(z->input)) {
654
dst = rb_str_new(0, 0);
658
RBASIC(dst)->klass = rb_cString;
670
err = z->func->reset(&z->stream);
672
raise_zlib_error(err, z->stream.msg);
674
z->flags = ZSTREAM_FLAG_READY;
677
z->stream.next_out = 0;
678
z->stream.avail_out = 0;
679
zstream_reset_input(z);
688
if (!ZSTREAM_IS_READY(z)) {
689
rb_warning("attempt to close uninitialized zstream; ignored.");
692
if (z->flags & ZSTREAM_FLAG_IN_STREAM) {
693
rb_warning("attempt to close unfinished zstream; reset forced.");
697
zstream_reset_input(z);
698
err = z->func->end(&z->stream);
700
raise_zlib_error(err, z->stream.msg);
707
zstream_run(z, src, len, flush)
715
volatile VALUE guard;
717
if (NIL_P(z->input) && len == 0) {
718
z->stream.next_in = "";
719
z->stream.avail_in = 0;
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'
731
if (z->stream.avail_out == 0) {
732
zstream_expand_buffer(z);
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();
741
if (err == Z_STREAM_END) {
742
z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
743
z->flags |= ZSTREAM_FLAG_FINISHED;
747
if (flush != Z_FINISH && err == Z_BUF_ERROR
748
&& z->stream.avail_out > 0) {
749
z->flags |= ZSTREAM_FLAG_IN_STREAM;
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);
756
raise_zlib_error(err, z->stream.msg);
758
if (z->stream.avail_out > 0) {
759
z->flags |= ZSTREAM_FLAG_IN_STREAM;
762
zstream_expand_buffer(z);
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 */
773
zstream_sync(z, src, len)
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);
786
zstream_discard_input(z,
787
RSTRING(z->input)->len - z->stream.avail_in);
788
zstream_append_input(z, src, len);
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);
798
if (len <= 0) return Qfalse;
800
z->stream.next_in = src;
801
z->stream.avail_in = len;
802
err = inflateSync(&z->stream);
804
zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
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);
819
rb_gc_mark(z->input);
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.");
837
if (ZSTREAM_IS_READY(z)) {
844
zstream_new(klass, funcs)
846
const struct zstream_funcs *funcs;
851
obj = Data_Make_Struct(klass, struct zstream,
852
zstream_mark, zstream_free, z);
853
zstream_init(z, funcs);
857
#define zstream_deflate_new(klass) zstream_new((klass), &deflate_funcs)
858
#define zstream_inflate_new(klass) zstream_new((klass), &inflate_funcs)
860
static struct zstream *
866
Data_Get_Struct(obj, struct zstream, z);
867
if (!ZSTREAM_IS_READY(z)) {
868
rb_raise(cZError, "stream is not ready");
874
/* ------------------------------------------------------------------------- */
877
* Document-class: Zlib::ZStream
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.
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
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
896
* Some particular instance methods consume the data in output buffer and
897
* return them as a String.
899
* Here is an ascii art for describing above:
901
* +================ an instance of Zlib::ZStream ================+
903
* || +--------+ +-------+ +--------+ ||
904
* || +--| output |<---------|zstream|<---------| input |<--+ ||
905
* || | | buffer | next_out+-------+next_in | buffer | | ||
906
* || | +--------+ +--------+ | ||
908
* +===|======================================================|===+
911
* "output data" "input data"
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.
917
* == Method Catalogue
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
924
* The higher level methods are listed below.
938
* Closes the stream. All operations on the closed stream will raise an
945
zstream_end(get_zstream(obj));
950
* Resets and initializes the stream. All data in both input and output buffer
954
rb_zstream_reset(obj)
957
zstream_reset(get_zstream(obj));
962
* Finishes the stream and flushes output buffer. See Zlib::Deflate#finish and
963
* Zlib::Inflate#finish for details of this behavior.
966
rb_zstream_finish(obj)
969
struct zstream *z = get_zstream(obj);
972
zstream_run(z, "", 0, Z_FINISH);
973
dst = zstream_detach_buffer(z);
975
OBJ_INFECT(dst, obj);
980
* Flushes input buffer and returns all data in that buffer.
983
rb_zstream_flush_next_in(obj)
989
Data_Get_Struct(obj, struct zstream, z);
990
dst = zstream_detach_input(z);
991
OBJ_INFECT(dst, obj);
996
* Flushes output buffer and returns all data in that buffer.
999
rb_zstream_flush_next_out(obj)
1005
Data_Get_Struct(obj, struct zstream, z);
1006
dst = zstream_detach_buffer(z);
1007
OBJ_INFECT(dst, obj);
1012
* Returns number of bytes of free spaces in output buffer. Because the free
1013
* space is allocated automatically, this method returns 0 normally.
1016
rb_zstream_avail_out(obj)
1020
Data_Get_Struct(obj, struct zstream, z);
1021
return rb_uint2inum(z->stream.avail_out);
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
1031
rb_zstream_set_avail_out(obj, size)
1034
struct zstream *z = get_zstream(obj);
1036
Check_Type(size, T_FIXNUM);
1037
zstream_expand_buffer_into(z, FIX2INT(size));
1042
* Returns bytes of data in the input buffer. Normally, returns 0.
1045
rb_zstream_avail_in(obj)
1049
Data_Get_Struct(obj, struct zstream, z);
1050
return INT2FIX(NIL_P(z->input) ? 0 : (int)(RSTRING(z->input)->len));
1054
* Returns the total bytes of the input data to the stream. FIXME
1057
rb_zstream_total_in(obj)
1060
return rb_uint2inum(get_zstream(obj)->stream.total_in);
1064
* Returns the total bytes of the output data from the stream. FIXME
1067
rb_zstream_total_out(obj)
1070
return rb_uint2inum(get_zstream(obj)->stream.total_out);
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>.
1079
rb_zstream_data_type(obj)
1082
return INT2FIX(get_zstream(obj)->stream.data_type);
1086
* Returns the adler-32 checksum.
1089
rb_zstream_adler(obj)
1092
return rb_uint2inum(get_zstream(obj)->stream.adler);
1096
* Returns true if the stream is finished.
1099
rb_zstream_finished_p(obj)
1102
return ZSTREAM_IS_FINISHED(get_zstream(obj)) ? Qtrue : Qfalse;
1106
* Returns true if the stream is closed.
1109
rb_zstream_closed_p(obj)
1113
Data_Get_Struct(obj, struct zstream, z);
1114
return ZSTREAM_IS_READY(z) ? Qfalse : Qtrue;
1118
/* ------------------------------------------------------------------------- */
1121
* Document-class: Zlib::Deflate
1123
* Zlib::Deflate is the class for compressing data. See Zlib::Stream for more
1127
#define FIXNUMARG(val, ifnil) \
1128
(NIL_P((val)) ? (ifnil) \
1129
: ((void)Check_Type((val), T_FIXNUM), FIX2INT((val))))
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)
1139
rb_deflate_s_allocate(klass)
1142
return zstream_deflate_new(klass);
1146
* call-seq: Zlib::Deflate.new(level=nil, windowBits=nil, memlevel=nil, strategy=nil)
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
1152
* TODO: document better!
1155
rb_deflate_initialize(argc, argv, obj)
1161
VALUE level, wbits, memlevel, strategy;
1164
rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy);
1165
Data_Get_Struct(obj, struct zstream, z);
1167
err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
1168
ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
1169
ARG_STRATEGY(strategy));
1171
raise_zlib_error(err, z->stream.msg);
1179
* Duplicates the deflate stream.
1182
rb_deflate_init_copy(self, orig)
1185
struct zstream *z1 = get_zstream(self);
1186
struct zstream *z2 = get_zstream(orig);
1189
err = deflateCopy(&z1->stream, &z2->stream);
1191
raise_zlib_error(err, 0);
1193
z1->flags = z2->flags;
1202
struct zstream *z = (struct zstream *)((VALUE *)args)[0];
1203
VALUE src = ((VALUE *)args)[1];
1205
zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_FINISH);
1206
return zstream_detach_buffer(z);
1210
* call-seq: Zlib::Deflate.deflate(string[, level])
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.
1217
* This method is almost equivalent to the following code:
1219
* def deflate(string, level)
1220
* z = Zlib::Deflate.new(level)
1221
* dst = z.deflate(string, Zlib::FINISH)
1226
* TODO: what's default value of +level+?
1230
rb_deflate_s_deflate(argc, argv, klass)
1236
VALUE src, level, dst, args[2];
1239
rb_scan_args(argc, argv, "11", &src, &level);
1241
lev = ARG_LEVEL(level);
1243
zstream_init_deflate(&z);
1244
err = deflateInit(&z.stream, lev);
1246
raise_zlib_error(err, z.stream.msg);
1250
args[0] = (VALUE)&z;
1252
dst = rb_ensure(deflate_run, (VALUE)args, zstream_end, (VALUE)&z);
1254
OBJ_INFECT(dst, src);
1259
do_deflate(z, src, flush)
1265
zstream_run(z, "", 0, Z_FINISH);
1269
if (flush != Z_NO_FLUSH || RSTRING(src)->len > 0) { /* prevent BUF_ERROR */
1270
zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, flush);
1275
* call-seq: deflate(string[, flush])
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.
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.
1286
* TODO: document better!
1289
rb_deflate_deflate(argc, argv, obj)
1294
struct zstream *z = get_zstream(obj);
1295
VALUE src, flush, dst;
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);
1302
OBJ_INFECT(dst, obj);
1307
* call-seq: << string
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.
1314
rb_deflate_addstr(obj, src)
1317
OBJ_INFECT(obj, src);
1318
do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
1323
* call-seq: flush(flush)
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.
1329
* TODO: document better!
1332
rb_deflate_flush(argc, argv, obj)
1337
struct zstream *z = get_zstream(obj);
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);
1346
dst = zstream_detach_buffer(z);
1348
OBJ_INFECT(dst, obj);
1353
* call-seq: params(level, strategy)
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
1359
* TODO: document better!
1362
rb_deflate_params(obj, v_level, v_strategy)
1363
VALUE obj, v_level, v_strategy;
1365
struct zstream *z = get_zstream(obj);
1366
int level, strategy;
1369
level = ARG_LEVEL(v_level);
1370
strategy = ARG_STRATEGY(v_strategy);
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);
1379
raise_zlib_error(err, z->stream.msg);
1386
* call-seq: set_dictionary(string)
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.
1392
* TODO: document better!
1395
rb_deflate_set_dictionary(obj, dic)
1398
struct zstream *z = get_zstream(obj);
1402
OBJ_INFECT(obj, dic);
1404
err = deflateSetDictionary(&z->stream,
1405
RSTRING(src)->ptr, RSTRING(src)->len);
1407
raise_zlib_error(err, z->stream.msg);
1414
/* ------------------------------------------------------------------------- */
1417
* Document-class: Zlib::Inflate
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,
1427
rb_inflate_s_allocate(klass)
1430
return zstream_inflate_new(klass);
1434
* call-seq: Zlib::Inflate.new(window_bits)
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.
1439
* TODO: document better!
1442
rb_inflate_initialize(argc, argv, obj)
1451
rb_scan_args(argc, argv, "01", &wbits);
1452
Data_Get_Struct(obj, struct zstream, z);
1454
err = inflateInit2(&z->stream, ARG_WBITS(wbits));
1456
raise_zlib_error(err, z->stream.msg);
1467
struct zstream *z = (struct zstream *)((VALUE *)args)[0];
1468
VALUE src = ((VALUE *)args)[1];
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);
1476
* call-seq: Zlib::Inflate.inflate(string)
1478
* Decompresses +string+. Raises a Zlib::NeedDict exception if a preset
1479
* dictionary is needed for decompression.
1481
* This method is almost equivalent to the following code:
1483
* def inflate(string)
1484
* zstream = Zlib::Inflate.new
1485
* buf = zstream.inflate(string)
1493
rb_inflate_s_inflate(obj, src)
1501
zstream_init_inflate(&z);
1502
err = inflateInit(&z.stream);
1504
raise_zlib_error(err, z.stream.msg);
1508
args[0] = (VALUE)&z;
1510
dst = rb_ensure(inflate_run, (VALUE)args, zstream_end, (VALUE)&z);
1512
OBJ_INFECT(dst, src);
1522
zstream_run(z, "", 0, Z_FINISH);
1526
if (RSTRING(src)->len > 0) { /* prevent Z_BUF_ERROR */
1527
zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_SYNC_FLUSH);
1532
* call-seq: inflate(string)
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.
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>)
1543
* TODO: document better!
1546
rb_inflate_inflate(obj, src)
1549
struct zstream *z = get_zstream(obj);
1552
OBJ_INFECT(obj, src);
1554
if (ZSTREAM_IS_FINISHED(z)) {
1556
dst = zstream_detach_buffer(z);
1560
zstream_append_buffer2(z, src);
1561
dst = rb_str_new(0, 0);
1566
dst = zstream_detach_buffer(z);
1567
if (ZSTREAM_IS_FINISHED(z)) {
1568
zstream_passthrough_input(z);
1572
OBJ_INFECT(dst, obj);
1577
* call-seq: << string
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.
1584
rb_inflate_addstr(obj, src)
1587
struct zstream *z = get_zstream(obj);
1589
OBJ_INFECT(obj, src);
1591
if (ZSTREAM_IS_FINISHED(z)) {
1594
zstream_append_buffer2(z, src);
1599
if (ZSTREAM_IS_FINISHED(z)) {
1600
zstream_passthrough_input(z);
1608
* call-seq: sync(string)
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.
1616
rb_inflate_sync(obj, src)
1619
struct zstream *z = get_zstream(obj);
1621
OBJ_INFECT(obj, src);
1623
return zstream_sync(z, RSTRING(src)->ptr, RSTRING(src)->len);
1627
* Quoted verbatim from original documentation:
1634
rb_inflate_sync_point_p(obj)
1637
struct zstream *z = get_zstream(obj);
1640
err = inflateSyncPoint(&z->stream);
1645
raise_zlib_error(err, z->stream.msg);
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.
1654
* TODO: document better!
1657
rb_inflate_set_dictionary(obj, dic)
1660
struct zstream *z = get_zstream(obj);
1664
OBJ_INFECT(obj, dic);
1666
err = inflateSetDictionary(&z->stream,
1667
RSTRING(src)->ptr, RSTRING(src)->len);
1669
raise_zlib_error(err, z->stream.msg);
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.
1684
/*------- .gz file header --------*/
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
1696
#define GZ_EXTRAFLAG_FAST 0x4
1697
#define GZ_EXTRAFLAG_SLOW 0x2
1700
#define OS_MSDOS 0x00
1701
#define OS_AMIGA 0x01
1703
#define OS_UNIX 0x03
1704
#define OS_ATARI 0x05
1706
#define OS_MACOS 0x07
1707
#define OS_TOPS20 0x0a
1708
#define OS_WIN32 0x0b
1710
#define OS_VMCMS 0x04
1711
#define OS_ZSYSTEM 0x08
1713
#define OS_QDOS 0x0c
1714
#define OS_RISCOS 0x0d
1715
#define OS_UNKNOWN 0xff
1718
#define OS_CODE OS_UNIX
1721
static ID id_write, id_read, id_flush, id_seek, id_close;
1722
static VALUE cGzError, cNoFooter, cCRCError, cLengthError;
1726
/*-------- gzfile internal APIs --------*/
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 */
1739
void (*end)(struct gzfile *);
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)
1746
#define GZFILE_IS_FINISHED(gz) \
1747
(ZSTREAM_IS_FINISHED(&gz->z) && (gz)->z.buf_filled == 0)
1749
#define GZFILE_READ_SIZE 2048
1757
rb_gc_mark(gz->orig_name);
1758
rb_gc_mark(gz->comment);
1759
zstream_mark(&gz->z);
1766
struct zstream *z = &gz->z;
1768
if (ZSTREAM_IS_READY(z)) {
1769
if (z->func == &deflate_funcs) {
1770
finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
1772
zstream_finalize(z);
1778
gzfile_new(klass, funcs, endfunc)
1780
const struct zstream_funcs *funcs;
1781
void (*endfunc) _((struct gzfile *));
1786
obj = Data_Make_Struct(klass, struct gzfile, gzfile_mark, gzfile_free, gz);
1787
zstream_init(&gz->z, funcs);
1791
gz->os_code = OS_CODE;
1792
gz->orig_name = Qnil;
1794
gz->crc = crc32(0, Z_NULL, 0);
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)
1809
zstream_reset(&gz->z);
1810
gz->crc = crc32(0, Z_NULL, 0);
1816
gzfile_close(gz, closeflag)
1824
gz->orig_name = Qnil;
1826
if (closeflag && rb_respond_to(io, id_close)) {
1827
rb_funcall(io, id_close, 0);
1832
gzfile_write_raw(gz)
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);
1853
str = rb_funcall(gz->io, id_read, 1, INT2FIX(GZFILE_READ_SIZE));
1855
Check_Type(str, T_STRING);
1861
gzfile_read_raw_ensure(gz, size)
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);
1876
gzfile_read_raw_until_zero(gz, offset)
1884
p = memchr(RSTRING(gz->z.input)->ptr + offset, '\0',
1885
RSTRING(gz->z.input)->len - offset);
1887
str = gzfile_read_raw(gz);
1889
rb_raise(cGzError, "unexpected end of file");
1891
offset = RSTRING(gz->z.input)->len;
1892
zstream_append_input2(&gz->z, str);
1899
const unsigned char *src;
1902
n = *(src++) & 0xff;
1903
n |= (*(src++) & 0xff) << 8;
1907
static unsigned long
1909
const unsigned char *src;
1912
n = *(src++) & 0xff;
1913
n |= (*(src++) & 0xff) << 8;
1914
n |= (*(src++) & 0xff) << 16;
1915
n |= (*(src++) & 0xffU) << 24;
1920
gzfile_set32(n, dst)
1924
*(dst++) = n & 0xff;
1925
*(dst++) = (n >> 8) & 0xff;
1926
*(dst++) = (n >> 16) & 0xff;
1927
*dst = (n >> 24) & 0xff;
1931
gzfile_make_header(gz)
1934
unsigned char buf[10]; /* the size of gzip header */
1935
unsigned char flags = 0, extraflags = 0;
1937
if (!NIL_P(gz->orig_name)) {
1938
flags |= GZ_FLAG_ORIG_NAME;
1940
if (!NIL_P(gz->comment)) {
1941
flags |= GZ_FLAG_COMMENT;
1943
if (gz->mtime == 0) {
1944
gz->mtime = time(0);
1947
if (gz->level == Z_BEST_SPEED) {
1948
extraflags |= GZ_EXTRAFLAG_FAST;
1950
else if (gz->level == Z_BEST_COMPRESSION) {
1951
extraflags |= GZ_EXTRAFLAG_SLOW;
1956
buf[2] = GZ_METHOD_DEFLATE;
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));
1963
if (!NIL_P(gz->orig_name)) {
1964
zstream_append_buffer2(&gz->z, gz->orig_name);
1965
zstream_append_buffer(&gz->z, "\0", 1);
1967
if (!NIL_P(gz->comment)) {
1968
zstream_append_buffer2(&gz->z, gz->comment);
1969
zstream_append_buffer(&gz->z, "\0", 1);
1972
gz->z.flags |= GZFILE_FLAG_HEADER_FINISHED;
1976
gzfile_make_footer(gz)
1979
unsigned char buf[8]; /* 8 is the size of gzip footer */
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;
1988
gzfile_read_header(gz)
1991
const unsigned char *head;
1995
if (!gzfile_read_raw_ensure(gz, 10)) { /* 10 is the size of gzip header */
1996
rb_raise(cGzError, "not in gzip format");
1999
head = RSTRING(gz->z.input)->ptr;
2001
if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {
2002
rb_raise(cGzError, "not in gzip format");
2004
if (head[2] != GZ_METHOD_DEFLATE) {
2005
rb_raise(cGzError, "unsupported compression method %d", head[2]);
2009
if (flags & GZ_FLAG_MULTIPART) {
2010
rb_raise(cGzError, "multi-part gzip file is not supported");
2012
else if (flags & GZ_FLAG_ENCRYPT) {
2013
rb_raise(cGzError, "encrypted gzip file is not supported");
2015
else if (flags & GZ_FLAG_UNKNOWN_MASK) {
2016
rb_raise(cGzError, "unknown flags 0x%02x", flags);
2019
if (head[8] & GZ_EXTRAFLAG_FAST) {
2020
gz->level = Z_BEST_SPEED;
2022
else if (head[8] & GZ_EXTRAFLAG_SLOW) {
2023
gz->level = Z_BEST_COMPRESSION;
2026
gz->level = Z_DEFAULT_COMPRESSION;
2029
gz->mtime = gzfile_get32(&head[4]);
2030
gz->os_code = head[9];
2031
zstream_discard_input(&gz->z, 10);
2033
if (flags & GZ_FLAG_EXTRA) {
2034
if (!gzfile_read_raw_ensure(gz, 2)) {
2035
rb_raise(cGzError, "unexpected end of file");
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");
2041
zstream_discard_input(&gz->z, 2 + len);
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);
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);
2058
if (gz->z.input != Qnil && RSTRING(gz->z.input)->len > 0) {
2059
zstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);
2064
gzfile_check_footer(gz)
2067
unsigned long crc, length;
2069
gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
2071
if (!gzfile_read_raw_ensure(gz, 8)) { /* 8 is the size of gzip footer */
2072
rb_raise(cNoFooter, "footer is not found");
2075
crc = gzfile_get32(RSTRING(gz->z.input)->ptr);
2076
length = gzfile_get32(RSTRING(gz->z.input)->ptr + 4);
2078
gz->z.stream.total_in += 8; /* to rewind correctly */
2079
zstream_discard_input(&gz->z, 8);
2081
if (gz->crc != crc) {
2082
rb_raise(cCRCError, "invalid compressed data -- crc error");
2084
if (gz->z.stream.total_out != length) {
2085
rb_raise(cLengthError, "invalid compressed data -- length error");
2090
gzfile_write(gz, str, len)
2095
if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2096
gzfile_make_header(gz);
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);
2104
gzfile_write_raw(gz);
2108
gzfile_read_more(gz)
2113
while (!ZSTREAM_IS_FINISHED(&gz->z)) {
2114
str = gzfile_read_raw(gz);
2116
if (!ZSTREAM_IS_FINISHED(&gz->z)) {
2117
rb_raise(cGzError, "unexpected end of file");
2121
if (RSTRING(str)->len > 0) { /* prevent Z_BUF_ERROR */
2122
zstream_run(&gz->z, RSTRING(str)->ptr, RSTRING(str)->len,
2125
if (gz->z.buf_filled > 0) break;
2127
return gz->z.buf_filled;
2131
gzfile_calc_crc(gz, str)
2135
if (RSTRING(str)->len <= gz->ungetc) {
2136
gz->ungetc -= RSTRING(str)->len;
2139
gz->crc = crc32(gz->crc, RSTRING(str)->ptr + gz->ungetc,
2140
RSTRING(str)->len - gz->ungetc);
2146
gzfile_read(gz, len)
2153
rb_raise(rb_eArgError, "negative length %d given", len);
2155
return rb_str_new(0, 0);
2156
while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
2157
gzfile_read_more(gz);
2159
if (GZFILE_IS_FINISHED(gz)) {
2160
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2161
gzfile_check_footer(gz);
2166
dst = zstream_shift_buffer(&gz->z, len);
2167
gzfile_calc_crc(gz, dst);
2169
OBJ_TAINT(dst); /* for safe */
2179
while (!ZSTREAM_IS_FINISHED(&gz->z)) {
2180
gzfile_read_more(gz);
2182
if (GZFILE_IS_FINISHED(gz)) {
2183
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2184
gzfile_check_footer(gz);
2186
return rb_str_new(0, 0);
2189
dst = zstream_detach_buffer(&gz->z);
2190
gzfile_calc_crc(gz, dst);
2192
OBJ_TAINT(dst); /* for safe */
2197
gzfile_ungetc(gz, c)
2201
zstream_buffer_ungetc(&gz->z, c);
2206
gzfile_writer_end_run(arg)
2209
struct gzfile *gz = (struct gzfile *)arg;
2211
if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2212
gzfile_make_header(gz);
2215
zstream_run(&gz->z, "", 0, Z_FINISH);
2216
gzfile_make_footer(gz);
2217
gzfile_write_raw(gz);
2223
gzfile_writer_end(gz)
2226
if (ZSTREAM_IS_CLOSING(&gz->z)) return;
2227
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
2229
rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
2233
gzfile_reader_end_run(arg)
2236
struct gzfile *gz = (struct gzfile *)arg;
2238
if (GZFILE_IS_FINISHED(gz)
2239
&& !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2240
gzfile_check_footer(gz);
2247
gzfile_reader_end(gz)
2250
if (ZSTREAM_IS_CLOSING(&gz->z)) return;
2251
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
2253
rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
2257
gzfile_reader_rewind(gz)
2262
n = gz->z.stream.total_in;
2263
if (!NIL_P(gz->z.input)) {
2264
n += RSTRING(gz->z.input)->len;
2267
rb_funcall(gz->io, id_seek, 2, rb_int2inum(-n), INT2FIX(1));
2272
gzfile_reader_get_unused(gz)
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);
2282
if (NIL_P(gz->z.input)) return Qnil;
2284
str = rb_str_dup(gz->z.input);
2285
OBJ_TAINT(str); /* for safe */
2289
static struct gzfile *
2295
Data_Get_Struct(obj, struct gzfile, gz);
2296
if (!ZSTREAM_IS_READY(&gz->z)) {
2297
rb_raise(cGzError, "closed gzip stream");
2303
/* ------------------------------------------------------------------------- */
2306
* Document-class: Zlib::GzipFile
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.
2312
* GzipReader should be used by associating an IO, or IO-like, object.
2317
gzfile_ensure_close(obj)
2322
Data_Get_Struct(obj, struct gzfile, gz);
2323
if (ZSTREAM_IS_READY(&gz->z)) {
2324
gzfile_close(gz, 1);
2330
* See Zlib::GzipReader#wrap and Zlib::GzipWriter#wrap.
2333
rb_gzfile_s_wrap(argc, argv, klass)
2338
VALUE obj = rb_class_new_instance(argc, argv, klass);
2340
if (rb_block_given_p()) {
2341
return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);
2349
* See Zlib::GzipReader#open and Zlib::GzipWriter#open.
2352
gzfile_s_open(argc, argv, klass, mode)
2361
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
2364
SafeStringValue(filename);
2365
io = rb_file_open(RSTRING(filename)->ptr, mode);
2368
return rb_gzfile_s_wrap(argc, argv, klass);
2375
rb_gzfile_to_io(obj)
2378
return get_gzfile(obj)->io;
2382
* Returns CRC value of the uncompressed data.
2388
return rb_uint2inum(get_gzfile(obj)->crc);
2392
* Returns last modification time recorded in the gzip file header.
2395
rb_gzfile_mtime(obj)
2398
return rb_time_new(get_gzfile(obj)->mtime, (time_t)0);
2402
* Returns compression level.
2405
rb_gzfile_level(obj)
2408
return INT2FIX(get_gzfile(obj)->level);
2412
* Returns OS code number recorded in the gzip file header.
2415
rb_gzfile_os_code(obj)
2418
return INT2FIX(get_gzfile(obj)->os_code);
2422
* Returns original filename recorded in the gzip file header, or +nil+ if
2423
* original filename is not present.
2426
rb_gzfile_orig_name(obj)
2429
VALUE str = get_gzfile(obj)->orig_name;
2431
str = rb_str_dup(str);
2433
OBJ_TAINT(str); /* for safe */
2438
* Returns comments recorded in the gzip file header, or nil if the comments
2442
rb_gzfile_comment(obj)
2445
VALUE str = get_gzfile(obj)->comment;
2447
str = rb_str_dup(str);
2449
OBJ_TAINT(str); /* for safe */
2457
rb_gzfile_lineno(obj)
2460
return INT2NUM(get_gzfile(obj)->lineno);
2467
rb_gzfile_set_lineno(obj, lineno)
2470
struct gzfile *gz = get_gzfile(obj);
2471
gz->lineno = NUM2INT(lineno);
2479
rb_gzfile_set_mtime(obj, mtime)
2482
struct gzfile *gz = get_gzfile(obj);
2485
if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
2486
rb_raise(cGzError, "header is already written");
2489
if (FIXNUM_P(time)) {
2490
gz->mtime = FIX2INT(mtime);
2493
val = rb_Integer(mtime);
2494
gz->mtime = FIXNUM_P(val) ? FIX2INT(val) : rb_big2ulong(val);
2503
rb_gzfile_set_orig_name(obj, str)
2506
struct gzfile *gz = get_gzfile(obj);
2510
if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
2511
rb_raise(cGzError, "header is already written");
2513
s = rb_str_dup(rb_str_to_str(str));
2514
p = memchr(RSTRING(s)->ptr, '\0', RSTRING(s)->len);
2516
rb_str_resize(s, p - RSTRING(s)->ptr);
2526
rb_gzfile_set_comment(obj, str)
2529
struct gzfile *gz = get_gzfile(obj);
2533
if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
2534
rb_raise(cGzError, "header is already written");
2536
s = rb_str_dup(rb_str_to_str(str));
2537
p = memchr(RSTRING(s)->ptr, '\0', RSTRING(s)->len);
2539
rb_str_resize(s, p - RSTRING(s)->ptr);
2546
* Closes the GzipFile object. This method calls close method of the
2547
* associated IO object. Returns the associated IO object.
2550
rb_gzfile_close(obj)
2553
struct gzfile *gz = get_gzfile(obj);
2557
gzfile_close(gz, 1);
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
2567
rb_gzfile_finish(obj)
2570
struct gzfile *gz = get_gzfile(obj);
2574
gzfile_close(gz, 0);
2582
rb_gzfile_closed_p(obj)
2586
Data_Get_Struct(obj, struct gzfile, gz);
2587
return NIL_P(gz->io) ? Qtrue : Qfalse;
2594
rb_gzfile_eof_p(obj)
2597
struct gzfile *gz = get_gzfile(obj);
2598
return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
2608
return (get_gzfile(obj)->z.flags & GZFILE_FLAG_SYNC) ? Qtrue : Qfalse;
2612
* call-seq: sync = flag
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.
2619
rb_gzfile_set_sync(obj, mode)
2622
struct gzfile *gz = get_gzfile(obj);
2625
gz->z.flags |= GZFILE_FLAG_SYNC;
2628
gz->z.flags &= ~GZFILE_FLAG_SYNC;
2637
rb_gzfile_total_in(obj)
2640
return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
2647
rb_gzfile_total_out(obj)
2650
struct gzfile *gz = get_gzfile(obj);
2651
return rb_uint2inum(gz->z.stream.total_out - gz->z.buf_filled);
2655
/* ------------------------------------------------------------------------- */
2658
* Document-class: Zlib::GzipWriter
2660
* Zlib::GzipWriter is a class for writing gzipped files. GzipWriter should
2661
* be used with an instance of IO, or IO-like, object.
2665
* Zlib::GzipWriter.open('hoge.gz') do |gz|
2666
* gz.write 'jugemu jugemu gokou no surikire...'
2669
* File.open('hoge.gz', 'w') do |f|
2670
* gz = Zlib::GzipWriter.new(f)
2671
* gz.write 'jugemu jugemu gokou no surikire...'
2675
* # TODO: test these. Are they equivalent? Can GzipWriter.new take a
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
2685
rb_gzwriter_s_allocate(klass)
2688
return gzfile_writer_new(klass);
2692
* call-seq: Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... }
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.
2699
rb_gzwriter_s_open(argc, argv, klass)
2704
return gzfile_s_open(argc, argv, klass, "wb");
2708
* call-seq: Zlib::GzipWriter.new(io, level, strategy)
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.
2716
rb_gzwriter_initialize(argc, argv, obj)
2722
VALUE io, level, strategy;
2725
rb_scan_args(argc, argv, "12", &io, &level, &strategy);
2726
Data_Get_Struct(obj, struct gzfile, gz);
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));
2733
raise_zlib_error(err, gz->z.stream.msg);
2736
ZSTREAM_READY(&gz->z);
2742
* call-seq: flush(flush=nil)
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>.
2749
rb_gzwriter_flush(argc, argv, obj)
2754
struct gzfile *gz = get_gzfile(obj);
2758
rb_scan_args(argc, argv, "01", &v_flush);
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);
2765
gzfile_write_raw(gz);
2766
if (rb_respond_to(gz->io, id_flush)) {
2767
rb_funcall(gz->io, id_flush, 0);
2776
rb_gzwriter_write(obj, str)
2779
struct gzfile *gz = get_gzfile(obj);
2781
if (TYPE(str) != T_STRING) {
2782
str = rb_obj_as_string(str);
2784
gzfile_write(gz, RSTRING(str)->ptr, RSTRING(str)->len);
2785
return INT2FIX(RSTRING(str)->len);
2792
rb_gzwriter_putc(obj, ch)
2795
struct gzfile *gz = get_gzfile(obj);
2796
char c = NUM2CHR(ch);
2798
gzfile_write(gz, &c, 1);
2805
* Document-method: <<
2808
#define rb_gzwriter_addstr rb_io_addstr
2810
* Document-method: printf
2813
#define rb_gzwriter_printf rb_io_printf
2815
* Document-method: print
2818
#define rb_gzwriter_print rb_io_print
2820
* Document-method: puts
2823
#define rb_gzwriter_puts rb_io_puts
2826
/* ------------------------------------------------------------------------- */
2829
* Document-class: Zlib::GzipReader
2831
* Zlib::GzipReader is the class for reading a gzipped file. GzipReader should
2832
* be used an IO, or -IO-lie, object.
2834
* Zlib::GzipReader.open('hoge.gz') {|gz|
2838
* File.open('hoge.gz') do |f|
2839
* gz = Zlib::GzipReader.new(f)
2844
* # TODO: test these. Are they equivalent? Can GzipReader.new take a
2847
* == Method Catalogue
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.
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.
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
2876
* - When Zlib::GzipReader#unused method is called after the object reaches
2879
* The rest of the methods are adequately described in their own
2884
rb_gzreader_s_allocate(klass)
2887
return gzfile_reader_new(klass);
2891
* call-seq: Zlib::GzipReader.open(filename) {|gz| ... }
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.
2898
rb_gzreader_s_open(argc, argv, klass)
2903
return gzfile_s_open(argc, argv, klass, "rb");
2907
* call-seq: Zlib::GzipReader.new(io)
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.
2913
* If the gzip file header is incorrect, raises an Zlib::GzipFile::Error
2917
rb_gzreader_initialize(obj, io)
2923
Data_Get_Struct(obj, struct gzfile, gz);
2925
/* this is undocumented feature of zlib */
2926
err = inflateInit2(&gz->z.stream, -MAX_WBITS);
2928
raise_zlib_error(err, gz->z.stream.msg);
2931
ZSTREAM_READY(&gz->z);
2932
gzfile_read_header(gz);
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.
2942
rb_gzreader_rewind(obj)
2945
struct gzfile *gz = get_gzfile(obj);
2946
gzfile_reader_rewind(gz);
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.
2955
rb_gzreader_unused(obj)
2959
Data_Get_Struct(obj, struct gzfile, gz);
2960
return gzfile_reader_get_unused(gz);
2964
* See Zlib::GzipReader documentation for a description.
2967
rb_gzreader_read(argc, argv, obj)
2972
struct gzfile *gz = get_gzfile(obj);
2976
rb_scan_args(argc, argv, "01", &vlen);
2978
return gzfile_read_all(gz);
2981
len = NUM2INT(vlen);
2983
rb_raise(rb_eArgError, "negative length %d given", len);
2985
return gzfile_read(gz, len);
2989
* See Zlib::GzipReader documentation for a description.
2992
rb_gzreader_getc(obj)
2995
struct gzfile *gz = get_gzfile(obj);
2998
dst = gzfile_read(gz, 1);
3000
dst = INT2FIX((unsigned int)(RSTRING(dst)->ptr[0]) & 0xff);
3006
* See Zlib::GzipReader documentation for a description.
3009
rb_gzreader_readchar(obj)
3013
dst = rb_gzreader_getc(obj);
3015
rb_raise(rb_eEOFError, "end of file reached");
3021
* See Zlib::GzipReader documentation for a description.
3024
rb_gzreader_each_byte(obj)
3028
while (!NIL_P(c = rb_gzreader_getc(obj))) {
3035
* See Zlib::GzipReader documentation for a description.
3038
rb_gzreader_ungetc(obj, ch)
3041
struct gzfile *gz = get_gzfile(obj);
3042
gzfile_ungetc(gz, NUM2CHR(ch));
3047
gzreader_skip_linebreaks(gz)
3054
while (gz->z.buf_filled == 0) {
3055
if (GZFILE_IS_FINISHED(gz)) return;
3056
gzfile_read_more(gz);
3059
p = RSTRING(gz->z.buf)->ptr;
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);
3070
p = RSTRING(gz->z.buf)->ptr;
3074
str = zstream_shift_buffer(&gz->z, n - 1);
3075
gzfile_calc_crc(gz, str);
3079
rscheck(rsptr, rslen, rs)
3084
if (RSTRING(rs)->ptr != rsptr && RSTRING(rs)->len != rslen)
3085
rb_raise(rb_eRuntimeError, "rs modified");
3089
gzreader_gets(argc, argv, obj)
3094
struct gzfile *gz = get_gzfile(obj);
3097
char *rsptr, *p, *res;
3105
rb_scan_args(argc, argv, "1", &rs);
3107
Check_Type(rs, T_STRING);
3112
dst = gzfile_read_all(gz);
3113
if (RSTRING(dst)->len != 0) gz->lineno++;
3117
if (RSTRING(rs)->len == 0) {
3122
rsptr = RSTRING(rs)->ptr;
3123
rslen = RSTRING(rs)->len;
3128
gzreader_skip_linebreaks(gz);
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);
3136
gzfile_read_more(gz);
3139
p = RSTRING(gz->z.buf)->ptr;
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;
3147
if (!rspara) rscheck(rsptr, rslen, rs);
3148
res = memchr(p, rsptr[0], (gz->z.buf_filled - n + 1));
3150
n = gz->z.buf_filled + 1;
3152
n += (long)(res - p);
3154
if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
3160
dst = gzfile_read(gz, n);
3162
gzreader_skip_linebreaks(gz);
3169
* See Zlib::GzipReader documentation for a description.
3172
rb_gzreader_gets(argc, argv, obj)
3178
dst = gzreader_gets(argc, argv, obj);
3180
rb_lastline_set(dst);
3186
* See Zlib::GzipReader documentation for a description.
3189
rb_gzreader_readline(argc, argv, obj)
3195
dst = rb_gzreader_gets(argc, argv, obj);
3197
rb_raise(rb_eEOFError, "end of file reached");
3203
* See Zlib::GzipReader documentation for a description.
3206
rb_gzreader_each(argc, argv, obj)
3212
while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
3219
* See Zlib::GzipReader documentation for a description.
3222
rb_gzreader_readlines(argc, argv, obj)
3229
while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
3230
rb_ary_push(dst, str);
3235
#endif /* GZIP_SUPPORT */
3240
* The Zlib module contains several classes for compressing and decompressing
3241
* streams, and for working with "gzip" files.
3245
* Following are the classes that are most likely to be of interest to the
3252
* There are two important base classes for the classes above: Zlib::ZStream
3253
* and Zlib::GzipFile. Everything else is an error class.
3260
* The Ruby/zlib version string.
3262
* Zlib::ZLIB_VERSION
3263
* The string which represents the version of zlib.h.
3268
* The integers representing data types which Zlib::ZStream#data_type
3271
* Zlib::NO_COMPRESSION
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.
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.
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.
3290
* The default value of windowBits which is an argument for
3291
* Zlib::Deflate.new and Zlib::Inflate.new.
3297
* The integers to control the output of the deflate stream, which are
3298
* an argument for Zlib::Deflate#deflate and so on.
3316
* The return values of Zlib::GzipFile#os_code method.
3320
VALUE mZlib, cZStream, cDeflate, cInflate;
3322
VALUE cGzipFile, cGzipWriter, cGzipReader;
3325
mZlib = rb_define_module("Zlib");
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);
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);
3341
rb_define_const(mZlib, "VERSION", rb_str_new2(RUBY_ZLIB_VERSION));
3342
rb_define_const(mZlib, "ZLIB_VERSION", rb_str_new2(ZLIB_VERSION));
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);
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));
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);
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);
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));
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));
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));
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));
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");
3415
cGzipFile = rb_define_class_under(mZlib, "GzipFile", rb_cObject);
3416
cGzError = rb_define_class_under(cGzipFile, "Error", cZError);
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);
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);
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);
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);
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);
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));
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));
3497
#endif /* GZIP_SUPPORT */
3500
/* Document error classes. */
3503
* Document-class: Zlib::Error
3505
* The superclass for all exceptions raised by Ruby/zlib.
3507
* The following exceptions are defined as subclasses of Zlib::Error. These
3508
* exceptions are raised when zlib library functions return with an error
3514
* - Zlib::StreamError
3517
* - Zlib::VersionError
3522
* Document-class: Zlib::GzipFile::Error
3524
* Base class of errors that occur when processing GZIP files.
3528
* Document-class: Zlib::GzipFile::NoFooter
3530
* Raised when gzip file footer is not found.
3534
* Document-class: Zlib::GzipFile::CRCError
3536
* Raised when the CRC checksum recorded in gzip file footer is not equivalent
3537
* to the CRC checksum of the actual uncompressed data.
3541
* Document-class: Zlib::GzipFile::LengthError
3543
* Raised when the data length recorded in the gzip file footer is not equivalent
3544
* to the length of the actual uncompressed data.