zlib 0.1.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +30 -3
- data/ext/zlib/extconf.rb +9 -4
- data/ext/zlib/zlib.c +414 -198
- data/zlib.gemspec +16 -10
- metadata +10 -58
- data/.gitignore +0 -12
- data/.travis.yml +0 -5
- data/Gemfile +0 -4
- data/Rakefile +0 -13
- data/bin/console +0 -14
- data/bin/setup +0 -8
data/ext/zlib/zlib.c
CHANGED
@@ -25,7 +25,11 @@
|
|
25
25
|
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
|
26
26
|
#endif
|
27
27
|
|
28
|
-
#define RUBY_ZLIB_VERSION
|
28
|
+
#define RUBY_ZLIB_VERSION "2.1.0"
|
29
|
+
|
30
|
+
#ifndef RB_PASS_CALLED_KEYWORDS
|
31
|
+
# define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
|
32
|
+
#endif
|
29
33
|
|
30
34
|
#ifndef GZIP_SUPPORT
|
31
35
|
#define GZIP_SUPPORT 1
|
@@ -52,7 +56,10 @@ max_uint(long n)
|
|
52
56
|
#define MAX_UINT(n) (uInt)(n)
|
53
57
|
#endif
|
54
58
|
|
55
|
-
|
59
|
+
#define OPTHASH_GIVEN_P(opts) \
|
60
|
+
(argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
|
61
|
+
|
62
|
+
static ID id_dictionaries, id_read, id_buffer;
|
56
63
|
|
57
64
|
/*--------- Prototypes --------*/
|
58
65
|
|
@@ -85,6 +92,7 @@ static void zstream_passthrough_input(struct zstream*);
|
|
85
92
|
static VALUE zstream_detach_input(struct zstream*);
|
86
93
|
static void zstream_reset(struct zstream*);
|
87
94
|
static VALUE zstream_end(struct zstream*);
|
95
|
+
static VALUE zstream_ensure_end(VALUE v);
|
88
96
|
static void zstream_run(struct zstream*, Bytef*, long, int);
|
89
97
|
static VALUE zstream_sync(struct zstream*, Bytef*, long);
|
90
98
|
static void zstream_mark(void*);
|
@@ -125,7 +133,7 @@ static VALUE rb_inflate_s_allocate(VALUE);
|
|
125
133
|
static VALUE rb_inflate_initialize(int, VALUE*, VALUE);
|
126
134
|
static VALUE rb_inflate_s_inflate(VALUE, VALUE);
|
127
135
|
static void do_inflate(struct zstream*, VALUE);
|
128
|
-
static VALUE rb_inflate_inflate(
|
136
|
+
static VALUE rb_inflate_inflate(int, VALUE*, VALUE);
|
129
137
|
static VALUE rb_inflate_addstr(VALUE, VALUE);
|
130
138
|
static VALUE rb_inflate_sync(VALUE, VALUE);
|
131
139
|
static VALUE rb_inflate_sync_point_p(VALUE);
|
@@ -140,19 +148,19 @@ static void gzfile_reset(struct gzfile*);
|
|
140
148
|
static void gzfile_close(struct gzfile*, int);
|
141
149
|
static void gzfile_write_raw(struct gzfile*);
|
142
150
|
static VALUE gzfile_read_raw_partial(VALUE);
|
143
|
-
static VALUE gzfile_read_raw_rescue(VALUE);
|
144
|
-
static VALUE gzfile_read_raw(struct gzfile
|
145
|
-
static int gzfile_read_raw_ensure(struct gzfile*, long);
|
151
|
+
static VALUE gzfile_read_raw_rescue(VALUE,VALUE);
|
152
|
+
static VALUE gzfile_read_raw(struct gzfile*, VALUE outbuf);
|
153
|
+
static int gzfile_read_raw_ensure(struct gzfile*, long, VALUE outbuf);
|
146
154
|
static char *gzfile_read_raw_until_zero(struct gzfile*, long);
|
147
155
|
static unsigned int gzfile_get16(const unsigned char*);
|
148
156
|
static unsigned long gzfile_get32(const unsigned char*);
|
149
157
|
static void gzfile_set32(unsigned long n, unsigned char*);
|
150
158
|
static void gzfile_make_header(struct gzfile*);
|
151
159
|
static void gzfile_make_footer(struct gzfile*);
|
152
|
-
static void gzfile_read_header(struct gzfile
|
153
|
-
static void gzfile_check_footer(struct gzfile
|
160
|
+
static void gzfile_read_header(struct gzfile*, VALUE outbuf);
|
161
|
+
static void gzfile_check_footer(struct gzfile*, VALUE outbuf);
|
154
162
|
static void gzfile_write(struct gzfile*, Bytef*, long);
|
155
|
-
static long gzfile_read_more(struct gzfile
|
163
|
+
static long gzfile_read_more(struct gzfile*, VALUE outbuf);
|
156
164
|
static void gzfile_calc_crc(struct gzfile*, VALUE);
|
157
165
|
static VALUE gzfile_read(struct gzfile*, long);
|
158
166
|
static VALUE gzfile_read_all(struct gzfile*);
|
@@ -197,7 +205,7 @@ static VALUE rb_gzwriter_s_allocate(VALUE);
|
|
197
205
|
static VALUE rb_gzwriter_s_open(int, VALUE*, VALUE);
|
198
206
|
static VALUE rb_gzwriter_initialize(int, VALUE*, VALUE);
|
199
207
|
static VALUE rb_gzwriter_flush(int, VALUE*, VALUE);
|
200
|
-
static VALUE rb_gzwriter_write(
|
208
|
+
static VALUE rb_gzwriter_write(int, VALUE*, VALUE);
|
201
209
|
static VALUE rb_gzwriter_putc(VALUE, VALUE);
|
202
210
|
|
203
211
|
static VALUE rb_gzreader_s_allocate(VALUE);
|
@@ -346,7 +354,9 @@ raise_zlib_error(int err, const char *msg)
|
|
346
354
|
static void
|
347
355
|
finalizer_warn(const char *msg)
|
348
356
|
{
|
357
|
+
#if 0
|
349
358
|
fprintf(stderr, "zlib(finalizer): %s\n", msg);
|
359
|
+
#endif
|
350
360
|
}
|
351
361
|
|
352
362
|
|
@@ -360,11 +370,7 @@ finalizer_warn(const char *msg)
|
|
360
370
|
static VALUE
|
361
371
|
rb_zlib_version(VALUE klass)
|
362
372
|
{
|
363
|
-
|
364
|
-
|
365
|
-
str = rb_str_new2(zlibVersion());
|
366
|
-
OBJ_TAINT(str); /* for safe */
|
367
|
-
return str;
|
373
|
+
return rb_str_new2(zlibVersion());
|
368
374
|
}
|
369
375
|
|
370
376
|
#if SIZEOF_LONG > SIZEOF_INT
|
@@ -406,6 +412,15 @@ do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt))
|
|
406
412
|
if (NIL_P(str)) {
|
407
413
|
sum = func(sum, Z_NULL, 0);
|
408
414
|
}
|
415
|
+
else if (rb_obj_is_kind_of(str, rb_cIO)) {
|
416
|
+
VALUE buf;
|
417
|
+
VALUE buflen = INT2NUM(8192);
|
418
|
+
|
419
|
+
while (!NIL_P(buf = rb_funcall(str, id_read, 1, buflen))) {
|
420
|
+
StringValue(buf);
|
421
|
+
sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(buf), RSTRING_LEN(buf));
|
422
|
+
}
|
423
|
+
}
|
409
424
|
else {
|
410
425
|
StringValue(str);
|
411
426
|
sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
|
@@ -421,6 +436,8 @@ do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt))
|
|
421
436
|
* Calculates Adler-32 checksum for +string+, and returns updated value of
|
422
437
|
* +adler+. If +string+ is omitted, it returns the Adler-32 initial value. If
|
423
438
|
* +adler+ is omitted, it assumes that the initial value is given to +adler+.
|
439
|
+
* If +string+ is an IO instance, reads from the IO until the IO returns nil
|
440
|
+
* and returns Adler-32 of all read data.
|
424
441
|
*
|
425
442
|
* Example usage:
|
426
443
|
*
|
@@ -451,7 +468,7 @@ rb_zlib_adler32(int argc, VALUE *argv, VALUE klass)
|
|
451
468
|
static VALUE
|
452
469
|
rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
|
453
470
|
{
|
454
|
-
|
471
|
+
return ULONG2NUM(
|
455
472
|
adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
|
456
473
|
}
|
457
474
|
#else
|
@@ -465,7 +482,9 @@ rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
|
|
465
482
|
*
|
466
483
|
* Calculates CRC checksum for +string+, and returns updated value of +crc+. If
|
467
484
|
* +string+ is omitted, it returns the CRC initial value. If +crc+ is omitted, it
|
468
|
-
* assumes that the initial value is given to +crc+.
|
485
|
+
* assumes that the initial value is given to +crc+. If +string+ is an IO instance,
|
486
|
+
* reads from the IO until the IO returns nil and returns CRC checksum of all read
|
487
|
+
* data.
|
469
488
|
*
|
470
489
|
* FIXME: expression.
|
471
490
|
*/
|
@@ -489,7 +508,7 @@ rb_zlib_crc32(int argc, VALUE *argv, VALUE klass)
|
|
489
508
|
static VALUE
|
490
509
|
rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
|
491
510
|
{
|
492
|
-
|
511
|
+
return ULONG2NUM(
|
493
512
|
crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
|
494
513
|
}
|
495
514
|
#else
|
@@ -529,6 +548,7 @@ struct zstream {
|
|
529
548
|
unsigned long flags;
|
530
549
|
VALUE buf;
|
531
550
|
VALUE input;
|
551
|
+
VALUE mutex;
|
532
552
|
z_stream stream;
|
533
553
|
const struct zstream_funcs {
|
534
554
|
int (*reset)(z_streamp);
|
@@ -543,7 +563,8 @@ struct zstream {
|
|
543
563
|
#define ZSTREAM_FLAG_CLOSING 0x8
|
544
564
|
#define ZSTREAM_FLAG_GZFILE 0x10 /* disallows yield from expand_buffer for
|
545
565
|
gzip*/
|
546
|
-
#define
|
566
|
+
#define ZSTREAM_REUSE_BUFFER 0x20
|
567
|
+
#define ZSTREAM_FLAG_UNUSED 0x40
|
547
568
|
|
548
569
|
#define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
|
549
570
|
#define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
|
@@ -552,6 +573,8 @@ struct zstream {
|
|
552
573
|
#define ZSTREAM_IS_GZFILE(z) ((z)->flags & ZSTREAM_FLAG_GZFILE)
|
553
574
|
#define ZSTREAM_BUF_FILLED(z) (NIL_P((z)->buf) ? 0 : RSTRING_LEN((z)->buf))
|
554
575
|
|
576
|
+
#define ZSTREAM_REUSE_BUFFER_P(z) ((z)->flags & ZSTREAM_REUSE_BUFFER)
|
577
|
+
|
555
578
|
#define ZSTREAM_EXPAND_BUFFER_OK 0
|
556
579
|
|
557
580
|
/* I think that more better value should be found,
|
@@ -601,6 +624,7 @@ zstream_init(struct zstream *z, const struct zstream_funcs *func)
|
|
601
624
|
z->flags = 0;
|
602
625
|
z->buf = Qnil;
|
603
626
|
z->input = Qnil;
|
627
|
+
z->mutex = rb_mutex_new();
|
604
628
|
z->stream.zalloc = zlib_mem_alloc;
|
605
629
|
z->stream.zfree = zlib_mem_free;
|
606
630
|
z->stream.opaque = Z_NULL;
|
@@ -627,14 +651,22 @@ zstream_expand_buffer(struct zstream *z)
|
|
627
651
|
long buf_filled = ZSTREAM_BUF_FILLED(z);
|
628
652
|
if (buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
|
629
653
|
int state = 0;
|
630
|
-
VALUE self = (VALUE)z->stream.opaque;
|
631
654
|
|
632
|
-
|
633
|
-
|
655
|
+
if (!ZSTREAM_REUSE_BUFFER_P(z)) {
|
656
|
+
rb_obj_reveal(z->buf, rb_cString);
|
657
|
+
}
|
634
658
|
|
659
|
+
rb_mutex_unlock(z->mutex);
|
635
660
|
rb_protect(rb_yield, z->buf, &state);
|
636
|
-
|
637
|
-
|
661
|
+
rb_mutex_lock(z->mutex);
|
662
|
+
|
663
|
+
if (ZSTREAM_REUSE_BUFFER_P(z)) {
|
664
|
+
rb_str_modify(z->buf);
|
665
|
+
rb_str_set_len(z->buf, 0);
|
666
|
+
}
|
667
|
+
else {
|
668
|
+
z->buf = Qnil;
|
669
|
+
}
|
638
670
|
zstream_expand_buffer_into(z, ZSTREAM_AVAIL_OUT_STEP_MAX);
|
639
671
|
|
640
672
|
if (state)
|
@@ -644,7 +676,7 @@ zstream_expand_buffer(struct zstream *z)
|
|
644
676
|
}
|
645
677
|
else {
|
646
678
|
zstream_expand_buffer_into(z,
|
647
|
-
|
679
|
+
ZSTREAM_AVAIL_OUT_STEP_MAX - buf_filled);
|
648
680
|
}
|
649
681
|
}
|
650
682
|
else {
|
@@ -738,7 +770,7 @@ zstream_append_buffer(struct zstream *z, const Bytef *src, long len)
|
|
738
770
|
static VALUE
|
739
771
|
zstream_detach_buffer(struct zstream *z)
|
740
772
|
{
|
741
|
-
VALUE dst
|
773
|
+
VALUE dst;
|
742
774
|
|
743
775
|
if (!ZSTREAM_IS_FINISHED(z) && !ZSTREAM_IS_GZFILE(z) &&
|
744
776
|
rb_block_given_p()) {
|
@@ -752,11 +784,11 @@ zstream_detach_buffer(struct zstream *z)
|
|
752
784
|
}
|
753
785
|
else {
|
754
786
|
dst = z->buf;
|
755
|
-
|
787
|
+
if (!ZSTREAM_REUSE_BUFFER_P(z)) {
|
788
|
+
rb_obj_reveal(dst, rb_cString);
|
789
|
+
}
|
756
790
|
}
|
757
791
|
|
758
|
-
OBJ_INFECT(dst, self);
|
759
|
-
|
760
792
|
z->buf = Qnil;
|
761
793
|
z->stream.next_out = 0;
|
762
794
|
z->stream.avail_out = 0;
|
@@ -845,19 +877,50 @@ zstream_append_input(struct zstream *z, const Bytef *src, long len)
|
|
845
877
|
static void
|
846
878
|
zstream_discard_input(struct zstream *z, long len)
|
847
879
|
{
|
848
|
-
if (NIL_P(z->input)
|
849
|
-
z->input = Qnil;
|
880
|
+
if (NIL_P(z->input)) {
|
850
881
|
}
|
851
|
-
else {
|
852
|
-
|
853
|
-
|
882
|
+
else if (RBASIC_CLASS(z->input) == 0) {
|
883
|
+
/* hidden, we created z->input and have complete control */
|
884
|
+
char *ptr;
|
885
|
+
long oldlen, newlen;
|
886
|
+
|
887
|
+
RSTRING_GETMEM(z->input, ptr, oldlen);
|
888
|
+
newlen = oldlen - len;
|
889
|
+
if (newlen > 0) {
|
890
|
+
memmove(ptr, ptr + len, newlen);
|
891
|
+
}
|
892
|
+
if (newlen < 0) {
|
893
|
+
newlen = 0;
|
894
|
+
}
|
895
|
+
rb_str_resize(z->input, newlen);
|
896
|
+
if (newlen == 0) {
|
897
|
+
rb_gc_force_recycle(z->input);
|
898
|
+
z->input = Qnil;
|
899
|
+
}
|
900
|
+
else {
|
901
|
+
rb_str_set_len(z->input, newlen);
|
902
|
+
}
|
903
|
+
}
|
904
|
+
else { /* do not mangle user-provided data */
|
905
|
+
if (RSTRING_LEN(z->input) <= len) {
|
906
|
+
z->input = Qnil;
|
907
|
+
}
|
908
|
+
else {
|
909
|
+
z->input = rb_str_substr(z->input, len,
|
910
|
+
RSTRING_LEN(z->input) - len);
|
911
|
+
}
|
854
912
|
}
|
855
913
|
}
|
856
914
|
|
857
915
|
static void
|
858
916
|
zstream_reset_input(struct zstream *z)
|
859
917
|
{
|
860
|
-
z->input
|
918
|
+
if (!NIL_P(z->input) && RBASIC_CLASS(z->input) == 0) {
|
919
|
+
rb_str_resize(z->input, 0);
|
920
|
+
}
|
921
|
+
else {
|
922
|
+
z->input = Qnil;
|
923
|
+
}
|
861
924
|
}
|
862
925
|
|
863
926
|
static void
|
@@ -882,7 +945,6 @@ zstream_detach_input(struct zstream *z)
|
|
882
945
|
rb_obj_reveal(dst, rb_cString);
|
883
946
|
}
|
884
947
|
z->input = Qnil;
|
885
|
-
rb_obj_reveal(dst, rb_cString);
|
886
948
|
return dst;
|
887
949
|
}
|
888
950
|
|
@@ -925,6 +987,12 @@ zstream_end(struct zstream *z)
|
|
925
987
|
return Qnil;
|
926
988
|
}
|
927
989
|
|
990
|
+
static VALUE
|
991
|
+
zstream_ensure_end(VALUE v)
|
992
|
+
{
|
993
|
+
return zstream_end((struct zstream *)v);
|
994
|
+
}
|
995
|
+
|
928
996
|
static void *
|
929
997
|
zstream_run_func(void *ptr)
|
930
998
|
{
|
@@ -981,6 +1049,7 @@ zstream_run_func(void *ptr)
|
|
981
1049
|
|
982
1050
|
/*
|
983
1051
|
* There is no safe way to interrupt z->run->func().
|
1052
|
+
* async-signal-safe
|
984
1053
|
*/
|
985
1054
|
static void
|
986
1055
|
zstream_unblock_func(void *ptr)
|
@@ -991,11 +1060,11 @@ zstream_unblock_func(void *ptr)
|
|
991
1060
|
}
|
992
1061
|
|
993
1062
|
static void
|
994
|
-
|
1063
|
+
zstream_run0(struct zstream *z, Bytef *src, long len, int flush)
|
995
1064
|
{
|
996
1065
|
struct zstream_run_args args;
|
997
1066
|
int err;
|
998
|
-
VALUE
|
1067
|
+
VALUE old_input = Qnil;
|
999
1068
|
|
1000
1069
|
args.z = z;
|
1001
1070
|
args.flush = flush;
|
@@ -1009,12 +1078,13 @@ zstream_run(struct zstream *z, Bytef *src, long len, int flush)
|
|
1009
1078
|
}
|
1010
1079
|
else {
|
1011
1080
|
zstream_append_input(z, src, len);
|
1012
|
-
z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
|
1013
|
-
z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
|
1014
1081
|
/* keep reference to `z->input' so as not to be garbage collected
|
1015
1082
|
after zstream_reset_input() and prevent `z->stream.next_in'
|
1016
1083
|
from dangling. */
|
1017
|
-
|
1084
|
+
old_input = zstream_detach_input(z);
|
1085
|
+
rb_obj_hide(old_input); /* for GVL release and later recycle */
|
1086
|
+
z->stream.next_in = (Bytef*)RSTRING_PTR(old_input);
|
1087
|
+
z->stream.avail_in = MAX_UINT(RSTRING_LEN(old_input));
|
1018
1088
|
}
|
1019
1089
|
|
1020
1090
|
if (z->stream.avail_out == 0) {
|
@@ -1022,8 +1092,20 @@ zstream_run(struct zstream *z, Bytef *src, long len, int flush)
|
|
1022
1092
|
}
|
1023
1093
|
|
1024
1094
|
loop:
|
1095
|
+
#ifndef RB_NOGVL_UBF_ASYNC_SAFE
|
1025
1096
|
err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)&args,
|
1026
1097
|
zstream_unblock_func, (void *)&args);
|
1098
|
+
#else
|
1099
|
+
err = (int)(VALUE)rb_nogvl(zstream_run_func, (void *)&args,
|
1100
|
+
zstream_unblock_func, (void *)&args,
|
1101
|
+
RB_NOGVL_UBF_ASYNC_SAFE);
|
1102
|
+
#endif
|
1103
|
+
|
1104
|
+
/* retry if no exception is thrown */
|
1105
|
+
if (err == Z_OK && args.interrupt) {
|
1106
|
+
args.interrupt = 0;
|
1107
|
+
goto loop;
|
1108
|
+
}
|
1027
1109
|
|
1028
1110
|
if (flush != Z_FINISH && err == Z_BUF_ERROR
|
1029
1111
|
&& z->stream.avail_out > 0) {
|
@@ -1052,13 +1134,42 @@ loop:
|
|
1052
1134
|
|
1053
1135
|
if (z->stream.avail_in > 0) {
|
1054
1136
|
zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
|
1055
|
-
|
1137
|
+
}
|
1138
|
+
if (!NIL_P(old_input)) {
|
1139
|
+
rb_str_resize(old_input, 0);
|
1140
|
+
rb_gc_force_recycle(old_input);
|
1056
1141
|
}
|
1057
1142
|
|
1058
1143
|
if (args.jump_state)
|
1059
1144
|
rb_jump_tag(args.jump_state);
|
1060
1145
|
}
|
1061
1146
|
|
1147
|
+
struct zstream_run_synchronized_args {
|
1148
|
+
struct zstream *z;
|
1149
|
+
Bytef *src;
|
1150
|
+
long len;
|
1151
|
+
int flush;
|
1152
|
+
};
|
1153
|
+
|
1154
|
+
static VALUE
|
1155
|
+
zstream_run_synchronized(VALUE value_arg)
|
1156
|
+
{
|
1157
|
+
struct zstream_run_synchronized_args *run_args = (struct zstream_run_synchronized_args *)value_arg;
|
1158
|
+
zstream_run0(run_args->z, run_args->src, run_args->len, run_args->flush);
|
1159
|
+
return Qnil;
|
1160
|
+
}
|
1161
|
+
|
1162
|
+
static void
|
1163
|
+
zstream_run(struct zstream *z, Bytef *src, long len, int flush)
|
1164
|
+
{
|
1165
|
+
struct zstream_run_synchronized_args run_args;
|
1166
|
+
run_args.z = z;
|
1167
|
+
run_args.src = src;
|
1168
|
+
run_args.len = len;
|
1169
|
+
run_args.flush = flush;
|
1170
|
+
rb_mutex_synchronize(z->mutex, zstream_run_synchronized, (VALUE)&run_args);
|
1171
|
+
}
|
1172
|
+
|
1062
1173
|
static VALUE
|
1063
1174
|
zstream_sync(struct zstream *z, Bytef *src, long len)
|
1064
1175
|
{
|
@@ -1104,6 +1215,7 @@ zstream_mark(void *p)
|
|
1104
1215
|
struct zstream *z = p;
|
1105
1216
|
rb_gc_mark(z->buf);
|
1106
1217
|
rb_gc_mark(z->input);
|
1218
|
+
rb_gc_mark(z->mutex);
|
1107
1219
|
}
|
1108
1220
|
|
1109
1221
|
static void
|
@@ -1285,7 +1397,6 @@ rb_zstream_flush_next_in(VALUE obj)
|
|
1285
1397
|
|
1286
1398
|
TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
|
1287
1399
|
dst = zstream_detach_input(z);
|
1288
|
-
OBJ_INFECT(dst, obj);
|
1289
1400
|
return dst;
|
1290
1401
|
}
|
1291
1402
|
|
@@ -1381,7 +1492,7 @@ rb_zstream_data_type(VALUE obj)
|
|
1381
1492
|
static VALUE
|
1382
1493
|
rb_zstream_adler(VALUE obj)
|
1383
1494
|
{
|
1384
|
-
|
1495
|
+
return rb_uint2inum(get_zstream(obj)->stream.adler);
|
1385
1496
|
}
|
1386
1497
|
|
1387
1498
|
/*
|
@@ -1604,9 +1715,8 @@ rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
|
|
1604
1715
|
|
1605
1716
|
args[0] = (VALUE)&z;
|
1606
1717
|
args[1] = src;
|
1607
|
-
dst = rb_ensure(deflate_run, (VALUE)args,
|
1718
|
+
dst = rb_ensure(deflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z);
|
1608
1719
|
|
1609
|
-
OBJ_INFECT(dst, src);
|
1610
1720
|
return dst;
|
1611
1721
|
}
|
1612
1722
|
|
@@ -1656,7 +1766,6 @@ rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
|
|
1656
1766
|
VALUE src, flush;
|
1657
1767
|
|
1658
1768
|
rb_scan_args(argc, argv, "11", &src, &flush);
|
1659
|
-
OBJ_INFECT(obj, src);
|
1660
1769
|
do_deflate(z, src, ARG_FLUSH(flush));
|
1661
1770
|
|
1662
1771
|
return zstream_detach_buffer(z);
|
@@ -1674,7 +1783,6 @@ rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
|
|
1674
1783
|
static VALUE
|
1675
1784
|
rb_deflate_addstr(VALUE obj, VALUE src)
|
1676
1785
|
{
|
1677
|
-
OBJ_INFECT(obj, src);
|
1678
1786
|
do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
|
1679
1787
|
return obj;
|
1680
1788
|
}
|
@@ -1774,7 +1882,6 @@ rb_deflate_set_dictionary(VALUE obj, VALUE dic)
|
|
1774
1882
|
VALUE src = dic;
|
1775
1883
|
int err;
|
1776
1884
|
|
1777
|
-
OBJ_INFECT(obj, dic);
|
1778
1885
|
StringValue(src);
|
1779
1886
|
err = deflateSetDictionary(&z->stream,
|
1780
1887
|
(Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
|
@@ -1919,9 +2026,8 @@ rb_inflate_s_inflate(VALUE obj, VALUE src)
|
|
1919
2026
|
|
1920
2027
|
args[0] = (VALUE)&z;
|
1921
2028
|
args[1] = src;
|
1922
|
-
dst = rb_ensure(inflate_run, (VALUE)args,
|
2029
|
+
dst = rb_ensure(inflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z);
|
1923
2030
|
|
1924
|
-
OBJ_INFECT(dst, src);
|
1925
2031
|
return dst;
|
1926
2032
|
}
|
1927
2033
|
|
@@ -1962,8 +2068,8 @@ rb_inflate_add_dictionary(VALUE obj, VALUE dictionary)
|
|
1962
2068
|
* Document-method: Zlib::Inflate#inflate
|
1963
2069
|
*
|
1964
2070
|
* call-seq:
|
1965
|
-
* inflate(deflate_string) -> String
|
1966
|
-
* inflate(deflate_string) { |chunk| ... } -> nil
|
2071
|
+
* inflate(deflate_string, buffer: nil) -> String
|
2072
|
+
* inflate(deflate_string, buffer: nil) { |chunk| ... } -> nil
|
1967
2073
|
*
|
1968
2074
|
* Inputs +deflate_string+ into the inflate stream and returns the output from
|
1969
2075
|
* the stream. Calling this method, both the input and the output buffer of
|
@@ -1973,6 +2079,15 @@ rb_inflate_add_dictionary(VALUE obj, VALUE dictionary)
|
|
1973
2079
|
* If a block is given consecutive inflated chunks from the +deflate_string+
|
1974
2080
|
* are yielded to the block and +nil+ is returned.
|
1975
2081
|
*
|
2082
|
+
* If a :buffer keyword argument is given and not nil:
|
2083
|
+
*
|
2084
|
+
* * The :buffer keyword should be a String, and will used as the output buffer.
|
2085
|
+
* Using this option can reuse the memory required during inflation.
|
2086
|
+
* * When not passing a block, the return value will be the same object as the
|
2087
|
+
* :buffer keyword argument.
|
2088
|
+
* * When passing a block, the yielded chunks will be the same value as the
|
2089
|
+
* :buffer keyword argument.
|
2090
|
+
*
|
1976
2091
|
* Raises a Zlib::NeedDict exception if a preset dictionary is needed to
|
1977
2092
|
* decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
|
1978
2093
|
* call this method again with an empty string to flush the stream:
|
@@ -1996,12 +2111,37 @@ rb_inflate_add_dictionary(VALUE obj, VALUE dictionary)
|
|
1996
2111
|
* See also Zlib::Inflate.new
|
1997
2112
|
*/
|
1998
2113
|
static VALUE
|
1999
|
-
rb_inflate_inflate(VALUE
|
2114
|
+
rb_inflate_inflate(int argc, VALUE* argv, VALUE obj)
|
2000
2115
|
{
|
2001
2116
|
struct zstream *z = get_zstream(obj);
|
2002
|
-
VALUE dst;
|
2117
|
+
VALUE dst, src, opts, buffer = Qnil;
|
2003
2118
|
|
2004
|
-
|
2119
|
+
if (OPTHASH_GIVEN_P(opts)) {
|
2120
|
+
VALUE buf;
|
2121
|
+
rb_get_kwargs(opts, &id_buffer, 0, 1, &buf);
|
2122
|
+
if (buf != Qundef && buf != Qnil) {
|
2123
|
+
buffer = StringValue(buf);
|
2124
|
+
}
|
2125
|
+
}
|
2126
|
+
if (buffer != Qnil) {
|
2127
|
+
if (!(ZSTREAM_REUSE_BUFFER_P(z) && z->buf == buffer)) {
|
2128
|
+
long len = RSTRING_LEN(buffer);
|
2129
|
+
if (len >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
|
2130
|
+
rb_str_modify(buffer);
|
2131
|
+
}
|
2132
|
+
else {
|
2133
|
+
len = ZSTREAM_AVAIL_OUT_STEP_MAX - len;
|
2134
|
+
rb_str_modify_expand(buffer, len);
|
2135
|
+
}
|
2136
|
+
rb_str_set_len(buffer, 0);
|
2137
|
+
z->flags |= ZSTREAM_REUSE_BUFFER;
|
2138
|
+
z->buf = buffer;
|
2139
|
+
}
|
2140
|
+
} else if (ZSTREAM_REUSE_BUFFER_P(z)) {
|
2141
|
+
z->flags &= ~ZSTREAM_REUSE_BUFFER;
|
2142
|
+
z->buf = Qnil;
|
2143
|
+
}
|
2144
|
+
rb_scan_args(argc, argv, "10", &src);
|
2005
2145
|
|
2006
2146
|
if (ZSTREAM_IS_FINISHED(z)) {
|
2007
2147
|
if (NIL_P(src)) {
|
@@ -2010,8 +2150,11 @@ rb_inflate_inflate(VALUE obj, VALUE src)
|
|
2010
2150
|
else {
|
2011
2151
|
StringValue(src);
|
2012
2152
|
zstream_append_buffer2(z, src);
|
2013
|
-
|
2014
|
-
|
2153
|
+
if (ZSTREAM_REUSE_BUFFER_P(z)) {
|
2154
|
+
dst = rb_str_resize(buffer, 0);
|
2155
|
+
} else {
|
2156
|
+
dst = rb_str_new(0, 0);
|
2157
|
+
}
|
2015
2158
|
}
|
2016
2159
|
}
|
2017
2160
|
else {
|
@@ -2037,8 +2180,6 @@ rb_inflate_addstr(VALUE obj, VALUE src)
|
|
2037
2180
|
{
|
2038
2181
|
struct zstream *z = get_zstream(obj);
|
2039
2182
|
|
2040
|
-
OBJ_INFECT(obj, src);
|
2041
|
-
|
2042
2183
|
if (ZSTREAM_IS_FINISHED(z)) {
|
2043
2184
|
if (!NIL_P(src)) {
|
2044
2185
|
StringValue(src);
|
@@ -2068,7 +2209,6 @@ rb_inflate_sync(VALUE obj, VALUE src)
|
|
2068
2209
|
{
|
2069
2210
|
struct zstream *z = get_zstream(obj);
|
2070
2211
|
|
2071
|
-
OBJ_INFECT(obj, src);
|
2072
2212
|
StringValue(src);
|
2073
2213
|
return zstream_sync(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src));
|
2074
2214
|
}
|
@@ -2110,7 +2250,6 @@ rb_inflate_set_dictionary(VALUE obj, VALUE dic)
|
|
2110
2250
|
VALUE src = dic;
|
2111
2251
|
int err;
|
2112
2252
|
|
2113
|
-
OBJ_INFECT(obj, dic);
|
2114
2253
|
StringValue(src);
|
2115
2254
|
err = inflateSetDictionary(&z->stream,
|
2116
2255
|
(Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
|
@@ -2167,7 +2306,7 @@ rb_inflate_set_dictionary(VALUE obj, VALUE dic)
|
|
2167
2306
|
#define OS_CODE OS_UNIX
|
2168
2307
|
#endif
|
2169
2308
|
|
2170
|
-
static ID id_write,
|
2309
|
+
static ID id_write, id_readpartial, id_flush, id_seek, id_close, id_path, id_input;
|
2171
2310
|
static VALUE cGzError, cNoFooter, cCRCError, cLengthError;
|
2172
2311
|
|
2173
2312
|
|
@@ -2191,7 +2330,6 @@ struct gzfile {
|
|
2191
2330
|
rb_encoding *enc2;
|
2192
2331
|
rb_econv_t *ec;
|
2193
2332
|
VALUE ecopts;
|
2194
|
-
char *cbuf;
|
2195
2333
|
VALUE path;
|
2196
2334
|
};
|
2197
2335
|
#define GZFILE_CBUF_CAPA 10
|
@@ -2199,12 +2337,23 @@ struct gzfile {
|
|
2199
2337
|
#define GZFILE_FLAG_SYNC ZSTREAM_FLAG_UNUSED
|
2200
2338
|
#define GZFILE_FLAG_HEADER_FINISHED (ZSTREAM_FLAG_UNUSED << 1)
|
2201
2339
|
#define GZFILE_FLAG_FOOTER_FINISHED (ZSTREAM_FLAG_UNUSED << 2)
|
2340
|
+
#define GZFILE_FLAG_MTIME_IS_SET (ZSTREAM_FLAG_UNUSED << 3)
|
2202
2341
|
|
2203
2342
|
#define GZFILE_IS_FINISHED(gz) \
|
2204
2343
|
(ZSTREAM_IS_FINISHED(&(gz)->z) && ZSTREAM_BUF_FILLED(&(gz)->z) == 0)
|
2205
2344
|
|
2206
2345
|
#define GZFILE_READ_SIZE 2048
|
2207
2346
|
|
2347
|
+
struct read_raw_arg {
|
2348
|
+
VALUE io;
|
2349
|
+
union {
|
2350
|
+
const VALUE argv[2]; /* for rb_funcallv */
|
2351
|
+
struct {
|
2352
|
+
VALUE len;
|
2353
|
+
VALUE buf;
|
2354
|
+
} in;
|
2355
|
+
} as;
|
2356
|
+
};
|
2208
2357
|
|
2209
2358
|
static void
|
2210
2359
|
gzfile_mark(void *p)
|
@@ -2231,22 +2380,13 @@ gzfile_free(void *p)
|
|
2231
2380
|
}
|
2232
2381
|
zstream_finalize(z);
|
2233
2382
|
}
|
2234
|
-
if (gz->cbuf) {
|
2235
|
-
xfree(gz->cbuf);
|
2236
|
-
}
|
2237
2383
|
xfree(gz);
|
2238
2384
|
}
|
2239
2385
|
|
2240
2386
|
static size_t
|
2241
2387
|
gzfile_memsize(const void *p)
|
2242
2388
|
{
|
2243
|
-
|
2244
|
-
size_t size = sizeof(struct gzfile);
|
2245
|
-
|
2246
|
-
if (gz->cbuf)
|
2247
|
-
size += GZFILE_CBUF_CAPA;
|
2248
|
-
|
2249
|
-
return size;
|
2389
|
+
return sizeof(struct gzfile);
|
2250
2390
|
}
|
2251
2391
|
|
2252
2392
|
static const rb_data_type_t gzfile_data_type = {
|
@@ -2275,7 +2415,6 @@ gzfile_init(struct gzfile *gz, const struct zstream_funcs *funcs, void (*endfunc
|
|
2275
2415
|
gz->ec = NULL;
|
2276
2416
|
gz->ecflags = 0;
|
2277
2417
|
gz->ecopts = Qnil;
|
2278
|
-
gz->cbuf = 0;
|
2279
2418
|
gz->path = Qnil;
|
2280
2419
|
}
|
2281
2420
|
|
@@ -2329,7 +2468,6 @@ gzfile_write_raw(struct gzfile *gz)
|
|
2329
2468
|
|
2330
2469
|
if (ZSTREAM_BUF_FILLED(&gz->z) > 0) {
|
2331
2470
|
str = zstream_detach_buffer(&gz->z);
|
2332
|
-
OBJ_TAINT(str); /* for safe */
|
2333
2471
|
rb_funcall(gz->io, id_write, 1, str);
|
2334
2472
|
if ((gz->z.flags & GZFILE_FLAG_SYNC)
|
2335
2473
|
&& rb_respond_to(gz->io, id_flush))
|
@@ -2340,21 +2478,23 @@ gzfile_write_raw(struct gzfile *gz)
|
|
2340
2478
|
static VALUE
|
2341
2479
|
gzfile_read_raw_partial(VALUE arg)
|
2342
2480
|
{
|
2343
|
-
struct
|
2481
|
+
struct read_raw_arg *ra = (struct read_raw_arg *)arg;
|
2344
2482
|
VALUE str;
|
2483
|
+
int argc = NIL_P(ra->as.argv[1]) ? 1 : 2;
|
2345
2484
|
|
2346
|
-
str =
|
2485
|
+
str = rb_funcallv(ra->io, id_readpartial, argc, ra->as.argv);
|
2347
2486
|
Check_Type(str, T_STRING);
|
2348
2487
|
return str;
|
2349
2488
|
}
|
2350
2489
|
|
2351
2490
|
static VALUE
|
2352
|
-
gzfile_read_raw_rescue(VALUE arg)
|
2491
|
+
gzfile_read_raw_rescue(VALUE arg, VALUE _)
|
2353
2492
|
{
|
2354
|
-
struct
|
2493
|
+
struct read_raw_arg *ra = (struct read_raw_arg *)arg;
|
2355
2494
|
VALUE str = Qnil;
|
2356
2495
|
if (rb_obj_is_kind_of(rb_errinfo(), rb_eNoMethodError)) {
|
2357
|
-
|
2496
|
+
int argc = NIL_P(ra->as.argv[1]) ? 1 : 2;
|
2497
|
+
str = rb_funcallv(ra->io, id_read, argc, ra->as.argv);
|
2358
2498
|
if (!NIL_P(str)) {
|
2359
2499
|
Check_Type(str, T_STRING);
|
2360
2500
|
}
|
@@ -2363,15 +2503,21 @@ gzfile_read_raw_rescue(VALUE arg)
|
|
2363
2503
|
}
|
2364
2504
|
|
2365
2505
|
static VALUE
|
2366
|
-
gzfile_read_raw(struct gzfile *gz)
|
2506
|
+
gzfile_read_raw(struct gzfile *gz, VALUE outbuf)
|
2367
2507
|
{
|
2368
|
-
|
2369
|
-
|
2508
|
+
struct read_raw_arg ra;
|
2509
|
+
|
2510
|
+
ra.io = gz->io;
|
2511
|
+
ra.as.in.len = INT2FIX(GZFILE_READ_SIZE);
|
2512
|
+
ra.as.in.buf = outbuf;
|
2513
|
+
|
2514
|
+
return rb_rescue2(gzfile_read_raw_partial, (VALUE)&ra,
|
2515
|
+
gzfile_read_raw_rescue, (VALUE)&ra,
|
2370
2516
|
rb_eEOFError, rb_eNoMethodError, (VALUE)0);
|
2371
2517
|
}
|
2372
2518
|
|
2373
2519
|
static int
|
2374
|
-
gzfile_read_raw_ensure(struct gzfile *gz, long size)
|
2520
|
+
gzfile_read_raw_ensure(struct gzfile *gz, long size, VALUE outbuf)
|
2375
2521
|
{
|
2376
2522
|
VALUE str;
|
2377
2523
|
|
@@ -2380,7 +2526,7 @@ gzfile_read_raw_ensure(struct gzfile *gz, long size)
|
|
2380
2526
|
rb_raise(cGzError, "unexpected end of string");
|
2381
2527
|
}
|
2382
2528
|
while (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) {
|
2383
|
-
str = gzfile_read_raw(gz);
|
2529
|
+
str = gzfile_read_raw(gz, outbuf);
|
2384
2530
|
if (NIL_P(str)) return 0;
|
2385
2531
|
zstream_append_input2(&gz->z, str);
|
2386
2532
|
}
|
@@ -2397,7 +2543,7 @@ gzfile_read_raw_until_zero(struct gzfile *gz, long offset)
|
|
2397
2543
|
p = memchr(RSTRING_PTR(gz->z.input) + offset, '\0',
|
2398
2544
|
RSTRING_LEN(gz->z.input) - offset);
|
2399
2545
|
if (p) break;
|
2400
|
-
str = gzfile_read_raw(gz);
|
2546
|
+
str = gzfile_read_raw(gz, Qnil);
|
2401
2547
|
if (NIL_P(str)) {
|
2402
2548
|
rb_raise(cGzError, "unexpected end of file");
|
2403
2549
|
}
|
@@ -2478,7 +2624,7 @@ gzfile_make_header(struct gzfile *gz)
|
|
2478
2624
|
if (!NIL_P(gz->comment)) {
|
2479
2625
|
flags |= GZ_FLAG_COMMENT;
|
2480
2626
|
}
|
2481
|
-
if (gz->
|
2627
|
+
if (!(gz->z.flags & GZFILE_FLAG_MTIME_IS_SET)) {
|
2482
2628
|
gz->mtime = time(0);
|
2483
2629
|
}
|
2484
2630
|
|
@@ -2522,13 +2668,14 @@ gzfile_make_footer(struct gzfile *gz)
|
|
2522
2668
|
}
|
2523
2669
|
|
2524
2670
|
static void
|
2525
|
-
gzfile_read_header(struct gzfile *gz)
|
2671
|
+
gzfile_read_header(struct gzfile *gz, VALUE outbuf)
|
2526
2672
|
{
|
2527
2673
|
const unsigned char *head;
|
2528
2674
|
long len;
|
2529
2675
|
char flags, *p;
|
2530
2676
|
|
2531
|
-
|
2677
|
+
/* 10 is the size of gzip header */
|
2678
|
+
if (!gzfile_read_raw_ensure(gz, 10, outbuf)) {
|
2532
2679
|
gzfile_raise(gz, cGzError, "not in gzip format");
|
2533
2680
|
}
|
2534
2681
|
|
@@ -2567,33 +2714,31 @@ gzfile_read_header(struct gzfile *gz)
|
|
2567
2714
|
zstream_discard_input(&gz->z, 10);
|
2568
2715
|
|
2569
2716
|
if (flags & GZ_FLAG_EXTRA) {
|
2570
|
-
if (!gzfile_read_raw_ensure(gz, 2)) {
|
2717
|
+
if (!gzfile_read_raw_ensure(gz, 2, outbuf)) {
|
2571
2718
|
rb_raise(cGzError, "unexpected end of file");
|
2572
2719
|
}
|
2573
2720
|
len = gzfile_get16((Bytef*)RSTRING_PTR(gz->z.input));
|
2574
|
-
if (!gzfile_read_raw_ensure(gz, 2 + len)) {
|
2721
|
+
if (!gzfile_read_raw_ensure(gz, 2 + len, outbuf)) {
|
2575
2722
|
rb_raise(cGzError, "unexpected end of file");
|
2576
2723
|
}
|
2577
2724
|
zstream_discard_input(&gz->z, 2 + len);
|
2578
2725
|
}
|
2579
2726
|
if (flags & GZ_FLAG_ORIG_NAME) {
|
2580
|
-
if (!gzfile_read_raw_ensure(gz, 1)) {
|
2727
|
+
if (!gzfile_read_raw_ensure(gz, 1, outbuf)) {
|
2581
2728
|
rb_raise(cGzError, "unexpected end of file");
|
2582
2729
|
}
|
2583
2730
|
p = gzfile_read_raw_until_zero(gz, 0);
|
2584
2731
|
len = p - RSTRING_PTR(gz->z.input);
|
2585
2732
|
gz->orig_name = rb_str_new(RSTRING_PTR(gz->z.input), len);
|
2586
|
-
OBJ_TAINT(gz->orig_name); /* for safe */
|
2587
2733
|
zstream_discard_input(&gz->z, len + 1);
|
2588
2734
|
}
|
2589
2735
|
if (flags & GZ_FLAG_COMMENT) {
|
2590
|
-
if (!gzfile_read_raw_ensure(gz, 1)) {
|
2736
|
+
if (!gzfile_read_raw_ensure(gz, 1, outbuf)) {
|
2591
2737
|
rb_raise(cGzError, "unexpected end of file");
|
2592
2738
|
}
|
2593
2739
|
p = gzfile_read_raw_until_zero(gz, 0);
|
2594
2740
|
len = p - RSTRING_PTR(gz->z.input);
|
2595
2741
|
gz->comment = rb_str_new(RSTRING_PTR(gz->z.input), len);
|
2596
|
-
OBJ_TAINT(gz->comment); /* for safe */
|
2597
2742
|
zstream_discard_input(&gz->z, len + 1);
|
2598
2743
|
}
|
2599
2744
|
|
@@ -2603,13 +2748,14 @@ gzfile_read_header(struct gzfile *gz)
|
|
2603
2748
|
}
|
2604
2749
|
|
2605
2750
|
static void
|
2606
|
-
gzfile_check_footer(struct gzfile *gz)
|
2751
|
+
gzfile_check_footer(struct gzfile *gz, VALUE outbuf)
|
2607
2752
|
{
|
2608
2753
|
unsigned long crc, length;
|
2609
2754
|
|
2610
2755
|
gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
|
2611
2756
|
|
2612
|
-
|
2757
|
+
/* 8 is the size of gzip footer */
|
2758
|
+
if (!gzfile_read_raw_ensure(gz, 8, outbuf)) {
|
2613
2759
|
gzfile_raise(gz, cNoFooter, "footer is not found");
|
2614
2760
|
}
|
2615
2761
|
|
@@ -2643,12 +2789,12 @@ gzfile_write(struct gzfile *gz, Bytef *str, long len)
|
|
2643
2789
|
}
|
2644
2790
|
|
2645
2791
|
static long
|
2646
|
-
gzfile_read_more(struct gzfile *gz)
|
2792
|
+
gzfile_read_more(struct gzfile *gz, VALUE outbuf)
|
2647
2793
|
{
|
2648
2794
|
VALUE str;
|
2649
2795
|
|
2650
2796
|
while (!ZSTREAM_IS_FINISHED(&gz->z)) {
|
2651
|
-
str = gzfile_read_raw(gz);
|
2797
|
+
str = gzfile_read_raw(gz, outbuf);
|
2652
2798
|
if (NIL_P(str)) {
|
2653
2799
|
if (!ZSTREAM_IS_FINISHED(&gz->z)) {
|
2654
2800
|
rb_raise(cGzError, "unexpected end of file");
|
@@ -2673,7 +2819,7 @@ gzfile_calc_crc(struct gzfile *gz, VALUE str)
|
|
2673
2819
|
}
|
2674
2820
|
else {
|
2675
2821
|
gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
|
2676
|
-
|
2822
|
+
RSTRING_LEN(str) - gz->ungetc);
|
2677
2823
|
gz->ungetc = 0;
|
2678
2824
|
}
|
2679
2825
|
}
|
@@ -2683,13 +2829,11 @@ gzfile_newstr(struct gzfile *gz, VALUE str)
|
|
2683
2829
|
{
|
2684
2830
|
if (!gz->enc2) {
|
2685
2831
|
rb_enc_associate(str, gz->enc);
|
2686
|
-
OBJ_TAINT(str); /* for safe */
|
2687
2832
|
return str;
|
2688
2833
|
}
|
2689
2834
|
if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
|
2690
2835
|
str = rb_econv_str_convert(gz->ec, str, ECONV_PARTIAL_INPUT);
|
2691
2836
|
rb_enc_associate(str, gz->enc);
|
2692
|
-
OBJ_TAINT(str);
|
2693
2837
|
return str;
|
2694
2838
|
}
|
2695
2839
|
return rb_str_conv_enc_opts(str, gz->enc2, gz->enc,
|
@@ -2704,11 +2848,11 @@ gzfile_fill(struct gzfile *gz, long len)
|
|
2704
2848
|
if (len == 0)
|
2705
2849
|
return 0;
|
2706
2850
|
while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) < len) {
|
2707
|
-
gzfile_read_more(gz);
|
2851
|
+
gzfile_read_more(gz, Qnil);
|
2708
2852
|
}
|
2709
2853
|
if (GZFILE_IS_FINISHED(gz)) {
|
2710
2854
|
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2711
|
-
gzfile_check_footer(gz);
|
2855
|
+
gzfile_check_footer(gz, Qnil);
|
2712
2856
|
}
|
2713
2857
|
return -1;
|
2714
2858
|
}
|
@@ -2736,9 +2880,6 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
|
|
2736
2880
|
if (len < 0)
|
2737
2881
|
rb_raise(rb_eArgError, "negative length %ld given", len);
|
2738
2882
|
|
2739
|
-
if (!NIL_P(outbuf))
|
2740
|
-
OBJ_TAINT(outbuf);
|
2741
|
-
|
2742
2883
|
if (len == 0) {
|
2743
2884
|
if (NIL_P(outbuf))
|
2744
2885
|
return rb_str_new(0, 0);
|
@@ -2748,11 +2889,11 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
|
|
2748
2889
|
}
|
2749
2890
|
}
|
2750
2891
|
while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) {
|
2751
|
-
gzfile_read_more(gz);
|
2892
|
+
gzfile_read_more(gz, outbuf);
|
2752
2893
|
}
|
2753
2894
|
if (GZFILE_IS_FINISHED(gz)) {
|
2754
2895
|
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2755
|
-
gzfile_check_footer(gz);
|
2896
|
+
gzfile_check_footer(gz, outbuf);
|
2756
2897
|
}
|
2757
2898
|
if (!NIL_P(outbuf))
|
2758
2899
|
rb_str_resize(outbuf, 0);
|
@@ -2765,10 +2906,10 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
|
|
2765
2906
|
if (!NIL_P(outbuf)) {
|
2766
2907
|
rb_str_resize(outbuf, RSTRING_LEN(dst));
|
2767
2908
|
memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
|
2768
|
-
|
2909
|
+
rb_str_resize(dst, 0);
|
2910
|
+
rb_gc_force_recycle(dst);
|
2769
2911
|
dst = outbuf;
|
2770
2912
|
}
|
2771
|
-
OBJ_TAINT(dst); /* for safe */
|
2772
2913
|
return dst;
|
2773
2914
|
}
|
2774
2915
|
|
@@ -2778,11 +2919,11 @@ gzfile_read_all(struct gzfile *gz)
|
|
2778
2919
|
VALUE dst;
|
2779
2920
|
|
2780
2921
|
while (!ZSTREAM_IS_FINISHED(&gz->z)) {
|
2781
|
-
gzfile_read_more(gz);
|
2922
|
+
gzfile_read_more(gz, Qnil);
|
2782
2923
|
}
|
2783
2924
|
if (GZFILE_IS_FINISHED(gz)) {
|
2784
2925
|
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2785
|
-
gzfile_check_footer(gz);
|
2926
|
+
gzfile_check_footer(gz, Qnil);
|
2786
2927
|
}
|
2787
2928
|
return rb_str_new(0, 0);
|
2788
2929
|
}
|
@@ -2790,7 +2931,6 @@ gzfile_read_all(struct gzfile *gz)
|
|
2790
2931
|
dst = zstream_detach_buffer(&gz->z);
|
2791
2932
|
if (NIL_P(dst)) return dst;
|
2792
2933
|
gzfile_calc_crc(gz, dst);
|
2793
|
-
OBJ_TAINT(dst);
|
2794
2934
|
return gzfile_newstr(gz, dst);
|
2795
2935
|
}
|
2796
2936
|
|
@@ -2802,11 +2942,11 @@ gzfile_getc(struct gzfile *gz)
|
|
2802
2942
|
|
2803
2943
|
len = rb_enc_mbmaxlen(gz->enc);
|
2804
2944
|
while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) < len) {
|
2805
|
-
gzfile_read_more(gz);
|
2945
|
+
gzfile_read_more(gz, Qnil);
|
2806
2946
|
}
|
2807
2947
|
if (GZFILE_IS_FINISHED(gz)) {
|
2808
2948
|
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2809
|
-
gzfile_check_footer(gz);
|
2949
|
+
gzfile_check_footer(gz, Qnil);
|
2810
2950
|
}
|
2811
2951
|
return Qnil;
|
2812
2952
|
}
|
@@ -2814,22 +2954,18 @@ gzfile_getc(struct gzfile *gz)
|
|
2814
2954
|
if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
|
2815
2955
|
const unsigned char *ss, *sp, *se;
|
2816
2956
|
unsigned char *ds, *dp, *de;
|
2957
|
+
VALUE cbuf = rb_enc_str_new(0, GZFILE_CBUF_CAPA, gz->enc);
|
2817
2958
|
|
2818
|
-
if (!gz->cbuf) {
|
2819
|
-
gz->cbuf = ALLOC_N(char, GZFILE_CBUF_CAPA);
|
2820
|
-
}
|
2821
2959
|
ss = sp = (const unsigned char*)RSTRING_PTR(gz->z.buf);
|
2822
2960
|
se = sp + ZSTREAM_BUF_FILLED(&gz->z);
|
2823
|
-
ds = dp = (unsigned char *)
|
2961
|
+
ds = dp = (unsigned char *)RSTRING_PTR(cbuf);
|
2824
2962
|
de = (unsigned char *)ds + GZFILE_CBUF_CAPA;
|
2825
2963
|
(void)rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
|
2826
2964
|
rb_econv_check_error(gz->ec);
|
2827
2965
|
dst = zstream_shift_buffer(&gz->z, sp - ss);
|
2828
2966
|
gzfile_calc_crc(gz, dst);
|
2829
|
-
|
2830
|
-
|
2831
|
-
OBJ_TAINT(dst);
|
2832
|
-
return dst;
|
2967
|
+
rb_str_resize(cbuf, dp - ds);
|
2968
|
+
return cbuf;
|
2833
2969
|
}
|
2834
2970
|
else {
|
2835
2971
|
buf = gz->z.buf;
|
@@ -2876,7 +3012,7 @@ gzfile_writer_end(struct gzfile *gz)
|
|
2876
3012
|
if (ZSTREAM_IS_CLOSING(&gz->z)) return;
|
2877
3013
|
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
|
2878
3014
|
|
2879
|
-
rb_ensure(gzfile_writer_end_run, (VALUE)gz,
|
3015
|
+
rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_ensure_end, (VALUE)&gz->z);
|
2880
3016
|
}
|
2881
3017
|
|
2882
3018
|
static VALUE
|
@@ -2886,7 +3022,7 @@ gzfile_reader_end_run(VALUE arg)
|
|
2886
3022
|
|
2887
3023
|
if (GZFILE_IS_FINISHED(gz)
|
2888
3024
|
&& !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2889
|
-
gzfile_check_footer(gz);
|
3025
|
+
gzfile_check_footer(gz, Qnil);
|
2890
3026
|
}
|
2891
3027
|
|
2892
3028
|
return Qnil;
|
@@ -2898,7 +3034,7 @@ gzfile_reader_end(struct gzfile *gz)
|
|
2898
3034
|
if (ZSTREAM_IS_CLOSING(&gz->z)) return;
|
2899
3035
|
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
|
2900
3036
|
|
2901
|
-
rb_ensure(gzfile_reader_end_run, (VALUE)gz,
|
3037
|
+
rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_ensure_end, (VALUE)&gz->z);
|
2902
3038
|
}
|
2903
3039
|
|
2904
3040
|
static void
|
@@ -2923,12 +3059,11 @@ gzfile_reader_get_unused(struct gzfile *gz)
|
|
2923
3059
|
if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;
|
2924
3060
|
if (!GZFILE_IS_FINISHED(gz)) return Qnil;
|
2925
3061
|
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2926
|
-
gzfile_check_footer(gz);
|
3062
|
+
gzfile_check_footer(gz, Qnil);
|
2927
3063
|
}
|
2928
3064
|
if (NIL_P(gz->z.input)) return Qnil;
|
2929
3065
|
|
2930
3066
|
str = rb_str_resurrect(gz->z.input);
|
2931
|
-
OBJ_TAINT(str); /* for safe */
|
2932
3067
|
return str;
|
2933
3068
|
}
|
2934
3069
|
|
@@ -2995,7 +3130,7 @@ static VALUE
|
|
2995
3130
|
new_wrap(VALUE tmp)
|
2996
3131
|
{
|
2997
3132
|
new_wrap_arg_t *arg = (new_wrap_arg_t *)tmp;
|
2998
|
-
return
|
3133
|
+
return rb_class_new_instance_kw(arg->argc, arg->argv, arg->klass, RB_PASS_CALLED_KEYWORDS);
|
2999
3134
|
}
|
3000
3135
|
|
3001
3136
|
static VALUE
|
@@ -3028,7 +3163,7 @@ gzfile_wrap(int argc, VALUE *argv, VALUE klass, int close_io_on_error)
|
|
3028
3163
|
}
|
3029
3164
|
}
|
3030
3165
|
else {
|
3031
|
-
obj =
|
3166
|
+
obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
|
3032
3167
|
}
|
3033
3168
|
|
3034
3169
|
if (rb_block_given_p()) {
|
@@ -3145,7 +3280,6 @@ rb_gzfile_orig_name(VALUE obj)
|
|
3145
3280
|
if (!NIL_P(str)) {
|
3146
3281
|
str = rb_str_dup(str);
|
3147
3282
|
}
|
3148
|
-
OBJ_TAINT(str); /* for safe */
|
3149
3283
|
return str;
|
3150
3284
|
}
|
3151
3285
|
|
@@ -3162,7 +3296,6 @@ rb_gzfile_comment(VALUE obj)
|
|
3162
3296
|
if (!NIL_P(str)) {
|
3163
3297
|
str = rb_str_dup(str);
|
3164
3298
|
}
|
3165
|
-
OBJ_TAINT(str); /* for safe */
|
3166
3299
|
return str;
|
3167
3300
|
}
|
3168
3301
|
|
@@ -3221,6 +3354,7 @@ rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
|
|
3221
3354
|
|
3222
3355
|
val = rb_Integer(mtime);
|
3223
3356
|
gz->mtime = NUM2UINT(val);
|
3357
|
+
gz->z.flags |= GZFILE_FLAG_MTIME_IS_SET;
|
3224
3358
|
|
3225
3359
|
return mtime;
|
3226
3360
|
}
|
@@ -3419,6 +3553,16 @@ rb_gzfile_path(VALUE obj)
|
|
3419
3553
|
return gz->path;
|
3420
3554
|
}
|
3421
3555
|
|
3556
|
+
static VALUE
|
3557
|
+
gzfile_initialize_path_partial(VALUE obj)
|
3558
|
+
{
|
3559
|
+
struct gzfile* gz;
|
3560
|
+
TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
|
3561
|
+
gz->path = rb_funcall(gz->io, id_path, 0);
|
3562
|
+
rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
|
3563
|
+
return Qnil;
|
3564
|
+
}
|
3565
|
+
|
3422
3566
|
static void
|
3423
3567
|
rb_gzfile_ecopts(struct gzfile *gz, VALUE opts)
|
3424
3568
|
{
|
@@ -3527,8 +3671,8 @@ rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
|
|
3527
3671
|
rb_gzfile_ecopts(gz, opt);
|
3528
3672
|
|
3529
3673
|
if (rb_respond_to(io, id_path)) {
|
3530
|
-
|
3531
|
-
|
3674
|
+
/* File#path may raise IOError in case when a path is unavailable */
|
3675
|
+
rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
|
3532
3676
|
}
|
3533
3677
|
|
3534
3678
|
return obj;
|
@@ -3566,18 +3710,23 @@ rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj)
|
|
3566
3710
|
* Same as IO.
|
3567
3711
|
*/
|
3568
3712
|
static VALUE
|
3569
|
-
rb_gzwriter_write(VALUE
|
3713
|
+
rb_gzwriter_write(int argc, VALUE *argv, VALUE obj)
|
3570
3714
|
{
|
3571
3715
|
struct gzfile *gz = get_gzfile(obj);
|
3572
|
-
|
3573
|
-
|
3574
|
-
|
3575
|
-
|
3576
|
-
|
3716
|
+
size_t total = 0;
|
3717
|
+
|
3718
|
+
while (argc-- > 0) {
|
3719
|
+
VALUE str = *argv++;
|
3720
|
+
if (!RB_TYPE_P(str, T_STRING))
|
3721
|
+
str = rb_obj_as_string(str);
|
3722
|
+
if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
|
3723
|
+
str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
|
3724
|
+
}
|
3725
|
+
gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
|
3726
|
+
total += RSTRING_LEN(str);
|
3727
|
+
RB_GC_GUARD(str);
|
3577
3728
|
}
|
3578
|
-
|
3579
|
-
RB_GC_GUARD(str);
|
3580
|
-
return INT2FIX(RSTRING_LEN(str));
|
3729
|
+
return SIZET2NUM(total);
|
3581
3730
|
}
|
3582
3731
|
|
3583
3732
|
/*
|
@@ -3692,6 +3841,60 @@ rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
|
|
3692
3841
|
return gzfile_s_open(argc, argv, klass, "rb");
|
3693
3842
|
}
|
3694
3843
|
|
3844
|
+
/*
|
3845
|
+
* Document-method: Zlib::GzipReader.zcat
|
3846
|
+
*
|
3847
|
+
* call-seq:
|
3848
|
+
* Zlib::GzipReader.zcat(io, options = {}, &block) => nil
|
3849
|
+
* Zlib::GzipReader.zcat(io, options = {}) => string
|
3850
|
+
*
|
3851
|
+
* Decompresses all gzip data in the +io+, handling multiple gzip
|
3852
|
+
* streams until the end of the +io+. There should not be any non-gzip
|
3853
|
+
* data after the gzip streams.
|
3854
|
+
*
|
3855
|
+
* If a block is given, it is yielded strings of uncompressed data,
|
3856
|
+
* and the method returns +nil+.
|
3857
|
+
* If a block is not given, the method returns the concatenation of
|
3858
|
+
* all uncompressed data in all gzip streams.
|
3859
|
+
*/
|
3860
|
+
static VALUE
|
3861
|
+
rb_gzreader_s_zcat(int argc, VALUE *argv, VALUE klass)
|
3862
|
+
{
|
3863
|
+
VALUE io, unused, obj, buf=0, tmpbuf;
|
3864
|
+
long pos;
|
3865
|
+
|
3866
|
+
rb_check_arity(argc, 1, 2);
|
3867
|
+
io = argv[0];
|
3868
|
+
|
3869
|
+
do {
|
3870
|
+
obj = rb_funcallv(klass, rb_intern("new"), argc, argv);
|
3871
|
+
if (rb_block_given_p()) {
|
3872
|
+
rb_gzreader_each(0, 0, obj);
|
3873
|
+
}
|
3874
|
+
else {
|
3875
|
+
if (!buf) {
|
3876
|
+
buf = rb_str_new(0, 0);
|
3877
|
+
}
|
3878
|
+
tmpbuf = gzfile_read_all(get_gzfile(obj));
|
3879
|
+
rb_str_cat(buf, RSTRING_PTR(tmpbuf), RSTRING_LEN(tmpbuf));
|
3880
|
+
}
|
3881
|
+
|
3882
|
+
rb_gzreader_read(0, 0, obj);
|
3883
|
+
pos = NUM2LONG(rb_funcall(io, rb_intern("pos"), 0));
|
3884
|
+
unused = rb_gzreader_unused(obj);
|
3885
|
+
rb_gzfile_finish(obj);
|
3886
|
+
if (!NIL_P(unused)) {
|
3887
|
+
pos -= NUM2LONG(rb_funcall(unused, rb_intern("length"), 0));
|
3888
|
+
rb_funcall(io, rb_intern("pos="), 1, LONG2NUM(pos));
|
3889
|
+
}
|
3890
|
+
} while (pos < NUM2LONG(rb_funcall(io, rb_intern("size"), 0)));
|
3891
|
+
|
3892
|
+
if (rb_block_given_p()) {
|
3893
|
+
return Qnil;
|
3894
|
+
}
|
3895
|
+
return buf;
|
3896
|
+
}
|
3897
|
+
|
3695
3898
|
/*
|
3696
3899
|
* Document-method: Zlib::GzipReader.new
|
3697
3900
|
*
|
@@ -3726,12 +3929,12 @@ rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
|
|
3726
3929
|
}
|
3727
3930
|
gz->io = io;
|
3728
3931
|
ZSTREAM_READY(&gz->z);
|
3729
|
-
gzfile_read_header(gz);
|
3932
|
+
gzfile_read_header(gz, Qnil);
|
3730
3933
|
rb_gzfile_ecopts(gz, opt);
|
3731
3934
|
|
3732
3935
|
if (rb_respond_to(io, id_path)) {
|
3733
|
-
|
3734
|
-
|
3936
|
+
/* File#path may raise IOError in case when a path is unavailable */
|
3937
|
+
rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
|
3735
3938
|
}
|
3736
3939
|
|
3737
3940
|
return obj;
|
@@ -3918,20 +4121,6 @@ rb_gzreader_each_byte(VALUE obj)
|
|
3918
4121
|
return Qnil;
|
3919
4122
|
}
|
3920
4123
|
|
3921
|
-
/*
|
3922
|
-
* Document-method: Zlib::GzipReader#bytes
|
3923
|
-
*
|
3924
|
-
* This is a deprecated alias for <code>each_byte</code>.
|
3925
|
-
*/
|
3926
|
-
static VALUE
|
3927
|
-
rb_gzreader_bytes(VALUE obj)
|
3928
|
-
{
|
3929
|
-
rb_warn("Zlib::GzipReader#bytes is deprecated; use #each_byte instead");
|
3930
|
-
if (!rb_block_given_p())
|
3931
|
-
return rb_enumeratorize(obj, ID2SYM(rb_intern("each_byte")), 0, 0);
|
3932
|
-
return rb_gzreader_each_byte(obj);
|
3933
|
-
}
|
3934
|
-
|
3935
4124
|
/*
|
3936
4125
|
* Document-method: Zlib::GzipReader#ungetc
|
3937
4126
|
*
|
@@ -3976,7 +4165,7 @@ gzreader_skip_linebreaks(struct gzfile *gz)
|
|
3976
4165
|
|
3977
4166
|
while (ZSTREAM_BUF_FILLED(&gz->z) == 0) {
|
3978
4167
|
if (GZFILE_IS_FINISHED(gz)) return;
|
3979
|
-
gzfile_read_more(gz);
|
4168
|
+
gzfile_read_more(gz, Qnil);
|
3980
4169
|
}
|
3981
4170
|
n = 0;
|
3982
4171
|
p = RSTRING_PTR(gz->z.buf);
|
@@ -3987,7 +4176,7 @@ gzreader_skip_linebreaks(struct gzfile *gz)
|
|
3987
4176
|
gzfile_calc_crc(gz, str);
|
3988
4177
|
while (ZSTREAM_BUF_FILLED(&gz->z) == 0) {
|
3989
4178
|
if (GZFILE_IS_FINISHED(gz)) return;
|
3990
|
-
gzfile_read_more(gz);
|
4179
|
+
gzfile_read_more(gz, Qnil);
|
3991
4180
|
}
|
3992
4181
|
n = 0;
|
3993
4182
|
p = RSTRING_PTR(gz->z.buf);
|
@@ -4109,7 +4298,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
|
|
4109
4298
|
if (ZSTREAM_BUF_FILLED(&gz->z) > 0) gz->lineno++;
|
4110
4299
|
return gzfile_read(gz, rslen);
|
4111
4300
|
}
|
4112
|
-
gzfile_read_more(gz);
|
4301
|
+
gzfile_read_more(gz, Qnil);
|
4113
4302
|
}
|
4114
4303
|
|
4115
4304
|
p = RSTRING_PTR(gz->z.buf);
|
@@ -4118,7 +4307,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
|
|
4118
4307
|
long filled;
|
4119
4308
|
if (n > ZSTREAM_BUF_FILLED(&gz->z)) {
|
4120
4309
|
if (ZSTREAM_IS_FINISHED(&gz->z)) break;
|
4121
|
-
gzfile_read_more(gz);
|
4310
|
+
gzfile_read_more(gz, Qnil);
|
4122
4311
|
p = RSTRING_PTR(gz->z.buf) + n - rslen;
|
4123
4312
|
}
|
4124
4313
|
if (!rspara) rscheck(rsptr, rslen, rs);
|
@@ -4158,6 +4347,8 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
|
|
4158
4347
|
* Document-method: Zlib::GzipReader#gets
|
4159
4348
|
*
|
4160
4349
|
* See Zlib::GzipReader documentation for a description.
|
4350
|
+
* However, note that this method can return +nil+ even if
|
4351
|
+
* #eof? returns false, unlike the behavior of File#gets.
|
4161
4352
|
*/
|
4162
4353
|
static VALUE
|
4163
4354
|
rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
|
@@ -4204,20 +4395,6 @@ rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
|
|
4204
4395
|
return obj;
|
4205
4396
|
}
|
4206
4397
|
|
4207
|
-
/*
|
4208
|
-
* Document-method: Zlib::GzipReader#lines
|
4209
|
-
*
|
4210
|
-
* This is a deprecated alias for <code>each_line</code>.
|
4211
|
-
*/
|
4212
|
-
static VALUE
|
4213
|
-
rb_gzreader_lines(int argc, VALUE *argv, VALUE obj)
|
4214
|
-
{
|
4215
|
-
rb_warn("Zlib::GzipReader#lines is deprecated; use #each_line instead");
|
4216
|
-
if (!rb_block_given_p())
|
4217
|
-
return rb_enumeratorize(obj, ID2SYM(rb_intern("each_line")), argc, argv);
|
4218
|
-
return rb_gzreader_each(argc, argv, obj);
|
4219
|
-
}
|
4220
|
-
|
4221
4398
|
/*
|
4222
4399
|
* Document-method: Zlib::GzipReader#readlines
|
4223
4400
|
*
|
@@ -4245,6 +4422,20 @@ rb_gzreader_external_encoding(VALUE self)
|
|
4245
4422
|
return rb_enc_from_encoding(get_gzfile(self)->enc);
|
4246
4423
|
}
|
4247
4424
|
|
4425
|
+
static VALUE
|
4426
|
+
zlib_gzip_end_rescue(VALUE arg)
|
4427
|
+
{
|
4428
|
+
struct gzfile *gz = (struct gzfile *)arg;
|
4429
|
+
gz->end(gz);
|
4430
|
+
return Qnil;
|
4431
|
+
}
|
4432
|
+
|
4433
|
+
static VALUE
|
4434
|
+
zlib_gzip_ensure(VALUE arg)
|
4435
|
+
{
|
4436
|
+
return rb_rescue(zlib_gzip_end_rescue, arg, NULL, Qnil);
|
4437
|
+
}
|
4438
|
+
|
4248
4439
|
static void
|
4249
4440
|
zlib_gzip_end(struct gzfile *gz)
|
4250
4441
|
{
|
@@ -4254,9 +4445,8 @@ zlib_gzip_end(struct gzfile *gz)
|
|
4254
4445
|
zstream_end(&gz->z);
|
4255
4446
|
}
|
4256
4447
|
|
4257
|
-
#define OPTHASH_GIVEN_P(opts) \
|
4258
|
-
(argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
|
4259
4448
|
static ID id_level, id_strategy;
|
4449
|
+
static VALUE zlib_gzip_run(VALUE arg);
|
4260
4450
|
|
4261
4451
|
/*
|
4262
4452
|
* call-seq:
|
@@ -4285,9 +4475,8 @@ zlib_s_gzip(int argc, VALUE *argv, VALUE klass)
|
|
4285
4475
|
{
|
4286
4476
|
struct gzfile gz0;
|
4287
4477
|
struct gzfile *gz = &gz0;
|
4288
|
-
long len;
|
4289
4478
|
int err;
|
4290
|
-
VALUE src, opts, level=Qnil, strategy=Qnil;
|
4479
|
+
VALUE src, opts, level=Qnil, strategy=Qnil, args[2];
|
4291
4480
|
|
4292
4481
|
if (OPTHASH_GIVEN_P(opts)) {
|
4293
4482
|
ID keyword_ids[2];
|
@@ -4309,9 +4498,23 @@ zlib_s_gzip(int argc, VALUE *argv, VALUE klass)
|
|
4309
4498
|
err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
|
4310
4499
|
-MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
|
4311
4500
|
if (err != Z_OK) {
|
4501
|
+
zlib_gzip_end(gz);
|
4312
4502
|
raise_zlib_error(err, gz->z.stream.msg);
|
4313
4503
|
}
|
4314
4504
|
ZSTREAM_READY(&gz->z);
|
4505
|
+
args[0] = (VALUE)gz;
|
4506
|
+
args[1] = src;
|
4507
|
+
return rb_ensure(zlib_gzip_run, (VALUE)args, zlib_gzip_ensure, (VALUE)gz);
|
4508
|
+
}
|
4509
|
+
|
4510
|
+
static VALUE
|
4511
|
+
zlib_gzip_run(VALUE arg)
|
4512
|
+
{
|
4513
|
+
VALUE *args = (VALUE *)arg;
|
4514
|
+
struct gzfile *gz = (struct gzfile *)args[0];
|
4515
|
+
VALUE src = args[1];
|
4516
|
+
long len;
|
4517
|
+
|
4315
4518
|
gzfile_make_header(gz);
|
4316
4519
|
len = RSTRING_LEN(src);
|
4317
4520
|
if (len > 0) {
|
@@ -4327,10 +4530,11 @@ static void
|
|
4327
4530
|
zlib_gunzip_end(struct gzfile *gz)
|
4328
4531
|
{
|
4329
4532
|
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
|
4330
|
-
gzfile_check_footer(gz);
|
4331
4533
|
zstream_end(&gz->z);
|
4332
4534
|
}
|
4333
4535
|
|
4536
|
+
static VALUE zlib_gunzip_run(VALUE arg);
|
4537
|
+
|
4334
4538
|
/*
|
4335
4539
|
* call-seq:
|
4336
4540
|
* Zlib.gunzip(src) -> String
|
@@ -4355,7 +4559,6 @@ zlib_gunzip(VALUE klass, VALUE src)
|
|
4355
4559
|
struct gzfile gz0;
|
4356
4560
|
struct gzfile *gz = &gz0;
|
4357
4561
|
int err;
|
4358
|
-
VALUE dst;
|
4359
4562
|
|
4360
4563
|
StringValue(src);
|
4361
4564
|
|
@@ -4367,15 +4570,25 @@ zlib_gunzip(VALUE klass, VALUE src)
|
|
4367
4570
|
gz->io = Qundef;
|
4368
4571
|
gz->z.input = src;
|
4369
4572
|
ZSTREAM_READY(&gz->z);
|
4370
|
-
|
4573
|
+
return rb_ensure(zlib_gunzip_run, (VALUE)gz, zlib_gzip_ensure, (VALUE)gz);
|
4574
|
+
}
|
4575
|
+
|
4576
|
+
static VALUE
|
4577
|
+
zlib_gunzip_run(VALUE arg)
|
4578
|
+
{
|
4579
|
+
struct gzfile *gz = (struct gzfile *)arg;
|
4580
|
+
VALUE dst;
|
4581
|
+
|
4582
|
+
gzfile_read_header(gz, Qnil);
|
4371
4583
|
dst = zstream_detach_buffer(&gz->z);
|
4372
4584
|
gzfile_calc_crc(gz, dst);
|
4373
|
-
|
4374
|
-
|
4375
|
-
|
4376
|
-
if (NIL_P(gz->z.input))
|
4585
|
+
if (!ZSTREAM_IS_FINISHED(&gz->z)) {
|
4586
|
+
rb_raise(cGzError, "unexpected end of file");
|
4587
|
+
}
|
4588
|
+
if (NIL_P(gz->z.input)) {
|
4377
4589
|
rb_raise(cNoFooter, "footer is not found");
|
4378
|
-
|
4590
|
+
}
|
4591
|
+
gzfile_check_footer(gz, Qnil);
|
4379
4592
|
return dst;
|
4380
4593
|
}
|
4381
4594
|
|
@@ -4384,6 +4597,11 @@ zlib_gunzip(VALUE klass, VALUE src)
|
|
4384
4597
|
void
|
4385
4598
|
Init_zlib(void)
|
4386
4599
|
{
|
4600
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
4601
|
+
rb_ext_ractor_safe(true);
|
4602
|
+
#endif
|
4603
|
+
|
4604
|
+
#undef rb_intern
|
4387
4605
|
VALUE mZlib, cZStream, cDeflate, cInflate;
|
4388
4606
|
#if GZIP_SUPPORT
|
4389
4607
|
VALUE cGzipFile, cGzipWriter, cGzipReader;
|
@@ -4477,7 +4695,7 @@ Init_zlib(void)
|
|
4477
4695
|
rb_define_alloc_func(cInflate, rb_inflate_s_allocate);
|
4478
4696
|
rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1);
|
4479
4697
|
rb_define_method(cInflate, "add_dictionary", rb_inflate_add_dictionary, 1);
|
4480
|
-
rb_define_method(cInflate, "inflate", rb_inflate_inflate, 1);
|
4698
|
+
rb_define_method(cInflate, "inflate", rb_inflate_inflate, -1);
|
4481
4699
|
rb_define_method(cInflate, "<<", rb_inflate_addstr, 1);
|
4482
4700
|
rb_define_method(cInflate, "sync", rb_inflate_sync, 1);
|
4483
4701
|
rb_define_method(cInflate, "sync_point?", rb_inflate_sync_point_p, 0);
|
@@ -4618,7 +4836,7 @@ Init_zlib(void)
|
|
4618
4836
|
rb_define_alloc_func(cGzipWriter, rb_gzwriter_s_allocate);
|
4619
4837
|
rb_define_method(cGzipWriter, "initialize", rb_gzwriter_initialize,-1);
|
4620
4838
|
rb_define_method(cGzipWriter, "flush", rb_gzwriter_flush, -1);
|
4621
|
-
rb_define_method(cGzipWriter, "write", rb_gzwriter_write, 1);
|
4839
|
+
rb_define_method(cGzipWriter, "write", rb_gzwriter_write, -1);
|
4622
4840
|
rb_define_method(cGzipWriter, "putc", rb_gzwriter_putc, 1);
|
4623
4841
|
rb_define_method(cGzipWriter, "<<", rb_gzwriter_addstr, 1);
|
4624
4842
|
rb_define_method(cGzipWriter, "printf", rb_gzwriter_printf, -1);
|
@@ -4626,6 +4844,7 @@ Init_zlib(void)
|
|
4626
4844
|
rb_define_method(cGzipWriter, "puts", rb_gzwriter_puts, -1);
|
4627
4845
|
|
4628
4846
|
rb_define_singleton_method(cGzipReader, "open", rb_gzreader_s_open,-1);
|
4847
|
+
rb_define_singleton_method(cGzipReader, "zcat", rb_gzreader_s_zcat, -1);
|
4629
4848
|
rb_define_alloc_func(cGzipReader, rb_gzreader_s_allocate);
|
4630
4849
|
rb_define_method(cGzipReader, "initialize", rb_gzreader_initialize, -1);
|
4631
4850
|
rb_define_method(cGzipReader, "rewind", rb_gzreader_rewind, 0);
|
@@ -4638,14 +4857,12 @@ Init_zlib(void)
|
|
4638
4857
|
rb_define_method(cGzipReader, "readbyte", rb_gzreader_readbyte, 0);
|
4639
4858
|
rb_define_method(cGzipReader, "each_byte", rb_gzreader_each_byte, 0);
|
4640
4859
|
rb_define_method(cGzipReader, "each_char", rb_gzreader_each_char, 0);
|
4641
|
-
rb_define_method(cGzipReader, "bytes", rb_gzreader_bytes, 0);
|
4642
4860
|
rb_define_method(cGzipReader, "ungetc", rb_gzreader_ungetc, 1);
|
4643
4861
|
rb_define_method(cGzipReader, "ungetbyte", rb_gzreader_ungetbyte, 1);
|
4644
4862
|
rb_define_method(cGzipReader, "gets", rb_gzreader_gets, -1);
|
4645
4863
|
rb_define_method(cGzipReader, "readline", rb_gzreader_readline, -1);
|
4646
4864
|
rb_define_method(cGzipReader, "each", rb_gzreader_each, -1);
|
4647
4865
|
rb_define_method(cGzipReader, "each_line", rb_gzreader_each, -1);
|
4648
|
-
rb_define_method(cGzipReader, "lines", rb_gzreader_lines, -1);
|
4649
4866
|
rb_define_method(cGzipReader, "readlines", rb_gzreader_readlines, -1);
|
4650
4867
|
rb_define_method(cGzipReader, "external_encoding", rb_gzreader_external_encoding, 0);
|
4651
4868
|
|
@@ -4687,6 +4904,7 @@ Init_zlib(void)
|
|
4687
4904
|
|
4688
4905
|
id_level = rb_intern("level");
|
4689
4906
|
id_strategy = rb_intern("strategy");
|
4907
|
+
id_buffer = rb_intern("buffer");
|
4690
4908
|
#endif /* GZIP_SUPPORT */
|
4691
4909
|
}
|
4692
4910
|
|
@@ -4807,5 +5025,3 @@ Init_zlib(void)
|
|
4807
5025
|
* Raised when the data length recorded in the gzip file footer is not equivalent
|
4808
5026
|
* to the length of the actual uncompressed data.
|
4809
5027
|
*/
|
4810
|
-
|
4811
|
-
|