rubysl-zlib 2.0.0 → 2.0.1
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 +4 -4
- data/.travis.yml +7 -5
- data/ext/rubysl/zlib/extconf.rb +5 -8
- data/ext/rubysl/zlib/zlib.c +1090 -881
- data/lib/rubysl/zlib.rb +1 -1
- data/lib/rubysl/zlib/version.rb +1 -1
- data/rubysl-zlib.gemspec +1 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1076e7a2ba523e3a8345ea34fe039b2184052466
|
4
|
+
data.tar.gz: c6b070cd9a773dd02db9ef613f373fc800abeae8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 415ef09bc699e6de21edae923dd75f8384e96b2851d428071fc454cab229224e0e7e7140d99175a69ee21524eff8f61dc63133054ee3274894a38c1396337d29
|
7
|
+
data.tar.gz: 0d111deffcf2c356940db2e85ca7cb230febafb2efa210b074a7340c8b9c6c6173160f1d15d84c0510782552b391bedc700d5e2c46a710ab955a0573f2c5de52
|
data/.travis.yml
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
language: ruby
|
2
|
+
before_install:
|
3
|
+
- rvm use $RVM --install --binary --fuzzy
|
4
|
+
- gem update --system
|
5
|
+
- gem --version
|
6
|
+
- gem install rubysl-bundler
|
2
7
|
env:
|
3
|
-
- RUBYLIB=lib
|
4
|
-
script: bundle exec mspec
|
5
|
-
rvm:
|
6
|
-
- 1.9.3
|
7
|
-
- rbx-nightly-19mode
|
8
|
+
- RVM=rbx-nightly-d21 RUBYLIB=lib
|
9
|
+
script: bundle exec mspec spec
|
data/ext/rubysl/zlib/extconf.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# extconf.rb
|
3
3
|
#
|
4
|
-
# $Id: extconf.rb
|
4
|
+
# $Id: extconf.rb 37527 2012-11-06 18:50:53Z luislavena $
|
5
5
|
#
|
6
6
|
|
7
7
|
require 'mkmf'
|
@@ -10,12 +10,12 @@ require 'rbconfig'
|
|
10
10
|
dir_config 'zlib'
|
11
11
|
|
12
12
|
|
13
|
-
if %w'z libz zlib1 zlib zdll'.find {|z| have_library(z, 'deflateReset')} and
|
13
|
+
if %w'z libz zlib1 zlib zdll zlibwapi'.find {|z| have_library(z, 'deflateReset')} and
|
14
14
|
have_header('zlib.h') then
|
15
15
|
|
16
16
|
defines = []
|
17
17
|
|
18
|
-
message 'checking for kind of operating system... '
|
18
|
+
Logging::message 'checking for kind of operating system... '
|
19
19
|
os_code = with_config('os-code') ||
|
20
20
|
case RUBY_PLATFORM.split('-',2)[1]
|
21
21
|
when 'amigaos' then
|
@@ -48,14 +48,11 @@ if %w'z libz zlib1 zlib zdll'.find {|z| have_library(z, 'deflateReset')} and
|
|
48
48
|
'OS_UNKNOWN' => 'Unknown',
|
49
49
|
}
|
50
50
|
unless OS_NAMES.key? os_code then
|
51
|
-
|
52
|
-
exit
|
51
|
+
raise "invalid OS_CODE `#{os_code}'"
|
53
52
|
end
|
54
|
-
message "#{OS_NAMES[os_code]}\n"
|
53
|
+
Logging::message "#{OS_NAMES[os_code]}\n"
|
55
54
|
defines << "OS_CODE=#{os_code}"
|
56
55
|
|
57
|
-
$CFLAGS += " -Wno-pointer-sign"
|
58
|
-
|
59
56
|
$defs.concat(defines.collect{|d|' -D'+d})
|
60
57
|
|
61
58
|
have_func('crc32_combine', 'zlib.h')
|
data/ext/rubysl/zlib/zlib.c
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
*
|
4
4
|
* Copyright (C) UENO Katsuhiro 2000-2003
|
5
5
|
*
|
6
|
-
* $Id: zlib.c
|
6
|
+
* $Id: zlib.c 42720 2013-08-28 20:36:21Z drbrain $
|
7
7
|
*/
|
8
8
|
|
9
9
|
#define RSTRING_NOT_MODIFIED 1
|
@@ -12,6 +12,7 @@
|
|
12
12
|
#include <zlib.h>
|
13
13
|
#include <time.h>
|
14
14
|
#include <ruby/io.h>
|
15
|
+
#include <ruby/thread.h>
|
15
16
|
|
16
17
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
17
18
|
# include <valgrind/memcheck.h>
|
@@ -22,8 +23,8 @@
|
|
22
23
|
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
|
23
24
|
# endif
|
24
25
|
#else
|
25
|
-
# define VALGRIND_MAKE_MEM_DEFINED(p, n)
|
26
|
-
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n)
|
26
|
+
# define VALGRIND_MAKE_MEM_DEFINED(p, n) 0
|
27
|
+
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
|
27
28
|
#endif
|
28
29
|
|
29
30
|
#define RUBY_ZLIB_VERSION "0.6.0"
|
@@ -58,6 +59,8 @@ max_uint(long n)
|
|
58
59
|
|
59
60
|
#define sizeof(x) ((int)sizeof(x))
|
60
61
|
|
62
|
+
static ID id_dictionaries;
|
63
|
+
|
61
64
|
/*--------- Prototypes --------*/
|
62
65
|
|
63
66
|
static NORETURN(void raise_zlib_error(int, const char*));
|
@@ -72,6 +75,7 @@ static void finalizer_warn(const char*);
|
|
72
75
|
|
73
76
|
struct zstream;
|
74
77
|
struct zstream_funcs;
|
78
|
+
struct zstream_run_args;
|
75
79
|
static void zstream_init(struct zstream*, const struct zstream_funcs*);
|
76
80
|
static void zstream_expand_buffer(struct zstream*);
|
77
81
|
static void zstream_expand_buffer_into(struct zstream*, unsigned long);
|
@@ -224,9 +228,50 @@ static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
|
|
224
228
|
/*
|
225
229
|
* Document-module: Zlib
|
226
230
|
*
|
227
|
-
*
|
231
|
+
* This module provides access to the {zlib library}[http://zlib.net]. Zlib is
|
232
|
+
* designed to be a portable, free, general-purpose, legally unencumbered --
|
233
|
+
* that is, not covered by any patents -- lossless data-compression library
|
234
|
+
* for use on virtually any computer hardware and operating system.
|
235
|
+
*
|
236
|
+
* The zlib compression library provides in-memory compression and
|
237
|
+
* decompression functions, including integrity checks of the uncompressed
|
238
|
+
* data.
|
239
|
+
*
|
240
|
+
* The zlib compressed data format is described in RFC 1950, which is a
|
241
|
+
* wrapper around a deflate stream which is described in RFC 1951.
|
242
|
+
*
|
243
|
+
* The library also supports reading and writing files in gzip (.gz) format
|
244
|
+
* with an interface similar to that of IO. The gzip format is described in
|
245
|
+
* RFC 1952 which is also a wrapper around a deflate stream.
|
246
|
+
*
|
247
|
+
* The zlib format was designed to be compact and fast for use in memory and on
|
248
|
+
* communications channels. The gzip format was designed for single-file
|
249
|
+
* compression on file systems, has a larger header than zlib to maintain
|
250
|
+
* directory information, and uses a different, slower check method than zlib.
|
251
|
+
*
|
252
|
+
* See your system's zlib.h for further information about zlib
|
253
|
+
*
|
254
|
+
* == Sample usage
|
255
|
+
*
|
256
|
+
* Using the wrapper to compress strings with default parameters is quite
|
257
|
+
* simple:
|
258
|
+
*
|
259
|
+
* require "zlib"
|
260
|
+
*
|
261
|
+
* data_to_compress = File.read("don_quixote.txt")
|
262
|
+
*
|
263
|
+
* puts "Input size: #{data_to_compress.size}"
|
264
|
+
* #=> Input size: 2347740
|
265
|
+
*
|
266
|
+
* data_compressed = Zlib::Deflate.deflate(data_to_compress)
|
267
|
+
*
|
268
|
+
* puts "Compressed size: #{data_compressed.size}"
|
269
|
+
* #=> Compressed size: 887238
|
270
|
+
*
|
271
|
+
* uncompressed_data = Zlib::Inflate.inflate(data_compressed)
|
228
272
|
*
|
229
|
-
*
|
273
|
+
* puts "Uncompressed data is: #{uncompressed_data}"
|
274
|
+
* #=> Uncompressed data is: The Project Gutenberg EBook of Don Quixote...
|
230
275
|
*
|
231
276
|
* == Class tree
|
232
277
|
*
|
@@ -251,8 +296,6 @@ static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
|
|
251
296
|
* - Zlib::GzipFile::CRCError
|
252
297
|
* - Zlib::GzipFile::NoFooter
|
253
298
|
*
|
254
|
-
* see also zlib.h
|
255
|
-
*
|
256
299
|
*/
|
257
300
|
void Init_zlib(void);
|
258
301
|
|
@@ -267,39 +310,39 @@ raise_zlib_error(int err, const char *msg)
|
|
267
310
|
VALUE exc;
|
268
311
|
|
269
312
|
if (!msg) {
|
270
|
-
|
313
|
+
msg = zError(err);
|
271
314
|
}
|
272
315
|
|
273
316
|
switch(err) {
|
274
317
|
case Z_STREAM_END:
|
275
|
-
|
276
|
-
|
318
|
+
exc = rb_exc_new2(cStreamEnd, msg);
|
319
|
+
break;
|
277
320
|
case Z_NEED_DICT:
|
278
|
-
|
279
|
-
|
321
|
+
exc = rb_exc_new2(cNeedDict, msg);
|
322
|
+
break;
|
280
323
|
case Z_STREAM_ERROR:
|
281
|
-
|
282
|
-
|
324
|
+
exc = rb_exc_new2(cStreamError, msg);
|
325
|
+
break;
|
283
326
|
case Z_DATA_ERROR:
|
284
|
-
|
285
|
-
|
327
|
+
exc = rb_exc_new2(cDataError, msg);
|
328
|
+
break;
|
286
329
|
case Z_BUF_ERROR:
|
287
|
-
|
288
|
-
|
330
|
+
exc = rb_exc_new2(cBufError, msg);
|
331
|
+
break;
|
289
332
|
case Z_VERSION_ERROR:
|
290
|
-
|
291
|
-
|
333
|
+
exc = rb_exc_new2(cVersionError, msg);
|
334
|
+
break;
|
292
335
|
case Z_MEM_ERROR:
|
293
|
-
|
294
|
-
|
336
|
+
exc = rb_exc_new2(cMemError, msg);
|
337
|
+
break;
|
295
338
|
case Z_ERRNO:
|
296
|
-
|
297
|
-
|
339
|
+
rb_sys_fail(msg);
|
340
|
+
/* no return */
|
298
341
|
default:
|
299
342
|
{
|
300
|
-
|
301
|
-
|
302
|
-
|
343
|
+
char buf[BUFSIZ];
|
344
|
+
snprintf(buf, BUFSIZ, "unknown zlib error %d: %s", err, msg);
|
345
|
+
exc = rb_exc_new2(cZError, buf);
|
303
346
|
}
|
304
347
|
}
|
305
348
|
|
@@ -338,11 +381,11 @@ static uLong
|
|
338
381
|
checksum_long(uLong (*func)(uLong, const Bytef*, uInt), uLong sum, const Bytef *ptr, long len)
|
339
382
|
{
|
340
383
|
if (len > UINT_MAX) {
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
384
|
+
do {
|
385
|
+
sum = func(sum, ptr, UINT_MAX);
|
386
|
+
ptr += UINT_MAX;
|
387
|
+
len -= UINT_MAX;
|
388
|
+
} while (len >= UINT_MAX);
|
346
389
|
}
|
347
390
|
if (len > 0) sum = func(sum, ptr, (uInt)len);
|
348
391
|
return sum;
|
@@ -363,21 +406,21 @@ do_checksum(argc, argv, func)
|
|
363
406
|
rb_scan_args(argc, argv, "02", &str, &vsum);
|
364
407
|
|
365
408
|
if (!NIL_P(vsum)) {
|
366
|
-
|
409
|
+
sum = NUM2ULONG(vsum);
|
367
410
|
}
|
368
411
|
else if (NIL_P(str)) {
|
369
|
-
|
412
|
+
sum = 0;
|
370
413
|
}
|
371
414
|
else {
|
372
|
-
|
415
|
+
sum = func(0, Z_NULL, 0);
|
373
416
|
}
|
374
417
|
|
375
418
|
if (NIL_P(str)) {
|
376
|
-
|
419
|
+
sum = func(sum, Z_NULL, 0);
|
377
420
|
}
|
378
421
|
else {
|
379
|
-
|
380
|
-
|
422
|
+
StringValue(str);
|
423
|
+
sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
|
381
424
|
}
|
382
425
|
return rb_uint2inum(sum);
|
383
426
|
}
|
@@ -414,7 +457,7 @@ static VALUE
|
|
414
457
|
rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
|
415
458
|
{
|
416
459
|
return ULONG2NUM(
|
417
|
-
|
460
|
+
adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
|
418
461
|
}
|
419
462
|
#else
|
420
463
|
#define rb_zlib_adler32_combine rb_f_notimplement
|
@@ -452,7 +495,7 @@ static VALUE
|
|
452
495
|
rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
|
453
496
|
{
|
454
497
|
return ULONG2NUM(
|
455
|
-
|
498
|
+
crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
|
456
499
|
}
|
457
500
|
#else
|
458
501
|
#define rb_zlib_crc32_combine rb_f_notimplement
|
@@ -478,7 +521,7 @@ rb_zlib_crc_table(VALUE obj)
|
|
478
521
|
dst = rb_ary_new2(256);
|
479
522
|
|
480
523
|
for (i = 0; i < 256; i++) {
|
481
|
-
|
524
|
+
rb_ary_push(dst, rb_uint2inum(crctbl[i]));
|
482
525
|
}
|
483
526
|
return dst;
|
484
527
|
}
|
@@ -494,9 +537,9 @@ struct zstream {
|
|
494
537
|
VALUE input;
|
495
538
|
z_stream stream;
|
496
539
|
const struct zstream_funcs {
|
497
|
-
|
498
|
-
|
499
|
-
|
540
|
+
int (*reset)(z_streamp);
|
541
|
+
int (*end)(z_streamp);
|
542
|
+
int (*run)(z_streamp, int);
|
500
543
|
} *func;
|
501
544
|
};
|
502
545
|
|
@@ -504,16 +547,22 @@ struct zstream {
|
|
504
547
|
#define ZSTREAM_FLAG_IN_STREAM 0x2
|
505
548
|
#define ZSTREAM_FLAG_FINISHED 0x4
|
506
549
|
#define ZSTREAM_FLAG_CLOSING 0x8
|
507
|
-
#define
|
550
|
+
#define ZSTREAM_FLAG_GZFILE 0x10 /* disallows yield from expand_buffer for
|
551
|
+
gzip*/
|
552
|
+
#define ZSTREAM_FLAG_UNUSED 0x20
|
508
553
|
|
509
554
|
#define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
|
510
555
|
#define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
|
511
556
|
#define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)
|
512
557
|
#define ZSTREAM_IS_CLOSING(z) ((z)->flags & ZSTREAM_FLAG_CLOSING)
|
558
|
+
#define ZSTREAM_IS_GZFILE(z) ((z)->flags & ZSTREAM_FLAG_GZFILE)
|
559
|
+
|
560
|
+
#define ZSTREAM_EXPAND_BUFFER_OK 0
|
513
561
|
|
514
562
|
/* I think that more better value should be found,
|
515
563
|
but I gave up finding it. B) */
|
516
564
|
#define ZSTREAM_INITIAL_BUFSIZE 1024
|
565
|
+
/* Allow a quick return when the thread is interrupted */
|
517
566
|
#define ZSTREAM_AVAIL_OUT_STEP_MAX 16384
|
518
567
|
#define ZSTREAM_AVAIL_OUT_STEP_MIN 2048
|
519
568
|
|
@@ -525,6 +574,13 @@ static const struct zstream_funcs inflate_funcs = {
|
|
525
574
|
inflateReset, inflateEnd, inflate,
|
526
575
|
};
|
527
576
|
|
577
|
+
struct zstream_run_args {
|
578
|
+
struct zstream * z;
|
579
|
+
int flush; /* stream flush value for inflate() or deflate() */
|
580
|
+
int interrupt; /* stop processing the stream and return to ruby */
|
581
|
+
int jump_state; /* for buffer expansion block break or exception */
|
582
|
+
int stream_output; /* for streaming zlib processing */
|
583
|
+
};
|
528
584
|
|
529
585
|
static voidpf
|
530
586
|
zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
|
@@ -534,7 +590,7 @@ zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
|
|
534
590
|
deflate is performing a conditional jump that depends on an
|
535
591
|
uninitialized value. Isn't that a bug?
|
536
592
|
http://www.zlib.net/zlib_faq.html#faq36 */
|
537
|
-
VALGRIND_MAKE_MEM_DEFINED(p, items * size);
|
593
|
+
(void)VALGRIND_MAKE_MEM_DEFINED(p, items * size);
|
538
594
|
return p;
|
539
595
|
}
|
540
596
|
|
@@ -568,75 +624,106 @@ zstream_init(struct zstream *z, const struct zstream_funcs *func)
|
|
568
624
|
static void
|
569
625
|
zstream_expand_buffer(struct zstream *z)
|
570
626
|
{
|
571
|
-
long inc;
|
572
|
-
|
573
627
|
if (NIL_P(z->buf)) {
|
574
|
-
|
575
|
-
|
576
|
-
z->buf = rb_str_new(0, ZSTREAM_INITIAL_BUFSIZE);
|
577
|
-
z->buf_filled = 0;
|
578
|
-
z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
|
579
|
-
z->stream.avail_out = ZSTREAM_INITIAL_BUFSIZE;
|
580
|
-
return;
|
628
|
+
zstream_expand_buffer_into(z, ZSTREAM_INITIAL_BUFSIZE);
|
629
|
+
return;
|
581
630
|
}
|
582
631
|
|
583
|
-
if (
|
584
|
-
|
585
|
-
|
632
|
+
if (!ZSTREAM_IS_GZFILE(z) && rb_block_given_p()) {
|
633
|
+
if (z->buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
|
634
|
+
int state = 0;
|
635
|
+
VALUE self = (VALUE)z->stream.opaque;
|
636
|
+
|
637
|
+
rb_str_resize(z->buf, z->buf_filled);
|
638
|
+
rb_obj_reveal(z->buf, rb_cString);
|
639
|
+
OBJ_INFECT(z->buf, self);
|
640
|
+
|
641
|
+
rb_protect(rb_yield, z->buf, &state);
|
642
|
+
|
643
|
+
z->buf = Qnil;
|
644
|
+
zstream_expand_buffer_into(z, ZSTREAM_AVAIL_OUT_STEP_MAX);
|
645
|
+
|
646
|
+
if (state)
|
647
|
+
rb_jump_tag(state);
|
648
|
+
|
649
|
+
return;
|
650
|
+
}
|
651
|
+
else {
|
652
|
+
zstream_expand_buffer_into(z,
|
653
|
+
ZSTREAM_AVAIL_OUT_STEP_MAX - z->buf_filled);
|
654
|
+
}
|
586
655
|
}
|
587
656
|
else {
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
657
|
+
if (RSTRING_LEN(z->buf) - z->buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
|
658
|
+
z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
|
659
|
+
}
|
660
|
+
else {
|
661
|
+
long inc = z->buf_filled / 2;
|
662
|
+
if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
|
663
|
+
inc = ZSTREAM_AVAIL_OUT_STEP_MIN;
|
664
|
+
}
|
665
|
+
rb_str_resize(z->buf, z->buf_filled + inc);
|
666
|
+
z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
|
667
|
+
(int)inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
|
668
|
+
}
|
669
|
+
z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
|
595
670
|
}
|
596
|
-
z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
|
597
671
|
}
|
598
672
|
|
599
673
|
static void
|
600
674
|
zstream_expand_buffer_into(struct zstream *z, unsigned long size)
|
601
675
|
{
|
602
676
|
if (NIL_P(z->buf)) {
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
677
|
+
/* I uses rb_str_new here not rb_str_buf_new because
|
678
|
+
rb_str_buf_new makes a zero-length string. */
|
679
|
+
z->buf = rb_str_new(0, size);
|
680
|
+
z->buf_filled = 0;
|
681
|
+
z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
|
682
|
+
z->stream.avail_out = MAX_UINT(size);
|
683
|
+
rb_obj_hide(z->buf);
|
609
684
|
}
|
610
685
|
else if (z->stream.avail_out != size) {
|
611
|
-
|
612
|
-
|
613
|
-
|
686
|
+
rb_str_resize(z->buf, z->buf_filled + size);
|
687
|
+
z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
|
688
|
+
z->stream.avail_out = MAX_UINT(size);
|
614
689
|
}
|
615
690
|
}
|
616
691
|
|
692
|
+
static void *
|
693
|
+
zstream_expand_buffer_protect(void *ptr)
|
694
|
+
{
|
695
|
+
struct zstream *z = (struct zstream *)ptr;
|
696
|
+
int state = 0;
|
697
|
+
|
698
|
+
rb_protect((VALUE (*)(VALUE))zstream_expand_buffer, (VALUE)z, &state);
|
699
|
+
|
700
|
+
return (void *)(VALUE)state;
|
701
|
+
}
|
702
|
+
|
617
703
|
static void
|
618
704
|
zstream_append_buffer(struct zstream *z, const Bytef *src, long len)
|
619
705
|
{
|
620
706
|
if (NIL_P(z->buf)) {
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
707
|
+
z->buf = rb_str_buf_new(len);
|
708
|
+
rb_str_buf_cat(z->buf, (const char*)src, len);
|
709
|
+
z->buf_filled = len;
|
710
|
+
z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
|
711
|
+
z->stream.avail_out = 0;
|
712
|
+
rb_obj_hide(z->buf);
|
713
|
+
return;
|
627
714
|
}
|
628
715
|
|
629
716
|
if (RSTRING_LEN(z->buf) < z->buf_filled + len) {
|
630
|
-
|
631
|
-
|
717
|
+
rb_str_resize(z->buf, z->buf_filled + len);
|
718
|
+
z->stream.avail_out = 0;
|
632
719
|
}
|
633
720
|
else {
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
721
|
+
if (z->stream.avail_out >= (uInt)len) {
|
722
|
+
z->stream.avail_out -= (uInt)len;
|
723
|
+
}
|
724
|
+
else {
|
725
|
+
z->stream.avail_out = 0;
|
726
|
+
}
|
640
727
|
}
|
641
728
|
memcpy(RSTRING_PTR(z->buf) + z->buf_filled, src, len);
|
642
729
|
z->buf_filled += len;
|
@@ -649,20 +736,36 @@ zstream_append_buffer(struct zstream *z, const Bytef *src, long len)
|
|
649
736
|
static VALUE
|
650
737
|
zstream_detach_buffer(struct zstream *z)
|
651
738
|
{
|
652
|
-
VALUE dst;
|
739
|
+
VALUE dst, self = (VALUE)z->stream.opaque;
|
740
|
+
|
741
|
+
if (!ZSTREAM_IS_FINISHED(z) && !ZSTREAM_IS_GZFILE(z) &&
|
742
|
+
rb_block_given_p()) {
|
743
|
+
/* prevent tiny yields mid-stream, save for next
|
744
|
+
* zstream_expand_buffer() or stream end */
|
745
|
+
return Qnil;
|
746
|
+
}
|
653
747
|
|
654
748
|
if (NIL_P(z->buf)) {
|
655
|
-
|
749
|
+
dst = rb_str_new(0, 0);
|
656
750
|
}
|
657
751
|
else {
|
658
|
-
|
659
|
-
|
752
|
+
dst = z->buf;
|
753
|
+
rb_str_resize(dst, z->buf_filled);
|
754
|
+
rb_obj_reveal(dst, rb_cString);
|
660
755
|
}
|
661
756
|
|
757
|
+
OBJ_INFECT(dst, self);
|
758
|
+
|
662
759
|
z->buf = Qnil;
|
663
760
|
z->buf_filled = 0;
|
664
761
|
z->stream.next_out = 0;
|
665
762
|
z->stream.avail_out = 0;
|
763
|
+
|
764
|
+
if (!ZSTREAM_IS_GZFILE(z) && rb_block_given_p()) {
|
765
|
+
rb_yield(dst);
|
766
|
+
dst = Qnil;
|
767
|
+
}
|
768
|
+
|
666
769
|
return dst;
|
667
770
|
}
|
668
771
|
|
@@ -673,17 +776,18 @@ zstream_shift_buffer(struct zstream *z, long len)
|
|
673
776
|
long buflen;
|
674
777
|
|
675
778
|
if (z->buf_filled <= len) {
|
676
|
-
|
779
|
+
return zstream_detach_buffer(z);
|
677
780
|
}
|
678
781
|
|
679
782
|
dst = rb_str_subseq(z->buf, 0, len);
|
783
|
+
rb_obj_reveal(dst, rb_cString);
|
680
784
|
z->buf_filled -= len;
|
681
785
|
memmove(RSTRING_PTR(z->buf), RSTRING_PTR(z->buf) + len,
|
682
|
-
|
786
|
+
z->buf_filled);
|
683
787
|
z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
|
684
788
|
buflen = RSTRING_LEN(z->buf) - z->buf_filled;
|
685
789
|
if (buflen > ZSTREAM_AVAIL_OUT_STEP_MAX) {
|
686
|
-
|
790
|
+
buflen = ZSTREAM_AVAIL_OUT_STEP_MAX;
|
687
791
|
}
|
688
792
|
z->stream.avail_out = (uInt)buflen;
|
689
793
|
|
@@ -694,16 +798,16 @@ static void
|
|
694
798
|
zstream_buffer_ungets(struct zstream *z, const Bytef *b, unsigned long len)
|
695
799
|
{
|
696
800
|
if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
|
697
|
-
|
801
|
+
zstream_expand_buffer_into(z, len);
|
698
802
|
}
|
699
803
|
|
700
804
|
memmove(RSTRING_PTR(z->buf) + len, RSTRING_PTR(z->buf), z->buf_filled);
|
701
805
|
memmove(RSTRING_PTR(z->buf), b, len);
|
702
806
|
z->buf_filled+=len;
|
703
807
|
if (z->stream.avail_out > 0) {
|
704
|
-
|
705
|
-
|
706
|
-
|
808
|
+
if (len > z->stream.avail_out) len = z->stream.avail_out;
|
809
|
+
z->stream.next_out+=len;
|
810
|
+
z->stream.avail_out-=(uInt)len;
|
707
811
|
}
|
708
812
|
}
|
709
813
|
|
@@ -711,15 +815,15 @@ static void
|
|
711
815
|
zstream_buffer_ungetbyte(struct zstream *z, int c)
|
712
816
|
{
|
713
817
|
if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
|
714
|
-
|
818
|
+
zstream_expand_buffer(z);
|
715
819
|
}
|
716
820
|
|
717
821
|
memmove(RSTRING_PTR(z->buf) + 1, RSTRING_PTR(z->buf), z->buf_filled);
|
718
822
|
RSTRING_PTR(z->buf)[0] = (char)c;
|
719
823
|
z->buf_filled++;
|
720
824
|
if (z->stream.avail_out > 0) {
|
721
|
-
|
722
|
-
|
825
|
+
z->stream.next_out++;
|
826
|
+
z->stream.avail_out--;
|
723
827
|
}
|
724
828
|
}
|
725
829
|
|
@@ -729,28 +833,29 @@ zstream_append_input(struct zstream *z, const Bytef *src, long len)
|
|
729
833
|
if (len <= 0) return;
|
730
834
|
|
731
835
|
if (NIL_P(z->input)) {
|
732
|
-
|
733
|
-
|
836
|
+
z->input = rb_str_buf_new(len);
|
837
|
+
rb_str_buf_cat(z->input, (const char*)src, len);
|
838
|
+
rb_obj_hide(z->input);
|
734
839
|
}
|
735
840
|
else {
|
736
|
-
|
841
|
+
rb_str_buf_cat(z->input, (const char*)src, len);
|
737
842
|
}
|
738
843
|
}
|
739
844
|
|
740
845
|
#define zstream_append_input2(z,v)\
|
741
|
-
RB_GC_GUARD(v)
|
846
|
+
RB_GC_GUARD(v),\
|
742
847
|
zstream_append_input((z), (Bytef*)RSTRING_PTR(v), RSTRING_LEN(v))
|
743
848
|
|
744
849
|
static void
|
745
850
|
zstream_discard_input(struct zstream *z, long len)
|
746
851
|
{
|
747
852
|
if (NIL_P(z->input) || RSTRING_LEN(z->input) <= len) {
|
748
|
-
|
853
|
+
z->input = Qnil;
|
749
854
|
}
|
750
855
|
else {
|
751
|
-
|
752
|
-
|
753
|
-
|
856
|
+
memmove(RSTRING_PTR(z->input), RSTRING_PTR(z->input) + len,
|
857
|
+
RSTRING_LEN(z->input) - len);
|
858
|
+
rb_str_resize(z->input, RSTRING_LEN(z->input) - len);
|
754
859
|
}
|
755
860
|
}
|
756
861
|
|
@@ -764,8 +869,8 @@ static void
|
|
764
869
|
zstream_passthrough_input(struct zstream *z)
|
765
870
|
{
|
766
871
|
if (!NIL_P(z->input)) {
|
767
|
-
|
768
|
-
|
872
|
+
zstream_append_buffer2(z, z->input);
|
873
|
+
z->input = Qnil;
|
769
874
|
}
|
770
875
|
}
|
771
876
|
|
@@ -775,12 +880,14 @@ zstream_detach_input(struct zstream *z)
|
|
775
880
|
VALUE dst;
|
776
881
|
|
777
882
|
if (NIL_P(z->input)) {
|
778
|
-
|
883
|
+
dst = rb_str_new(0, 0);
|
779
884
|
}
|
780
885
|
else {
|
781
|
-
|
886
|
+
dst = z->input;
|
887
|
+
rb_obj_reveal(dst, rb_cString);
|
782
888
|
}
|
783
889
|
z->input = Qnil;
|
890
|
+
rb_obj_reveal(dst, rb_cString);
|
784
891
|
return dst;
|
785
892
|
}
|
786
893
|
|
@@ -791,7 +898,7 @@ zstream_reset(struct zstream *z)
|
|
791
898
|
|
792
899
|
err = z->func->reset(&z->stream);
|
793
900
|
if (err != Z_OK) {
|
794
|
-
|
901
|
+
raise_zlib_error(err, z->stream.msg);
|
795
902
|
}
|
796
903
|
z->flags = ZSTREAM_FLAG_READY;
|
797
904
|
z->buf = Qnil;
|
@@ -807,109 +914,173 @@ zstream_end(struct zstream *z)
|
|
807
914
|
int err;
|
808
915
|
|
809
916
|
if (!ZSTREAM_IS_READY(z)) {
|
810
|
-
|
811
|
-
|
917
|
+
rb_warning("attempt to close uninitialized zstream; ignored.");
|
918
|
+
return Qnil;
|
812
919
|
}
|
813
920
|
if (z->flags & ZSTREAM_FLAG_IN_STREAM) {
|
814
|
-
|
815
|
-
|
921
|
+
rb_warning("attempt to close unfinished zstream; reset forced.");
|
922
|
+
zstream_reset(z);
|
816
923
|
}
|
817
924
|
|
818
925
|
zstream_reset_input(z);
|
819
926
|
err = z->func->end(&z->stream);
|
820
927
|
if (err != Z_OK) {
|
821
|
-
|
928
|
+
raise_zlib_error(err, z->stream.msg);
|
822
929
|
}
|
823
930
|
z->flags = 0;
|
824
931
|
return Qnil;
|
825
932
|
}
|
826
933
|
|
934
|
+
static void *
|
935
|
+
zstream_run_func(void *ptr)
|
936
|
+
{
|
937
|
+
struct zstream_run_args *args = (struct zstream_run_args *)ptr;
|
938
|
+
int err, state, flush = args->flush;
|
939
|
+
struct zstream *z = args->z;
|
940
|
+
uInt n;
|
941
|
+
|
942
|
+
err = Z_OK;
|
943
|
+
while (!args->interrupt) {
|
944
|
+
n = z->stream.avail_out;
|
945
|
+
err = z->func->run(&z->stream, flush);
|
946
|
+
z->buf_filled += n - z->stream.avail_out;
|
947
|
+
|
948
|
+
if (err == Z_STREAM_END) {
|
949
|
+
z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
|
950
|
+
z->flags |= ZSTREAM_FLAG_FINISHED;
|
951
|
+
break;
|
952
|
+
}
|
953
|
+
|
954
|
+
if (err != Z_OK && err != Z_BUF_ERROR)
|
955
|
+
break;
|
956
|
+
|
957
|
+
if (z->stream.avail_out > 0) {
|
958
|
+
z->flags |= ZSTREAM_FLAG_IN_STREAM;
|
959
|
+
break;
|
960
|
+
}
|
961
|
+
|
962
|
+
if (z->stream.avail_in == 0 && z->func == &inflate_funcs) {
|
963
|
+
/* break here because inflate() return Z_BUF_ERROR when avail_in == 0. */
|
964
|
+
/* but deflate() could be called with avail_in == 0 (there's hidden buffer
|
965
|
+
in zstream->state) */
|
966
|
+
z->flags |= ZSTREAM_FLAG_IN_STREAM;
|
967
|
+
break;
|
968
|
+
}
|
969
|
+
|
970
|
+
state = (int)(VALUE)rb_thread_call_with_gvl(zstream_expand_buffer_protect,
|
971
|
+
(void *)z);
|
972
|
+
|
973
|
+
if (state) {
|
974
|
+
err = Z_OK; /* buffer expanded but stream processing was stopped */
|
975
|
+
args->jump_state = state;
|
976
|
+
break;
|
977
|
+
}
|
978
|
+
}
|
979
|
+
|
980
|
+
return (void *)(VALUE)err;
|
981
|
+
}
|
982
|
+
|
983
|
+
/*
|
984
|
+
* There is no safe way to interrupt z->run->func().
|
985
|
+
*/
|
986
|
+
static void
|
987
|
+
zstream_unblock_func(void *ptr)
|
988
|
+
{
|
989
|
+
struct zstream_run_args *args = (struct zstream_run_args *)ptr;
|
990
|
+
|
991
|
+
args->interrupt = 1;
|
992
|
+
}
|
993
|
+
|
827
994
|
static void
|
828
995
|
zstream_run(struct zstream *z, Bytef *src, long len, int flush)
|
829
996
|
{
|
830
|
-
|
997
|
+
struct zstream_run_args args;
|
831
998
|
int err;
|
832
999
|
volatile VALUE guard = Qnil;
|
833
1000
|
|
1001
|
+
args.z = z;
|
1002
|
+
args.flush = flush;
|
1003
|
+
args.interrupt = 0;
|
1004
|
+
args.jump_state = 0;
|
1005
|
+
args.stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p();
|
1006
|
+
|
834
1007
|
if (NIL_P(z->input) && len == 0) {
|
835
|
-
|
836
|
-
|
1008
|
+
z->stream.next_in = (Bytef*)"";
|
1009
|
+
z->stream.avail_in = 0;
|
837
1010
|
}
|
838
1011
|
else {
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
1012
|
+
zstream_append_input(z, src, len);
|
1013
|
+
z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
|
1014
|
+
z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
|
1015
|
+
/* keep reference to `z->input' so as not to be garbage collected
|
1016
|
+
after zstream_reset_input() and prevent `z->stream.next_in'
|
1017
|
+
from dangling. */
|
1018
|
+
guard = z->input;
|
846
1019
|
}
|
847
1020
|
|
848
1021
|
if (z->stream.avail_out == 0) {
|
849
|
-
|
1022
|
+
zstream_expand_buffer(z);
|
850
1023
|
}
|
851
1024
|
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
rb_thread_schedule();
|
860
|
-
|
861
|
-
if (err == Z_STREAM_END) {
|
862
|
-
z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
|
863
|
-
z->flags |= ZSTREAM_FLAG_FINISHED;
|
864
|
-
break;
|
865
|
-
}
|
866
|
-
if (err != Z_OK) {
|
867
|
-
if (flush != Z_FINISH && err == Z_BUF_ERROR
|
868
|
-
&& z->stream.avail_out > 0) {
|
869
|
-
z->flags |= ZSTREAM_FLAG_IN_STREAM;
|
870
|
-
break;
|
871
|
-
}
|
872
|
-
zstream_reset_input(z);
|
873
|
-
if (z->stream.avail_in > 0) {
|
874
|
-
zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
|
875
|
-
}
|
876
|
-
raise_zlib_error(err, z->stream.msg);
|
877
|
-
}
|
878
|
-
if (z->stream.avail_out > 0) {
|
879
|
-
z->flags |= ZSTREAM_FLAG_IN_STREAM;
|
880
|
-
break;
|
881
|
-
}
|
882
|
-
zstream_expand_buffer(z);
|
1025
|
+
loop:
|
1026
|
+
err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)&args,
|
1027
|
+
zstream_unblock_func, (void *)&args);
|
1028
|
+
|
1029
|
+
if (flush != Z_FINISH && err == Z_BUF_ERROR
|
1030
|
+
&& z->stream.avail_out > 0) {
|
1031
|
+
z->flags |= ZSTREAM_FLAG_IN_STREAM;
|
883
1032
|
}
|
884
1033
|
|
885
1034
|
zstream_reset_input(z);
|
1035
|
+
|
1036
|
+
if (err != Z_OK && err != Z_STREAM_END) {
|
1037
|
+
if (z->stream.avail_in > 0) {
|
1038
|
+
zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
|
1039
|
+
}
|
1040
|
+
if (err == Z_NEED_DICT) {
|
1041
|
+
VALUE self = (VALUE)z->stream.opaque;
|
1042
|
+
if (self) {
|
1043
|
+
VALUE dicts = rb_ivar_get(self, id_dictionaries);
|
1044
|
+
VALUE dict = rb_hash_aref(dicts, rb_uint2inum(z->stream.adler));
|
1045
|
+
if (!NIL_P(dict)) {
|
1046
|
+
rb_inflate_set_dictionary(self, dict);
|
1047
|
+
goto loop;
|
1048
|
+
}
|
1049
|
+
}
|
1050
|
+
}
|
1051
|
+
raise_zlib_error(err, z->stream.msg);
|
1052
|
+
}
|
1053
|
+
|
886
1054
|
if (z->stream.avail_in > 0) {
|
887
|
-
|
888
|
-
guard = Qnil; /* prevent tail call to make guard effective */
|
1055
|
+
zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
|
1056
|
+
RB_GC_GUARD(guard) = Qnil; /* prevent tail call to make guard effective */
|
889
1057
|
}
|
1058
|
+
|
1059
|
+
if (args.jump_state)
|
1060
|
+
rb_jump_tag(args.jump_state);
|
890
1061
|
}
|
891
1062
|
|
892
1063
|
static VALUE
|
893
1064
|
zstream_sync(struct zstream *z, Bytef *src, long len)
|
894
1065
|
{
|
895
|
-
VALUE rest;
|
1066
|
+
/* VALUE rest; */
|
896
1067
|
int err;
|
897
1068
|
|
898
1069
|
if (!NIL_P(z->input)) {
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
1070
|
+
z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
|
1071
|
+
z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
|
1072
|
+
err = inflateSync(&z->stream);
|
1073
|
+
if (err == Z_OK) {
|
1074
|
+
zstream_discard_input(z,
|
1075
|
+
RSTRING_LEN(z->input) - z->stream.avail_in);
|
1076
|
+
zstream_append_input(z, src, len);
|
1077
|
+
return Qtrue;
|
1078
|
+
}
|
1079
|
+
zstream_reset_input(z);
|
1080
|
+
if (err != Z_DATA_ERROR) {
|
1081
|
+
/* rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in); */
|
1082
|
+
raise_zlib_error(err, z->stream.msg);
|
1083
|
+
}
|
913
1084
|
}
|
914
1085
|
|
915
1086
|
if (len <= 0) return Qfalse;
|
@@ -918,12 +1089,12 @@ zstream_sync(struct zstream *z, Bytef *src, long len)
|
|
918
1089
|
z->stream.avail_in = MAX_UINT(len);
|
919
1090
|
err = inflateSync(&z->stream);
|
920
1091
|
if (err == Z_OK) {
|
921
|
-
|
922
|
-
|
1092
|
+
zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
|
1093
|
+
return Qtrue;
|
923
1094
|
}
|
924
1095
|
if (err != Z_DATA_ERROR) {
|
925
|
-
|
926
|
-
|
1096
|
+
/* rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in); */
|
1097
|
+
raise_zlib_error(err, z->stream.msg);
|
927
1098
|
}
|
928
1099
|
return Qfalse;
|
929
1100
|
}
|
@@ -940,16 +1111,16 @@ zstream_finalize(struct zstream *z)
|
|
940
1111
|
{
|
941
1112
|
int err = z->func->end(&z->stream);
|
942
1113
|
if (err == Z_STREAM_ERROR)
|
943
|
-
|
1114
|
+
finalizer_warn("the stream state was inconsistent.");
|
944
1115
|
if (err == Z_DATA_ERROR)
|
945
|
-
|
1116
|
+
finalizer_warn("the stream was freed prematurely.");
|
946
1117
|
}
|
947
1118
|
|
948
1119
|
static void
|
949
1120
|
zstream_free(struct zstream *z)
|
950
1121
|
{
|
951
1122
|
if (ZSTREAM_IS_READY(z)) {
|
952
|
-
|
1123
|
+
zstream_finalize(z);
|
953
1124
|
}
|
954
1125
|
xfree(z);
|
955
1126
|
}
|
@@ -961,8 +1132,9 @@ zstream_new(VALUE klass, const struct zstream_funcs *funcs)
|
|
961
1132
|
struct zstream *z;
|
962
1133
|
|
963
1134
|
obj = Data_Make_Struct(klass, struct zstream,
|
964
|
-
|
1135
|
+
zstream_mark, zstream_free, z);
|
965
1136
|
zstream_init(z, funcs);
|
1137
|
+
z->stream.opaque = (voidpf)obj;
|
966
1138
|
return obj;
|
967
1139
|
}
|
968
1140
|
|
@@ -976,7 +1148,7 @@ get_zstream(VALUE obj)
|
|
976
1148
|
|
977
1149
|
Data_Get_Struct(obj, struct zstream, z);
|
978
1150
|
if (!ZSTREAM_IS_READY(z)) {
|
979
|
-
|
1151
|
+
rb_raise(cZError, "stream is not ready");
|
980
1152
|
}
|
981
1153
|
return z;
|
982
1154
|
}
|
@@ -1068,24 +1240,28 @@ rb_zstream_reset(VALUE obj)
|
|
1068
1240
|
}
|
1069
1241
|
|
1070
1242
|
/*
|
1071
|
-
*
|
1072
|
-
*
|
1243
|
+
* call-seq:
|
1244
|
+
* finish -> String
|
1245
|
+
* finish { |chunk| ... } -> nil
|
1246
|
+
*
|
1247
|
+
* Finishes the stream and flushes output buffer. If a block is given each
|
1248
|
+
* chunk is yielded to the block until the input buffer has been flushed to
|
1249
|
+
* the output buffer.
|
1073
1250
|
*/
|
1074
1251
|
static VALUE
|
1075
1252
|
rb_zstream_finish(VALUE obj)
|
1076
1253
|
{
|
1077
1254
|
struct zstream *z = get_zstream(obj);
|
1078
|
-
VALUE dst;
|
1079
1255
|
|
1080
1256
|
zstream_run(z, (Bytef*)"", 0, Z_FINISH);
|
1081
|
-
dst = zstream_detach_buffer(z);
|
1082
1257
|
|
1083
|
-
|
1084
|
-
return dst;
|
1258
|
+
return zstream_detach_buffer(z);
|
1085
1259
|
}
|
1086
1260
|
|
1087
1261
|
/*
|
1088
|
-
*
|
1262
|
+
* call-seq:
|
1263
|
+
* flush_next_in -> input
|
1264
|
+
*
|
1089
1265
|
*/
|
1090
1266
|
static VALUE
|
1091
1267
|
rb_zstream_flush_next_in(VALUE obj)
|
@@ -1100,18 +1276,22 @@ rb_zstream_flush_next_in(VALUE obj)
|
|
1100
1276
|
}
|
1101
1277
|
|
1102
1278
|
/*
|
1103
|
-
*
|
1279
|
+
* call-seq:
|
1280
|
+
* flush_next_out -> String
|
1281
|
+
* flush_next_out { |chunk| ... } -> nil
|
1282
|
+
*
|
1283
|
+
* Flushes output buffer and returns all data in that buffer. If a block is
|
1284
|
+
* given each chunk is yielded to the block until the current output buffer
|
1285
|
+
* has been flushed.
|
1104
1286
|
*/
|
1105
1287
|
static VALUE
|
1106
1288
|
rb_zstream_flush_next_out(VALUE obj)
|
1107
1289
|
{
|
1108
1290
|
struct zstream *z;
|
1109
|
-
VALUE dst;
|
1110
1291
|
|
1111
1292
|
Data_Get_Struct(obj, struct zstream, z);
|
1112
|
-
|
1113
|
-
|
1114
|
-
return dst;
|
1293
|
+
|
1294
|
+
return zstream_detach_buffer(z);
|
1115
1295
|
}
|
1116
1296
|
|
1117
1297
|
/*
|
@@ -1188,7 +1368,7 @@ rb_zstream_data_type(VALUE obj)
|
|
1188
1368
|
static VALUE
|
1189
1369
|
rb_zstream_adler(VALUE obj)
|
1190
1370
|
{
|
1191
|
-
|
1371
|
+
return rb_uint2inum(get_zstream(obj)->stream.adler);
|
1192
1372
|
}
|
1193
1373
|
|
1194
1374
|
/*
|
@@ -1241,60 +1421,73 @@ rb_deflate_s_allocate(VALUE klass)
|
|
1241
1421
|
/*
|
1242
1422
|
* Document-method: Zlib::Deflate.new
|
1243
1423
|
*
|
1244
|
-
* call-seq:
|
1424
|
+
* call-seq:
|
1425
|
+
* Zlib::Deflate.new(level=DEFAULT_COMPRESSION, window_bits=MAX_WBITS, mem_level=DEF_MEM_LEVEL, strategy=DEFAULT_STRATEGY)
|
1426
|
+
*
|
1427
|
+
* Creates a new deflate stream for compression. If a given argument is nil,
|
1428
|
+
* the default value of that argument is used.
|
1245
1429
|
*
|
1246
|
-
*
|
1430
|
+
* The +level+ sets the compression level for the deflate stream between 0 (no
|
1431
|
+
* compression) and 9 (best compression. The following constants have been
|
1432
|
+
* defined to make code more readable:
|
1247
1433
|
*
|
1248
|
-
*
|
1249
|
-
*
|
1250
|
-
*
|
1251
|
-
*
|
1252
|
-
* An Integer for the windowBits size. Should be
|
1253
|
-
* in the range 8..15, larger values of this parameter
|
1254
|
-
* result in better at the expense of memory usage.
|
1255
|
-
* +memlevel+::
|
1256
|
-
* Specifies how much memory should be allocated for
|
1257
|
-
* the internal compression state.
|
1258
|
-
* Between DEF_MEM_LEVEL and MAX_MEM_LEVEL
|
1259
|
-
* +strategy+::
|
1260
|
-
* A parameter to tune the compression algorithm. Use the
|
1261
|
-
* DEFAULT_STRATEGY for normal data, FILTERED for data produced by a
|
1262
|
-
* filter (or predictor), HUFFMAN_ONLY to force Huffman encoding only (no
|
1263
|
-
* string match).
|
1434
|
+
* * Zlib::NO_COMPRESSION = 0
|
1435
|
+
* * Zlib::BEST_SPEED = 1
|
1436
|
+
* * Zlib::DEFAULT_COMPRESSION = 6
|
1437
|
+
* * Zlib::BEST_COMPRESSION = 9
|
1264
1438
|
*
|
1265
|
-
*
|
1439
|
+
* The +window_bits+ sets the size of the history buffer and should be between
|
1440
|
+
* 8 and 15. Larger values of this parameter result in better compression at
|
1441
|
+
* the expense of memory usage.
|
1266
1442
|
*
|
1267
|
-
*
|
1268
|
-
*
|
1269
|
-
*
|
1443
|
+
* The +mem_level+ specifies how much memory should be allocated for the
|
1444
|
+
* internal compression state. 1 uses minimum memory but is slow and reduces
|
1445
|
+
* compression ratio while 9 uses maximum memory for optimal speed. The
|
1446
|
+
* default value is 8. Two constants are defined:
|
1270
1447
|
*
|
1448
|
+
* * Zlib::DEF_MEM_LEVEL
|
1449
|
+
* * Zlib::MAX_MEM_LEVEL
|
1271
1450
|
*
|
1272
|
-
*
|
1451
|
+
* The +strategy+ sets the deflate compression strategy. The following
|
1452
|
+
* strategies are available:
|
1273
1453
|
*
|
1274
|
-
*
|
1454
|
+
* Zlib::DEFAULT_STRATEGY:: For normal data
|
1455
|
+
* Zlib::FILTERED:: For data produced by a filter or predictor
|
1456
|
+
* Zlib::FIXED:: Prevents dynamic Huffman codes
|
1457
|
+
* Zlib::HUFFMAN_ONLY:: Prevents string matching
|
1458
|
+
* Zlib::RLE:: Designed for better compression of PNG image data
|
1275
1459
|
*
|
1276
|
-
*
|
1277
|
-
* #=> #<File:compressed.file>
|
1278
|
-
* f << Zlib::Deflate.new().deflate(File.read("big.file"))
|
1279
|
-
* #=> #<File:compressed.file>
|
1280
|
-
* f.close
|
1281
|
-
* #=> nil
|
1460
|
+
* See the constants for further description.
|
1282
1461
|
*
|
1283
|
-
*
|
1462
|
+
* == Examples
|
1284
1463
|
*
|
1285
|
-
*
|
1286
|
-
* #=> #<File:compressed.file>
|
1287
|
-
* zd = Zlib::Deflate.new(Zlib::BEST_COMPRESSION, 15, Zlib::MAX_MEM_LEVEL, Zlib::HUFFMAN_ONLY)
|
1288
|
-
* #=> #<Zlib::Deflate:0x000000008610a0>
|
1289
|
-
* compressed_file << zd.deflate(File.read("big.file"))
|
1290
|
-
* #=> "\xD4z\xC6\xDE\b\xA1K\x1Ej\x8A ..."
|
1291
|
-
* compressed_file.close
|
1292
|
-
* #=> nil
|
1293
|
-
* zd.close
|
1294
|
-
* #=> nil
|
1464
|
+
* === Basic
|
1295
1465
|
*
|
1296
|
-
*
|
1466
|
+
* open "compressed.file", "w+" do |io|
|
1467
|
+
* io << Zlib::Deflate.new.deflate(File.read("big.file"))
|
1468
|
+
* end
|
1469
|
+
*
|
1470
|
+
* === Custom compression
|
1471
|
+
*
|
1472
|
+
* open "compressed.file", "w+" do |compressed_io|
|
1473
|
+
* deflate = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
|
1474
|
+
* Zlib::MAX_WBITS,
|
1475
|
+
* Zlib::MAX_MEM_LEVEL,
|
1476
|
+
* Zlib::HUFFMAN_ONLY)
|
1477
|
+
*
|
1478
|
+
* begin
|
1479
|
+
* open "big.file" do |big_io|
|
1480
|
+
* until big_io.eof? do
|
1481
|
+
* compressed_io << zd.deflate(big_io.read(16384))
|
1482
|
+
* end
|
1483
|
+
* end
|
1484
|
+
* ensure
|
1485
|
+
* deflate.close
|
1486
|
+
* end
|
1487
|
+
* end
|
1297
1488
|
*
|
1489
|
+
* While this example will work, for best optimization review the flags for
|
1490
|
+
* your specific time, memory usage and output space requirements.
|
1298
1491
|
*/
|
1299
1492
|
static VALUE
|
1300
1493
|
rb_deflate_initialize(int argc, VALUE *argv, VALUE obj)
|
@@ -1307,10 +1500,10 @@ rb_deflate_initialize(int argc, VALUE *argv, VALUE obj)
|
|
1307
1500
|
Data_Get_Struct(obj, struct zstream, z);
|
1308
1501
|
|
1309
1502
|
err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
|
1310
|
-
|
1311
|
-
|
1503
|
+
ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
|
1504
|
+
ARG_STRATEGY(strategy));
|
1312
1505
|
if (err != Z_OK) {
|
1313
|
-
|
1506
|
+
raise_zlib_error(err, z->stream.msg);
|
1314
1507
|
}
|
1315
1508
|
ZSTREAM_READY(z);
|
1316
1509
|
|
@@ -1333,7 +1526,7 @@ rb_deflate_init_copy(VALUE self, VALUE orig)
|
|
1333
1526
|
|
1334
1527
|
err = deflateCopy(&z1->stream, &z2->stream);
|
1335
1528
|
if (err != Z_OK) {
|
1336
|
-
|
1529
|
+
raise_zlib_error(err, 0);
|
1337
1530
|
}
|
1338
1531
|
z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input);
|
1339
1532
|
z1->buf = NIL_P(z2->buf) ? Qnil : rb_str_dup(z2->buf);
|
@@ -1356,19 +1549,19 @@ deflate_run(VALUE args)
|
|
1356
1549
|
/*
|
1357
1550
|
* Document-method: Zlib::Deflate.deflate
|
1358
1551
|
*
|
1359
|
-
* call-seq:
|
1360
|
-
*
|
1552
|
+
* call-seq:
|
1553
|
+
* Zlib.deflate(string[, level])
|
1554
|
+
* Zlib::Deflate.deflate(string[, level])
|
1361
1555
|
*
|
1362
1556
|
* Compresses the given +string+. Valid values of level are
|
1363
|
-
*
|
1364
|
-
*
|
1365
|
-
* integer from 0 to 9 (the default is 6).
|
1557
|
+
* Zlib::NO_COMPRESSION, Zlib::BEST_SPEED, Zlib::BEST_COMPRESSION,
|
1558
|
+
* Zlib::DEFAULT_COMPRESSION, or an integer from 0 to 9 (the default is 6).
|
1366
1559
|
*
|
1367
1560
|
* This method is almost equivalent to the following code:
|
1368
1561
|
*
|
1369
1562
|
* def deflate(string, level)
|
1370
1563
|
* z = Zlib::Deflate.new(level)
|
1371
|
-
* dst = z.deflate(string, Zlib::
|
1564
|
+
* dst = z.deflate(string, Zlib::FINISH)
|
1372
1565
|
* z.close
|
1373
1566
|
* dst
|
1374
1567
|
* end
|
@@ -1390,7 +1583,7 @@ rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
|
|
1390
1583
|
zstream_init_deflate(&z);
|
1391
1584
|
err = deflateInit(&z.stream, lev);
|
1392
1585
|
if (err != Z_OK) {
|
1393
|
-
|
1586
|
+
raise_zlib_error(err, z.stream.msg);
|
1394
1587
|
}
|
1395
1588
|
ZSTREAM_READY(&z);
|
1396
1589
|
|
@@ -1406,65 +1599,56 @@ static void
|
|
1406
1599
|
do_deflate(struct zstream *z, VALUE src, int flush)
|
1407
1600
|
{
|
1408
1601
|
if (NIL_P(src)) {
|
1409
|
-
|
1410
|
-
|
1602
|
+
zstream_run(z, (Bytef*)"", 0, Z_FINISH);
|
1603
|
+
return;
|
1411
1604
|
}
|
1412
1605
|
StringValue(src);
|
1413
1606
|
if (flush != Z_NO_FLUSH || RSTRING_LEN(src) > 0) { /* prevent BUF_ERROR */
|
1414
|
-
|
1607
|
+
zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), flush);
|
1415
1608
|
}
|
1416
1609
|
}
|
1417
1610
|
|
1418
1611
|
/*
|
1419
|
-
* Document-method: Zlib
|
1612
|
+
* Document-method: Zlib::Deflate#deflate
|
1420
1613
|
*
|
1421
|
-
* call-seq:
|
1422
|
-
*
|
1423
|
-
*
|
1424
|
-
*
|
1425
|
-
* +string+::
|
1426
|
-
* String
|
1427
|
-
*
|
1428
|
-
* +flush+::
|
1429
|
-
* Integer representing a flush code. Either NO_FLUSH,
|
1430
|
-
* SYNC_FLUSH, FULL_FLUSH, or FINISH. See zlib.h for details.
|
1431
|
-
* Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
|
1432
|
-
* decide how much data to accumulate before producing output, in order to
|
1433
|
-
* maximize compression.
|
1434
|
-
*
|
1435
|
-
* == Description
|
1614
|
+
* call-seq:
|
1615
|
+
* z.deflate(string, flush = Zlib::NO_FLUSH) -> String
|
1616
|
+
* z.deflate(string, flush = Zlib::NO_FLUSH) { |chunk| ... } -> nil
|
1436
1617
|
*
|
1437
1618
|
* Inputs +string+ into the deflate stream and returns the output from the
|
1438
1619
|
* stream. On calling this method, both the input and the output buffers of
|
1439
|
-
* the stream are flushed.
|
1440
|
-
*
|
1441
|
-
* If +string+ is nil, this method finishes the
|
1620
|
+
* the stream are flushed. If +string+ is nil, this method finishes the
|
1442
1621
|
* stream, just like Zlib::ZStream#finish.
|
1443
1622
|
*
|
1444
|
-
*
|
1623
|
+
* If a block is given consecutive deflated chunks from the +string+ are
|
1624
|
+
* yielded to the block and +nil+ is returned.
|
1625
|
+
*
|
1626
|
+
* The +flush+ parameter specifies the flush mode. The following constants
|
1627
|
+
* may be used:
|
1445
1628
|
*
|
1446
|
-
*
|
1447
|
-
*
|
1448
|
-
*
|
1629
|
+
* Zlib::NO_FLUSH:: The default
|
1630
|
+
* Zlib::SYNC_FLUSH:: Flushes the output to a byte boundary
|
1631
|
+
* Zlib::FULL_FLUSH:: SYNC_FLUSH + resets the compression state
|
1632
|
+
* Zlib::FINISH:: Pending input is processed, pending output is flushed.
|
1633
|
+
*
|
1634
|
+
* See the constants for further description.
|
1449
1635
|
*
|
1450
1636
|
*/
|
1451
1637
|
static VALUE
|
1452
1638
|
rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
|
1453
1639
|
{
|
1454
1640
|
struct zstream *z = get_zstream(obj);
|
1455
|
-
VALUE src, flush
|
1641
|
+
VALUE src, flush;
|
1456
1642
|
|
1457
1643
|
rb_scan_args(argc, argv, "11", &src, &flush);
|
1458
1644
|
OBJ_INFECT(obj, src);
|
1459
1645
|
do_deflate(z, src, ARG_FLUSH(flush));
|
1460
|
-
dst = zstream_detach_buffer(z);
|
1461
1646
|
|
1462
|
-
|
1463
|
-
return dst;
|
1647
|
+
return zstream_detach_buffer(z);
|
1464
1648
|
}
|
1465
1649
|
|
1466
1650
|
/*
|
1467
|
-
* Document-method: Zlib::Deflate
|
1651
|
+
* Document-method: Zlib::Deflate#<<
|
1468
1652
|
*
|
1469
1653
|
* call-seq: << string
|
1470
1654
|
*
|
@@ -1483,31 +1667,32 @@ rb_deflate_addstr(VALUE obj, VALUE src)
|
|
1483
1667
|
/*
|
1484
1668
|
* Document-method: Zlib::Deflate#flush
|
1485
1669
|
*
|
1486
|
-
* call-seq:
|
1670
|
+
* call-seq:
|
1671
|
+
* flush(flush = Zlib::SYNC_FLUSH) -> String
|
1672
|
+
* flush(flush = Zlib::SYNC_FLUSH) { |chunk| ... } -> nil
|
1487
1673
|
*
|
1488
|
-
* This method is equivalent to <tt>deflate('', flush)</tt>.
|
1489
|
-
*
|
1490
|
-
* to
|
1491
|
-
*
|
1492
|
-
* Please visit your zlib.h for a deeper detail on NO_FLUSH, SYNC_FLUSH, FULL_FLUSH, and FINISH
|
1674
|
+
* This method is equivalent to <tt>deflate('', flush)</tt>. This method is
|
1675
|
+
* just provided to improve the readability of your Ruby program. If a block
|
1676
|
+
* is given chunks of deflate output are yielded to the block until the buffer
|
1677
|
+
* is flushed.
|
1493
1678
|
*
|
1679
|
+
* See Zlib::Deflate#deflate for detail on the +flush+ constants NO_FLUSH,
|
1680
|
+
* SYNC_FLUSH, FULL_FLUSH and FINISH.
|
1494
1681
|
*/
|
1495
1682
|
static VALUE
|
1496
1683
|
rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
|
1497
1684
|
{
|
1498
1685
|
struct zstream *z = get_zstream(obj);
|
1499
|
-
VALUE v_flush
|
1686
|
+
VALUE v_flush;
|
1500
1687
|
int flush;
|
1501
1688
|
|
1502
1689
|
rb_scan_args(argc, argv, "01", &v_flush);
|
1503
1690
|
flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
|
1504
1691
|
if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
|
1505
|
-
|
1692
|
+
zstream_run(z, (Bytef*)"", 0, flush);
|
1506
1693
|
}
|
1507
|
-
dst = zstream_detach_buffer(z);
|
1508
1694
|
|
1509
|
-
|
1510
|
-
return dst;
|
1695
|
+
return zstream_detach_buffer(z);
|
1511
1696
|
}
|
1512
1697
|
|
1513
1698
|
/*
|
@@ -1515,18 +1700,11 @@ rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
|
|
1515
1700
|
*
|
1516
1701
|
* call-seq: params(level, strategy)
|
1517
1702
|
*
|
1518
|
-
* Changes the parameters of the deflate stream
|
1519
|
-
*
|
1520
|
-
*
|
1703
|
+
* Changes the parameters of the deflate stream to allow changes between
|
1704
|
+
* different types of data that require different types of compression. Any
|
1705
|
+
* unprocessed data is flushed before changing the params.
|
1521
1706
|
*
|
1522
|
-
* +level
|
1523
|
-
* An Integer compression level between
|
1524
|
-
* BEST_SPEED and BEST_COMPRESSION
|
1525
|
-
* +strategy+::
|
1526
|
-
* A parameter to tune the compression algorithm. Use the
|
1527
|
-
* DEFAULT_STRATEGY for normal data, FILTERED for data produced by a
|
1528
|
-
* filter (or predictor), HUFFMAN_ONLY to force Huffman encoding only (no
|
1529
|
-
* string match).
|
1707
|
+
* See Zlib::Deflate.new for a description of +level+ and +strategy+.
|
1530
1708
|
*
|
1531
1709
|
*/
|
1532
1710
|
static VALUE
|
@@ -1544,14 +1722,14 @@ rb_deflate_params(VALUE obj, VALUE v_level, VALUE v_strategy)
|
|
1544
1722
|
err = deflateParams(&z->stream, level, strategy);
|
1545
1723
|
z->buf_filled += n - z->stream.avail_out;
|
1546
1724
|
while (err == Z_BUF_ERROR) {
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1725
|
+
rb_warning("deflateParams() returned Z_BUF_ERROR");
|
1726
|
+
zstream_expand_buffer(z);
|
1727
|
+
n = z->stream.avail_out;
|
1728
|
+
err = deflateParams(&z->stream, level, strategy);
|
1729
|
+
z->buf_filled += n - z->stream.avail_out;
|
1552
1730
|
}
|
1553
1731
|
if (err != Z_OK) {
|
1554
|
-
|
1732
|
+
raise_zlib_error(err, z->stream.msg);
|
1555
1733
|
}
|
1556
1734
|
|
1557
1735
|
return Qnil;
|
@@ -1581,9 +1759,9 @@ rb_deflate_set_dictionary(VALUE obj, VALUE dic)
|
|
1581
1759
|
OBJ_INFECT(obj, dic);
|
1582
1760
|
StringValue(src);
|
1583
1761
|
err = deflateSetDictionary(&z->stream,
|
1584
|
-
|
1762
|
+
(Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
|
1585
1763
|
if (err != Z_OK) {
|
1586
|
-
|
1764
|
+
raise_zlib_error(err, z->stream.msg);
|
1587
1765
|
}
|
1588
1766
|
|
1589
1767
|
return dic;
|
@@ -1600,52 +1778,57 @@ rb_deflate_set_dictionary(VALUE obj, VALUE dic)
|
|
1600
1778
|
* dup) itself.
|
1601
1779
|
*/
|
1602
1780
|
|
1603
|
-
|
1604
|
-
|
1605
1781
|
static VALUE
|
1606
1782
|
rb_inflate_s_allocate(VALUE klass)
|
1607
1783
|
{
|
1608
|
-
|
1784
|
+
VALUE inflate = zstream_inflate_new(klass);
|
1785
|
+
rb_ivar_set(inflate, id_dictionaries, rb_hash_new());
|
1786
|
+
return inflate;
|
1609
1787
|
}
|
1610
1788
|
|
1611
1789
|
/*
|
1612
1790
|
* Document-method: Zlib::Inflate.new
|
1613
1791
|
*
|
1614
|
-
* call-seq:
|
1792
|
+
* call-seq:
|
1793
|
+
* Zlib::Inflate.new(window_bits = Zlib::MAX_WBITS)
|
1615
1794
|
*
|
1616
|
-
*
|
1795
|
+
* Creates a new inflate stream for decompression. +window_bits+ sets the
|
1796
|
+
* size of the history buffer and can have the following values:
|
1617
1797
|
*
|
1618
|
-
*
|
1619
|
-
*
|
1620
|
-
*
|
1621
|
-
* result in better at the expense of memory usage.
|
1798
|
+
* 0::
|
1799
|
+
* Have inflate use the window size from the zlib header of the compressed
|
1800
|
+
* stream.
|
1622
1801
|
*
|
1623
|
-
*
|
1802
|
+
* (8..15)
|
1803
|
+
* Overrides the window size of the inflate header in the compressed stream.
|
1804
|
+
* The window size must be greater than or equal to the window size of the
|
1805
|
+
* compressed stream.
|
1624
1806
|
*
|
1625
|
-
*
|
1626
|
-
*
|
1627
|
-
*
|
1628
|
-
*
|
1807
|
+
* Greater than 15::
|
1808
|
+
* Add 32 to window_bits to enable zlib and gzip decoding with automatic
|
1809
|
+
* header detection, or add 16 to decode only the gzip format (a
|
1810
|
+
* Zlib::DataError will be raised for a non-gzip stream).
|
1629
1811
|
*
|
1630
|
-
*
|
1631
|
-
*
|
1632
|
-
*
|
1812
|
+
* (-8..-15)::
|
1813
|
+
* Enables raw deflate mode which will not generate a check value, and will
|
1814
|
+
* not look for any check values for comparison at the end of the stream.
|
1633
1815
|
*
|
1634
|
-
*
|
1816
|
+
* This is for use with other formats that use the deflate compressed data
|
1817
|
+
* format such as zip which provide their own check values.
|
1635
1818
|
*
|
1636
|
-
*
|
1637
|
-
* zi.close
|
1638
|
-
* cf.close
|
1819
|
+
* == Example
|
1639
1820
|
*
|
1640
|
-
*
|
1821
|
+
* open "compressed.file" do |compressed_io|
|
1822
|
+
* zi = Zlib::Inflate.new(Zlib::MAX_WBITS + 32)
|
1641
1823
|
*
|
1642
|
-
*
|
1643
|
-
*
|
1644
|
-
*
|
1645
|
-
*
|
1646
|
-
*
|
1647
|
-
*
|
1648
|
-
*
|
1824
|
+
* begin
|
1825
|
+
* open "uncompressed.file", "w+" do |uncompressed_io|
|
1826
|
+
* uncompressed_io << zi.inflate(compressed_io.read)
|
1827
|
+
* end
|
1828
|
+
* ensure
|
1829
|
+
* zi.close
|
1830
|
+
* end
|
1831
|
+
* end
|
1649
1832
|
*
|
1650
1833
|
*/
|
1651
1834
|
static VALUE
|
@@ -1660,7 +1843,7 @@ rb_inflate_initialize(int argc, VALUE *argv, VALUE obj)
|
|
1660
1843
|
|
1661
1844
|
err = inflateInit2(&z->stream, ARG_WBITS(wbits));
|
1662
1845
|
if (err != Z_OK) {
|
1663
|
-
|
1846
|
+
raise_zlib_error(err, z->stream.msg);
|
1664
1847
|
}
|
1665
1848
|
ZSTREAM_READY(z);
|
1666
1849
|
|
@@ -1679,9 +1862,11 @@ inflate_run(VALUE args)
|
|
1679
1862
|
}
|
1680
1863
|
|
1681
1864
|
/*
|
1682
|
-
* Document-method: Zlib::
|
1865
|
+
* Document-method: Zlib::inflate
|
1683
1866
|
*
|
1684
|
-
* call-seq:
|
1867
|
+
* call-seq:
|
1868
|
+
* Zlib.inflate(string)
|
1869
|
+
* Zlib::Inflate.inflate(string)
|
1685
1870
|
*
|
1686
1871
|
* Decompresses +string+. Raises a Zlib::NeedDict exception if a preset
|
1687
1872
|
* dictionary is needed for decompression.
|
@@ -1710,7 +1895,7 @@ rb_inflate_s_inflate(VALUE obj, VALUE src)
|
|
1710
1895
|
zstream_init_inflate(&z);
|
1711
1896
|
err = inflateInit(&z.stream);
|
1712
1897
|
if (err != Z_OK) {
|
1713
|
-
|
1898
|
+
raise_zlib_error(err, z.stream.msg);
|
1714
1899
|
}
|
1715
1900
|
ZSTREAM_READY(&z);
|
1716
1901
|
|
@@ -1726,28 +1911,68 @@ static void
|
|
1726
1911
|
do_inflate(struct zstream *z, VALUE src)
|
1727
1912
|
{
|
1728
1913
|
if (NIL_P(src)) {
|
1729
|
-
|
1730
|
-
|
1914
|
+
zstream_run(z, (Bytef*)"", 0, Z_FINISH);
|
1915
|
+
return;
|
1731
1916
|
}
|
1732
1917
|
StringValue(src);
|
1733
|
-
if (RSTRING_LEN(src) > 0) { /* prevent Z_BUF_ERROR */
|
1734
|
-
|
1918
|
+
if (RSTRING_LEN(src) > 0 || z->stream.avail_in > 0) { /* prevent Z_BUF_ERROR */
|
1919
|
+
zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
|
1735
1920
|
}
|
1736
1921
|
}
|
1737
1922
|
|
1923
|
+
/* Document-method: Zlib::Inflate#add_dictionary
|
1924
|
+
*
|
1925
|
+
* call-seq: add_dictionary(string)
|
1926
|
+
*
|
1927
|
+
* Provide the inflate stream with a dictionary that may be required in the
|
1928
|
+
* future. Multiple dictionaries may be provided. The inflate stream will
|
1929
|
+
* automatically choose the correct user-provided dictionary based on the
|
1930
|
+
* stream's required dictionary.
|
1931
|
+
*/
|
1932
|
+
static VALUE
|
1933
|
+
rb_inflate_add_dictionary(VALUE obj, VALUE dictionary) {
|
1934
|
+
VALUE dictionaries = rb_ivar_get(obj, id_dictionaries);
|
1935
|
+
VALUE checksum = do_checksum(1, &dictionary, adler32);
|
1936
|
+
|
1937
|
+
rb_hash_aset(dictionaries, checksum, dictionary);
|
1938
|
+
|
1939
|
+
return obj;
|
1940
|
+
}
|
1941
|
+
|
1738
1942
|
/*
|
1739
1943
|
* Document-method: Zlib::Inflate#inflate
|
1740
1944
|
*
|
1741
|
-
* call-seq:
|
1945
|
+
* call-seq:
|
1946
|
+
* inflate(deflate_string) -> String
|
1947
|
+
* inflate(deflate_string) { |chunk| ... } -> nil
|
1948
|
+
*
|
1949
|
+
* Inputs +deflate_string+ into the inflate stream and returns the output from
|
1950
|
+
* the stream. Calling this method, both the input and the output buffer of
|
1951
|
+
* the stream are flushed. If string is +nil+, this method finishes the
|
1952
|
+
* stream, just like Zlib::ZStream#finish.
|
1742
1953
|
*
|
1743
|
-
*
|
1744
|
-
*
|
1745
|
-
* stream are flushed. If string is +nil+, this method finishes the stream,
|
1746
|
-
* just like Zlib::ZStream#finish.
|
1954
|
+
* If a block is given consecutive inflated chunks from the +deflate_string+
|
1955
|
+
* are yielded to the block and +nil+ is returned.
|
1747
1956
|
*
|
1748
1957
|
* Raises a Zlib::NeedDict exception if a preset dictionary is needed to
|
1749
1958
|
* decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
|
1750
|
-
* call this method again with an empty string
|
1959
|
+
* call this method again with an empty string to flush the stream:
|
1960
|
+
*
|
1961
|
+
* inflater = Zlib::Inflate.new
|
1962
|
+
*
|
1963
|
+
* begin
|
1964
|
+
* out = inflater.inflate compressed
|
1965
|
+
* rescue Zlib::NeedDict
|
1966
|
+
* # ensure the dictionary matches the stream's required dictionary
|
1967
|
+
* raise unless inflater.adler == Zlib.adler32(dictionary)
|
1968
|
+
*
|
1969
|
+
* inflater.set_dictionary dictionary
|
1970
|
+
* inflater.inflate ''
|
1971
|
+
* end
|
1972
|
+
*
|
1973
|
+
* # ...
|
1974
|
+
*
|
1975
|
+
* inflater.close
|
1751
1976
|
*
|
1752
1977
|
* See also Zlib::Inflate.new
|
1753
1978
|
*/
|
@@ -1760,24 +1985,24 @@ rb_inflate_inflate(VALUE obj, VALUE src)
|
|
1760
1985
|
OBJ_INFECT(obj, src);
|
1761
1986
|
|
1762
1987
|
if (ZSTREAM_IS_FINISHED(z)) {
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1988
|
+
if (NIL_P(src)) {
|
1989
|
+
dst = zstream_detach_buffer(z);
|
1990
|
+
}
|
1991
|
+
else {
|
1992
|
+
StringValue(src);
|
1993
|
+
zstream_append_buffer2(z, src);
|
1994
|
+
dst = rb_str_new(0, 0);
|
1995
|
+
OBJ_INFECT(dst, obj);
|
1996
|
+
}
|
1771
1997
|
}
|
1772
1998
|
else {
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1999
|
+
do_inflate(z, src);
|
2000
|
+
dst = zstream_detach_buffer(z);
|
2001
|
+
if (ZSTREAM_IS_FINISHED(z)) {
|
2002
|
+
zstream_passthrough_input(z);
|
2003
|
+
}
|
1778
2004
|
}
|
1779
2005
|
|
1780
|
-
OBJ_INFECT(dst, obj);
|
1781
2006
|
return dst;
|
1782
2007
|
}
|
1783
2008
|
|
@@ -1796,16 +2021,16 @@ rb_inflate_addstr(VALUE obj, VALUE src)
|
|
1796
2021
|
OBJ_INFECT(obj, src);
|
1797
2022
|
|
1798
2023
|
if (ZSTREAM_IS_FINISHED(z)) {
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
2024
|
+
if (!NIL_P(src)) {
|
2025
|
+
StringValue(src);
|
2026
|
+
zstream_append_buffer2(z, src);
|
2027
|
+
}
|
1803
2028
|
}
|
1804
2029
|
else {
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
2030
|
+
do_inflate(z, src);
|
2031
|
+
if (ZSTREAM_IS_FINISHED(z)) {
|
2032
|
+
zstream_passthrough_input(z);
|
2033
|
+
}
|
1809
2034
|
}
|
1810
2035
|
|
1811
2036
|
return obj;
|
@@ -1844,10 +2069,10 @@ rb_inflate_sync_point_p(VALUE obj)
|
|
1844
2069
|
|
1845
2070
|
err = inflateSyncPoint(&z->stream);
|
1846
2071
|
if (err == 1) {
|
1847
|
-
|
2072
|
+
return Qtrue;
|
1848
2073
|
}
|
1849
2074
|
if (err != Z_OK) {
|
1850
|
-
|
2075
|
+
raise_zlib_error(err, z->stream.msg);
|
1851
2076
|
}
|
1852
2077
|
return Qfalse;
|
1853
2078
|
}
|
@@ -1869,9 +2094,9 @@ rb_inflate_set_dictionary(VALUE obj, VALUE dic)
|
|
1869
2094
|
OBJ_INFECT(obj, dic);
|
1870
2095
|
StringValue(src);
|
1871
2096
|
err = inflateSetDictionary(&z->stream,
|
1872
|
-
|
2097
|
+
(Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
|
1873
2098
|
if (err != Z_OK) {
|
1874
|
-
|
2099
|
+
raise_zlib_error(err, z->stream.msg);
|
1875
2100
|
}
|
1876
2101
|
|
1877
2102
|
return dic;
|
@@ -1979,13 +2204,13 @@ gzfile_free(struct gzfile *gz)
|
|
1979
2204
|
struct zstream *z = &gz->z;
|
1980
2205
|
|
1981
2206
|
if (ZSTREAM_IS_READY(z)) {
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
2207
|
+
if (z->func == &deflate_funcs) {
|
2208
|
+
finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
|
2209
|
+
}
|
2210
|
+
zstream_finalize(z);
|
1986
2211
|
}
|
1987
2212
|
if (gz->cbuf) {
|
1988
|
-
|
2213
|
+
xfree(gz->cbuf);
|
1989
2214
|
}
|
1990
2215
|
xfree(gz);
|
1991
2216
|
}
|
@@ -2001,6 +2226,7 @@ gzfile_new(klass, funcs, endfunc)
|
|
2001
2226
|
|
2002
2227
|
obj = Data_Make_Struct(klass, struct gzfile, gzfile_mark, gzfile_free, gz);
|
2003
2228
|
zstream_init(&gz->z, funcs);
|
2229
|
+
gz->z.flags |= ZSTREAM_FLAG_GZFILE;
|
2004
2230
|
gz->io = Qnil;
|
2005
2231
|
gz->level = 0;
|
2006
2232
|
gz->mtime = 0;
|
@@ -2033,11 +2259,10 @@ gzfile_reset(struct gzfile *gz)
|
|
2033
2259
|
gz->lineno = 0;
|
2034
2260
|
gz->ungetc = 0;
|
2035
2261
|
/* TODO: Encodings
|
2036
|
-
*
|
2037
2262
|
if (gz->ec) {
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2263
|
+
rb_econv_close(gz->ec);
|
2264
|
+
gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
|
2265
|
+
gz->ecflags, gz->ecopts);
|
2041
2266
|
}
|
2042
2267
|
*/
|
2043
2268
|
}
|
@@ -2052,7 +2277,7 @@ gzfile_close(struct gzfile *gz, int closeflag)
|
|
2052
2277
|
gz->orig_name = Qnil;
|
2053
2278
|
gz->comment = Qnil;
|
2054
2279
|
if (closeflag && rb_respond_to(io, id_close)) {
|
2055
|
-
|
2280
|
+
rb_funcall(io, id_close, 0);
|
2056
2281
|
}
|
2057
2282
|
}
|
2058
2283
|
|
@@ -2062,12 +2287,12 @@ gzfile_write_raw(struct gzfile *gz)
|
|
2062
2287
|
VALUE str;
|
2063
2288
|
|
2064
2289
|
if (gz->z.buf_filled > 0) {
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
2069
|
-
|
2070
|
-
|
2290
|
+
str = zstream_detach_buffer(&gz->z);
|
2291
|
+
OBJ_TAINT(str); /* for safe */
|
2292
|
+
rb_funcall(gz->io, id_write, 1, str);
|
2293
|
+
if ((gz->z.flags & GZFILE_FLAG_SYNC)
|
2294
|
+
&& rb_respond_to(gz->io, id_flush))
|
2295
|
+
rb_funcall(gz->io, id_flush, 0);
|
2071
2296
|
}
|
2072
2297
|
}
|
2073
2298
|
|
@@ -2110,9 +2335,9 @@ gzfile_read_raw_ensure(struct gzfile *gz, long size)
|
|
2110
2335
|
VALUE str;
|
2111
2336
|
|
2112
2337
|
while (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) {
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2338
|
+
str = gzfile_read_raw(gz);
|
2339
|
+
if (NIL_P(str)) return 0;
|
2340
|
+
zstream_append_input2(&gz->z, str);
|
2116
2341
|
}
|
2117
2342
|
return 1;
|
2118
2343
|
}
|
@@ -2124,15 +2349,15 @@ gzfile_read_raw_until_zero(struct gzfile *gz, long offset)
|
|
2124
2349
|
char *p;
|
2125
2350
|
|
2126
2351
|
for (;;) {
|
2127
|
-
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2135
|
-
|
2352
|
+
p = memchr(RSTRING_PTR(gz->z.input) + offset, '\0',
|
2353
|
+
RSTRING_LEN(gz->z.input) - offset);
|
2354
|
+
if (p) break;
|
2355
|
+
str = gzfile_read_raw(gz);
|
2356
|
+
if (NIL_P(str)) {
|
2357
|
+
rb_raise(cGzError, "unexpected end of file");
|
2358
|
+
}
|
2359
|
+
offset = RSTRING_LEN(gz->z.input);
|
2360
|
+
zstream_append_input2(&gz->z, str);
|
2136
2361
|
}
|
2137
2362
|
return p;
|
2138
2363
|
}
|
@@ -2171,7 +2396,7 @@ gzfile_raise(struct gzfile *gz, VALUE klass, const char *message)
|
|
2171
2396
|
{
|
2172
2397
|
VALUE exc = rb_exc_new2(klass, message);
|
2173
2398
|
if (!NIL_P(gz->z.input)) {
|
2174
|
-
|
2399
|
+
rb_ivar_set(exc, id_input, rb_str_resurrect(gz->z.input));
|
2175
2400
|
}
|
2176
2401
|
rb_exc_raise(exc);
|
2177
2402
|
}
|
@@ -2188,10 +2413,10 @@ gzfile_error_inspect(VALUE error)
|
|
2188
2413
|
VALUE input = rb_attr_get(error, id_input);
|
2189
2414
|
|
2190
2415
|
if (!NIL_P(input)) {
|
2191
|
-
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2416
|
+
rb_str_resize(str, RSTRING_LEN(str)-1);
|
2417
|
+
rb_str_cat2(str, ", input=");
|
2418
|
+
rb_str_append(str, rb_str_inspect(input));
|
2419
|
+
rb_str_cat2(str, ">");
|
2195
2420
|
}
|
2196
2421
|
return str;
|
2197
2422
|
}
|
@@ -2203,20 +2428,20 @@ gzfile_make_header(struct gzfile *gz)
|
|
2203
2428
|
unsigned char flags = 0, extraflags = 0;
|
2204
2429
|
|
2205
2430
|
if (!NIL_P(gz->orig_name)) {
|
2206
|
-
|
2431
|
+
flags |= GZ_FLAG_ORIG_NAME;
|
2207
2432
|
}
|
2208
2433
|
if (!NIL_P(gz->comment)) {
|
2209
|
-
|
2434
|
+
flags |= GZ_FLAG_COMMENT;
|
2210
2435
|
}
|
2211
2436
|
if (gz->mtime == 0) {
|
2212
|
-
|
2437
|
+
gz->mtime = time(0);
|
2213
2438
|
}
|
2214
2439
|
|
2215
2440
|
if (gz->level == Z_BEST_SPEED) {
|
2216
|
-
|
2441
|
+
extraflags |= GZ_EXTRAFLAG_FAST;
|
2217
2442
|
}
|
2218
2443
|
else if (gz->level == Z_BEST_COMPRESSION) {
|
2219
|
-
|
2444
|
+
extraflags |= GZ_EXTRAFLAG_SLOW;
|
2220
2445
|
}
|
2221
2446
|
|
2222
2447
|
buf[0] = GZ_MAGIC1;
|
@@ -2229,12 +2454,12 @@ gzfile_make_header(struct gzfile *gz)
|
|
2229
2454
|
zstream_append_buffer(&gz->z, buf, sizeof(buf));
|
2230
2455
|
|
2231
2456
|
if (!NIL_P(gz->orig_name)) {
|
2232
|
-
|
2233
|
-
|
2457
|
+
zstream_append_buffer2(&gz->z, gz->orig_name);
|
2458
|
+
zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
|
2234
2459
|
}
|
2235
2460
|
if (!NIL_P(gz->comment)) {
|
2236
|
-
|
2237
|
-
|
2461
|
+
zstream_append_buffer2(&gz->z, gz->comment);
|
2462
|
+
zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
|
2238
2463
|
}
|
2239
2464
|
|
2240
2465
|
gz->z.flags |= GZFILE_FLAG_HEADER_FINISHED;
|
@@ -2259,37 +2484,37 @@ gzfile_read_header(struct gzfile *gz)
|
|
2259
2484
|
char flags, *p;
|
2260
2485
|
|
2261
2486
|
if (!gzfile_read_raw_ensure(gz, 10)) { /* 10 is the size of gzip header */
|
2262
|
-
|
2487
|
+
gzfile_raise(gz, cGzError, "not in gzip format");
|
2263
2488
|
}
|
2264
2489
|
|
2265
2490
|
head = (unsigned char*)RSTRING_PTR(gz->z.input);
|
2266
2491
|
|
2267
2492
|
if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {
|
2268
|
-
|
2493
|
+
gzfile_raise(gz, cGzError, "not in gzip format");
|
2269
2494
|
}
|
2270
2495
|
if (head[2] != GZ_METHOD_DEFLATE) {
|
2271
|
-
|
2496
|
+
rb_raise(cGzError, "unsupported compression method %d", head[2]);
|
2272
2497
|
}
|
2273
2498
|
|
2274
2499
|
flags = head[3];
|
2275
2500
|
if (flags & GZ_FLAG_MULTIPART) {
|
2276
|
-
|
2501
|
+
rb_raise(cGzError, "multi-part gzip file is not supported");
|
2277
2502
|
}
|
2278
2503
|
else if (flags & GZ_FLAG_ENCRYPT) {
|
2279
|
-
|
2504
|
+
rb_raise(cGzError, "encrypted gzip file is not supported");
|
2280
2505
|
}
|
2281
2506
|
else if (flags & GZ_FLAG_UNKNOWN_MASK) {
|
2282
|
-
|
2507
|
+
rb_raise(cGzError, "unknown flags 0x%02x", flags);
|
2283
2508
|
}
|
2284
2509
|
|
2285
2510
|
if (head[8] & GZ_EXTRAFLAG_FAST) {
|
2286
|
-
|
2511
|
+
gz->level = Z_BEST_SPEED;
|
2287
2512
|
}
|
2288
2513
|
else if (head[8] & GZ_EXTRAFLAG_SLOW) {
|
2289
|
-
|
2514
|
+
gz->level = Z_BEST_COMPRESSION;
|
2290
2515
|
}
|
2291
2516
|
else {
|
2292
|
-
|
2517
|
+
gz->level = Z_DEFAULT_COMPRESSION;
|
2293
2518
|
}
|
2294
2519
|
|
2295
2520
|
gz->mtime = gzfile_get32(&head[4]);
|
@@ -2297,38 +2522,38 @@ gzfile_read_header(struct gzfile *gz)
|
|
2297
2522
|
zstream_discard_input(&gz->z, 10);
|
2298
2523
|
|
2299
2524
|
if (flags & GZ_FLAG_EXTRA) {
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2525
|
+
if (!gzfile_read_raw_ensure(gz, 2)) {
|
2526
|
+
rb_raise(cGzError, "unexpected end of file");
|
2527
|
+
}
|
2528
|
+
len = gzfile_get16((Bytef*)RSTRING_PTR(gz->z.input));
|
2529
|
+
if (!gzfile_read_raw_ensure(gz, 2 + len)) {
|
2530
|
+
rb_raise(cGzError, "unexpected end of file");
|
2531
|
+
}
|
2532
|
+
zstream_discard_input(&gz->z, 2 + len);
|
2308
2533
|
}
|
2309
2534
|
if (flags & GZ_FLAG_ORIG_NAME) {
|
2310
|
-
|
2311
|
-
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2315
|
-
|
2316
|
-
|
2317
|
-
|
2535
|
+
if (!gzfile_read_raw_ensure(gz, 1)) {
|
2536
|
+
rb_raise(cGzError, "unexpected end of file");
|
2537
|
+
}
|
2538
|
+
p = gzfile_read_raw_until_zero(gz, 0);
|
2539
|
+
len = p - RSTRING_PTR(gz->z.input);
|
2540
|
+
gz->orig_name = rb_str_new(RSTRING_PTR(gz->z.input), len);
|
2541
|
+
OBJ_TAINT(gz->orig_name); /* for safe */
|
2542
|
+
zstream_discard_input(&gz->z, len + 1);
|
2318
2543
|
}
|
2319
2544
|
if (flags & GZ_FLAG_COMMENT) {
|
2320
|
-
|
2321
|
-
|
2322
|
-
|
2323
|
-
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2327
|
-
|
2545
|
+
if (!gzfile_read_raw_ensure(gz, 1)) {
|
2546
|
+
rb_raise(cGzError, "unexpected end of file");
|
2547
|
+
}
|
2548
|
+
p = gzfile_read_raw_until_zero(gz, 0);
|
2549
|
+
len = p - RSTRING_PTR(gz->z.input);
|
2550
|
+
gz->comment = rb_str_new(RSTRING_PTR(gz->z.input), len);
|
2551
|
+
OBJ_TAINT(gz->comment); /* for safe */
|
2552
|
+
zstream_discard_input(&gz->z, len + 1);
|
2328
2553
|
}
|
2329
2554
|
|
2330
2555
|
if (gz->z.input != Qnil && RSTRING_LEN(gz->z.input) > 0) {
|
2331
|
-
|
2556
|
+
zstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);
|
2332
2557
|
}
|
2333
2558
|
}
|
2334
2559
|
|
@@ -2340,7 +2565,7 @@ gzfile_check_footer(struct gzfile *gz)
|
|
2340
2565
|
gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
|
2341
2566
|
|
2342
2567
|
if (!gzfile_read_raw_ensure(gz, 8)) { /* 8 is the size of gzip footer */
|
2343
|
-
|
2568
|
+
gzfile_raise(gz, cNoFooter, "footer is not found");
|
2344
2569
|
}
|
2345
2570
|
|
2346
2571
|
crc = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input));
|
@@ -2350,10 +2575,10 @@ gzfile_check_footer(struct gzfile *gz)
|
|
2350
2575
|
zstream_discard_input(&gz->z, 8);
|
2351
2576
|
|
2352
2577
|
if (gz->crc != crc) {
|
2353
|
-
|
2578
|
+
rb_raise(cCRCError, "invalid compressed data -- crc error");
|
2354
2579
|
}
|
2355
2580
|
if ((uint32_t)gz->z.stream.total_out != length) {
|
2356
|
-
|
2581
|
+
rb_raise(cLengthError, "invalid compressed data -- length error");
|
2357
2582
|
}
|
2358
2583
|
}
|
2359
2584
|
|
@@ -2361,13 +2586,13 @@ static void
|
|
2361
2586
|
gzfile_write(struct gzfile *gz, Bytef *str, long len)
|
2362
2587
|
{
|
2363
2588
|
if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
|
2364
|
-
|
2589
|
+
gzfile_make_header(gz);
|
2365
2590
|
}
|
2366
2591
|
|
2367
2592
|
if (len > 0 || (gz->z.flags & GZFILE_FLAG_SYNC)) {
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2593
|
+
gz->crc = checksum_long(crc32, gz->crc, str, len);
|
2594
|
+
zstream_run(&gz->z, str, len, (gz->z.flags & GZFILE_FLAG_SYNC)
|
2595
|
+
? Z_SYNC_FLUSH : Z_NO_FLUSH);
|
2371
2596
|
}
|
2372
2597
|
gzfile_write_raw(gz);
|
2373
2598
|
}
|
@@ -2378,18 +2603,18 @@ gzfile_read_more(struct gzfile *gz)
|
|
2378
2603
|
volatile VALUE str;
|
2379
2604
|
|
2380
2605
|
while (!ZSTREAM_IS_FINISHED(&gz->z)) {
|
2381
|
-
|
2382
|
-
|
2383
|
-
|
2384
|
-
|
2385
|
-
|
2386
|
-
|
2387
|
-
|
2388
|
-
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2606
|
+
str = gzfile_read_raw(gz);
|
2607
|
+
if (NIL_P(str)) {
|
2608
|
+
if (!ZSTREAM_IS_FINISHED(&gz->z)) {
|
2609
|
+
rb_raise(cGzError, "unexpected end of file");
|
2610
|
+
}
|
2611
|
+
break;
|
2612
|
+
}
|
2613
|
+
if (RSTRING_LEN(str) > 0) { /* prevent Z_BUF_ERROR */
|
2614
|
+
zstream_run(&gz->z, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str),
|
2615
|
+
Z_SYNC_FLUSH);
|
2616
|
+
}
|
2617
|
+
if (gz->z.buf_filled > 0) break;
|
2393
2618
|
}
|
2394
2619
|
return gz->z.buf_filled;
|
2395
2620
|
}
|
@@ -2398,12 +2623,12 @@ static void
|
|
2398
2623
|
gzfile_calc_crc(struct gzfile *gz, VALUE str)
|
2399
2624
|
{
|
2400
2625
|
if (RSTRING_LEN(str) <= gz->ungetc) {
|
2401
|
-
|
2626
|
+
gz->ungetc -= RSTRING_LEN(str);
|
2402
2627
|
}
|
2403
2628
|
else {
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2629
|
+
gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
|
2630
|
+
RSTRING_LEN(str) - gz->ungetc);
|
2631
|
+
gz->ungetc = 0;
|
2407
2632
|
}
|
2408
2633
|
}
|
2409
2634
|
|
@@ -2411,20 +2636,19 @@ static VALUE
|
|
2411
2636
|
gzfile_newstr(struct gzfile *gz, VALUE str)
|
2412
2637
|
{
|
2413
2638
|
if (!gz->enc2) {
|
2414
|
-
|
2415
|
-
|
2416
|
-
|
2639
|
+
rb_enc_associate(str, gz->enc);
|
2640
|
+
OBJ_TAINT(str); /* for safe */
|
2641
|
+
return str;
|
2417
2642
|
}
|
2418
2643
|
/* TODO: Encodings
|
2419
|
-
*
|
2420
2644
|
if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
|
2421
2645
|
str = rb_econv_str_convert(gz->ec, str, ECONV_PARTIAL_INPUT);
|
2422
|
-
|
2423
|
-
|
2424
|
-
|
2646
|
+
rb_enc_associate(str, gz->enc);
|
2647
|
+
OBJ_TAINT(str);
|
2648
|
+
return str;
|
2425
2649
|
}
|
2426
2650
|
return rb_str_conv_enc_opts(str, gz->enc2, gz->enc,
|
2427
|
-
|
2651
|
+
gz->ecflags, gz->ecopts);
|
2428
2652
|
*/
|
2429
2653
|
return str;
|
2430
2654
|
}
|
@@ -2435,15 +2659,15 @@ gzfile_fill(struct gzfile *gz, long len)
|
|
2435
2659
|
if (len < 0)
|
2436
2660
|
rb_raise(rb_eArgError, "negative length %ld given", len);
|
2437
2661
|
if (len == 0)
|
2438
|
-
|
2662
|
+
return 0;
|
2439
2663
|
while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
|
2440
|
-
|
2664
|
+
gzfile_read_more(gz);
|
2441
2665
|
}
|
2442
2666
|
if (GZFILE_IS_FINISHED(gz)) {
|
2443
|
-
|
2444
|
-
|
2445
|
-
|
2446
|
-
|
2667
|
+
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2668
|
+
gzfile_check_footer(gz);
|
2669
|
+
}
|
2670
|
+
return -1;
|
2447
2671
|
}
|
2448
2672
|
return len < gz->z.buf_filled ? len : gz->z.buf_filled;
|
2449
2673
|
}
|
@@ -2457,7 +2681,7 @@ gzfile_read(struct gzfile *gz, long len)
|
|
2457
2681
|
if (len == 0) return rb_str_new(0, 0);
|
2458
2682
|
if (len < 0) return Qnil;
|
2459
2683
|
dst = zstream_shift_buffer(&gz->z, len);
|
2460
|
-
gzfile_calc_crc(gz, dst);
|
2684
|
+
if (!NIL_P(dst)) gzfile_calc_crc(gz, dst);
|
2461
2685
|
return dst;
|
2462
2686
|
}
|
2463
2687
|
|
@@ -2470,7 +2694,7 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
|
|
2470
2694
|
rb_raise(rb_eArgError, "negative length %ld given", len);
|
2471
2695
|
|
2472
2696
|
if (!NIL_P(outbuf))
|
2473
|
-
|
2697
|
+
OBJ_TAINT(outbuf);
|
2474
2698
|
|
2475
2699
|
if (len == 0) {
|
2476
2700
|
if (NIL_P(outbuf))
|
@@ -2481,15 +2705,15 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
|
|
2481
2705
|
}
|
2482
2706
|
}
|
2483
2707
|
while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled == 0) {
|
2484
|
-
|
2708
|
+
gzfile_read_more(gz);
|
2485
2709
|
}
|
2486
2710
|
if (GZFILE_IS_FINISHED(gz)) {
|
2487
|
-
|
2488
|
-
|
2489
|
-
|
2711
|
+
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2712
|
+
gzfile_check_footer(gz);
|
2713
|
+
}
|
2490
2714
|
if (!NIL_P(outbuf))
|
2491
2715
|
rb_str_resize(outbuf, 0);
|
2492
|
-
|
2716
|
+
rb_raise(rb_eEOFError, "end of file reached");
|
2493
2717
|
}
|
2494
2718
|
|
2495
2719
|
dst = zstream_shift_buffer(&gz->z, len);
|
@@ -2498,7 +2722,7 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
|
|
2498
2722
|
if (!NIL_P(outbuf)) {
|
2499
2723
|
rb_str_resize(outbuf, RSTRING_LEN(dst));
|
2500
2724
|
memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
|
2501
|
-
|
2725
|
+
dst = outbuf;
|
2502
2726
|
}
|
2503
2727
|
OBJ_TAINT(dst); /* for safe */
|
2504
2728
|
return dst;
|
@@ -2510,16 +2734,17 @@ gzfile_read_all(struct gzfile *gz)
|
|
2510
2734
|
VALUE dst;
|
2511
2735
|
|
2512
2736
|
while (!ZSTREAM_IS_FINISHED(&gz->z)) {
|
2513
|
-
|
2737
|
+
gzfile_read_more(gz);
|
2514
2738
|
}
|
2515
2739
|
if (GZFILE_IS_FINISHED(gz)) {
|
2516
|
-
|
2517
|
-
|
2518
|
-
|
2519
|
-
|
2740
|
+
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2741
|
+
gzfile_check_footer(gz);
|
2742
|
+
}
|
2743
|
+
return rb_str_new(0, 0);
|
2520
2744
|
}
|
2521
2745
|
|
2522
2746
|
dst = zstream_detach_buffer(&gz->z);
|
2747
|
+
if (NIL_P(dst)) return dst;
|
2523
2748
|
gzfile_calc_crc(gz, dst);
|
2524
2749
|
OBJ_TAINT(dst);
|
2525
2750
|
return gzfile_newstr(gz, dst);
|
@@ -2533,47 +2758,46 @@ gzfile_getc(struct gzfile *gz)
|
|
2533
2758
|
|
2534
2759
|
len = rb_enc_mbmaxlen(gz->enc);
|
2535
2760
|
while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
|
2536
|
-
|
2761
|
+
gzfile_read_more(gz);
|
2537
2762
|
}
|
2538
2763
|
if (GZFILE_IS_FINISHED(gz)) {
|
2539
|
-
|
2540
|
-
|
2541
|
-
|
2542
|
-
|
2764
|
+
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2765
|
+
gzfile_check_footer(gz);
|
2766
|
+
}
|
2767
|
+
return Qnil;
|
2543
2768
|
}
|
2544
2769
|
|
2545
2770
|
/* TODO: Encodings
|
2546
|
-
*
|
2547
2771
|
if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
|
2548
|
-
|
2549
|
-
|
2550
|
-
rb_econv_result_t res;
|
2772
|
+
const unsigned char *ss, *sp, *se;
|
2773
|
+
unsigned char *ds, *dp, *de;
|
2551
2774
|
|
2552
|
-
|
2553
|
-
|
2554
|
-
|
2775
|
+
if (!gz->cbuf) {
|
2776
|
+
gz->cbuf = ALLOC_N(char, GZFILE_CBUF_CAPA);
|
2777
|
+
}
|
2555
2778
|
ss = sp = (const unsigned char*)RSTRING_PTR(gz->z.buf);
|
2556
2779
|
se = sp + gz->z.buf_filled;
|
2557
2780
|
ds = dp = (unsigned char *)gz->cbuf;
|
2558
2781
|
de = (unsigned char *)ds + GZFILE_CBUF_CAPA;
|
2559
|
-
|
2782
|
+
(void)rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
|
2560
2783
|
rb_econv_check_error(gz->ec);
|
2561
|
-
|
2562
|
-
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2784
|
+
dst = zstream_shift_buffer(&gz->z, sp - ss);
|
2785
|
+
gzfile_calc_crc(gz, dst);
|
2786
|
+
dst = rb_str_new(gz->cbuf, dp - ds);
|
2787
|
+
rb_enc_associate(dst, gz->enc);
|
2788
|
+
OBJ_TAINT(dst);
|
2789
|
+
return dst;
|
2567
2790
|
}
|
2568
2791
|
else {
|
2569
2792
|
*/
|
2570
|
-
|
2571
|
-
|
2572
|
-
|
2573
|
-
|
2574
|
-
|
2793
|
+
buf = gz->z.buf;
|
2794
|
+
len = rb_enc_mbclen(RSTRING_PTR(buf), RSTRING_END(buf), gz->enc);
|
2795
|
+
dst = gzfile_read(gz, len);
|
2796
|
+
if (NIL_P(dst)) return dst;
|
2797
|
+
return gzfile_newstr(gz, dst);
|
2798
|
+
/* TODO: Encodings
|
2575
2799
|
}
|
2576
|
-
|
2800
|
+
*/
|
2577
2801
|
}
|
2578
2802
|
|
2579
2803
|
static void
|
@@ -2596,7 +2820,7 @@ gzfile_writer_end_run(VALUE arg)
|
|
2596
2820
|
struct gzfile *gz = (struct gzfile *)arg;
|
2597
2821
|
|
2598
2822
|
if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
|
2599
|
-
|
2823
|
+
gzfile_make_header(gz);
|
2600
2824
|
}
|
2601
2825
|
|
2602
2826
|
zstream_run(&gz->z, (Bytef*)"", 0, Z_FINISH);
|
@@ -2621,8 +2845,8 @@ gzfile_reader_end_run(VALUE arg)
|
|
2621
2845
|
struct gzfile *gz = (struct gzfile *)arg;
|
2622
2846
|
|
2623
2847
|
if (GZFILE_IS_FINISHED(gz)
|
2624
|
-
|
2625
|
-
|
2848
|
+
&& !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2849
|
+
gzfile_check_footer(gz);
|
2626
2850
|
}
|
2627
2851
|
|
2628
2852
|
return Qnil;
|
@@ -2644,7 +2868,7 @@ gzfile_reader_rewind(struct gzfile *gz)
|
|
2644
2868
|
|
2645
2869
|
n = gz->z.stream.total_in;
|
2646
2870
|
if (!NIL_P(gz->z.input)) {
|
2647
|
-
|
2871
|
+
n += RSTRING_LEN(gz->z.input);
|
2648
2872
|
}
|
2649
2873
|
|
2650
2874
|
rb_funcall(gz->io, id_seek, 2, rb_int2inum(-n), INT2FIX(1));
|
@@ -2659,11 +2883,11 @@ gzfile_reader_get_unused(struct gzfile *gz)
|
|
2659
2883
|
if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;
|
2660
2884
|
if (!GZFILE_IS_FINISHED(gz)) return Qnil;
|
2661
2885
|
if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
|
2662
|
-
|
2886
|
+
gzfile_check_footer(gz);
|
2663
2887
|
}
|
2664
2888
|
if (NIL_P(gz->z.input)) return Qnil;
|
2665
2889
|
|
2666
|
-
str =
|
2890
|
+
str = rb_str_resurrect(gz->z.input);
|
2667
2891
|
OBJ_TAINT(str); /* for safe */
|
2668
2892
|
return str;
|
2669
2893
|
}
|
@@ -2675,7 +2899,7 @@ get_gzfile(VALUE obj)
|
|
2675
2899
|
|
2676
2900
|
Data_Get_Struct(obj, struct gzfile, gz);
|
2677
2901
|
if (!ZSTREAM_IS_READY(&gz->z)) {
|
2678
|
-
|
2902
|
+
rb_raise(cGzError, "closed gzip stream");
|
2679
2903
|
}
|
2680
2904
|
return gz;
|
2681
2905
|
}
|
@@ -2741,7 +2965,7 @@ gzfile_ensure_close(VALUE obj)
|
|
2741
2965
|
|
2742
2966
|
Data_Get_Struct(obj, struct gzfile, gz);
|
2743
2967
|
if (ZSTREAM_IS_READY(&gz->z)) {
|
2744
|
-
|
2968
|
+
gzfile_close(gz, 1);
|
2745
2969
|
}
|
2746
2970
|
return Qnil;
|
2747
2971
|
}
|
@@ -2752,40 +2976,43 @@ gzfile_wrap(int argc, VALUE *argv, VALUE klass, int close_io_on_error)
|
|
2752
2976
|
VALUE obj;
|
2753
2977
|
|
2754
2978
|
if (close_io_on_error) {
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2979
|
+
int state = 0;
|
2980
|
+
new_wrap_arg_t arg;
|
2981
|
+
arg.argc = argc;
|
2982
|
+
arg.argv = argv;
|
2983
|
+
arg.klass = klass;
|
2984
|
+
obj = rb_protect(new_wrap, (VALUE)&arg, &state);
|
2985
|
+
if (state) {
|
2986
|
+
rb_io_close(argv[0]);
|
2987
|
+
rb_jump_tag(state);
|
2988
|
+
}
|
2765
2989
|
}
|
2766
2990
|
else {
|
2767
|
-
|
2991
|
+
obj = rb_class_new_instance(argc, argv, klass);
|
2768
2992
|
}
|
2769
2993
|
|
2770
2994
|
if (rb_block_given_p()) {
|
2771
|
-
|
2995
|
+
return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);
|
2772
2996
|
}
|
2773
2997
|
else {
|
2774
|
-
|
2998
|
+
return obj;
|
2775
2999
|
}
|
2776
3000
|
}
|
2777
3001
|
|
2778
3002
|
/*
|
2779
3003
|
* Document-method: Zlib::GzipFile.wrap
|
2780
3004
|
*
|
2781
|
-
* call-seq:
|
3005
|
+
* call-seq:
|
3006
|
+
* Zlib::GzipReader.wrap(io, ...) { |gz| ... }
|
3007
|
+
* Zlib::GzipWriter.wrap(io, ...) { |gz| ... }
|
2782
3008
|
*
|
2783
|
-
* Creates a
|
2784
|
-
* executes the block with the newly created
|
2785
|
-
* just like File.open.
|
2786
|
-
*
|
2787
|
-
*
|
2788
|
-
*
|
3009
|
+
* Creates a GzipReader or GzipWriter associated with +io+, passing in any
|
3010
|
+
* necessary extra options, and executes the block with the newly created
|
3011
|
+
* object just like File.open.
|
3012
|
+
*
|
3013
|
+
* The GzipFile object will be closed automatically after executing the block.
|
3014
|
+
* If you want to keep the associated IO object open, you may call
|
3015
|
+
* Zlib::GzipFile#finish method in the block.
|
2789
3016
|
*/
|
2790
3017
|
static VALUE
|
2791
3018
|
rb_gzfile_s_wrap(int argc, VALUE *argv, VALUE klass)
|
@@ -2804,7 +3031,7 @@ gzfile_s_open(int argc, VALUE *argv, VALUE klass, const char *mode)
|
|
2804
3031
|
VALUE io, filename;
|
2805
3032
|
|
2806
3033
|
if (argc < 1) {
|
2807
|
-
|
3034
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
|
2808
3035
|
}
|
2809
3036
|
filename = argv[0];
|
2810
3037
|
io = rb_file_open_str(filename, mode);
|
@@ -2878,7 +3105,7 @@ rb_gzfile_orig_name(VALUE obj)
|
|
2878
3105
|
{
|
2879
3106
|
VALUE str = get_gzfile(obj)->orig_name;
|
2880
3107
|
if (!NIL_P(str)) {
|
2881
|
-
|
3108
|
+
str = rb_str_dup(str);
|
2882
3109
|
}
|
2883
3110
|
OBJ_TAINT(str); /* for safe */
|
2884
3111
|
return str;
|
@@ -2895,7 +3122,7 @@ rb_gzfile_comment(VALUE obj)
|
|
2895
3122
|
{
|
2896
3123
|
VALUE str = get_gzfile(obj)->comment;
|
2897
3124
|
if (!NIL_P(str)) {
|
2898
|
-
|
3125
|
+
str = rb_str_dup(str);
|
2899
3126
|
}
|
2900
3127
|
OBJ_TAINT(str); /* for safe */
|
2901
3128
|
return str;
|
@@ -2938,16 +3165,12 @@ rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
|
|
2938
3165
|
VALUE val;
|
2939
3166
|
|
2940
3167
|
if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
|
2941
|
-
|
3168
|
+
rb_raise(cGzError, "header is already written");
|
2942
3169
|
}
|
2943
3170
|
|
2944
|
-
|
2945
|
-
|
2946
|
-
|
2947
|
-
else {
|
2948
|
-
val = rb_Integer(mtime);
|
2949
|
-
gz->mtime = FIXNUM_P(val) ? FIX2UINT(val) : rb_big2ulong(val);
|
2950
|
-
}
|
3171
|
+
val = rb_Integer(mtime);
|
3172
|
+
gz->mtime = NUM2UINT(val);
|
3173
|
+
|
2951
3174
|
return mtime;
|
2952
3175
|
}
|
2953
3176
|
|
@@ -2964,12 +3187,12 @@ rb_gzfile_set_orig_name(VALUE obj, VALUE str)
|
|
2964
3187
|
char *p;
|
2965
3188
|
|
2966
3189
|
if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
|
2967
|
-
|
3190
|
+
rb_raise(cGzError, "header is already written");
|
2968
3191
|
}
|
2969
3192
|
s = rb_str_dup(rb_str_to_str(str));
|
2970
3193
|
p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
|
2971
3194
|
if (p) {
|
2972
|
-
|
3195
|
+
rb_str_resize(s, p - RSTRING_PTR(s));
|
2973
3196
|
}
|
2974
3197
|
gz->orig_name = s;
|
2975
3198
|
return str;
|
@@ -2988,12 +3211,12 @@ rb_gzfile_set_comment(VALUE obj, VALUE str)
|
|
2988
3211
|
char *p;
|
2989
3212
|
|
2990
3213
|
if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
|
2991
|
-
|
3214
|
+
rb_raise(cGzError, "header is already written");
|
2992
3215
|
}
|
2993
3216
|
s = rb_str_dup(rb_str_to_str(str));
|
2994
3217
|
p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
|
2995
3218
|
if (p) {
|
2996
|
-
|
3219
|
+
rb_str_resize(s, p - RSTRING_PTR(s));
|
2997
3220
|
}
|
2998
3221
|
gz->comment = s;
|
2999
3222
|
return str;
|
@@ -3087,10 +3310,10 @@ rb_gzfile_set_sync(VALUE obj, VALUE mode)
|
|
3087
3310
|
struct gzfile *gz = get_gzfile(obj);
|
3088
3311
|
|
3089
3312
|
if (RTEST(mode)) {
|
3090
|
-
|
3313
|
+
gz->z.flags |= GZFILE_FLAG_SYNC;
|
3091
3314
|
}
|
3092
3315
|
else {
|
3093
|
-
|
3316
|
+
gz->z.flags &= ~GZFILE_FLAG_SYNC;
|
3094
3317
|
}
|
3095
3318
|
return mode;
|
3096
3319
|
}
|
@@ -3137,18 +3360,17 @@ rb_gzfile_path(VALUE obj)
|
|
3137
3360
|
static void
|
3138
3361
|
rb_gzfile_ecopts(struct gzfile *gz, VALUE opts)
|
3139
3362
|
{
|
3140
|
-
|
3141
|
-
*
|
3363
|
+
/* TODO: Encodings
|
3142
3364
|
if (!NIL_P(opts)) {
|
3143
|
-
|
3365
|
+
rb_io_extract_encoding_option(opts, &gz->enc, &gz->enc2, NULL);
|
3144
3366
|
}
|
3145
3367
|
if (gz->enc2) {
|
3146
|
-
|
3147
|
-
|
3148
|
-
|
3149
|
-
|
3368
|
+
gz->ecflags = rb_econv_prepare_opts(opts, &opts);
|
3369
|
+
gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
|
3370
|
+
gz->ecflags, opts);
|
3371
|
+
gz->ecopts = opts;
|
3150
3372
|
}
|
3151
|
-
|
3373
|
+
*/
|
3152
3374
|
}
|
3153
3375
|
|
3154
3376
|
/* ------------------------------------------------------------------------- */
|
@@ -3206,12 +3428,17 @@ rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
|
|
3206
3428
|
}
|
3207
3429
|
|
3208
3430
|
/*
|
3209
|
-
* call-seq:
|
3431
|
+
* call-seq:
|
3432
|
+
* Zlib::GzipWriter.new(io, level = nil, strategy = nil, options = {})
|
3210
3433
|
*
|
3211
3434
|
* Creates a GzipWriter object associated with +io+. +level+ and +strategy+
|
3212
3435
|
* should be the same as the arguments of Zlib::Deflate.new. The GzipWriter
|
3213
|
-
* object writes gzipped data to +io+.
|
3214
|
-
* +write+ method that behaves same as write
|
3436
|
+
* object writes gzipped data to +io+. +io+ must respond to the
|
3437
|
+
* +write+ method that behaves the same as IO#write.
|
3438
|
+
*
|
3439
|
+
* The +options+ hash may be used to set the encoding of the data.
|
3440
|
+
* +:external_encoding+, +:internal_encoding+ and +:encoding+ may be set as in
|
3441
|
+
* IO::new.
|
3215
3442
|
*/
|
3216
3443
|
static VALUE
|
3217
3444
|
rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
|
@@ -3221,8 +3448,8 @@ rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
|
|
3221
3448
|
int err;
|
3222
3449
|
|
3223
3450
|
if (argc > 1) {
|
3224
|
-
|
3225
|
-
|
3451
|
+
opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
|
3452
|
+
if (!NIL_P(opt)) argc--;
|
3226
3453
|
}
|
3227
3454
|
|
3228
3455
|
rb_scan_args(argc, argv, "12", &io, &level, &strategy);
|
@@ -3231,17 +3458,17 @@ rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
|
|
3231
3458
|
/* this is undocumented feature of zlib */
|
3232
3459
|
gz->level = ARG_LEVEL(level);
|
3233
3460
|
err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
|
3234
|
-
|
3461
|
+
-MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
|
3235
3462
|
if (err != Z_OK) {
|
3236
|
-
|
3463
|
+
raise_zlib_error(err, gz->z.stream.msg);
|
3237
3464
|
}
|
3238
3465
|
gz->io = io;
|
3239
3466
|
ZSTREAM_READY(&gz->z);
|
3240
3467
|
rb_gzfile_ecopts(gz, opt);
|
3241
3468
|
|
3242
3469
|
if (rb_respond_to(io, id_path)) {
|
3243
|
-
|
3244
|
-
|
3470
|
+
gz->path = rb_funcall(gz->io, id_path, 0);
|
3471
|
+
rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
|
3245
3472
|
}
|
3246
3473
|
|
3247
3474
|
return obj;
|
@@ -3265,12 +3492,12 @@ rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj)
|
|
3265
3492
|
|
3266
3493
|
flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
|
3267
3494
|
if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
|
3268
|
-
|
3495
|
+
zstream_run(&gz->z, (Bytef*)"", 0, flush);
|
3269
3496
|
}
|
3270
3497
|
|
3271
3498
|
gzfile_write_raw(gz);
|
3272
3499
|
if (rb_respond_to(gz->io, id_flush)) {
|
3273
|
-
|
3500
|
+
rb_funcall(gz->io, id_flush, 0);
|
3274
3501
|
}
|
3275
3502
|
return obj;
|
3276
3503
|
}
|
@@ -3283,10 +3510,10 @@ rb_gzwriter_write(VALUE obj, VALUE str)
|
|
3283
3510
|
{
|
3284
3511
|
struct gzfile *gz = get_gzfile(obj);
|
3285
3512
|
|
3286
|
-
if (
|
3287
|
-
|
3513
|
+
if (!RB_TYPE_P(str, T_STRING))
|
3514
|
+
str = rb_obj_as_string(str);
|
3288
3515
|
if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
|
3289
|
-
|
3516
|
+
str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
|
3290
3517
|
}
|
3291
3518
|
gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
|
3292
3519
|
return INT2FIX(RSTRING_LEN(str));
|
@@ -3335,7 +3562,7 @@ rb_gzwriter_putc(VALUE obj, VALUE ch)
|
|
3335
3562
|
* Document-class: Zlib::GzipReader
|
3336
3563
|
*
|
3337
3564
|
* Zlib::GzipReader is the class for reading a gzipped file. GzipReader should
|
3338
|
-
* be used an IO, or -IO-
|
3565
|
+
* be used an IO, or -IO-like, object.
|
3339
3566
|
*
|
3340
3567
|
* Zlib::GzipReader.open('hoge.gz') {|gz|
|
3341
3568
|
* print gz.read
|
@@ -3407,11 +3634,16 @@ rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
|
|
3407
3634
|
/*
|
3408
3635
|
* Document-method: Zlib::GzipReader.new
|
3409
3636
|
*
|
3410
|
-
* call-seq:
|
3637
|
+
* call-seq:
|
3638
|
+
* Zlib::GzipReader.new(io, options = {})
|
3411
3639
|
*
|
3412
3640
|
* Creates a GzipReader object associated with +io+. The GzipReader object reads
|
3413
|
-
* gzipped data from +io+, and parses/decompresses
|
3414
|
-
* a +read+ method that behaves same as the
|
3641
|
+
* gzipped data from +io+, and parses/decompresses it. The +io+ must
|
3642
|
+
* have a +read+ method that behaves same as the IO#read.
|
3643
|
+
*
|
3644
|
+
* The +options+ hash may be used to set the encoding of the data.
|
3645
|
+
* +:external_encoding+, +:internal_encoding+ and +:encoding+ may be set as in
|
3646
|
+
* IO::new.
|
3415
3647
|
*
|
3416
3648
|
* If the gzip file header is incorrect, raises an Zlib::GzipFile::Error
|
3417
3649
|
* exception.
|
@@ -3429,7 +3661,7 @@ rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
|
|
3429
3661
|
/* this is undocumented feature of zlib */
|
3430
3662
|
err = inflateInit2(&gz->z.stream, -MAX_WBITS);
|
3431
3663
|
if (err != Z_OK) {
|
3432
|
-
|
3664
|
+
raise_zlib_error(err, gz->z.stream.msg);
|
3433
3665
|
}
|
3434
3666
|
gz->io = io;
|
3435
3667
|
ZSTREAM_READY(&gz->z);
|
@@ -3437,8 +3669,8 @@ rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
|
|
3437
3669
|
rb_gzfile_ecopts(gz, opt);
|
3438
3670
|
|
3439
3671
|
if (rb_respond_to(io, id_path)) {
|
3440
|
-
|
3441
|
-
|
3672
|
+
gz->path = rb_funcall(gz->io, id_path, 0);
|
3673
|
+
rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
|
3442
3674
|
}
|
3443
3675
|
|
3444
3676
|
return obj;
|
@@ -3486,12 +3718,12 @@ rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
|
|
3486
3718
|
|
3487
3719
|
rb_scan_args(argc, argv, "01", &vlen);
|
3488
3720
|
if (NIL_P(vlen)) {
|
3489
|
-
|
3721
|
+
return gzfile_read_all(gz);
|
3490
3722
|
}
|
3491
3723
|
|
3492
3724
|
len = NUM2INT(vlen);
|
3493
3725
|
if (len < 0) {
|
3494
|
-
|
3726
|
+
rb_raise(rb_eArgError, "negative length %ld given", len);
|
3495
3727
|
}
|
3496
3728
|
return gzfile_read(gz, len);
|
3497
3729
|
}
|
@@ -3519,7 +3751,7 @@ rb_gzreader_readpartial(int argc, VALUE *argv, VALUE obj)
|
|
3519
3751
|
|
3520
3752
|
len = NUM2INT(vlen);
|
3521
3753
|
if (len < 0) {
|
3522
|
-
|
3754
|
+
rb_raise(rb_eArgError, "negative length %ld given", len);
|
3523
3755
|
}
|
3524
3756
|
if (!NIL_P(outbuf))
|
3525
3757
|
Check_Type(outbuf, T_STRING);
|
@@ -3550,7 +3782,7 @@ rb_gzreader_readchar(VALUE obj)
|
|
3550
3782
|
VALUE dst;
|
3551
3783
|
dst = rb_gzreader_getc(obj);
|
3552
3784
|
if (NIL_P(dst)) {
|
3553
|
-
|
3785
|
+
rb_raise(rb_eEOFError, "end of file reached");
|
3554
3786
|
}
|
3555
3787
|
return dst;
|
3556
3788
|
}
|
@@ -3568,7 +3800,7 @@ rb_gzreader_getbyte(VALUE obj)
|
|
3568
3800
|
|
3569
3801
|
dst = gzfile_read(gz, 1);
|
3570
3802
|
if (!NIL_P(dst)) {
|
3571
|
-
|
3803
|
+
dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
|
3572
3804
|
}
|
3573
3805
|
return dst;
|
3574
3806
|
}
|
@@ -3584,7 +3816,7 @@ rb_gzreader_readbyte(VALUE obj)
|
|
3584
3816
|
VALUE dst;
|
3585
3817
|
dst = rb_gzreader_getbyte(obj);
|
3586
3818
|
if (NIL_P(dst)) {
|
3587
|
-
|
3819
|
+
rb_raise(rb_eEOFError, "end of file reached");
|
3588
3820
|
}
|
3589
3821
|
return dst;
|
3590
3822
|
}
|
@@ -3602,7 +3834,7 @@ rb_gzreader_each_char(VALUE obj)
|
|
3602
3834
|
RETURN_ENUMERATOR(obj, 0, 0);
|
3603
3835
|
|
3604
3836
|
while (!NIL_P(c = rb_gzreader_getc(obj))) {
|
3605
|
-
|
3837
|
+
rb_yield(c);
|
3606
3838
|
}
|
3607
3839
|
return Qnil;
|
3608
3840
|
}
|
@@ -3620,11 +3852,25 @@ rb_gzreader_each_byte(VALUE obj)
|
|
3620
3852
|
RETURN_ENUMERATOR(obj, 0, 0);
|
3621
3853
|
|
3622
3854
|
while (!NIL_P(c = rb_gzreader_getbyte(obj))) {
|
3623
|
-
|
3855
|
+
rb_yield(c);
|
3624
3856
|
}
|
3625
3857
|
return Qnil;
|
3626
3858
|
}
|
3627
3859
|
|
3860
|
+
/*
|
3861
|
+
* Document-method: Zlib::GzipReader#bytes
|
3862
|
+
*
|
3863
|
+
* This is a deprecated alias for <code>each_byte</code>.
|
3864
|
+
*/
|
3865
|
+
static VALUE
|
3866
|
+
rb_gzreader_bytes(VALUE obj)
|
3867
|
+
{
|
3868
|
+
rb_warn("Zlib::GzipReader#bytes is deprecated; use #each_byte instead");
|
3869
|
+
if (!rb_block_given_p())
|
3870
|
+
return rb_enumeratorize(obj, ID2SYM(rb_intern("each_byte")), 0, 0);
|
3871
|
+
return rb_gzreader_each_byte(obj);
|
3872
|
+
}
|
3873
|
+
|
3628
3874
|
/*
|
3629
3875
|
* Document-method: Zlib::GzipReader#ungetc
|
3630
3876
|
*
|
@@ -3636,11 +3882,11 @@ rb_gzreader_ungetc(VALUE obj, VALUE s)
|
|
3636
3882
|
struct gzfile *gz;
|
3637
3883
|
|
3638
3884
|
if (FIXNUM_P(s))
|
3639
|
-
|
3885
|
+
return rb_gzreader_ungetbyte(obj, s);
|
3640
3886
|
gz = get_gzfile(obj);
|
3641
3887
|
StringValue(s);
|
3642
3888
|
if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
|
3643
|
-
|
3889
|
+
s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2);
|
3644
3890
|
}
|
3645
3891
|
gzfile_ungets(gz, (const Bytef*)RSTRING_PTR(s), RSTRING_LEN(s));
|
3646
3892
|
return Qnil;
|
@@ -3667,23 +3913,23 @@ gzreader_skip_linebreaks(struct gzfile *gz)
|
|
3667
3913
|
int n;
|
3668
3914
|
|
3669
3915
|
while (gz->z.buf_filled == 0) {
|
3670
|
-
|
3671
|
-
|
3916
|
+
if (GZFILE_IS_FINISHED(gz)) return;
|
3917
|
+
gzfile_read_more(gz);
|
3672
3918
|
}
|
3673
3919
|
n = 0;
|
3674
3920
|
p = RSTRING_PTR(gz->z.buf);
|
3675
3921
|
|
3676
3922
|
while (n++, *(p++) == '\n') {
|
3677
|
-
|
3678
|
-
|
3679
|
-
|
3680
|
-
|
3681
|
-
|
3682
|
-
|
3683
|
-
|
3684
|
-
|
3685
|
-
|
3686
|
-
|
3923
|
+
if (n >= gz->z.buf_filled) {
|
3924
|
+
str = zstream_detach_buffer(&gz->z);
|
3925
|
+
gzfile_calc_crc(gz, str);
|
3926
|
+
while (gz->z.buf_filled == 0) {
|
3927
|
+
if (GZFILE_IS_FINISHED(gz)) return;
|
3928
|
+
gzfile_read_more(gz);
|
3929
|
+
}
|
3930
|
+
n = 0;
|
3931
|
+
p = RSTRING_PTR(gz->z.buf);
|
3932
|
+
}
|
3687
3933
|
}
|
3688
3934
|
|
3689
3935
|
str = zstream_shift_buffer(&gz->z, n - 1);
|
@@ -3694,7 +3940,7 @@ static void
|
|
3694
3940
|
rscheck(const char *rsptr, long rslen, VALUE rs)
|
3695
3941
|
{
|
3696
3942
|
if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen)
|
3697
|
-
|
3943
|
+
rb_raise(rb_eRuntimeError, "rs modified");
|
3698
3944
|
}
|
3699
3945
|
|
3700
3946
|
static long
|
@@ -3705,15 +3951,15 @@ gzreader_charboundary(struct gzfile *gz, long n)
|
|
3705
3951
|
char *p = rb_enc_left_char_head(s, s + n, e, gz->enc);
|
3706
3952
|
long l = p - s;
|
3707
3953
|
if (l < n) {
|
3708
|
-
|
3709
|
-
|
3710
|
-
|
3711
|
-
|
3712
|
-
|
3713
|
-
|
3714
|
-
|
3715
|
-
|
3716
|
-
|
3954
|
+
n = rb_enc_precise_mbclen(p, e, gz->enc);
|
3955
|
+
if (MBCLEN_NEEDMORE_P(n)) {
|
3956
|
+
if ((l = gzfile_fill(gz, l + MBCLEN_NEEDMORE_LEN(n))) > 0) {
|
3957
|
+
return l;
|
3958
|
+
}
|
3959
|
+
}
|
3960
|
+
else if (MBCLEN_CHARFOUND_P(n)) {
|
3961
|
+
return l + MBCLEN_CHARFOUND_LEN(n);
|
3962
|
+
}
|
3717
3963
|
}
|
3718
3964
|
return n;
|
3719
3965
|
}
|
@@ -3732,110 +3978,112 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
|
|
3732
3978
|
int maxlen = rb_enc_mbmaxlen(enc);
|
3733
3979
|
|
3734
3980
|
if (argc == 0) {
|
3735
|
-
|
3981
|
+
rs = rb_rs;
|
3736
3982
|
}
|
3737
3983
|
else {
|
3738
|
-
|
3739
|
-
|
3740
|
-
|
3741
|
-
|
3742
|
-
|
3743
|
-
|
3744
|
-
|
3745
|
-
|
3746
|
-
|
3747
|
-
|
3748
|
-
|
3749
|
-
|
3750
|
-
|
3751
|
-
|
3752
|
-
|
3753
|
-
|
3754
|
-
|
3755
|
-
|
3756
|
-
|
3757
|
-
|
3984
|
+
VALUE lim, tmp;
|
3985
|
+
|
3986
|
+
rb_scan_args(argc, argv, "11", &rs, &lim);
|
3987
|
+
if (!NIL_P(lim)) {
|
3988
|
+
if (!NIL_P(rs)) StringValue(rs);
|
3989
|
+
}
|
3990
|
+
else if (!NIL_P(rs)) {
|
3991
|
+
tmp = rb_check_string_type(rs);
|
3992
|
+
if (NIL_P(tmp)) {
|
3993
|
+
lim = rs;
|
3994
|
+
rs = rb_rs;
|
3995
|
+
}
|
3996
|
+
else {
|
3997
|
+
rs = tmp;
|
3998
|
+
}
|
3999
|
+
}
|
4000
|
+
if (!NIL_P(lim)) {
|
4001
|
+
limit = NUM2LONG(lim);
|
4002
|
+
if (limit == 0) return rb_str_new(0,0);
|
4003
|
+
}
|
3758
4004
|
}
|
3759
4005
|
|
3760
4006
|
if (NIL_P(rs)) {
|
3761
|
-
|
3762
|
-
|
3763
|
-
|
3764
|
-
|
3765
|
-
|
3766
|
-
|
3767
|
-
|
3768
|
-
|
3769
|
-
|
3770
|
-
|
3771
|
-
|
3772
|
-
|
3773
|
-
|
3774
|
-
|
3775
|
-
|
3776
|
-
|
3777
|
-
|
3778
|
-
|
3779
|
-
|
3780
|
-
|
4007
|
+
if (limit < 0) {
|
4008
|
+
dst = gzfile_read_all(gz);
|
4009
|
+
if (RSTRING_LEN(dst) == 0) return Qnil;
|
4010
|
+
}
|
4011
|
+
else if ((n = gzfile_fill(gz, limit)) <= 0) {
|
4012
|
+
return Qnil;
|
4013
|
+
}
|
4014
|
+
else {
|
4015
|
+
if (maxlen > 1 && n >= limit && !GZFILE_IS_FINISHED(gz)) {
|
4016
|
+
n = gzreader_charboundary(gz, n);
|
4017
|
+
}
|
4018
|
+
else {
|
4019
|
+
n = limit;
|
4020
|
+
}
|
4021
|
+
dst = zstream_shift_buffer(&gz->z, n);
|
4022
|
+
if (NIL_P(dst)) return dst;
|
4023
|
+
gzfile_calc_crc(gz, dst);
|
4024
|
+
dst = gzfile_newstr(gz, dst);
|
4025
|
+
}
|
4026
|
+
gz->lineno++;
|
4027
|
+
return dst;
|
3781
4028
|
}
|
3782
4029
|
|
3783
4030
|
if (RSTRING_LEN(rs) == 0) {
|
3784
|
-
|
3785
|
-
|
3786
|
-
|
4031
|
+
rsptr = "\n\n";
|
4032
|
+
rslen = 2;
|
4033
|
+
rspara = 1;
|
3787
4034
|
} else {
|
3788
|
-
|
3789
|
-
|
3790
|
-
|
4035
|
+
rsptr = RSTRING_PTR(rs);
|
4036
|
+
rslen = RSTRING_LEN(rs);
|
4037
|
+
rspara = 0;
|
3791
4038
|
}
|
3792
4039
|
|
3793
4040
|
if (rspara) {
|
3794
|
-
|
4041
|
+
gzreader_skip_linebreaks(gz);
|
3795
4042
|
}
|
3796
4043
|
|
3797
4044
|
while (gz->z.buf_filled < rslen) {
|
3798
|
-
|
3799
|
-
|
3800
|
-
|
3801
|
-
|
3802
|
-
|
4045
|
+
if (ZSTREAM_IS_FINISHED(&gz->z)) {
|
4046
|
+
if (gz->z.buf_filled > 0) gz->lineno++;
|
4047
|
+
return gzfile_read(gz, rslen);
|
4048
|
+
}
|
4049
|
+
gzfile_read_more(gz);
|
3803
4050
|
}
|
3804
4051
|
|
3805
4052
|
p = RSTRING_PTR(gz->z.buf);
|
3806
4053
|
n = rslen;
|
3807
4054
|
for (;;) {
|
3808
|
-
|
3809
|
-
|
3810
|
-
|
3811
|
-
|
3812
|
-
|
3813
|
-
|
3814
|
-
|
3815
|
-
|
3816
|
-
|
3817
|
-
|
3818
|
-
|
3819
|
-
|
3820
|
-
|
3821
|
-
|
3822
|
-
|
3823
|
-
|
3824
|
-
|
3825
|
-
|
3826
|
-
|
3827
|
-
|
3828
|
-
|
3829
|
-
|
4055
|
+
long filled;
|
4056
|
+
if (n > gz->z.buf_filled) {
|
4057
|
+
if (ZSTREAM_IS_FINISHED(&gz->z)) break;
|
4058
|
+
gzfile_read_more(gz);
|
4059
|
+
p = RSTRING_PTR(gz->z.buf) + n - rslen;
|
4060
|
+
}
|
4061
|
+
if (!rspara) rscheck(rsptr, rslen, rs);
|
4062
|
+
filled = gz->z.buf_filled;
|
4063
|
+
if (limit > 0 && filled >= limit) {
|
4064
|
+
filled = limit;
|
4065
|
+
}
|
4066
|
+
res = memchr(p, rsptr[0], (filled - n + 1));
|
4067
|
+
if (!res) {
|
4068
|
+
n = filled;
|
4069
|
+
if (limit > 0 && filled >= limit) break;
|
4070
|
+
n++;
|
4071
|
+
} else {
|
4072
|
+
n += (long)(res - p);
|
4073
|
+
p = res;
|
4074
|
+
if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
|
4075
|
+
p++, n++;
|
4076
|
+
}
|
3830
4077
|
}
|
3831
4078
|
if (maxlen > 1 && n == limit && (gz->z.buf_filled > n || !ZSTREAM_IS_FINISHED(&gz->z))) {
|
3832
|
-
|
4079
|
+
n = gzreader_charboundary(gz, n);
|
3833
4080
|
}
|
3834
4081
|
|
3835
4082
|
gz->lineno++;
|
3836
4083
|
dst = gzfile_read(gz, n);
|
4084
|
+
if (NIL_P(dst)) return dst;
|
3837
4085
|
if (rspara) {
|
3838
|
-
|
4086
|
+
gzreader_skip_linebreaks(gz);
|
3839
4087
|
}
|
3840
4088
|
|
3841
4089
|
return gzfile_newstr(gz, dst);
|
@@ -3852,7 +4100,7 @@ rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
|
|
3852
4100
|
VALUE dst;
|
3853
4101
|
dst = gzreader_gets(argc, argv, obj);
|
3854
4102
|
if (!NIL_P(dst)) {
|
3855
|
-
|
4103
|
+
rb_lastline_set(dst);
|
3856
4104
|
}
|
3857
4105
|
return dst;
|
3858
4106
|
}
|
@@ -3868,7 +4116,7 @@ rb_gzreader_readline(int argc, VALUE *argv, VALUE obj)
|
|
3868
4116
|
VALUE dst;
|
3869
4117
|
dst = rb_gzreader_gets(argc, argv, obj);
|
3870
4118
|
if (NIL_P(dst)) {
|
3871
|
-
|
4119
|
+
rb_raise(rb_eEOFError, "end of file reached");
|
3872
4120
|
}
|
3873
4121
|
return dst;
|
3874
4122
|
}
|
@@ -3886,11 +4134,25 @@ rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
|
|
3886
4134
|
RETURN_ENUMERATOR(obj, 0, 0);
|
3887
4135
|
|
3888
4136
|
while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
|
3889
|
-
|
4137
|
+
rb_yield(str);
|
3890
4138
|
}
|
3891
4139
|
return obj;
|
3892
4140
|
}
|
3893
4141
|
|
4142
|
+
/*
|
4143
|
+
* Document-method: Zlib::GzipReader#lines
|
4144
|
+
*
|
4145
|
+
* This is a deprecated alias for <code>each_line</code>.
|
4146
|
+
*/
|
4147
|
+
static VALUE
|
4148
|
+
rb_gzreader_lines(int argc, VALUE *argv, VALUE obj)
|
4149
|
+
{
|
4150
|
+
rb_warn("Zlib::GzipReader#lines is deprecated; use #each_line instead");
|
4151
|
+
if (!rb_block_given_p())
|
4152
|
+
return rb_enumeratorize(obj, ID2SYM(rb_intern("each_line")), argc, argv);
|
4153
|
+
return rb_gzreader_each(argc, argv, obj);
|
4154
|
+
}
|
4155
|
+
|
3894
4156
|
/*
|
3895
4157
|
* Document-method: Zlib::GzipReader#readlines
|
3896
4158
|
*
|
@@ -3902,96 +4164,13 @@ rb_gzreader_readlines(int argc, VALUE *argv, VALUE obj)
|
|
3902
4164
|
VALUE str, dst;
|
3903
4165
|
dst = rb_ary_new();
|
3904
4166
|
while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
|
3905
|
-
|
4167
|
+
rb_ary_push(dst, str);
|
3906
4168
|
}
|
3907
4169
|
return dst;
|
3908
4170
|
}
|
3909
4171
|
|
3910
4172
|
#endif /* GZIP_SUPPORT */
|
3911
4173
|
|
3912
|
-
|
3913
|
-
|
3914
|
-
/*
|
3915
|
-
* Document-module: Zlib
|
3916
|
-
*
|
3917
|
-
* The Zlib module contains several classes for compressing and decompressing
|
3918
|
-
* streams, and for working with "gzip" files.
|
3919
|
-
*
|
3920
|
-
* == Classes
|
3921
|
-
*
|
3922
|
-
* Following are the classes that are most likely to be of interest to the
|
3923
|
-
* user:
|
3924
|
-
* Zlib::Inflate
|
3925
|
-
* Zlib::Deflate
|
3926
|
-
* Zlib::GzipReader
|
3927
|
-
* Zlib::GzipWriter
|
3928
|
-
*
|
3929
|
-
* There are two important base classes for the classes above: Zlib::ZStream
|
3930
|
-
* and Zlib::GzipFile. Everything else is an error class.
|
3931
|
-
*
|
3932
|
-
* == Constants
|
3933
|
-
*
|
3934
|
-
* Here's a list.
|
3935
|
-
*
|
3936
|
-
* Zlib::VERSION
|
3937
|
-
* The Ruby/zlib version string.
|
3938
|
-
*
|
3939
|
-
* Zlib::ZLIB_VERSION
|
3940
|
-
* The string which represents the version of zlib.h.
|
3941
|
-
*
|
3942
|
-
* Zlib::BINARY
|
3943
|
-
* Zlib::ASCII
|
3944
|
-
* Zlib::UNKNOWN
|
3945
|
-
* The integers representing data types which Zlib::ZStream#data_type
|
3946
|
-
* method returns.
|
3947
|
-
*
|
3948
|
-
* Zlib::NO_COMPRESSION
|
3949
|
-
* Zlib::BEST_SPEED
|
3950
|
-
* Zlib::BEST_COMPRESSION
|
3951
|
-
* Zlib::DEFAULT_COMPRESSION
|
3952
|
-
* The integers representing compression levels which are an argument
|
3953
|
-
* for Zlib::Deflate.new, Zlib::Deflate#deflate, and so on.
|
3954
|
-
*
|
3955
|
-
* Zlib::FILTERED
|
3956
|
-
* Zlib::HUFFMAN_ONLY
|
3957
|
-
* Zlib::DEFAULT_STRATEGY
|
3958
|
-
* The integers representing compression methods which are an argument
|
3959
|
-
* for Zlib::Deflate.new and Zlib::Deflate#params.
|
3960
|
-
*
|
3961
|
-
* Zlib::DEF_MEM_LEVEL
|
3962
|
-
* Zlib::MAX_MEM_LEVEL
|
3963
|
-
* The integers representing memory levels which are an argument for
|
3964
|
-
* Zlib::Deflate.new, Zlib::Deflate#params, and so on.
|
3965
|
-
*
|
3966
|
-
* Zlib::MAX_WBITS
|
3967
|
-
* The default value of windowBits which is an argument for
|
3968
|
-
* Zlib::Deflate.new and Zlib::Inflate.new.
|
3969
|
-
*
|
3970
|
-
* Zlib::NO_FLUSH
|
3971
|
-
* Zlib::SYNC_FLUSH
|
3972
|
-
* Zlib::FULL_FLUSH
|
3973
|
-
* Zlib::FINISH
|
3974
|
-
* The integers to control the output of the deflate stream, which are
|
3975
|
-
* an argument for Zlib::Deflate#deflate and so on.
|
3976
|
-
*
|
3977
|
-
* Zlib::OS_CODE
|
3978
|
-
* Zlib::OS_MSDOS
|
3979
|
-
* Zlib::OS_AMIGA
|
3980
|
-
* Zlib::OS_VMS
|
3981
|
-
* Zlib::OS_UNIX
|
3982
|
-
* Zlib::OS_VMCMS
|
3983
|
-
* Zlib::OS_ATARI
|
3984
|
-
* Zlib::OS_OS2
|
3985
|
-
* Zlib::OS_MACOS
|
3986
|
-
* Zlib::OS_ZSYSTEM
|
3987
|
-
* Zlib::OS_CPM
|
3988
|
-
* Zlib::OS_TOPS20
|
3989
|
-
* Zlib::OS_WIN32
|
3990
|
-
* Zlib::OS_QDOS
|
3991
|
-
* Zlib::OS_RISCOS
|
3992
|
-
* Zlib::OS_UNKNOWN
|
3993
|
-
* The return values of Zlib::GzipFile#os_code method.
|
3994
|
-
*/
|
3995
4174
|
void
|
3996
4175
|
Init_zlib()
|
3997
4176
|
{
|
@@ -4002,6 +4181,8 @@ Init_zlib()
|
|
4002
4181
|
|
4003
4182
|
mZlib = rb_define_module("Zlib");
|
4004
4183
|
|
4184
|
+
id_dictionaries = rb_intern("@dictionaries");
|
4185
|
+
|
4005
4186
|
cZError = rb_define_class_under(mZlib, "Error", rb_eStandardError);
|
4006
4187
|
cStreamEnd = rb_define_class_under(mZlib, "StreamEnd", cZError);
|
4007
4188
|
cNeedDict = rb_define_class_under(mZlib, "NeedDict", cZError);
|
@@ -4043,14 +4224,29 @@ Init_zlib()
|
|
4043
4224
|
rb_define_method(cZStream, "flush_next_in", rb_zstream_flush_next_in, 0);
|
4044
4225
|
rb_define_method(cZStream, "flush_next_out", rb_zstream_flush_next_out, 0);
|
4045
4226
|
|
4046
|
-
/*
|
4047
|
-
*
|
4227
|
+
/* Represents binary data as guessed by deflate.
|
4228
|
+
*
|
4229
|
+
* See Zlib::Deflate#data_type. */
|
4048
4230
|
rb_define_const(mZlib, "BINARY", INT2FIX(Z_BINARY));
|
4049
|
-
|
4050
|
-
|
4231
|
+
|
4232
|
+
/* Represents text data as guessed by deflate.
|
4233
|
+
*
|
4234
|
+
* NOTE: The underlying constant Z_ASCII was deprecated in favor of Z_TEXT
|
4235
|
+
* in zlib 1.2.2. New applications should not use this constant.
|
4236
|
+
*
|
4237
|
+
* See Zlib::Deflate#data_type. */
|
4051
4238
|
rb_define_const(mZlib, "ASCII", INT2FIX(Z_ASCII));
|
4052
|
-
|
4053
|
-
|
4239
|
+
|
4240
|
+
#ifdef Z_TEXT
|
4241
|
+
/* Represents text data as guessed by deflate.
|
4242
|
+
*
|
4243
|
+
* See Zlib::Deflate#data_type. */
|
4244
|
+
rb_define_const(mZlib, "TEXT", INT2FIX(Z_TEXT));
|
4245
|
+
#endif
|
4246
|
+
|
4247
|
+
/* Represents an unknown data type as guessed by deflate.
|
4248
|
+
*
|
4249
|
+
* See Zlib::Deflate#data_type. */
|
4054
4250
|
rb_define_const(mZlib, "UNKNOWN", INT2FIX(Z_UNKNOWN));
|
4055
4251
|
|
4056
4252
|
cDeflate = rb_define_class_under(mZlib, "Deflate", cZStream);
|
@@ -4070,77 +4266,91 @@ Init_zlib()
|
|
4070
4266
|
rb_define_singleton_method(mZlib, "inflate", rb_inflate_s_inflate, 1);
|
4071
4267
|
rb_define_alloc_func(cInflate, rb_inflate_s_allocate);
|
4072
4268
|
rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1);
|
4269
|
+
rb_define_method(cInflate, "add_dictionary", rb_inflate_add_dictionary, 1);
|
4073
4270
|
rb_define_method(cInflate, "inflate", rb_inflate_inflate, 1);
|
4074
4271
|
rb_define_method(cInflate, "<<", rb_inflate_addstr, 1);
|
4075
4272
|
rb_define_method(cInflate, "sync", rb_inflate_sync, 1);
|
4076
4273
|
rb_define_method(cInflate, "sync_point?", rb_inflate_sync_point_p, 0);
|
4077
4274
|
rb_define_method(cInflate, "set_dictionary", rb_inflate_set_dictionary, 1);
|
4078
4275
|
|
4079
|
-
/* compression
|
4080
|
-
*
|
4081
|
-
|
4276
|
+
/* No compression, passes through data untouched. Use this for appending
|
4277
|
+
* pre-compressed data to a deflate stream.
|
4278
|
+
*/
|
4082
4279
|
rb_define_const(mZlib, "NO_COMPRESSION", INT2FIX(Z_NO_COMPRESSION));
|
4083
|
-
/* compression level
|
4084
|
-
*
|
4085
|
-
* Which is an argument for Deflate.new, Deflate#deflate, and so on. */
|
4280
|
+
/* Fastest compression level, but with with lowest space savings. */
|
4086
4281
|
rb_define_const(mZlib, "BEST_SPEED", INT2FIX(Z_BEST_SPEED));
|
4087
|
-
/* compression level
|
4088
|
-
*
|
4089
|
-
* Which is an argument for Deflate.new, Deflate#deflate, and so on. */
|
4282
|
+
/* Slowest compression level, but with the best space savings. */
|
4090
4283
|
rb_define_const(mZlib, "BEST_COMPRESSION", INT2FIX(Z_BEST_COMPRESSION));
|
4091
|
-
/* compression level -
|
4092
|
-
*
|
4093
|
-
|
4284
|
+
/* Default compression level which is a good trade-off between space and
|
4285
|
+
* time
|
4286
|
+
*/
|
4094
4287
|
rb_define_const(mZlib, "DEFAULT_COMPRESSION",
|
4095
|
-
|
4096
|
-
|
4097
|
-
/*
|
4098
|
-
*
|
4099
|
-
*
|
4288
|
+
INT2FIX(Z_DEFAULT_COMPRESSION));
|
4289
|
+
|
4290
|
+
/* Deflate strategy for data produced by a filter (or predictor). The
|
4291
|
+
* effect of FILTERED is to force more Huffman codes and less string
|
4292
|
+
* matching; it is somewhat intermediate between DEFAULT_STRATEGY and
|
4293
|
+
* HUFFMAN_ONLY. Filtered data consists mostly of small values with a
|
4294
|
+
* somewhat random distribution.
|
4295
|
+
*/
|
4100
4296
|
rb_define_const(mZlib, "FILTERED", INT2FIX(Z_FILTERED));
|
4101
|
-
|
4102
|
-
|
4103
|
-
* Which is an argument for Deflate.new and Deflate#params. */
|
4297
|
+
|
4298
|
+
/* Deflate strategy which uses Huffman codes only (no string matching). */
|
4104
4299
|
rb_define_const(mZlib, "HUFFMAN_ONLY", INT2FIX(Z_HUFFMAN_ONLY));
|
4105
|
-
|
4106
|
-
|
4107
|
-
|
4300
|
+
|
4301
|
+
#ifdef Z_RLE
|
4302
|
+
/* Deflate compression strategy designed to be almost as fast as
|
4303
|
+
* HUFFMAN_ONLY, but give better compression for PNG image data.
|
4304
|
+
*/
|
4305
|
+
rb_define_const(mZlib, "RLE", INT2FIX(Z_RLE));
|
4306
|
+
#endif
|
4307
|
+
|
4308
|
+
#ifdef Z_FIXED
|
4309
|
+
/* Deflate strategy which prevents the use of dynamic Huffman codes,
|
4310
|
+
* allowing for a simpler decoder for specialized applications.
|
4311
|
+
*/
|
4312
|
+
rb_define_const(mZlib, "FIXED", INT2FIX(Z_FIXED));
|
4313
|
+
#endif
|
4314
|
+
|
4315
|
+
/* Default deflate strategy which is used for normal data. */
|
4108
4316
|
rb_define_const(mZlib, "DEFAULT_STRATEGY", INT2FIX(Z_DEFAULT_STRATEGY));
|
4109
4317
|
|
4110
|
-
|
4111
|
-
|
4112
|
-
|
4318
|
+
/* The maximum size of the zlib history buffer. Note that zlib allows
|
4319
|
+
* larger values to enable different inflate modes. See Zlib::Inflate.new
|
4320
|
+
* for details.
|
4321
|
+
*/
|
4113
4322
|
rb_define_const(mZlib, "MAX_WBITS", INT2FIX(MAX_WBITS));
|
4114
|
-
|
4115
|
-
|
4116
|
-
|
4117
|
-
* Which are an argument for Deflate.new, Deflate#params, and so on. */
|
4323
|
+
|
4324
|
+
/* The default memory level for allocating zlib deflate compression state.
|
4325
|
+
*/
|
4118
4326
|
rb_define_const(mZlib, "DEF_MEM_LEVEL", INT2FIX(DEF_MEM_LEVEL));
|
4119
|
-
|
4120
|
-
|
4121
|
-
|
4122
|
-
* Deflate.new, Deflate#params, and so on. */
|
4327
|
+
|
4328
|
+
/* The maximum memory level for allocating zlib deflate compression state.
|
4329
|
+
*/
|
4123
4330
|
rb_define_const(mZlib, "MAX_MEM_LEVEL", INT2FIX(MAX_MEM_LEVEL));
|
4124
4331
|
|
4125
|
-
/*
|
4126
|
-
*
|
4127
|
-
*
|
4128
|
-
|
4332
|
+
/* NO_FLUSH is the default flush method and allows deflate to decide how
|
4333
|
+
* much data to accumulate before producing output in order to maximize
|
4334
|
+
* compression.
|
4335
|
+
*/
|
4129
4336
|
rb_define_const(mZlib, "NO_FLUSH", INT2FIX(Z_NO_FLUSH));
|
4130
|
-
|
4131
|
-
|
4132
|
-
*
|
4133
|
-
*
|
4337
|
+
|
4338
|
+
/* The SYNC_FLUSH method flushes all pending output to the output buffer
|
4339
|
+
* and the output is aligned on a byte boundary. Flushing may degrade
|
4340
|
+
* compression so it should be used only when necessary, such as at a
|
4341
|
+
* request or response boundary for a network stream.
|
4342
|
+
*/
|
4134
4343
|
rb_define_const(mZlib, "SYNC_FLUSH", INT2FIX(Z_SYNC_FLUSH));
|
4135
|
-
|
4136
|
-
|
4137
|
-
*
|
4138
|
-
*
|
4344
|
+
|
4345
|
+
/* Flushes all output as with SYNC_FLUSH, and the compression state is
|
4346
|
+
* reset so that decompression can restart from this point if previous
|
4347
|
+
* compressed data has been damaged or if random access is desired. Like
|
4348
|
+
* SYNC_FLUSH, using FULL_FLUSH too often can seriously degrade
|
4349
|
+
* compression.
|
4350
|
+
*/
|
4139
4351
|
rb_define_const(mZlib, "FULL_FLUSH", INT2FIX(Z_FULL_FLUSH));
|
4140
|
-
|
4141
|
-
|
4142
|
-
* The integers to control the output of the deflate stream, which are
|
4143
|
-
* an argument for Deflate#deflate and so on. */
|
4352
|
+
|
4353
|
+
/* Processes all pending input and flushes pending output. */
|
4144
4354
|
rb_define_const(mZlib, "FINISH", INT2FIX(Z_FINISH));
|
4145
4355
|
|
4146
4356
|
#if GZIP_SUPPORT
|
@@ -4218,48 +4428,47 @@ Init_zlib()
|
|
4218
4428
|
rb_define_method(cGzipReader, "readbyte", rb_gzreader_readbyte, 0);
|
4219
4429
|
rb_define_method(cGzipReader, "each_byte", rb_gzreader_each_byte, 0);
|
4220
4430
|
rb_define_method(cGzipReader, "each_char", rb_gzreader_each_char, 0);
|
4221
|
-
rb_define_method(cGzipReader, "bytes",
|
4431
|
+
rb_define_method(cGzipReader, "bytes", rb_gzreader_bytes, 0);
|
4222
4432
|
rb_define_method(cGzipReader, "ungetc", rb_gzreader_ungetc, 1);
|
4223
4433
|
rb_define_method(cGzipReader, "ungetbyte", rb_gzreader_ungetbyte, 1);
|
4224
4434
|
rb_define_method(cGzipReader, "gets", rb_gzreader_gets, -1);
|
4225
4435
|
rb_define_method(cGzipReader, "readline", rb_gzreader_readline, -1);
|
4226
4436
|
rb_define_method(cGzipReader, "each", rb_gzreader_each, -1);
|
4227
4437
|
rb_define_method(cGzipReader, "each_line", rb_gzreader_each, -1);
|
4228
|
-
rb_define_method(cGzipReader, "lines",
|
4438
|
+
rb_define_method(cGzipReader, "lines", rb_gzreader_lines, -1);
|
4229
4439
|
rb_define_method(cGzipReader, "readlines", rb_gzreader_readlines, -1);
|
4230
4440
|
|
4231
|
-
/*
|
4441
|
+
/* The OS code of current host */
|
4232
4442
|
rb_define_const(mZlib, "OS_CODE", INT2FIX(OS_CODE));
|
4233
|
-
/*
|
4443
|
+
/* OS code for MSDOS hosts */
|
4234
4444
|
rb_define_const(mZlib, "OS_MSDOS", INT2FIX(OS_MSDOS));
|
4235
|
-
/*
|
4445
|
+
/* OS code for Amiga hosts */
|
4236
4446
|
rb_define_const(mZlib, "OS_AMIGA", INT2FIX(OS_AMIGA));
|
4237
|
-
/*
|
4447
|
+
/* OS code for VMS hosts */
|
4238
4448
|
rb_define_const(mZlib, "OS_VMS", INT2FIX(OS_VMS));
|
4239
|
-
/*
|
4449
|
+
/* OS code for UNIX hosts */
|
4240
4450
|
rb_define_const(mZlib, "OS_UNIX", INT2FIX(OS_UNIX));
|
4241
|
-
/*
|
4451
|
+
/* OS code for Atari hosts */
|
4242
4452
|
rb_define_const(mZlib, "OS_ATARI", INT2FIX(OS_ATARI));
|
4243
|
-
/*
|
4453
|
+
/* OS code for OS2 hosts */
|
4244
4454
|
rb_define_const(mZlib, "OS_OS2", INT2FIX(OS_OS2));
|
4245
|
-
/*
|
4455
|
+
/* OS code for Mac OS hosts */
|
4246
4456
|
rb_define_const(mZlib, "OS_MACOS", INT2FIX(OS_MACOS));
|
4247
|
-
/*
|
4457
|
+
/* OS code for TOPS-20 hosts */
|
4248
4458
|
rb_define_const(mZlib, "OS_TOPS20", INT2FIX(OS_TOPS20));
|
4249
|
-
/*
|
4459
|
+
/* OS code for Win32 hosts */
|
4250
4460
|
rb_define_const(mZlib, "OS_WIN32", INT2FIX(OS_WIN32));
|
4251
|
-
|
4252
|
-
/* From GzipFile#os_code - 0x04 */
|
4461
|
+
/* OS code for VM OS hosts */
|
4253
4462
|
rb_define_const(mZlib, "OS_VMCMS", INT2FIX(OS_VMCMS));
|
4254
|
-
/*
|
4463
|
+
/* OS code for Z-System hosts */
|
4255
4464
|
rb_define_const(mZlib, "OS_ZSYSTEM", INT2FIX(OS_ZSYSTEM));
|
4256
|
-
/*
|
4465
|
+
/* OS code for CP/M hosts */
|
4257
4466
|
rb_define_const(mZlib, "OS_CPM", INT2FIX(OS_CPM));
|
4258
|
-
/*
|
4467
|
+
/* OS code for QDOS hosts */
|
4259
4468
|
rb_define_const(mZlib, "OS_QDOS", INT2FIX(OS_QDOS));
|
4260
|
-
/*
|
4469
|
+
/* OS code for RISC OS hosts */
|
4261
4470
|
rb_define_const(mZlib, "OS_RISCOS", INT2FIX(OS_RISCOS));
|
4262
|
-
/*
|
4471
|
+
/* OS code for unknown hosts */
|
4263
4472
|
rb_define_const(mZlib, "OS_UNKNOWN", INT2FIX(OS_UNKNOWN));
|
4264
4473
|
|
4265
4474
|
#endif /* GZIP_SUPPORT */
|