32
32
/*--------- Prototypes --------*/
34
static NORETURN(void raise_zlib_error _((int, const char *)));
34
static NORETURN(void raise_zlib_error _((int, const char*)));
35
35
static VALUE rb_zlib_version _((VALUE));
36
36
static VALUE do_checksum _((int, VALUE*, uLong (*) _((uLong, const Bytef*, uInt))));
37
37
static VALUE rb_zlib_adler32 _((int, VALUE*, VALUE));
39
39
static VALUE rb_zlib_crc_table _((VALUE));
40
40
static voidpf zlib_mem_alloc _((voidpf, uInt, uInt));
41
41
static void zlib_mem_free _((voidpf, voidpf));
42
static void finalizer_warn _((const char*));
44
45
struct zstream_funcs;
45
static void zstream_init _((struct zstream*, const struct zstream_funcs *));
46
static void zstream_init _((struct zstream*, const struct zstream_funcs*));
46
47
static void zstream_expand_buffer _((struct zstream*));
47
48
static void zstream_expand_buffer_into _((struct zstream*, int));
48
static void zstream_append_buffer _((struct zstream*, const char*, int));
49
static void zstream_append_buffer _((struct zstream*, const Bytef*, int));
49
50
static VALUE zstream_detach_buffer _((struct zstream*));
50
51
static VALUE zstream_shift_buffer _((struct zstream*, int));
51
52
static void zstream_buffer_ungetc _((struct zstream*, int));
52
static void zstream_append_input _((struct zstream*, const char*, unsigned int));
53
static void zstream_append_input _((struct zstream*, const Bytef*, unsigned int));
53
54
static void zstream_discard_input _((struct zstream*, unsigned int));
54
55
static void zstream_reset_input _((struct zstream*));
55
56
static void zstream_passthrough_input _((struct zstream*));
62
63
static void zstream_free _((struct zstream*));
63
64
static VALUE zstream_new _((VALUE, const struct zstream_funcs*));
64
65
static struct zstream *get_zstream _((VALUE));
66
static void zstream_finalize _((struct zstream*));
66
68
static VALUE rb_zstream_end _((VALUE));
67
69
static VALUE rb_zstream_reset _((VALUE));
127
129
static VALUE gzfile_read _((struct gzfile*, int));
128
130
static VALUE gzfile_read_all _((struct gzfile*));
129
131
static void gzfile_ungetc _((struct gzfile*, int));
130
static VALUE gzfile_finalize _((VALUE));
132
static VALUE gzfile_writer_end_run _((VALUE));
131
133
static void gzfile_writer_end _((struct gzfile*));
134
static VALUE gzfile_reader_end_run _((VALUE));
132
135
static void gzfile_reader_end _((struct gzfile*));
133
136
static void gzfile_reader_rewind _((struct gzfile*));
134
137
static VALUE gzfile_reader_get_unused _((struct gzfile*));
262
274
do_checksum(argc, argv, func)
265
uLong (*func) _((uLong, const Bytef *, uInt));
277
uLong (*func) _((uLong, const Bytef*, uInt));
268
280
unsigned long sum;
286
298
StringValue(str);
287
sum = func(sum, RSTRING(str)->ptr, RSTRING(str)->len);
299
sum = func(sum, (Bytef*)RSTRING(str)->ptr, RSTRING(str)->len);
289
301
return rb_uint2inum(sum);
365
377
#define ZSTREAM_FLAG_READY 0x1
366
378
#define ZSTREAM_FLAG_IN_STREAM 0x2
367
379
#define ZSTREAM_FLAG_FINISHED 0x4
368
#define ZSTREAM_FLAG_FINALIZE 0x8
369
#define ZSTREAM_FLAG_CLOSED 0x10
370
#define ZSTREAM_FLAG_UNUSED 0x20
380
#define ZSTREAM_FLAG_CLOSING 0x8
381
#define ZSTREAM_FLAG_UNUSED 0x10
372
383
#define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
373
384
#define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
374
385
#define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)
375
#define ZSTREAM_IS_FINALIZE(z) ((z)->flags & ZSTREAM_FLAG_FINALIZE)
376
#define ZSTREAM_IS_CLOSED(z) ((z)->flags & ZSTREAM_FLAG_CLOSED)
386
#define ZSTREAM_IS_CLOSING(z) ((z)->flags & ZSTREAM_FLAG_CLOSING)
378
388
/* I think that more better value should be found,
379
389
but I gave up finding it. B) */
439
449
rb_str_buf_new makes a zero-length string. */
440
450
z->buf = rb_str_new(0, ZSTREAM_INITIAL_BUFSIZE);
441
451
z->buf_filled = 0;
442
z->stream.next_out = RSTRING(z->buf)->ptr;
452
z->stream.next_out = (Bytef*)RSTRING(z->buf)->ptr;
443
453
z->stream.avail_out = ZSTREAM_INITIAL_BUFSIZE;
444
454
RBASIC(z->buf)->klass = 0;
458
468
z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
459
469
inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
461
z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;
471
z->stream.next_out = (Bytef*)RSTRING(z->buf)->ptr + z->buf_filled;
471
481
rb_str_buf_new makes a zero-length string. */
472
482
z->buf = rb_str_new(0, size);
473
483
z->buf_filled = 0;
474
z->stream.next_out = RSTRING(z->buf)->ptr;
484
z->stream.next_out = (Bytef*)RSTRING(z->buf)->ptr;
475
485
z->stream.avail_out = size;
476
486
RBASIC(z->buf)->klass = 0;
478
488
else if (z->stream.avail_out != size) {
479
489
rb_str_resize(z->buf, z->buf_filled + size);
480
z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;
490
z->stream.next_out = (Bytef*)RSTRING(z->buf)->ptr + z->buf_filled;
481
491
z->stream.avail_out = size;
486
496
zstream_append_buffer(z, src, len)
487
497
struct zstream *z;
491
501
if (NIL_P(z->buf)) {
492
502
z->buf = rb_str_buf_new(len);
493
rb_str_buf_cat(z->buf, src, len);
503
rb_str_buf_cat(z->buf, (char*)src, len);
494
504
z->buf_filled = len;
495
z->stream.next_out = RSTRING(z->buf)->ptr;
505
z->stream.next_out = (Bytef*)RSTRING(z->buf)->ptr;
496
506
z->stream.avail_out = 0;
497
507
RBASIC(z->buf)->klass = 0;
513
523
memcpy(RSTRING(z->buf)->ptr + z->buf_filled, src, len);
514
524
z->buf_filled += len;
515
z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;
525
z->stream.next_out = (Bytef*)RSTRING(z->buf)->ptr + z->buf_filled;
518
528
#define zstream_append_buffer2(z,v) \
519
zstream_append_buffer((z),RSTRING(v)->ptr,RSTRING(v)->len)
529
zstream_append_buffer((z),(Bytef*)RSTRING(v)->ptr,RSTRING(v)->len)
522
532
zstream_detach_buffer(z)
556
566
z->buf_filled -= len;
557
567
memmove(RSTRING(z->buf)->ptr, RSTRING(z->buf)->ptr + len,
559
z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;
569
z->stream.next_out = (Bytef*)RSTRING(z->buf)->ptr + z->buf_filled;
560
570
z->stream.avail_out = RSTRING(z->buf)->len - z->buf_filled;
561
571
if (z->stream.avail_out > ZSTREAM_AVAIL_OUT_STEP_MAX) {
562
572
z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
587
597
zstream_append_input(z, src, len)
588
598
struct zstream *z;
590
600
unsigned int len;
592
602
if (len <= 0) return;
594
604
if (NIL_P(z->input)) {
595
605
z->input = rb_str_buf_new(len);
596
rb_str_buf_cat(z->input, src, len);
606
rb_str_buf_cat(z->input, (char*)src, len);
597
607
RBASIC(z->input)->klass = 0;
600
rb_str_buf_cat(z->input, src, len);
610
rb_str_buf_cat(z->input, (char*)src, len);
604
614
#define zstream_append_input2(z,v)\
605
zstream_append_input((z), RSTRING(v)->ptr, RSTRING(v)->len)
615
zstream_append_input((z), (Bytef*)RSTRING(v)->ptr, RSTRING(v)->len)
608
618
zstream_discard_input(z, len)
663
673
err = z->func->reset(&z->stream);
664
if (err != Z_OK && !ZSTREAM_IS_FINALIZE(z)) {
665
675
raise_zlib_error(err, z->stream.msg);
667
677
z->flags = ZSTREAM_FLAG_READY;
681
if (!ZSTREAM_IS_READY(z) && !ZSTREAM_IS_FINALIZE(z)) {
682
if (RTEST(ruby_debug)) {
683
rb_warning("attempt to close uninitialized zstream; ignored.");
691
if (!ZSTREAM_IS_READY(z)) {
692
rb_warning("attempt to close uninitialized zstream; ignored.");
687
695
if (z->flags & ZSTREAM_FLAG_IN_STREAM) {
688
if (RTEST(ruby_debug)) {
689
rb_warning("attempt to close unfinished zstream; reset forced.");
696
rb_warning("attempt to close unfinished zstream; reset forced.");
691
697
zstream_reset(z);
694
700
zstream_reset_input(z);
695
701
err = z->func->end(&z->stream);
696
if (err != Z_OK && !ZSTREAM_IS_FINALIZE(z)) {
697
703
raise_zlib_error(err, z->stream.msg);
712
718
volatile VALUE guard;
714
720
if (NIL_P(z->input) && len == 0) {
715
z->stream.next_in = "";
721
z->stream.next_in = (Bytef*)"";
716
722
z->stream.avail_in = 0;
719
725
zstream_append_input(z, src, len);
720
z->stream.next_in = RSTRING(z->input)->ptr;
726
z->stream.next_in = (Bytef*)RSTRING(z->input)->ptr;
721
727
z->stream.avail_in = RSTRING(z->input)->len;
722
728
/* keep reference to `z->input' so as not to be garbage collected
723
729
after zstream_reset_input() and prevent `z->stream.next_in'
787
794
zstream_reset_input(z);
788
795
if (err != Z_DATA_ERROR) {
789
rest = rb_str_new(z->stream.next_in, z->stream.avail_in);
796
rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in);
790
797
raise_zlib_error(err, z->stream.msg);
803
810
if (err != Z_DATA_ERROR) {
804
rest = rb_str_new(z->stream.next_in, z->stream.avail_in);
811
rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in);
805
812
raise_zlib_error(err, z->stream.msg);
829
int err = z->func->end(&z->stream);
830
if (err == Z_STREAM_ERROR)
831
finalizer_warn("the stream state was inconsistent.");
832
if (err == Z_DATA_ERROR)
833
finalizer_warn("the stream was freed prematurely.");
820
838
struct zstream *z;
822
z->flags |= ZSTREAM_FLAG_FINALIZE;
840
if (ZSTREAM_IS_READY(z)) {
953
972
struct zstream *z = get_zstream(obj);
956
zstream_run(z, "", 0, Z_FINISH);
975
zstream_run(z, (Bytef*)"", 0, Z_FINISH);
957
976
dst = zstream_detach_buffer(z);
959
978
OBJ_INFECT(dst, obj);
1183
1202
deflate_run(args)
1186
struct zstream *z = (struct zstream *)((VALUE *)args)[0];
1187
VALUE src = ((VALUE *)args)[1];
1205
struct zstream *z = (struct zstream*)((VALUE*)args)[0];
1206
VALUE src = ((VALUE*)args)[1];
1189
zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_FINISH);
1208
zstream_run(z, (Bytef*)RSTRING(src)->ptr, RSTRING(src)->len, Z_FINISH);
1190
1209
return zstream_detach_buffer(z);
1248
1267
if (NIL_P(src)) {
1249
zstream_run(z, "", 0, Z_FINISH);
1268
zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1252
1271
StringValue(src);
1253
1272
if (flush != Z_NO_FLUSH || RSTRING(src)->len > 0) { /* prevent BUF_ERROR */
1254
zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, flush);
1273
zstream_run(z, (Bytef*)RSTRING(src)->ptr, RSTRING(src)->len, flush);
1325
1344
rb_scan_args(argc, argv, "01", &v_flush);
1326
1345
flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
1327
1346
if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
1328
zstream_run(z, "", 0, flush);
1347
zstream_run(z, (Bytef*)"", 0, flush);
1330
1349
dst = zstream_detach_buffer(z);
1356
1375
err = deflateParams(&z->stream, level, strategy);
1357
1376
while (err == Z_BUF_ERROR) {
1358
if (RTEST(ruby_debug)) {
1359
rb_warning("deflateParams() returned Z_BUF_ERROR");
1377
rb_warning("deflateParams() returned Z_BUF_ERROR");
1361
1378
zstream_expand_buffer(z);
1362
1379
err = deflateParams(&z->stream, level, strategy);
1388
1405
OBJ_INFECT(obj, dic);
1389
1406
StringValue(src);
1390
1407
err = deflateSetDictionary(&z->stream,
1391
RSTRING(src)->ptr, RSTRING(src)->len);
1408
(Bytef*)RSTRING(src)->ptr, RSTRING(src)->len);
1392
1409
if (err != Z_OK) {
1393
1410
raise_zlib_error(err, z->stream.msg);
1450
1467
inflate_run(args)
1453
struct zstream *z = (struct zstream *)((VALUE *)args)[0];
1454
VALUE src = ((VALUE *)args)[1];
1470
struct zstream *z = (struct zstream*)((VALUE*)args)[0];
1471
VALUE src = ((VALUE*)args)[1];
1456
zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_SYNC_FLUSH);
1457
zstream_run(z, "", 0, Z_FINISH); /* for checking errors */
1473
zstream_run(z, (Bytef*)RSTRING(src)->ptr, RSTRING(src)->len, Z_SYNC_FLUSH);
1474
zstream_run(z, (Bytef*)"", 0, Z_FINISH); /* for checking errors */
1458
1475
return zstream_detach_buffer(z);
1507
1524
if (NIL_P(src)) {
1508
zstream_run(z, "", 0, Z_FINISH);
1525
zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1511
1528
StringValue(src);
1512
1529
if (RSTRING(src)->len > 0) { /* prevent Z_BUF_ERROR */
1513
zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_SYNC_FLUSH);
1530
zstream_run(z, (Bytef*)RSTRING(src)->ptr, RSTRING(src)->len, Z_SYNC_FLUSH);
1650
1667
OBJ_INFECT(obj, dic);
1651
1668
StringValue(src);
1652
1669
err = inflateSetDictionary(&z->stream,
1653
RSTRING(src)->ptr, RSTRING(src)->len);
1670
(Bytef*)RSTRING(src)->ptr, RSTRING(src)->len);
1654
1671
if (err != Z_OK) {
1655
1672
raise_zlib_error(err, z->stream.msg);
1749
1766
gzfile_free(gz)
1750
1767
struct gzfile *gz;
1752
gz->z.flags |= ZSTREAM_FLAG_FINALIZE;
1753
if (ZSTREAM_IS_READY(&gz->z)) {
1769
struct zstream *z = &gz->z;
1771
if (ZSTREAM_IS_READY(z)) {
1772
if (z->func == &deflate_funcs) {
1773
finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
1775
zstream_finalize(z);
1830
1851
gzfile_read_raw_partial(arg)
1833
struct gzfile *gz = (struct gzfile *)arg;
1854
struct gzfile *gz = (struct gzfile*)arg;
1836
1857
str = rb_funcall(gz->io, id_readpartial, 1, INT2FIX(GZFILE_READ_SIZE));
1842
1863
gzfile_read_raw_rescue(arg)
1845
struct gzfile *gz = (struct gzfile *)arg;
1866
struct gzfile *gz = (struct gzfile*)arg;
1846
1867
VALUE str = Qnil;
1847
1868
if (rb_obj_is_kind_of(ruby_errinfo, rb_eNoMethodError)) {
1848
1869
str = rb_funcall(gz->io, id_read, 1, INT2FIX(GZFILE_READ_SIZE));
1936
1957
gzfile_make_header(gz)
1937
1958
struct gzfile *gz;
1939
unsigned char buf[10]; /* the size of gzip header */
1960
Bytef buf[10]; /* the size of gzip header */
1940
1961
unsigned char flags = 0, extraflags = 0;
1942
1963
if (!NIL_P(gz->orig_name)) {
1968
1989
if (!NIL_P(gz->orig_name)) {
1969
1990
zstream_append_buffer2(&gz->z, gz->orig_name);
1970
zstream_append_buffer(&gz->z, "\0", 1);
1991
zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
1972
1993
if (!NIL_P(gz->comment)) {
1973
1994
zstream_append_buffer2(&gz->z, gz->comment);
1974
zstream_append_buffer(&gz->z, "\0", 1);
1995
zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
1977
1998
gz->z.flags |= GZFILE_FLAG_HEADER_FINISHED;
1981
2002
gzfile_make_footer(gz)
1982
2003
struct gzfile *gz;
1984
unsigned char buf[8]; /* 8 is the size of gzip footer */
2005
Bytef buf[8]; /* 8 is the size of gzip footer */
1986
2007
gzfile_set32(gz->crc, buf);
1987
2008
gzfile_set32(gz->z.stream.total_in, &buf[4]);
2001
2022
rb_raise(cGzError, "not in gzip format");
2004
head = RSTRING(gz->z.input)->ptr;
2025
head = (unsigned char*)RSTRING(gz->z.input)->ptr;
2006
2027
if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {
2007
2028
rb_raise(cGzError, "not in gzip format");
2039
2060
if (!gzfile_read_raw_ensure(gz, 2)) {
2040
2061
rb_raise(cGzError, "unexpected end of file");
2042
len = gzfile_get16(RSTRING(gz->z.input)->ptr);
2063
len = gzfile_get16((Bytef*)RSTRING(gz->z.input)->ptr);
2043
2064
if (!gzfile_read_raw_ensure(gz, 2 + len)) {
2044
2065
rb_raise(cGzError, "unexpected end of file");
2077
2098
rb_raise(cNoFooter, "footer is not found");
2080
crc = gzfile_get32(RSTRING(gz->z.input)->ptr);
2081
length = gzfile_get32(RSTRING(gz->z.input)->ptr + 4);
2101
crc = gzfile_get32((Bytef*)RSTRING(gz->z.input)->ptr);
2102
length = gzfile_get32((Bytef*)RSTRING(gz->z.input)->ptr + 4);
2083
2104
gz->z.stream.total_in += 8; /* to rewind correctly */
2084
2105
zstream_discard_input(&gz->z, 8);
2126
2147
if (RSTRING(str)->len > 0) { /* prevent Z_BUF_ERROR */
2127
zstream_run(&gz->z, RSTRING(str)->ptr, RSTRING(str)->len,
2148
zstream_run(&gz->z, (Bytef*)RSTRING(str)->ptr, RSTRING(str)->len,
2130
2151
if (gz->z.buf_filled > 0) break;
2141
2162
gz->ungetc -= RSTRING(str)->len;
2144
gz->crc = crc32(gz->crc, RSTRING(str)->ptr + gz->ungetc,
2165
gz->crc = crc32(gz->crc, (Bytef*)RSTRING(str)->ptr + gz->ungetc,
2145
2166
RSTRING(str)->len - gz->ungetc);
2146
2167
gz->ungetc = 0;
2259
gzfile_finalize(obj)
2280
gzfile_writer_end_run(arg)
2262
struct gzfile *gz = (struct gzfile *)obj;
2283
struct gzfile *gz = (struct gzfile *)arg;
2285
if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2286
gzfile_make_header(gz);
2289
zstream_run(&gz->z, (Bytef*)"", 0, Z_FINISH);
2290
gzfile_make_footer(gz);
2263
2291
gzfile_write_raw(gz);
2268
2297
gzfile_writer_end(gz)
2269
2298
struct gzfile *gz;
2273
if (ZSTREAM_IS_CLOSED(&gz->z)) return;
2274
gz->z.flags |= ZSTREAM_FLAG_CLOSED;
2276
if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2277
gzfile_make_header(gz);
2280
zstream_run(&gz->z, "", 0, Z_FINISH);
2281
gzfile_make_footer(gz);
2283
if (ZSTREAM_IS_FINALIZE(&gz->z)) {
2284
if (NIL_P(gz->io)) return;
2285
rb_warn("Zlib::GzipWriter object must be closed explicitly.");
2286
if (!SPECIAL_CONST_P(gz->io) && OBJ_IS_FREED(gz->io)) {
2290
rb_protect(gzfile_finalize, (VALUE)gz, &aborted);
2293
rb_warn("gzip footer is not written; broken gzip file");
2295
zstream_end(&gz->z);
2298
gzfile_write_raw(gz);
2299
zstream_end(&gz->z);
2300
if (ZSTREAM_IS_CLOSING(&gz->z)) return;
2301
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
2303
rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
2303
gzfile_reader_end(gz)
2307
gzfile_reader_end_run(arg)
2306
if (ZSTREAM_IS_CLOSED(&gz->z)) return;
2307
gz->z.flags |= ZSTREAM_FLAG_CLOSED;
2310
struct gzfile *gz = (struct gzfile *)arg;
2309
2312
if (GZFILE_IS_FINISHED(gz)
2310
&& !ZSTREAM_IS_FINALIZE(&gz->z)
2311
2313
&& !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2312
2314
gzfile_check_footer(gz);
2315
zstream_end(&gz->z);
2321
gzfile_reader_end(gz)
2324
if (ZSTREAM_IS_CLOSING(&gz->z)) return;
2325
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
2327
rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
2822
2834
flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
2823
2835
if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
2824
zstream_run(&gz->z, "", 0, flush);
2836
zstream_run(&gz->z, (Bytef*)"", 0, flush);
2827
2839
gzfile_write_raw(gz);
2843
2855
if (TYPE(str) != T_STRING) {
2844
2856
str = rb_obj_as_string(str);
2846
gzfile_write(gz, RSTRING(str)->ptr, RSTRING(str)->len);
2858
gzfile_write(gz, (Bytef*)RSTRING(str)->ptr, RSTRING(str)->len);
2847
2859
return INT2FIX(RSTRING(str)->len);