zlib 0.1.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
|