PageRenderTime 109ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/ext/zlib/zlib.c

https://github.com/wanabe/ruby
C | 5027 lines | 3125 code | 550 blank | 1352 comment | 462 complexity | e1a45e150b172a14dc9b2912e1df3ab7 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0, 0BSD, Unlicense, GPL-2.0, BSD-3-Clause
  1. /*
  2. * zlib.c - An interface for zlib.
  3. *
  4. * Copyright (C) UENO Katsuhiro 2000-2003
  5. *
  6. * $Id$
  7. */
  8. #include <ruby.h>
  9. #include <zlib.h>
  10. #include <time.h>
  11. #include <ruby/io.h>
  12. #include <ruby/thread.h>
  13. #ifdef HAVE_VALGRIND_MEMCHECK_H
  14. # include <valgrind/memcheck.h>
  15. # ifndef VALGRIND_MAKE_MEM_DEFINED
  16. # define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE((p), (n))
  17. # endif
  18. # ifndef VALGRIND_MAKE_MEM_UNDEFINED
  19. # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
  20. # endif
  21. #else
  22. # define VALGRIND_MAKE_MEM_DEFINED(p, n) 0
  23. # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
  24. #endif
  25. #define RUBY_ZLIB_VERSION "1.1.0"
  26. #ifndef RB_PASS_CALLED_KEYWORDS
  27. # define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
  28. #endif
  29. #ifndef GZIP_SUPPORT
  30. #define GZIP_SUPPORT 1
  31. #endif
  32. /* from zutil.h */
  33. #ifndef DEF_MEM_LEVEL
  34. #if MAX_MEM_LEVEL >= 8
  35. #define DEF_MEM_LEVEL 8
  36. #else
  37. #define DEF_MEM_LEVEL MAX_MEM_LEVEL
  38. #endif
  39. #endif
  40. #if SIZEOF_LONG > SIZEOF_INT
  41. static inline uInt
  42. max_uint(long n)
  43. {
  44. if (n > UINT_MAX) n = UINT_MAX;
  45. return (uInt)n;
  46. }
  47. #define MAX_UINT(n) max_uint(n)
  48. #else
  49. #define MAX_UINT(n) (uInt)(n)
  50. #endif
  51. #define OPTHASH_GIVEN_P(opts) \
  52. (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
  53. static ID id_dictionaries, id_read, id_buffer;
  54. /*--------- Prototypes --------*/
  55. static NORETURN(void raise_zlib_error(int, const char*));
  56. static VALUE rb_zlib_version(VALUE);
  57. static VALUE do_checksum(int, VALUE*, uLong (*)(uLong, const Bytef*, uInt));
  58. static VALUE rb_zlib_adler32(int, VALUE*, VALUE);
  59. static VALUE rb_zlib_crc32(int, VALUE*, VALUE);
  60. static VALUE rb_zlib_crc_table(VALUE);
  61. static voidpf zlib_mem_alloc(voidpf, uInt, uInt);
  62. static void zlib_mem_free(voidpf, voidpf);
  63. static void finalizer_warn(const char*);
  64. struct zstream;
  65. struct zstream_funcs;
  66. struct zstream_run_args;
  67. static void zstream_init(struct zstream*, const struct zstream_funcs*);
  68. static void zstream_expand_buffer(struct zstream*);
  69. static void zstream_expand_buffer_into(struct zstream*, unsigned long);
  70. static int zstream_expand_buffer_non_stream(struct zstream *z);
  71. static void zstream_append_buffer(struct zstream*, const Bytef*, long);
  72. static VALUE zstream_detach_buffer(struct zstream*);
  73. static VALUE zstream_shift_buffer(struct zstream*, long);
  74. static void zstream_buffer_ungets(struct zstream*, const Bytef*, unsigned long);
  75. static void zstream_buffer_ungetbyte(struct zstream*, int);
  76. static void zstream_append_input(struct zstream*, const Bytef*, long);
  77. static void zstream_discard_input(struct zstream*, long);
  78. static void zstream_reset_input(struct zstream*);
  79. static void zstream_passthrough_input(struct zstream*);
  80. static VALUE zstream_detach_input(struct zstream*);
  81. static void zstream_reset(struct zstream*);
  82. static VALUE zstream_end(struct zstream*);
  83. static VALUE zstream_ensure_end(VALUE v);
  84. static void zstream_run(struct zstream*, Bytef*, long, int);
  85. static VALUE zstream_sync(struct zstream*, Bytef*, long);
  86. static void zstream_mark(void*);
  87. static void zstream_free(void*);
  88. static VALUE zstream_new(VALUE, const struct zstream_funcs*);
  89. static struct zstream *get_zstream(VALUE);
  90. static void zstream_finalize(struct zstream*);
  91. static VALUE rb_zstream_end(VALUE);
  92. static VALUE rb_zstream_reset(VALUE);
  93. static VALUE rb_zstream_finish(VALUE);
  94. static VALUE rb_zstream_flush_next_in(VALUE);
  95. static VALUE rb_zstream_flush_next_out(VALUE);
  96. static VALUE rb_zstream_avail_out(VALUE);
  97. static VALUE rb_zstream_set_avail_out(VALUE, VALUE);
  98. static VALUE rb_zstream_avail_in(VALUE);
  99. static VALUE rb_zstream_total_in(VALUE);
  100. static VALUE rb_zstream_total_out(VALUE);
  101. static VALUE rb_zstream_data_type(VALUE);
  102. static VALUE rb_zstream_adler(VALUE);
  103. static VALUE rb_zstream_finished_p(VALUE);
  104. static VALUE rb_zstream_closed_p(VALUE);
  105. static VALUE rb_deflate_s_allocate(VALUE);
  106. static VALUE rb_deflate_initialize(int, VALUE*, VALUE);
  107. static VALUE rb_deflate_init_copy(VALUE, VALUE);
  108. static VALUE deflate_run(VALUE);
  109. static VALUE rb_deflate_s_deflate(int, VALUE*, VALUE);
  110. static void do_deflate(struct zstream*, VALUE, int);
  111. static VALUE rb_deflate_deflate(int, VALUE*, VALUE);
  112. static VALUE rb_deflate_addstr(VALUE, VALUE);
  113. static VALUE rb_deflate_flush(int, VALUE*, VALUE);
  114. static VALUE rb_deflate_params(VALUE, VALUE, VALUE);
  115. static VALUE rb_deflate_set_dictionary(VALUE, VALUE);
  116. static VALUE inflate_run(VALUE);
  117. static VALUE rb_inflate_s_allocate(VALUE);
  118. static VALUE rb_inflate_initialize(int, VALUE*, VALUE);
  119. static VALUE rb_inflate_s_inflate(VALUE, VALUE);
  120. static void do_inflate(struct zstream*, VALUE);
  121. static VALUE rb_inflate_inflate(int, VALUE*, VALUE);
  122. static VALUE rb_inflate_addstr(VALUE, VALUE);
  123. static VALUE rb_inflate_sync(VALUE, VALUE);
  124. static VALUE rb_inflate_sync_point_p(VALUE);
  125. static VALUE rb_inflate_set_dictionary(VALUE, VALUE);
  126. #if GZIP_SUPPORT
  127. struct gzfile;
  128. static void gzfile_mark(void*);
  129. static void gzfile_free(void*);
  130. static VALUE gzfile_new(VALUE, const struct zstream_funcs*, void (*) _((struct gzfile*)));
  131. static void gzfile_reset(struct gzfile*);
  132. static void gzfile_close(struct gzfile*, int);
  133. static void gzfile_write_raw(struct gzfile*);
  134. static VALUE gzfile_read_raw_partial(VALUE);
  135. static VALUE gzfile_read_raw_rescue(VALUE,VALUE);
  136. static VALUE gzfile_read_raw(struct gzfile*, VALUE outbuf);
  137. static int gzfile_read_raw_ensure(struct gzfile*, long, VALUE outbuf);
  138. static char *gzfile_read_raw_until_zero(struct gzfile*, long);
  139. static unsigned int gzfile_get16(const unsigned char*);
  140. static unsigned long gzfile_get32(const unsigned char*);
  141. static void gzfile_set32(unsigned long n, unsigned char*);
  142. static void gzfile_make_header(struct gzfile*);
  143. static void gzfile_make_footer(struct gzfile*);
  144. static void gzfile_read_header(struct gzfile*, VALUE outbuf);
  145. static void gzfile_check_footer(struct gzfile*, VALUE outbuf);
  146. static void gzfile_write(struct gzfile*, Bytef*, long);
  147. static long gzfile_read_more(struct gzfile*, VALUE outbuf);
  148. static void gzfile_calc_crc(struct gzfile*, VALUE);
  149. static VALUE gzfile_read(struct gzfile*, long);
  150. static VALUE gzfile_read_all(struct gzfile*);
  151. static void gzfile_ungets(struct gzfile*, const Bytef*, long);
  152. static void gzfile_ungetbyte(struct gzfile*, int);
  153. static VALUE gzfile_writer_end_run(VALUE);
  154. static void gzfile_writer_end(struct gzfile*);
  155. static VALUE gzfile_reader_end_run(VALUE);
  156. static void gzfile_reader_end(struct gzfile*);
  157. static void gzfile_reader_rewind(struct gzfile*);
  158. static VALUE gzfile_reader_get_unused(struct gzfile*);
  159. static struct gzfile *get_gzfile(VALUE);
  160. static VALUE gzfile_ensure_close(VALUE);
  161. static VALUE rb_gzfile_s_wrap(int, VALUE*, VALUE);
  162. static VALUE gzfile_s_open(int, VALUE*, VALUE, const char*);
  163. NORETURN(static void gzfile_raise(struct gzfile *, VALUE, const char *));
  164. static VALUE gzfile_error_inspect(VALUE);
  165. static VALUE rb_gzfile_to_io(VALUE);
  166. static VALUE rb_gzfile_crc(VALUE);
  167. static VALUE rb_gzfile_mtime(VALUE);
  168. static VALUE rb_gzfile_level(VALUE);
  169. static VALUE rb_gzfile_os_code(VALUE);
  170. static VALUE rb_gzfile_orig_name(VALUE);
  171. static VALUE rb_gzfile_comment(VALUE);
  172. static VALUE rb_gzfile_lineno(VALUE);
  173. static VALUE rb_gzfile_set_lineno(VALUE, VALUE);
  174. static VALUE rb_gzfile_set_mtime(VALUE, VALUE);
  175. static VALUE rb_gzfile_set_orig_name(VALUE, VALUE);
  176. static VALUE rb_gzfile_set_comment(VALUE, VALUE);
  177. static VALUE rb_gzfile_close(VALUE);
  178. static VALUE rb_gzfile_finish(VALUE);
  179. static VALUE rb_gzfile_closed_p(VALUE);
  180. static VALUE rb_gzfile_eof_p(VALUE);
  181. static VALUE rb_gzfile_sync(VALUE);
  182. static VALUE rb_gzfile_set_sync(VALUE, VALUE);
  183. static VALUE rb_gzfile_total_in(VALUE);
  184. static VALUE rb_gzfile_total_out(VALUE);
  185. static VALUE rb_gzfile_path(VALUE);
  186. static VALUE rb_gzwriter_s_allocate(VALUE);
  187. static VALUE rb_gzwriter_s_open(int, VALUE*, VALUE);
  188. static VALUE rb_gzwriter_initialize(int, VALUE*, VALUE);
  189. static VALUE rb_gzwriter_flush(int, VALUE*, VALUE);
  190. static VALUE rb_gzwriter_write(int, VALUE*, VALUE);
  191. static VALUE rb_gzwriter_putc(VALUE, VALUE);
  192. static VALUE rb_gzreader_s_allocate(VALUE);
  193. static VALUE rb_gzreader_s_open(int, VALUE*, VALUE);
  194. static VALUE rb_gzreader_initialize(int, VALUE*, VALUE);
  195. static VALUE rb_gzreader_rewind(VALUE);
  196. static VALUE rb_gzreader_unused(VALUE);
  197. static VALUE rb_gzreader_read(int, VALUE*, VALUE);
  198. static VALUE rb_gzreader_getc(VALUE);
  199. static VALUE rb_gzreader_readchar(VALUE);
  200. static VALUE rb_gzreader_each_byte(VALUE);
  201. static VALUE rb_gzreader_ungetc(VALUE, VALUE);
  202. static VALUE rb_gzreader_ungetbyte(VALUE, VALUE);
  203. static void gzreader_skip_linebreaks(struct gzfile*);
  204. static VALUE gzreader_gets(int, VALUE*, VALUE);
  205. static VALUE rb_gzreader_gets(int, VALUE*, VALUE);
  206. static VALUE rb_gzreader_readline(int, VALUE*, VALUE);
  207. static VALUE rb_gzreader_each(int, VALUE*, VALUE);
  208. static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
  209. #endif /* GZIP_SUPPORT */
  210. /*
  211. * Document-module: Zlib
  212. *
  213. * This module provides access to the {zlib library}[http://zlib.net]. Zlib is
  214. * designed to be a portable, free, general-purpose, legally unencumbered --
  215. * that is, not covered by any patents -- lossless data-compression library
  216. * for use on virtually any computer hardware and operating system.
  217. *
  218. * The zlib compression library provides in-memory compression and
  219. * decompression functions, including integrity checks of the uncompressed
  220. * data.
  221. *
  222. * The zlib compressed data format is described in RFC 1950, which is a
  223. * wrapper around a deflate stream which is described in RFC 1951.
  224. *
  225. * The library also supports reading and writing files in gzip (.gz) format
  226. * with an interface similar to that of IO. The gzip format is described in
  227. * RFC 1952 which is also a wrapper around a deflate stream.
  228. *
  229. * The zlib format was designed to be compact and fast for use in memory and on
  230. * communications channels. The gzip format was designed for single-file
  231. * compression on file systems, has a larger header than zlib to maintain
  232. * directory information, and uses a different, slower check method than zlib.
  233. *
  234. * See your system's zlib.h for further information about zlib
  235. *
  236. * == Sample usage
  237. *
  238. * Using the wrapper to compress strings with default parameters is quite
  239. * simple:
  240. *
  241. * require "zlib"
  242. *
  243. * data_to_compress = File.read("don_quixote.txt")
  244. *
  245. * puts "Input size: #{data_to_compress.size}"
  246. * #=> Input size: 2347740
  247. *
  248. * data_compressed = Zlib::Deflate.deflate(data_to_compress)
  249. *
  250. * puts "Compressed size: #{data_compressed.size}"
  251. * #=> Compressed size: 887238
  252. *
  253. * uncompressed_data = Zlib::Inflate.inflate(data_compressed)
  254. *
  255. * puts "Uncompressed data is: #{uncompressed_data}"
  256. * #=> Uncompressed data is: The Project Gutenberg EBook of Don Quixote...
  257. *
  258. * == Class tree
  259. *
  260. * - Zlib::Deflate
  261. * - Zlib::Inflate
  262. * - Zlib::ZStream
  263. * - Zlib::Error
  264. * - Zlib::StreamEnd
  265. * - Zlib::NeedDict
  266. * - Zlib::DataError
  267. * - Zlib::StreamError
  268. * - Zlib::MemError
  269. * - Zlib::BufError
  270. * - Zlib::VersionError
  271. *
  272. * (if you have GZIP_SUPPORT)
  273. * - Zlib::GzipReader
  274. * - Zlib::GzipWriter
  275. * - Zlib::GzipFile
  276. * - Zlib::GzipFile::Error
  277. * - Zlib::GzipFile::LengthError
  278. * - Zlib::GzipFile::CRCError
  279. * - Zlib::GzipFile::NoFooter
  280. *
  281. */
  282. void Init_zlib(void);
  283. /*--------- Exceptions --------*/
  284. static VALUE cZError, cStreamEnd, cNeedDict;
  285. static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError;
  286. static void
  287. raise_zlib_error(int err, const char *msg)
  288. {
  289. VALUE exc;
  290. if (!msg) {
  291. msg = zError(err);
  292. }
  293. switch(err) {
  294. case Z_STREAM_END:
  295. exc = rb_exc_new2(cStreamEnd, msg);
  296. break;
  297. case Z_NEED_DICT:
  298. exc = rb_exc_new2(cNeedDict, msg);
  299. break;
  300. case Z_STREAM_ERROR:
  301. exc = rb_exc_new2(cStreamError, msg);
  302. break;
  303. case Z_DATA_ERROR:
  304. exc = rb_exc_new2(cDataError, msg);
  305. break;
  306. case Z_BUF_ERROR:
  307. exc = rb_exc_new2(cBufError, msg);
  308. break;
  309. case Z_VERSION_ERROR:
  310. exc = rb_exc_new2(cVersionError, msg);
  311. break;
  312. case Z_MEM_ERROR:
  313. exc = rb_exc_new2(cMemError, msg);
  314. break;
  315. case Z_ERRNO:
  316. rb_sys_fail(msg);
  317. /* no return */
  318. default:
  319. exc = rb_exc_new_str(cZError,
  320. rb_sprintf("unknown zlib error %d: %s", err, msg));
  321. }
  322. rb_exc_raise(exc);
  323. }
  324. /*--- Warning (in finalizer) ---*/
  325. static void
  326. finalizer_warn(const char *msg)
  327. {
  328. #if 0
  329. fprintf(stderr, "zlib(finalizer): %s\n", msg);
  330. #endif
  331. }
  332. /*-------- module Zlib --------*/
  333. /*
  334. * Document-method: Zlib.zlib_version
  335. *
  336. * Returns the string which represents the version of zlib library.
  337. */
  338. static VALUE
  339. rb_zlib_version(VALUE klass)
  340. {
  341. return rb_str_new2(zlibVersion());
  342. }
  343. #if SIZEOF_LONG > SIZEOF_INT
  344. static uLong
  345. checksum_long(uLong (*func)(uLong, const Bytef*, uInt), uLong sum, const Bytef *ptr, long len)
  346. {
  347. if (len > UINT_MAX) {
  348. do {
  349. sum = func(sum, ptr, UINT_MAX);
  350. ptr += UINT_MAX;
  351. len -= UINT_MAX;
  352. } while (len >= UINT_MAX);
  353. }
  354. if (len > 0) sum = func(sum, ptr, (uInt)len);
  355. return sum;
  356. }
  357. #else
  358. #define checksum_long(func, sum, ptr, len) (func)((sum), (ptr), (len))
  359. #endif
  360. static VALUE
  361. do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt))
  362. {
  363. VALUE str, vsum;
  364. unsigned long sum;
  365. rb_scan_args(argc, argv, "02", &str, &vsum);
  366. if (!NIL_P(vsum)) {
  367. sum = NUM2ULONG(vsum);
  368. }
  369. else if (NIL_P(str)) {
  370. sum = 0;
  371. }
  372. else {
  373. sum = func(0, Z_NULL, 0);
  374. }
  375. if (NIL_P(str)) {
  376. sum = func(sum, Z_NULL, 0);
  377. }
  378. else if (rb_obj_is_kind_of(str, rb_cIO)) {
  379. VALUE buf;
  380. VALUE buflen = INT2NUM(8192);
  381. while (!NIL_P(buf = rb_funcall(str, id_read, 1, buflen))) {
  382. StringValue(buf);
  383. sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(buf), RSTRING_LEN(buf));
  384. }
  385. }
  386. else {
  387. StringValue(str);
  388. sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
  389. }
  390. return rb_uint2inum(sum);
  391. }
  392. /*
  393. * Document-method: Zlib.adler32
  394. *
  395. * call-seq: Zlib.adler32(string, adler)
  396. *
  397. * Calculates Adler-32 checksum for +string+, and returns updated value of
  398. * +adler+. If +string+ is omitted, it returns the Adler-32 initial value. If
  399. * +adler+ is omitted, it assumes that the initial value is given to +adler+.
  400. * If +string+ is an IO instance, reads from the IO until the IO returns nil
  401. * and returns Adler-32 of all read data.
  402. *
  403. * Example usage:
  404. *
  405. * require "zlib"
  406. *
  407. * data = "foo"
  408. * puts "Adler32 checksum: #{Zlib.adler32(data).to_s(16)}"
  409. * #=> Adler32 checksum: 2820145
  410. *
  411. */
  412. static VALUE
  413. rb_zlib_adler32(int argc, VALUE *argv, VALUE klass)
  414. {
  415. return do_checksum(argc, argv, adler32);
  416. }
  417. #ifdef HAVE_ADLER32_COMBINE
  418. /*
  419. * Document-method: Zlib.adler32_combine
  420. *
  421. * call-seq: Zlib.adler32_combine(adler1, adler2, len2)
  422. *
  423. * Combine two Adler-32 check values in to one. +alder1+ is the first Adler-32
  424. * value, +adler2+ is the second Adler-32 value. +len2+ is the length of the
  425. * string used to generate +adler2+.
  426. *
  427. */
  428. static VALUE
  429. rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
  430. {
  431. return ULONG2NUM(
  432. adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
  433. }
  434. #else
  435. #define rb_zlib_adler32_combine rb_f_notimplement
  436. #endif
  437. /*
  438. * Document-method: Zlib.crc32
  439. *
  440. * call-seq: Zlib.crc32(string, crc)
  441. *
  442. * Calculates CRC checksum for +string+, and returns updated value of +crc+. If
  443. * +string+ is omitted, it returns the CRC initial value. If +crc+ is omitted, it
  444. * assumes that the initial value is given to +crc+. If +string+ is an IO instance,
  445. * reads from the IO until the IO returns nil and returns CRC checksum of all read
  446. * data.
  447. *
  448. * FIXME: expression.
  449. */
  450. static VALUE
  451. rb_zlib_crc32(int argc, VALUE *argv, VALUE klass)
  452. {
  453. return do_checksum(argc, argv, crc32);
  454. }
  455. #ifdef HAVE_CRC32_COMBINE
  456. /*
  457. * Document-method: Zlib.crc32_combine
  458. *
  459. * call-seq: Zlib.crc32_combine(crc1, crc2, len2)
  460. *
  461. * Combine two CRC-32 check values in to one. +crc1+ is the first CRC-32
  462. * value, +crc2+ is the second CRC-32 value. +len2+ is the length of the
  463. * string used to generate +crc2+.
  464. *
  465. */
  466. static VALUE
  467. rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
  468. {
  469. return ULONG2NUM(
  470. crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
  471. }
  472. #else
  473. #define rb_zlib_crc32_combine rb_f_notimplement
  474. #endif
  475. /*
  476. * Document-method: Zlib.crc_table
  477. *
  478. * Returns the table for calculating CRC checksum as an array.
  479. */
  480. static VALUE
  481. rb_zlib_crc_table(VALUE obj)
  482. {
  483. #if !defined(HAVE_TYPE_Z_CRC_T)
  484. /* z_crc_t is defined since zlib-1.2.7. */
  485. typedef unsigned long z_crc_t;
  486. #endif
  487. const z_crc_t *crctbl;
  488. VALUE dst;
  489. int i;
  490. crctbl = get_crc_table();
  491. dst = rb_ary_new2(256);
  492. for (i = 0; i < 256; i++) {
  493. rb_ary_push(dst, rb_uint2inum(crctbl[i]));
  494. }
  495. return dst;
  496. }
  497. /*-------- zstream - internal APIs --------*/
  498. struct zstream {
  499. unsigned long flags;
  500. VALUE buf;
  501. VALUE input;
  502. VALUE mutex;
  503. z_stream stream;
  504. const struct zstream_funcs {
  505. int (*reset)(z_streamp);
  506. int (*end)(z_streamp);
  507. int (*run)(z_streamp, int);
  508. } *func;
  509. };
  510. #define ZSTREAM_FLAG_READY 0x1
  511. #define ZSTREAM_FLAG_IN_STREAM 0x2
  512. #define ZSTREAM_FLAG_FINISHED 0x4
  513. #define ZSTREAM_FLAG_CLOSING 0x8
  514. #define ZSTREAM_FLAG_GZFILE 0x10 /* disallows yield from expand_buffer for
  515. gzip*/
  516. #define ZSTREAM_REUSE_BUFFER 0x20
  517. #define ZSTREAM_FLAG_UNUSED 0x40
  518. #define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
  519. #define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
  520. #define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)
  521. #define ZSTREAM_IS_CLOSING(z) ((z)->flags & ZSTREAM_FLAG_CLOSING)
  522. #define ZSTREAM_IS_GZFILE(z) ((z)->flags & ZSTREAM_FLAG_GZFILE)
  523. #define ZSTREAM_BUF_FILLED(z) (NIL_P((z)->buf) ? 0 : RSTRING_LEN((z)->buf))
  524. #define ZSTREAM_REUSE_BUFFER_P(z) ((z)->flags & ZSTREAM_REUSE_BUFFER)
  525. #define ZSTREAM_EXPAND_BUFFER_OK 0
  526. /* I think that more better value should be found,
  527. but I gave up finding it. B) */
  528. #define ZSTREAM_INITIAL_BUFSIZE 1024
  529. /* Allow a quick return when the thread is interrupted */
  530. #define ZSTREAM_AVAIL_OUT_STEP_MAX 16384
  531. #define ZSTREAM_AVAIL_OUT_STEP_MIN 2048
  532. static const struct zstream_funcs deflate_funcs = {
  533. deflateReset, deflateEnd, deflate,
  534. };
  535. static const struct zstream_funcs inflate_funcs = {
  536. inflateReset, inflateEnd, inflate,
  537. };
  538. struct zstream_run_args {
  539. struct zstream * z;
  540. int flush; /* stream flush value for inflate() or deflate() */
  541. int interrupt; /* stop processing the stream and return to ruby */
  542. int jump_state; /* for buffer expansion block break or exception */
  543. int stream_output; /* for streaming zlib processing */
  544. };
  545. static voidpf
  546. zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
  547. {
  548. voidpf p = xmalloc2(items, size);
  549. /* zlib FAQ: Valgrind (or some similar memory access checker) says that
  550. deflate is performing a conditional jump that depends on an
  551. uninitialized value. Isn't that a bug?
  552. http://www.zlib.net/zlib_faq.html#faq36 */
  553. (void)VALGRIND_MAKE_MEM_DEFINED(p, items * size);
  554. return p;
  555. }
  556. static void
  557. zlib_mem_free(voidpf opaque, voidpf address)
  558. {
  559. xfree(address);
  560. }
  561. static void
  562. zstream_init(struct zstream *z, const struct zstream_funcs *func)
  563. {
  564. z->flags = 0;
  565. z->buf = Qnil;
  566. z->input = Qnil;
  567. z->mutex = rb_mutex_new();
  568. z->stream.zalloc = zlib_mem_alloc;
  569. z->stream.zfree = zlib_mem_free;
  570. z->stream.opaque = Z_NULL;
  571. z->stream.msg = Z_NULL;
  572. z->stream.next_in = Z_NULL;
  573. z->stream.avail_in = 0;
  574. z->stream.next_out = Z_NULL;
  575. z->stream.avail_out = 0;
  576. z->func = func;
  577. }
  578. #define zstream_init_deflate(z) zstream_init((z), &deflate_funcs)
  579. #define zstream_init_inflate(z) zstream_init((z), &inflate_funcs)
  580. static void
  581. zstream_expand_buffer(struct zstream *z)
  582. {
  583. if (NIL_P(z->buf)) {
  584. zstream_expand_buffer_into(z, ZSTREAM_INITIAL_BUFSIZE);
  585. return;
  586. }
  587. if (!ZSTREAM_IS_GZFILE(z) && rb_block_given_p()) {
  588. long buf_filled = ZSTREAM_BUF_FILLED(z);
  589. if (buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
  590. int state = 0;
  591. if (!ZSTREAM_REUSE_BUFFER_P(z)) {
  592. rb_obj_reveal(z->buf, rb_cString);
  593. }
  594. rb_mutex_unlock(z->mutex);
  595. rb_protect(rb_yield, z->buf, &state);
  596. rb_mutex_lock(z->mutex);
  597. if (ZSTREAM_REUSE_BUFFER_P(z)) {
  598. rb_str_modify(z->buf);
  599. rb_str_set_len(z->buf, 0);
  600. }
  601. else {
  602. z->buf = Qnil;
  603. }
  604. zstream_expand_buffer_into(z, ZSTREAM_AVAIL_OUT_STEP_MAX);
  605. if (state)
  606. rb_jump_tag(state);
  607. return;
  608. }
  609. else {
  610. zstream_expand_buffer_into(z,
  611. ZSTREAM_AVAIL_OUT_STEP_MAX - buf_filled);
  612. }
  613. }
  614. else {
  615. zstream_expand_buffer_non_stream(z);
  616. }
  617. }
  618. static void
  619. zstream_expand_buffer_into(struct zstream *z, unsigned long size)
  620. {
  621. if (NIL_P(z->buf)) {
  622. /* I uses rb_str_new here not rb_str_buf_new because
  623. rb_str_buf_new makes a zero-length string. */
  624. z->buf = rb_str_buf_new(size);
  625. z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
  626. z->stream.avail_out = MAX_UINT(size);
  627. rb_obj_hide(z->buf);
  628. }
  629. else if (z->stream.avail_out != size) {
  630. rb_str_modify_expand(z->buf, size);
  631. z->stream.next_out = (Bytef*)RSTRING_END(z->buf);
  632. z->stream.avail_out = MAX_UINT(size);
  633. }
  634. }
  635. static void *
  636. zstream_expand_buffer_protect(void *ptr)
  637. {
  638. struct zstream *z = (struct zstream *)ptr;
  639. int state = 0;
  640. rb_protect((VALUE (*)(VALUE))zstream_expand_buffer, (VALUE)z, &state);
  641. return (void *)(VALUE)state;
  642. }
  643. static int
  644. zstream_expand_buffer_non_stream(struct zstream *z)
  645. {
  646. long inc, len = ZSTREAM_BUF_FILLED(z);
  647. if (rb_str_capacity(z->buf) - len >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
  648. z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
  649. }
  650. else {
  651. inc = len / 2;
  652. if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
  653. inc = ZSTREAM_AVAIL_OUT_STEP_MIN;
  654. }
  655. rb_str_modify_expand(z->buf, inc);
  656. z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
  657. (int)inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
  658. }
  659. z->stream.next_out = (Bytef*)RSTRING_END(z->buf);
  660. return ZSTREAM_EXPAND_BUFFER_OK;
  661. }
  662. static void
  663. zstream_append_buffer(struct zstream *z, const Bytef *src, long len)
  664. {
  665. if (NIL_P(z->buf)) {
  666. z->buf = rb_str_buf_new(len);
  667. rb_str_buf_cat(z->buf, (const char*)src, len);
  668. z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
  669. z->stream.avail_out = 0;
  670. rb_obj_hide(z->buf);
  671. return;
  672. }
  673. if ((long)rb_str_capacity(z->buf) < ZSTREAM_BUF_FILLED(z) + len) {
  674. rb_str_modify_expand(z->buf, len);
  675. z->stream.avail_out = 0;
  676. }
  677. else {
  678. if (z->stream.avail_out >= (uInt)len) {
  679. z->stream.avail_out -= (uInt)len;
  680. }
  681. else {
  682. z->stream.avail_out = 0;
  683. }
  684. }
  685. rb_str_cat(z->buf, (const char *)src, len);
  686. z->stream.next_out = (Bytef*)RSTRING_END(z->buf);
  687. }
  688. #define zstream_append_buffer2(z,v) \
  689. zstream_append_buffer((z),(Bytef*)RSTRING_PTR(v),RSTRING_LEN(v))
  690. static VALUE
  691. zstream_detach_buffer(struct zstream *z)
  692. {
  693. VALUE dst;
  694. if (!ZSTREAM_IS_FINISHED(z) && !ZSTREAM_IS_GZFILE(z) &&
  695. rb_block_given_p()) {
  696. /* prevent tiny yields mid-stream, save for next
  697. * zstream_expand_buffer() or stream end */
  698. return Qnil;
  699. }
  700. if (NIL_P(z->buf)) {
  701. dst = rb_str_new(0, 0);
  702. }
  703. else {
  704. dst = z->buf;
  705. if (!ZSTREAM_REUSE_BUFFER_P(z)) {
  706. rb_obj_reveal(dst, rb_cString);
  707. }
  708. }
  709. z->buf = Qnil;
  710. z->stream.next_out = 0;
  711. z->stream.avail_out = 0;
  712. if (!ZSTREAM_IS_GZFILE(z) && rb_block_given_p()) {
  713. rb_yield(dst);
  714. dst = Qnil;
  715. }
  716. return dst;
  717. }
  718. static VALUE
  719. zstream_shift_buffer(struct zstream *z, long len)
  720. {
  721. VALUE dst;
  722. char *bufptr;
  723. long buflen = ZSTREAM_BUF_FILLED(z);
  724. if (buflen <= len) {
  725. return zstream_detach_buffer(z);
  726. }
  727. bufptr = RSTRING_PTR(z->buf);
  728. dst = rb_str_new(bufptr, len);
  729. buflen -= len;
  730. memmove(bufptr, bufptr + len, buflen);
  731. rb_str_set_len(z->buf, buflen);
  732. z->stream.next_out = (Bytef*)RSTRING_END(z->buf);
  733. buflen = (long)rb_str_capacity(z->buf) - ZSTREAM_BUF_FILLED(z);
  734. if (buflen > ZSTREAM_AVAIL_OUT_STEP_MAX) {
  735. buflen = ZSTREAM_AVAIL_OUT_STEP_MAX;
  736. }
  737. z->stream.avail_out = (uInt)buflen;
  738. return dst;
  739. }
  740. static void
  741. zstream_buffer_ungets(struct zstream *z, const Bytef *b, unsigned long len)
  742. {
  743. char *bufptr;
  744. long filled;
  745. if (NIL_P(z->buf) || (long)rb_str_capacity(z->buf) <= ZSTREAM_BUF_FILLED(z)) {
  746. zstream_expand_buffer_into(z, len);
  747. }
  748. RSTRING_GETMEM(z->buf, bufptr, filled);
  749. memmove(bufptr + len, bufptr, filled);
  750. memmove(bufptr, b, len);
  751. rb_str_set_len(z->buf, filled + len);
  752. if (z->stream.avail_out > 0) {
  753. if (len > z->stream.avail_out) len = z->stream.avail_out;
  754. z->stream.next_out+=len;
  755. z->stream.avail_out-=(uInt)len;
  756. }
  757. }
  758. static void
  759. zstream_buffer_ungetbyte(struct zstream *z, int c)
  760. {
  761. Bytef cc = (Bytef)c;
  762. zstream_buffer_ungets(z, &cc, 1);
  763. }
  764. static void
  765. zstream_append_input(struct zstream *z, const Bytef *src, long len)
  766. {
  767. if (len <= 0) return;
  768. if (NIL_P(z->input)) {
  769. z->input = rb_str_buf_new(len);
  770. rb_str_buf_cat(z->input, (const char*)src, len);
  771. rb_obj_hide(z->input);
  772. }
  773. else {
  774. rb_str_buf_cat(z->input, (const char*)src, len);
  775. }
  776. }
  777. #define zstream_append_input2(z,v)\
  778. RB_GC_GUARD(v),\
  779. zstream_append_input((z), (Bytef*)RSTRING_PTR(v), RSTRING_LEN(v))
  780. static void
  781. zstream_discard_input(struct zstream *z, long len)
  782. {
  783. if (NIL_P(z->input)) {
  784. }
  785. else if (RBASIC_CLASS(z->input) == 0) {
  786. /* hidden, we created z->input and have complete control */
  787. char *ptr;
  788. long oldlen, newlen;
  789. RSTRING_GETMEM(z->input, ptr, oldlen);
  790. newlen = oldlen - len;
  791. if (newlen > 0) {
  792. memmove(ptr, ptr + len, newlen);
  793. }
  794. if (newlen < 0) {
  795. newlen = 0;
  796. }
  797. rb_str_resize(z->input, newlen);
  798. if (newlen == 0) {
  799. rb_gc_force_recycle(z->input);
  800. z->input = Qnil;
  801. }
  802. else {
  803. rb_str_set_len(z->input, newlen);
  804. }
  805. }
  806. else { /* do not mangle user-provided data */
  807. if (RSTRING_LEN(z->input) <= len) {
  808. z->input = Qnil;
  809. }
  810. else {
  811. z->input = rb_str_substr(z->input, len,
  812. RSTRING_LEN(z->input) - len);
  813. }
  814. }
  815. }
  816. static void
  817. zstream_reset_input(struct zstream *z)
  818. {
  819. if (!NIL_P(z->input) && RBASIC_CLASS(z->input) == 0) {
  820. rb_str_resize(z->input, 0);
  821. }
  822. else {
  823. z->input = Qnil;
  824. }
  825. }
  826. static void
  827. zstream_passthrough_input(struct zstream *z)
  828. {
  829. if (!NIL_P(z->input)) {
  830. zstream_append_buffer2(z, z->input);
  831. z->input = Qnil;
  832. }
  833. }
  834. static VALUE
  835. zstream_detach_input(struct zstream *z)
  836. {
  837. VALUE dst;
  838. if (NIL_P(z->input)) {
  839. dst = rb_str_new(0, 0);
  840. }
  841. else {
  842. dst = z->input;
  843. rb_obj_reveal(dst, rb_cString);
  844. }
  845. z->input = Qnil;
  846. return dst;
  847. }
  848. static void
  849. zstream_reset(struct zstream *z)
  850. {
  851. int err;
  852. err = z->func->reset(&z->stream);
  853. if (err != Z_OK) {
  854. raise_zlib_error(err, z->stream.msg);
  855. }
  856. z->flags = ZSTREAM_FLAG_READY;
  857. z->buf = Qnil;
  858. z->stream.next_out = 0;
  859. z->stream.avail_out = 0;
  860. zstream_reset_input(z);
  861. }
  862. static VALUE
  863. zstream_end(struct zstream *z)
  864. {
  865. int err;
  866. if (!ZSTREAM_IS_READY(z)) {
  867. rb_warning("attempt to close uninitialized zstream; ignored.");
  868. return Qnil;
  869. }
  870. if (z->flags & ZSTREAM_FLAG_IN_STREAM) {
  871. rb_warning("attempt to close unfinished zstream; reset forced.");
  872. zstream_reset(z);
  873. }
  874. zstream_reset_input(z);
  875. err = z->func->end(&z->stream);
  876. if (err != Z_OK) {
  877. raise_zlib_error(err, z->stream.msg);
  878. }
  879. z->flags = 0;
  880. return Qnil;
  881. }
  882. static VALUE
  883. zstream_ensure_end(VALUE v)
  884. {
  885. return zstream_end((struct zstream *)v);
  886. }
  887. static void *
  888. zstream_run_func(void *ptr)
  889. {
  890. struct zstream_run_args *args = (struct zstream_run_args *)ptr;
  891. int err, state, flush = args->flush;
  892. struct zstream *z = args->z;
  893. uInt n;
  894. err = Z_OK;
  895. while (!args->interrupt) {
  896. n = z->stream.avail_out;
  897. err = z->func->run(&z->stream, flush);
  898. rb_str_set_len(z->buf, ZSTREAM_BUF_FILLED(z) + (n - z->stream.avail_out));
  899. if (err == Z_STREAM_END) {
  900. z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
  901. z->flags |= ZSTREAM_FLAG_FINISHED;
  902. break;
  903. }
  904. if (err != Z_OK && err != Z_BUF_ERROR)
  905. break;
  906. if (z->stream.avail_out > 0) {
  907. z->flags |= ZSTREAM_FLAG_IN_STREAM;
  908. break;
  909. }
  910. if (z->stream.avail_in == 0 && z->func == &inflate_funcs) {
  911. /* break here because inflate() return Z_BUF_ERROR when avail_in == 0. */
  912. /* but deflate() could be called with avail_in == 0 (there's hidden buffer
  913. in zstream->state) */
  914. z->flags |= ZSTREAM_FLAG_IN_STREAM;
  915. break;
  916. }
  917. if (args->stream_output) {
  918. state = (int)(VALUE)rb_thread_call_with_gvl(zstream_expand_buffer_protect,
  919. (void *)z);
  920. }
  921. else {
  922. state = zstream_expand_buffer_non_stream(z);
  923. }
  924. if (state) {
  925. err = Z_OK; /* buffer expanded but stream processing was stopped */
  926. args->jump_state = state;
  927. break;
  928. }
  929. }
  930. return (void *)(VALUE)err;
  931. }
  932. /*
  933. * There is no safe way to interrupt z->run->func().
  934. * async-signal-safe
  935. */
  936. static void
  937. zstream_unblock_func(void *ptr)
  938. {
  939. struct zstream_run_args *args = (struct zstream_run_args *)ptr;
  940. args->interrupt = 1;
  941. }
  942. static void
  943. zstream_run0(struct zstream *z, Bytef *src, long len, int flush)
  944. {
  945. struct zstream_run_args args;
  946. int err;
  947. VALUE old_input = Qnil;
  948. args.z = z;
  949. args.flush = flush;
  950. args.interrupt = 0;
  951. args.jump_state = 0;
  952. args.stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p();
  953. if (NIL_P(z->input) && len == 0) {
  954. z->stream.next_in = (Bytef*)"";
  955. z->stream.avail_in = 0;
  956. }
  957. else {
  958. zstream_append_input(z, src, len);
  959. /* keep reference to `z->input' so as not to be garbage collected
  960. after zstream_reset_input() and prevent `z->stream.next_in'
  961. from dangling. */
  962. old_input = zstream_detach_input(z);
  963. rb_obj_hide(old_input); /* for GVL release and later recycle */
  964. z->stream.next_in = (Bytef*)RSTRING_PTR(old_input);
  965. z->stream.avail_in = MAX_UINT(RSTRING_LEN(old_input));
  966. }
  967. if (z->stream.avail_out == 0) {
  968. zstream_expand_buffer(z);
  969. }
  970. loop:
  971. #ifndef RB_NOGVL_UBF_ASYNC_SAFE
  972. err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)&args,
  973. zstream_unblock_func, (void *)&args);
  974. #else
  975. err = (int)(VALUE)rb_nogvl(zstream_run_func, (void *)&args,
  976. zstream_unblock_func, (void *)&args,
  977. RB_NOGVL_UBF_ASYNC_SAFE);
  978. #endif
  979. /* retry if no exception is thrown */
  980. if (err == Z_OK && args.interrupt) {
  981. args.interrupt = 0;
  982. goto loop;
  983. }
  984. if (flush != Z_FINISH && err == Z_BUF_ERROR
  985. && z->stream.avail_out > 0) {
  986. z->flags |= ZSTREAM_FLAG_IN_STREAM;
  987. }
  988. zstream_reset_input(z);
  989. if (err != Z_OK && err != Z_STREAM_END) {
  990. if (z->stream.avail_in > 0) {
  991. zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
  992. }
  993. if (err == Z_NEED_DICT) {
  994. VALUE self = (VALUE)z->stream.opaque;
  995. if (self) {
  996. VALUE dicts = rb_ivar_get(self, id_dictionaries);
  997. VALUE dict = rb_hash_aref(dicts, rb_uint2inum(z->stream.adler));
  998. if (!NIL_P(dict)) {
  999. rb_inflate_set_dictionary(self, dict);
  1000. goto loop;
  1001. }
  1002. }
  1003. }
  1004. raise_zlib_error(err, z->stream.msg);
  1005. }
  1006. if (z->stream.avail_in > 0) {
  1007. zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
  1008. }
  1009. if (!NIL_P(old_input)) {
  1010. rb_str_resize(old_input, 0);
  1011. rb_gc_force_recycle(old_input);
  1012. }
  1013. if (args.jump_state)
  1014. rb_jump_tag(args.jump_state);
  1015. }
  1016. struct zstream_run_synchronized_args {
  1017. struct zstream *z;
  1018. Bytef *src;
  1019. long len;
  1020. int flush;
  1021. };
  1022. static VALUE
  1023. zstream_run_synchronized(VALUE value_arg)
  1024. {
  1025. struct zstream_run_synchronized_args *run_args = (struct zstream_run_synchronized_args *)value_arg;
  1026. zstream_run0(run_args->z, run_args->src, run_args->len, run_args->flush);
  1027. return Qnil;
  1028. }
  1029. static void
  1030. zstream_run(struct zstream *z, Bytef *src, long len, int flush)
  1031. {
  1032. struct zstream_run_synchronized_args run_args;
  1033. run_args.z = z;
  1034. run_args.src = src;
  1035. run_args.len = len;
  1036. run_args.flush = flush;
  1037. rb_mutex_synchronize(z->mutex, zstream_run_synchronized, (VALUE)&run_args);
  1038. }
  1039. static VALUE
  1040. zstream_sync(struct zstream *z, Bytef *src, long len)
  1041. {
  1042. /* VALUE rest; */
  1043. int err;
  1044. if (!NIL_P(z->input)) {
  1045. z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
  1046. z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
  1047. err = inflateSync(&z->stream);
  1048. if (err == Z_OK) {
  1049. zstream_discard_input(z,
  1050. RSTRING_LEN(z->input) - z->stream.avail_in);
  1051. zstream_append_input(z, src, len);
  1052. return Qtrue;
  1053. }
  1054. zstream_reset_input(z);
  1055. if (err != Z_DATA_ERROR) {
  1056. /* rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in); */
  1057. raise_zlib_error(err, z->stream.msg);
  1058. }
  1059. }
  1060. if (len <= 0) return Qfalse;
  1061. z->stream.next_in = src;
  1062. z->stream.avail_in = MAX_UINT(len);
  1063. err = inflateSync(&z->stream);
  1064. if (err == Z_OK) {
  1065. zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
  1066. return Qtrue;
  1067. }
  1068. if (err != Z_DATA_ERROR) {
  1069. /* rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in); */
  1070. raise_zlib_error(err, z->stream.msg);
  1071. }
  1072. return Qfalse;
  1073. }
  1074. static void
  1075. zstream_mark(void *p)
  1076. {
  1077. struct zstream *z = p;
  1078. rb_gc_mark(z->buf);
  1079. rb_gc_mark(z->input);
  1080. rb_gc_mark(z->mutex);
  1081. }
  1082. static void
  1083. zstream_finalize(struct zstream *z)
  1084. {
  1085. int err = z->func->end(&z->stream);
  1086. if (err == Z_STREAM_ERROR)
  1087. finalizer_warn("the stream state was inconsistent.");
  1088. if (err == Z_DATA_ERROR)
  1089. finalizer_warn("the stream was freed prematurely.");
  1090. }
  1091. static void
  1092. zstream_free(void *p)
  1093. {
  1094. struct zstream *z = p;
  1095. if (ZSTREAM_IS_READY(z)) {
  1096. zstream_finalize(z);
  1097. }
  1098. xfree(z);
  1099. }
  1100. static size_t
  1101. zstream_memsize(const void *p)
  1102. {
  1103. /* n.b. this does not track memory managed via zalloc/zfree callbacks */
  1104. return sizeof(struct zstream);
  1105. }
  1106. static const rb_data_type_t zstream_data_type = {
  1107. "zstream",
  1108. { zstream_mark, zstream_free, zstream_memsize, },
  1109. 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
  1110. };
  1111. static VALUE
  1112. zstream_new(VALUE klass, const struct zstream_funcs *funcs)
  1113. {
  1114. VALUE obj;
  1115. struct zstream *z;
  1116. obj = TypedData_Make_Struct(klass, struct zstream, &zstream_data_type, z);
  1117. zstream_init(z, funcs);
  1118. z->stream.opaque = (voidpf)obj;
  1119. return obj;
  1120. }
  1121. #define zstream_deflate_new(klass) zstream_new((klass), &deflate_funcs)
  1122. #define zstream_inflate_new(klass) zstream_new((klass), &inflate_funcs)
  1123. static struct zstream *
  1124. get_zstream(VALUE obj)
  1125. {
  1126. struct zstream *z;
  1127. TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
  1128. if (!ZSTREAM_IS_READY(z)) {
  1129. rb_raise(cZError, "stream is not ready");
  1130. }
  1131. return z;
  1132. }
  1133. /* ------------------------------------------------------------------------- */
  1134. /*
  1135. * Document-class: Zlib::ZStream
  1136. *
  1137. * Zlib::ZStream is the abstract class for the stream which handles the
  1138. * compressed data. The operations are defined in the subclasses:
  1139. * Zlib::Deflate for compression, and Zlib::Inflate for decompression.
  1140. *
  1141. * An instance of Zlib::ZStream has one stream (struct zstream in the source)
  1142. * and two variable-length buffers which associated to the input (next_in) of
  1143. * the stream and the output (next_out) of the stream. In this document,
  1144. * "input buffer" means the buffer for input, and "output buffer" means the
  1145. * buffer for output.
  1146. *
  1147. * Data input into an instance of Zlib::ZStream are temporally stored into
  1148. * the end of input buffer, and then data in input buffer are processed from
  1149. * the beginning of the buffer until no more output from the stream is
  1150. * produced (i.e. until avail_out > 0 after processing). During processing,
  1151. * output buffer is allocated and expanded automatically to hold all output
  1152. * data.
  1153. *
  1154. * Some particular instance methods consume the data in output buffer and
  1155. * return them as a String.
  1156. *
  1157. * Here is an ascii art for describing above:
  1158. *
  1159. * +================ an instance of Zlib::ZStream ================+
  1160. * || ||
  1161. * || +--------+ +-------+ +--------+ ||
  1162. * || +--| output |<---------|zstream|<---------| input |<--+ ||
  1163. * || | | buffer | next_out+-------+next_in | buffer | | ||
  1164. * || | +--------+ +--------+ | ||
  1165. * || | | ||
  1166. * +===|======================================================|===+
  1167. * | |
  1168. * v |
  1169. * "output data" "input data"
  1170. *
  1171. * If an error occurs during processing input buffer, an exception which is a
  1172. * subclass of Zlib::Error is raised. At that time, both input and output
  1173. * buffer keep their conditions at the time when the error occurs.
  1174. *
  1175. * == Method Catalogue
  1176. *
  1177. * Many of the methods in this class are fairly low-level and unlikely to be
  1178. * of interest to users. In fact, users are unlikely to use this class
  1179. * directly; rather they will be interested in Zlib::Inflate and
  1180. * Zlib::Deflate.
  1181. *
  1182. * The higher level methods are listed below.
  1183. *
  1184. * - #total_in
  1185. * - #total_out
  1186. * - #data_type
  1187. * - #adler
  1188. * - #reset
  1189. * - #finish
  1190. * - #finished?
  1191. * - #close
  1192. * - #closed?
  1193. */
  1194. /*
  1195. * Closes the stream. All operations on the closed stream will raise an
  1196. * exception.
  1197. */
  1198. static VALUE
  1199. rb_zstream_end(VALUE obj)
  1200. {
  1201. zstream_end(get_zstream(obj));
  1202. return Qnil;
  1203. }
  1204. /*
  1205. * Resets and initializes the stream. All data in both input and output buffer
  1206. * are discarded.
  1207. */
  1208. static VALUE
  1209. rb_zstream_reset(VALUE obj)
  1210. {
  1211. zstream_reset(get_zstream(obj));
  1212. return Qnil;
  1213. }
  1214. /*
  1215. * call-seq:
  1216. * finish -> String
  1217. * finish { |chunk| ... } -> nil
  1218. *
  1219. * Finishes the stream and flushes output buffer. If a block is given each
  1220. * chunk is yielded to the block until the input buffer has been flushed to
  1221. * the output buffer.
  1222. */
  1223. static VALUE
  1224. rb_zstream_finish(VALUE obj)
  1225. {
  1226. struct zstream *z = get_zstream(obj);
  1227. zstream_run(z, (Bytef*)"", 0, Z_FINISH);
  1228. return zstream_detach_buffer(z);
  1229. }
  1230. /*
  1231. * call-seq:
  1232. * flush_next_in -> input
  1233. *
  1234. */
  1235. static VALUE
  1236. rb_zstream_flush_next_in(VALUE obj)
  1237. {
  1238. struct zstream *z;
  1239. VALUE dst;
  1240. TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
  1241. dst = zstream_detach_input(z);
  1242. return dst;
  1243. }
  1244. /*
  1245. * call-seq:
  1246. * flush_next_out -> String
  1247. * flush_next_out { |chunk| ... } -> nil
  1248. *
  1249. * Flushes output buffer and returns all data in that buffer. If a block is
  1250. * given each chunk is yielded to the block until the current output buffer
  1251. * has been flushed.
  1252. */
  1253. static VALUE
  1254. rb_zstream_flush_next_out(VALUE obj)
  1255. {
  1256. struct zstream *z;
  1257. TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
  1258. return zstream_detach_buffer(z);
  1259. }
  1260. /*
  1261. * Returns number of bytes of free spaces in output buffer. Because the free
  1262. * space is allocated automatically, this method returns 0 normally.
  1263. */
  1264. static VALUE
  1265. rb_zstream_avail_out(VALUE obj)
  1266. {
  1267. struct zstream *z;
  1268. TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
  1269. return rb_uint2inum(z->stream.avail_out);
  1270. }
  1271. /*
  1272. * Allocates +size+ bytes of free space in the output buffer. If there are more
  1273. * than +size+ bytes already in the buffer, the buffer is truncated. Because
  1274. * free space is allocated automatically, you usually don't need to use this
  1275. * method.
  1276. */
  1277. static VALUE
  1278. rb_zstream_set_avail_out(VALUE obj, VALUE size)
  1279. {
  1280. struct zstream *z = get_zstream(obj);
  1281. zstream_expand_buffer_into(z, FIX2INT(size));
  1282. return size;
  1283. }
  1284. /*
  1285. * Returns bytes of data in the input buffer. Normally, returns 0.
  1286. */
  1287. static VALUE
  1288. rb_zstream_avail_in(VALUE obj)
  1289. {
  1290. struct zstream *z;
  1291. TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
  1292. return INT2FIX(NIL_P(z->input) ? 0 : (int)(RSTRING_LEN(z->input)));
  1293. }
  1294. /*
  1295. * Returns the total bytes of the input data to the stream. FIXME
  1296. */
  1297. static VALUE
  1298. rb_zstream_total_in(VALUE obj)
  1299. {
  1300. return rb_uint2inum(get_zstream(obj)->stream.total_in);
  1301. }
  1302. /*
  1303. * Returns the total bytes of the output data from the stream. FIXME
  1304. */
  1305. static VALUE
  1306. rb_zstream_total_out(VALUE obj)
  1307. {
  1308. return rb_uint2inum(get_zstream(obj)->stream.total_out);
  1309. }
  1310. /*
  1311. * Guesses the type of the data which have been inputed into the stream. The
  1312. * returned value is either <tt>BINARY</tt>, <tt>ASCII</tt>, or
  1313. * <tt>UNKNOWN</tt>.
  1314. */
  1315. static VALUE
  1316. rb_zstream_data_type(VALUE obj)
  1317. {
  1318. return INT2FIX(get_zstream(obj)->stream.data_type);
  1319. }
  1320. /*
  1321. * Returns the adler-32 checksum.
  1322. */
  1323. static VALUE
  1324. rb_zstream_adler(VALUE obj)
  1325. {
  1326. return rb_uint2inum(get_zstream(obj)->stream.adler);
  1327. }
  1328. /*
  1329. * Returns true if the stream is finished.
  1330. */
  1331. static VALUE
  1332. rb_zstream_finished_p(VALUE obj)
  1333. {
  1334. return ZSTREAM_IS_FINISHED(get_zstream(obj)) ? Qtrue : Qfalse;
  1335. }
  1336. /*
  1337. * Returns true if the stream is closed.
  1338. */
  1339. static VALUE
  1340. rb_zstream_closed_p(VALUE obj)
  1341. {
  1342. struct zstream *z;
  1343. TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
  1344. return ZSTREAM_IS_READY(z) ? Qfalse : Qtrue;
  1345. }
  1346. /* ------------------------------------------------------------------------- */
  1347. /*
  1348. * Document-class: Zlib::Deflate
  1349. *
  1350. * Zlib::Deflate is the class for compressing data. See Zlib::ZStream for more
  1351. * information.
  1352. */
  1353. #define FIXNUMARG(val, ifnil) \
  1354. (NIL_P((val)) ? (ifnil) \
  1355. : (FIX2INT((val))))
  1356. #define ARG_LEVEL(val) FIXNUMARG((val), Z_DEFAULT_COMPRESSION)
  1357. #define ARG_WBITS(val) FIXNUMARG((val), MAX_WBITS)
  1358. #define ARG_MEMLEVEL(val) FIXNUMARG((val), DEF_MEM_LEVEL)
  1359. #define ARG_STRATEGY(val) FIXNUMARG((val), Z_DEFAULT_STRATEGY)
  1360. #define ARG_FLUSH(val) FIXNUMARG((val), Z_NO_FLUSH)
  1361. static VALUE
  1362. rb_deflate_s_allocate(VALUE klass)
  1363. {
  1364. return zstream_deflate_new(klass);
  1365. }
  1366. /*
  1367. * Document-method: Zlib::Deflate.new
  1368. *
  1369. * call-seq:
  1370. * Zlib::Deflate.new(level=DEFAULT_COMPRESSION, window_bits=MAX_WBITS, mem_level=DEF_MEM_LEVEL, strategy=DEFAULT_STRATEGY)
  1371. *
  1372. * Creates a new deflate stream for compression. If a given argument is nil,
  1373. * the default value of that argument is used.
  1374. *
  1375. * The +level+ sets the compression level for the deflate stream between 0 (no
  1376. * compression) and 9 (best compression). The following constants have been
  1377. * defined to make code more readable:
  1378. *
  1379. * * Zlib::DEFAULT_COMPRESSION
  1380. * * Zlib::NO_COMPRESSION
  1381. * * Zlib::BEST_SPEED
  1382. * * Zlib::BEST_COMPRESSION
  1383. *
  1384. * See http://www.zlib.net/manual.html#Constants for further information.
  1385. *
  1386. * The +window_bits+ sets the size of the history buffer and should be between
  1387. * 8 and 15. Larger values of this parameter result in better compression at
  1388. * the expense of memory usage.
  1389. *
  1390. * The +mem_level+ specifies how much memory should be allocated for the
  1391. * internal compression state. 1 uses minimum memory but is slow and reduces
  1392. * compression ratio while 9 uses maximum memory for optimal speed. The
  1393. * default value is 8. Two constants are defined:
  1394. *
  1395. * * Zlib::DEF_MEM_LEVEL
  1396. * * Zlib::MAX_MEM_LEVEL
  1397. *
  1398. * The +strategy+ sets the deflate compression strategy. The following
  1399. * strategies are available:
  1400. *
  1401. * Zlib::DEFAULT_STRATEGY:: For normal data
  1402. * Zlib::FILTERED:: For data produced by a filter or predictor
  1403. * Zlib::FIXED:: Prevents dynamic Huffman codes
  1404. * Zlib::HUFFMAN_ONLY:: Prevents string matching
  1405. * Zlib::RLE:: Designed for better compression of PNG image data
  1406. *
  1407. * See the constants for further description.
  1408. *
  1409. * == Examples
  1410. *
  1411. * === Basic
  1412. *
  1413. * open "compressed.file", "w+" do |io|
  1414. * io << Zlib::Deflate.new.deflate(File.read("big.file"))
  1415. * end
  1416. *
  1417. * === Custom compression
  1418. *
  1419. * open "compressed.file", "w+" do |compressed_io|
  1420. * deflate = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
  1421. * Zlib::MAX_WBITS,
  1422. * Zlib::MAX_MEM_LEVEL,
  1423. * Zlib::HUFFMAN_ONLY)
  1424. *
  1425. * begin
  1426. * open "big.file" do |big_io|
  1427. * until big_io.eof? do
  1428. * compressed_io << zd.deflate(big_io.read(16384))
  1429. * end
  1430. * end
  1431. * ensure
  1432. * deflate.close
  1433. * end
  1434. * end
  1435. *
  1436. * While this example will work, for best optimization review the flags for
  1437. * your specific time, memory usage and output space requirements.
  1438. */
  1439. static VALUE
  1440. rb_deflate_initialize(int argc, VALUE *argv, VALUE obj)
  1441. {
  1442. struct zstream *z;
  1443. VALUE level, wbits, memlevel, strategy;
  1444. int err;
  1445. rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy);
  1446. TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
  1447. err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
  1448. ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
  1449. ARG_STRATEGY(strategy));
  1450. if (err != Z_OK) {
  1451. raise_zlib_error(err, z->stream.msg);
  1452. }
  1453. ZSTREAM_READY(z);
  1454. return obj;
  1455. }
  1456. /*
  1457. * Document-method: Zlib::Deflate#initialize_copy
  1458. *
  1459. * Duplicates the deflate stream.
  1460. */
  1461. static VALUE
  1462. rb_deflate_init_copy(VALUE self, VALUE orig)
  1463. {
  1464. struct zstream *z1, *z2;
  1465. int err;
  1466. TypedData_Get_Struct(self, struct zstream, &zstream_data_type, z1);
  1467. z2 = get_zstream(orig);
  1468. if (z1 == z2) return self;
  1469. err = deflateCopy(&z1->stream, &z2->stream);
  1470. if (err != Z_OK) {
  1471. raise_zlib_error(err, 0);
  1472. }
  1473. z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input);
  1474. z1->buf = NIL_P(z2->buf) ? Qnil : rb_str_dup(z2->buf);
  1475. z1->flags = z2->flags;
  1476. return self;
  1477. }
  1478. static VALUE
  1479. deflate_run(VALUE args)
  1480. {
  1481. struct zstream *z = (struct zstream*)((VALUE*)args)[0];
  1482. VALUE src = ((VALUE*)args)[1];
  1483. zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_FINISH);
  1484. return zstream_detach_buffer(z);
  1485. }
  1486. /*
  1487. * Document-method: Zlib::Deflate.deflate
  1488. *
  1489. * call-seq:
  1490. * Zlib.deflate(string[, level])
  1491. * Zlib::Deflate.deflate(string[, level])
  1492. *
  1493. * Compresses the given +string+. Valid values of level are
  1494. * Zlib::NO_COMPRESSION, Zlib::BEST_SPEED, Zlib::BEST_COMPRESSION,
  1495. * Zlib::DEFAULT_COMPRESSION, or an integer from 0 to 9.
  1496. *
  1497. * This method is almost equivalent to the following code:
  1498. *
  1499. * def deflate(string, level)
  1500. * z = Zlib::Deflate.new(level)
  1501. * dst = z.deflate(string, Zlib::FINISH)
  1502. * z.close
  1503. * dst
  1504. * end
  1505. *
  1506. * See also Zlib.inflate
  1507. *
  1508. */
  1509. static VALUE
  1510. rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
  1511. {
  1512. struct zstream z;
  1513. VALUE src, level, dst, args[2];
  1514. int err, lev;
  1515. rb_scan_args(argc, argv, "11", &src, &level);
  1516. lev = ARG_LEVEL(level);
  1517. StringValue(src);
  1518. zstream_init_deflate(&z);
  1519. err = deflateInit(&z.stream, lev);
  1520. if (err != Z_OK) {
  1521. raise_zlib_error(err, z.stream.msg);
  1522. }
  1523. ZSTREAM_READY(&z);
  1524. args[0] = (VALUE)&z;
  1525. args[1] = src;
  1526. dst = rb_ensure(deflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z);
  1527. return dst;
  1528. }
  1529. static void
  1530. do_deflate(struct zstream *z, VALUE src, int flush)
  1531. {
  1532. if (NIL_P(src)) {
  1533. zstream_run(z, (Bytef*)"", 0, Z_FINISH);
  1534. return;
  1535. }
  1536. StringValue(src);
  1537. if (flush != Z_NO_FLUSH || RSTRING_LEN(src) > 0) { /* prevent BUF_ERROR */
  1538. zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), flush);
  1539. }
  1540. }
  1541. /*
  1542. * Document-method: Zlib::Deflate#deflate
  1543. *
  1544. * call-seq:
  1545. * z.deflate(string, flush = Zlib::NO_FLUSH) -> String
  1546. * z.deflate(string, flush = Zlib::NO_FLUSH) { |chunk| ... } -> nil
  1547. *
  1548. * Inputs +string+ into the deflate stream and returns the output from the
  1549. * stream. On calling this method, both the input and the output buffers of
  1550. * the stream are flushed. If +string+ is nil, this method finishes the
  1551. * stream, just like Zlib::ZStream#finish.
  1552. *
  1553. * If a block is given consecutive deflated chunks from the +string+ are
  1554. * yielded to the block and +nil+ is returned.
  1555. *
  1556. * The +flush+ parameter specifies the flush mode. The following constants
  1557. * may be used:
  1558. *
  1559. * Zlib::NO_FLUSH:: The default
  1560. * Zlib::SYNC_FLUSH:: Flushes the output to a byte boundary
  1561. * Zlib::FULL_FLUSH:: SYNC_FLUSH + resets the compression state
  1562. * Zlib::FINISH:: Pending input is processed, pending output is flushed.
  1563. *
  1564. * See the constants for further description.
  1565. *
  1566. */
  1567. static VALUE
  1568. rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
  1569. {
  1570. struct zstream *z = get_zstream(obj);
  1571. VALUE src, flush;
  1572. rb_scan_args(argc, argv, "11", &src, &flush);
  1573. do_deflate(z, src, ARG_FLUSH(flush));
  1574. return zstream_detach_buffer(z);
  1575. }
  1576. /*
  1577. * Document-method: Zlib::Deflate#<<
  1578. *
  1579. * call-seq: << string
  1580. *
  1581. * Inputs +string+ into the deflate stream just like Zlib::Deflate#deflate, but
  1582. * returns the Zlib::Deflate object itself. The output from the stream is
  1583. * preserved in output buffer.
  1584. */
  1585. static VALUE
  1586. rb_deflate_addstr(VALUE obj, VALUE src)
  1587. {
  1588. do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
  1589. return obj;
  1590. }
  1591. /*
  1592. * Document-method: Zlib::Deflate#flush
  1593. *
  1594. * call-seq:
  1595. * flush(flush = Zlib::SYNC_FLUSH) -> String
  1596. * flush(flush = Zlib::SYNC_FLUSH) { |chunk| ... } -> nil
  1597. *
  1598. * This method is equivalent to <tt>deflate('', flush)</tt>. This method is
  1599. * just provided to improve the readability of your Ruby program. If a block
  1600. * is given chunks of deflate output are yielded to the block until the buffer
  1601. * is flushed.
  1602. *
  1603. * See Zlib::Deflate#deflate for detail on the +flush+ constants NO_FLUSH,
  1604. * SYNC_FLUSH, FULL_FLUSH and FINISH.
  1605. */
  1606. static VALUE
  1607. rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
  1608. {
  1609. struct zstream *z = get_zstream(obj);
  1610. VALUE v_flush;
  1611. int flush;
  1612. rb_scan_args(argc, argv, "01", &v_flush);
  1613. flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
  1614. if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
  1615. zstream_run(z, (Bytef*)"", 0, flush);
  1616. }
  1617. return zstream_detach_buffer(z);
  1618. }
  1619. /*
  1620. * Document-method: Zlib::Deflate.params
  1621. *
  1622. * call-seq: params(level, strategy)
  1623. *
  1624. * Changes the parameters of the deflate stream to allow changes between
  1625. * different types of data that require different types of compression. Any
  1626. * unprocessed data is flushed before changing the params.
  1627. *
  1628. * See Zlib::Deflate.new for a description of +level+ and +strategy+.
  1629. *
  1630. */
  1631. static VALUE
  1632. rb_deflate_params(VALUE obj, VALUE v_level, VALUE v_strategy)
  1633. {
  1634. struct zstream *z = get_zstream(obj);
  1635. int level, strategy;
  1636. int err;
  1637. uInt n;
  1638. long filled;
  1639. level = ARG_LEVEL(v_level);
  1640. strategy = ARG_STRATEGY(v_strategy);
  1641. n = z->stream.avail_out;
  1642. err = deflateParams(&z->stream, level, strategy);
  1643. filled = n - z->stream.avail_out;
  1644. while (err == Z_BUF_ERROR) {
  1645. rb_warning("deflateParams() returned Z_BUF_ERROR");
  1646. zstream_expand_buffer(z);
  1647. rb_str_set_len(z->buf, RSTRING_LEN(z->buf) + filled);
  1648. n = z->stream.avail_out;
  1649. err = deflateParams(&z->stream, level, strategy);
  1650. filled = n - z->stream.avail_out;
  1651. }
  1652. if (err != Z_OK) {
  1653. raise_zlib_error(err, z->stream.msg);
  1654. }
  1655. rb_str_set_len(z->buf, RSTRING_LEN(z->buf) + filled);
  1656. return Qnil;
  1657. }
  1658. /*
  1659. * Document-method: Zlib::Deflate.set_dictionary
  1660. *
  1661. * call-seq: set_dictionary(string)
  1662. *
  1663. * Sets the preset dictionary and returns +string+. This method is available
  1664. * just only after Zlib::Deflate.new or Zlib::ZStream#reset method was called.
  1665. * See zlib.h for details.
  1666. *
  1667. * Can raise errors of Z_STREAM_ERROR if a parameter is invalid (such as
  1668. * NULL dictionary) or the stream state is inconsistent, Z_DATA_ERROR if
  1669. * the given dictionary doesn't match the expected one (incorrect adler32 value)
  1670. *
  1671. */
  1672. static VALUE
  1673. rb_deflate_set_dictionary(VALUE obj, VALUE dic)
  1674. {
  1675. struct zstream *z = get_zstream(obj);
  1676. VALUE src = dic;
  1677. int err;
  1678. StringValue(src);
  1679. err = deflateSetDictionary(&z->stream,
  1680. (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
  1681. if (err != Z_OK) {
  1682. raise_zlib_error(err, z->stream.msg);
  1683. }
  1684. return dic;
  1685. }
  1686. /* ------------------------------------------------------------------------- */
  1687. /*
  1688. * Document-class: Zlib::Inflate
  1689. *
  1690. * Zlib:Inflate is the class for decompressing compressed data. Unlike
  1691. * Zlib::Deflate, an instance of this class is not able to duplicate (clone,
  1692. * dup) itself.
  1693. */
  1694. static VALUE
  1695. rb_inflate_s_allocate(VALUE klass)
  1696. {
  1697. VALUE inflate = zstream_inflate_new(klass);
  1698. rb_ivar_set(inflate, id_dictionaries, rb_hash_new());
  1699. return inflate;
  1700. }
  1701. /*
  1702. * Document-method: Zlib::Inflate.new
  1703. *
  1704. * call-seq:
  1705. * Zlib::Inflate.new(window_bits = Zlib::MAX_WBITS)
  1706. *
  1707. * Creates a new inflate stream for decompression. +window_bits+ sets the
  1708. * size of the history buffer and can have the following values:
  1709. *
  1710. * 0::
  1711. * Have inflate use the window size from the zlib header of the compressed
  1712. * stream.
  1713. *
  1714. * (8..15)::
  1715. * Overrides the window size of the inflate header in the compressed stream.
  1716. * The window size must be greater than or equal to the window size of the
  1717. * compressed stream.
  1718. *
  1719. * Greater than 15::
  1720. * Add 32 to window_bits to enable zlib and gzip decoding with automatic
  1721. * header detection, or add 16 to decode only the gzip format (a
  1722. * Zlib::DataError will be raised for a non-gzip stream).
  1723. *
  1724. * (-8..-15)::
  1725. * Enables raw deflate mode which will not generate a check value, and will
  1726. * not look for any check values for comparison at the end of the stream.
  1727. *
  1728. * This is for use with other formats that use the deflate compressed data
  1729. * format such as zip which provide their own check values.
  1730. *
  1731. * == Example
  1732. *
  1733. * open "compressed.file" do |compressed_io|
  1734. * zi = Zlib::Inflate.new(Zlib::MAX_WBITS + 32)
  1735. *
  1736. * begin
  1737. * open "uncompressed.file", "w+" do |uncompressed_io|
  1738. * uncompressed_io << zi.inflate(compressed_io.read)
  1739. * end
  1740. * ensure
  1741. * zi.close
  1742. * end
  1743. * end
  1744. *
  1745. */
  1746. static VALUE
  1747. rb_inflate_initialize(int argc, VALUE *argv, VALUE obj)
  1748. {
  1749. struct zstream *z;
  1750. VALUE wbits;
  1751. int err;
  1752. rb_scan_args(argc, argv, "01", &wbits);
  1753. TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z);
  1754. err = inflateInit2(&z->stream, ARG_WBITS(wbits));
  1755. if (err != Z_OK) {
  1756. raise_zlib_error(err, z->stream.msg);
  1757. }
  1758. ZSTREAM_READY(z);
  1759. return obj;
  1760. }
  1761. static VALUE
  1762. inflate_run(VALUE args)
  1763. {
  1764. struct zstream *z = (struct zstream*)((VALUE*)args)[0];
  1765. VALUE src = ((VALUE*)args)[1];
  1766. zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
  1767. zstream_run(z, (Bytef*)"", 0, Z_FINISH); /* for checking errors */
  1768. return zstream_detach_buffer(z);
  1769. }
  1770. /*
  1771. * Document-method: Zlib::inflate
  1772. *
  1773. * call-seq:
  1774. * Zlib.inflate(string)
  1775. * Zlib::Inflate.inflate(string)
  1776. *
  1777. * Decompresses +string+. Raises a Zlib::NeedDict exception if a preset
  1778. * dictionary is needed for decompression.
  1779. *
  1780. * This method is almost equivalent to the following code:
  1781. *
  1782. * def inflate(string)
  1783. * zstream = Zlib::Inflate.new
  1784. * buf = zstream.inflate(string)
  1785. * zstream.finish
  1786. * zstream.close
  1787. * buf
  1788. * end
  1789. *
  1790. * See also Zlib.deflate
  1791. *
  1792. */
  1793. static VALUE
  1794. rb_inflate_s_inflate(VALUE obj, VALUE src)
  1795. {
  1796. struct zstream z;
  1797. VALUE dst, args[2];
  1798. int err;
  1799. StringValue(src);
  1800. zstream_init_inflate(&z);
  1801. err = inflateInit(&z.stream);
  1802. if (err != Z_OK) {
  1803. raise_zlib_error(err, z.stream.msg);
  1804. }
  1805. ZSTREAM_READY(&z);
  1806. args[0] = (VALUE)&z;
  1807. args[1] = src;
  1808. dst = rb_ensure(inflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z);
  1809. return dst;
  1810. }
  1811. static void
  1812. do_inflate(struct zstream *z, VALUE src)
  1813. {
  1814. if (NIL_P(src)) {
  1815. zstream_run(z, (Bytef*)"", 0, Z_FINISH);
  1816. return;
  1817. }
  1818. StringValue(src);
  1819. if (RSTRING_LEN(src) > 0 || z->stream.avail_in > 0) { /* prevent Z_BUF_ERROR */
  1820. zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
  1821. }
  1822. }
  1823. /* Document-method: Zlib::Inflate#add_dictionary
  1824. *
  1825. * call-seq: add_dictionary(string)
  1826. *
  1827. * Provide the inflate stream with a dictionary that may be required in the
  1828. * future. Multiple dictionaries may be provided. The inflate stream will
  1829. * automatically choose the correct user-provided dictionary based on the
  1830. * stream's required dictionary.
  1831. */
  1832. static VALUE
  1833. rb_inflate_add_dictionary(VALUE obj, VALUE dictionary)
  1834. {
  1835. VALUE dictionaries = rb_ivar_get(obj, id_dictionaries);
  1836. VALUE checksum = do_checksum(1, &dictionary, adler32);
  1837. rb_hash_aset(dictionaries, checksum, dictionary);
  1838. return obj;
  1839. }
  1840. /*
  1841. * Document-method: Zlib::Inflate#inflate
  1842. *
  1843. * call-seq:
  1844. * inflate(deflate_string, buffer: nil) -> String
  1845. * inflate(deflate_string, buffer: nil) { |chunk| ... } -> nil
  1846. *
  1847. * Inputs +deflate_string+ into the inflate stream and returns the output from
  1848. * the stream. Calling this method, both the input and the output buffer of
  1849. * the stream are flushed. If string is +nil+, this method finishes the
  1850. * stream, just like Zlib::ZStream#finish.
  1851. *
  1852. * If a block is given consecutive inflated chunks from the +deflate_string+
  1853. * are yielded to the block and +nil+ is returned.
  1854. *
  1855. * If a :buffer keyword argument is given and not nil:
  1856. *
  1857. * * The :buffer keyword should be a String, and will used as the output buffer.
  1858. * Using this option can reuse the memory required during inflation.
  1859. * * When not passing a block, the return value will be the same object as the
  1860. * :buffer keyword argument.
  1861. * * When passing a block, the yielded chunks will be the same value as the
  1862. * :buffer keyword argument.
  1863. *
  1864. * Raises a Zlib::NeedDict exception if a preset dictionary is needed to
  1865. * decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
  1866. * call this method again with an empty string to flush the stream:
  1867. *
  1868. * inflater = Zlib::Inflate.new
  1869. *
  1870. * begin
  1871. * out = inflater.inflate compressed
  1872. * rescue Zlib::NeedDict
  1873. * # ensure the dictionary matches the stream's required dictionary
  1874. * raise unless inflater.adler == Zlib.adler32(dictionary)
  1875. *
  1876. * inflater.set_dictionary dictionary
  1877. * inflater.inflate ''
  1878. * end
  1879. *
  1880. * # ...
  1881. *
  1882. * inflater.close
  1883. *
  1884. * See also Zlib::Inflate.new
  1885. */
  1886. static VALUE
  1887. rb_inflate_inflate(int argc, VALUE* argv, VALUE obj)
  1888. {
  1889. struct zstream *z = get_zstream(obj);
  1890. VALUE dst, src, opts, buffer = Qnil;
  1891. if (OPTHASH_GIVEN_P(opts)) {
  1892. VALUE buf;
  1893. rb_get_kwargs(opts, &id_buffer, 0, 1, &buf);
  1894. if (buf != Qundef && buf != Qnil) {
  1895. buffer = StringValue(buf);
  1896. }
  1897. }
  1898. if (buffer != Qnil) {
  1899. if (!(ZSTREAM_REUSE_BUFFER_P(z) && z->buf == buffer)) {
  1900. long len = RSTRING_LEN(buffer);
  1901. if (len >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
  1902. rb_str_modify(buffer);
  1903. }
  1904. else {
  1905. len = ZSTREAM_AVAIL_OUT_STEP_MAX - len;
  1906. rb_str_modify_expand(buffer, len);
  1907. }
  1908. rb_str_set_len(buffer, 0);
  1909. z->flags |= ZSTREAM_REUSE_BUFFER;
  1910. z->buf = buffer;
  1911. }
  1912. } else if (ZSTREAM_REUSE_BUFFER_P(z)) {
  1913. z->flags &= ~ZSTREAM_REUSE_BUFFER;
  1914. z->buf = Qnil;
  1915. }
  1916. rb_scan_args(argc, argv, "10", &src);
  1917. if (ZSTREAM_IS_FINISHED(z)) {
  1918. if (NIL_P(src)) {
  1919. dst = zstream_detach_buffer(z);
  1920. }
  1921. else {
  1922. StringValue(src);
  1923. zstream_append_buffer2(z, src);
  1924. if (ZSTREAM_REUSE_BUFFER_P(z)) {
  1925. dst = rb_str_resize(buffer, 0);
  1926. } else {
  1927. dst = rb_str_new(0, 0);
  1928. }
  1929. }
  1930. }
  1931. else {
  1932. do_inflate(z, src);
  1933. dst = zstream_detach_buffer(z);
  1934. if (ZSTREAM_IS_FINISHED(z)) {
  1935. zstream_passthrough_input(z);
  1936. }
  1937. }
  1938. return dst;
  1939. }
  1940. /*
  1941. * call-seq: << string
  1942. *
  1943. * Inputs +string+ into the inflate stream just like Zlib::Inflate#inflate, but
  1944. * returns the Zlib::Inflate object itself. The output from the stream is
  1945. * preserved in output buffer.
  1946. */
  1947. static VALUE
  1948. rb_inflate_addstr(VALUE obj, VALUE src)
  1949. {
  1950. struct zstream *z = get_zstream(obj);
  1951. if (ZSTREAM_IS_FINISHED(z)) {
  1952. if (!NIL_P(src)) {
  1953. StringValue(src);
  1954. zstream_append_buffer2(z, src);
  1955. }
  1956. }
  1957. else {
  1958. do_inflate(z, src);
  1959. if (ZSTREAM_IS_FINISHED(z)) {
  1960. zstream_passthrough_input(z);
  1961. }
  1962. }
  1963. return obj;
  1964. }
  1965. /*
  1966. * call-seq: sync(string)
  1967. *
  1968. * Inputs +string+ into the end of input buffer and skips data until a full
  1969. * flush point can be found. If the point is found in the buffer, this method
  1970. * flushes the buffer and returns false. Otherwise it returns +true+ and the
  1971. * following data of full flush point is preserved in the buffer.
  1972. */
  1973. static VALUE
  1974. rb_inflate_sync(VALUE obj, VALUE src)
  1975. {
  1976. struct zstream *z = get_zstream(obj);
  1977. StringValue(src);
  1978. return zstream_sync(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src));
  1979. }
  1980. /*
  1981. * Quoted verbatim from original documentation:
  1982. *
  1983. * What is this?
  1984. *
  1985. * <tt>:)</tt>
  1986. */
  1987. static VALUE
  1988. rb_inflate_sync_point_p(VALUE obj)
  1989. {
  1990. struct zstream *z = get_zstream(obj);
  1991. int err;
  1992. err = inflateSyncPoint(&z->stream);
  1993. if (err == 1) {
  1994. return Qtrue;
  1995. }
  1996. if (err != Z_OK) {
  1997. raise_zlib_error(err, z->stream.msg);
  1998. }
  1999. return Qfalse;
  2000. }
  2001. /*
  2002. * Document-method: Zlib::Inflate#set_dictionary
  2003. *
  2004. * Sets the preset dictionary and returns +string+. This method is available just
  2005. * only after a Zlib::NeedDict exception was raised. See zlib.h for details.
  2006. *
  2007. */
  2008. static VALUE
  2009. rb_inflate_set_dictionary(VALUE obj, VALUE dic)
  2010. {
  2011. struct zstream *z = get_zstream(obj);
  2012. VALUE src = dic;
  2013. int err;
  2014. StringValue(src);
  2015. err = inflateSetDictionary(&z->stream,
  2016. (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
  2017. if (err != Z_OK) {
  2018. raise_zlib_error(err, z->stream.msg);
  2019. }
  2020. return dic;
  2021. }
  2022. #if GZIP_SUPPORT
  2023. /* NOTE: Features for gzip files of Ruby/zlib are written from scratch
  2024. * and using undocumented feature of zlib, negative wbits.
  2025. * I don't think gzFile APIs of zlib are good for Ruby.
  2026. */
  2027. /*------- .gz file header --------*/
  2028. #define GZ_MAGIC1 0x1f
  2029. #define GZ_MAGIC2 0x8b
  2030. #define GZ_METHOD_DEFLATE 8
  2031. #define GZ_FLAG_MULTIPART 0x2
  2032. #define GZ_FLAG_EXTRA 0x4
  2033. #define GZ_FLAG_ORIG_NAME 0x8
  2034. #define GZ_FLAG_COMMENT 0x10
  2035. #define GZ_FLAG_ENCRYPT 0x20
  2036. #define GZ_FLAG_UNKNOWN_MASK 0xc0
  2037. #define GZ_EXTRAFLAG_FAST 0x4
  2038. #define GZ_EXTRAFLAG_SLOW 0x2
  2039. /* from zutil.h */
  2040. #define OS_MSDOS 0x00
  2041. #define OS_AMIGA 0x01
  2042. #define OS_VMS 0x02
  2043. #define OS_UNIX 0x03
  2044. #define OS_ATARI 0x05
  2045. #define OS_OS2 0x06
  2046. #define OS_MACOS 0x07
  2047. #define OS_TOPS20 0x0a
  2048. #define OS_WIN32 0x0b
  2049. #define OS_VMCMS 0x04
  2050. #define OS_ZSYSTEM 0x08
  2051. #define OS_CPM 0x09
  2052. #define OS_QDOS 0x0c
  2053. #define OS_RISCOS 0x0d
  2054. #define OS_UNKNOWN 0xff
  2055. #ifndef OS_CODE
  2056. #define OS_CODE OS_UNIX
  2057. #endif
  2058. static ID id_write, id_readpartial, id_flush, id_seek, id_close, id_path, id_input;
  2059. static VALUE cGzError, cNoFooter, cCRCError, cLengthError;
  2060. /*-------- gzfile internal APIs --------*/
  2061. struct gzfile {
  2062. struct zstream z;
  2063. VALUE io;
  2064. int level;
  2065. int os_code; /* for header */
  2066. time_t mtime; /* for header */
  2067. VALUE orig_name; /* for header; must be a String */
  2068. VALUE comment; /* for header; must be a String */
  2069. unsigned long crc;
  2070. int ecflags;
  2071. int lineno;
  2072. long ungetc;
  2073. void (*end)(struct gzfile *);
  2074. rb_encoding *enc;
  2075. rb_encoding *enc2;
  2076. rb_econv_t *ec;
  2077. VALUE ecopts;
  2078. VALUE path;
  2079. };
  2080. #define GZFILE_CBUF_CAPA 10
  2081. #define GZFILE_FLAG_SYNC ZSTREAM_FLAG_UNUSED
  2082. #define GZFILE_FLAG_HEADER_FINISHED (ZSTREAM_FLAG_UNUSED << 1)
  2083. #define GZFILE_FLAG_FOOTER_FINISHED (ZSTREAM_FLAG_UNUSED << 2)
  2084. #define GZFILE_FLAG_MTIME_IS_SET (ZSTREAM_FLAG_UNUSED << 3)
  2085. #define GZFILE_IS_FINISHED(gz) \
  2086. (ZSTREAM_IS_FINISHED(&(gz)->z) && ZSTREAM_BUF_FILLED(&(gz)->z) == 0)
  2087. #define GZFILE_READ_SIZE 2048
  2088. struct read_raw_arg {
  2089. VALUE io;
  2090. union {
  2091. const VALUE argv[2]; /* for rb_funcallv */
  2092. struct {
  2093. VALUE len;
  2094. VALUE buf;
  2095. } in;
  2096. } as;
  2097. };
  2098. static void
  2099. gzfile_mark(void *p)
  2100. {
  2101. struct gzfile *gz = p;
  2102. rb_gc_mark(gz->io);
  2103. rb_gc_mark(gz->orig_name);
  2104. rb_gc_mark(gz->comment);
  2105. zstream_mark(&gz->z);
  2106. rb_gc_mark(gz->ecopts);
  2107. rb_gc_mark(gz->path);
  2108. }
  2109. static void
  2110. gzfile_free(void *p)
  2111. {
  2112. struct gzfile *gz = p;
  2113. struct zstream *z = &gz->z;
  2114. if (ZSTREAM_IS_READY(z)) {
  2115. if (z->func == &deflate_funcs) {
  2116. finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
  2117. }
  2118. zstream_finalize(z);
  2119. }
  2120. xfree(gz);
  2121. }
  2122. static size_t
  2123. gzfile_memsize(const void *p)
  2124. {
  2125. return sizeof(struct gzfile);
  2126. }
  2127. static const rb_data_type_t gzfile_data_type = {
  2128. "gzfile",
  2129. { gzfile_mark, gzfile_free, gzfile_memsize, },
  2130. 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
  2131. };
  2132. static void
  2133. gzfile_init(struct gzfile *gz, const struct zstream_funcs *funcs, void (*endfunc)(struct gzfile *))
  2134. {
  2135. zstream_init(&gz->z, funcs);
  2136. gz->z.flags |= ZSTREAM_FLAG_GZFILE;
  2137. gz->io = Qnil;
  2138. gz->level = 0;
  2139. gz->mtime = 0;
  2140. gz->os_code = OS_CODE;
  2141. gz->orig_name = Qnil;
  2142. gz->comment = Qnil;
  2143. gz->crc = crc32(0, Z_NULL, 0);
  2144. gz->lineno = 0;
  2145. gz->ungetc = 0;
  2146. gz->end = endfunc;
  2147. gz->enc = rb_default_external_encoding();
  2148. gz->enc2 = 0;
  2149. gz->ec = NULL;
  2150. gz->ecflags = 0;
  2151. gz->ecopts = Qnil;
  2152. gz->path = Qnil;
  2153. }
  2154. static VALUE
  2155. gzfile_new(VALUE klass, const struct zstream_funcs *funcs, void (*endfunc)(struct gzfile *))
  2156. {
  2157. VALUE obj;
  2158. struct gzfile *gz;
  2159. obj = TypedData_Make_Struct(klass, struct gzfile, &gzfile_data_type, gz);
  2160. gzfile_init(gz, funcs, endfunc);
  2161. return obj;
  2162. }
  2163. #define gzfile_writer_new(gz) gzfile_new((gz),&deflate_funcs,gzfile_writer_end)
  2164. #define gzfile_reader_new(gz) gzfile_new((gz),&inflate_funcs,gzfile_reader_end)
  2165. static void
  2166. gzfile_reset(struct gzfile *gz)
  2167. {
  2168. zstream_reset(&gz->z);
  2169. gz->z.flags |= ZSTREAM_FLAG_GZFILE;
  2170. gz->crc = crc32(0, Z_NULL, 0);
  2171. gz->lineno = 0;
  2172. gz->ungetc = 0;
  2173. if (gz->ec) {
  2174. rb_econv_close(gz->ec);
  2175. gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
  2176. gz->ecflags, gz->ecopts);
  2177. }
  2178. }
  2179. static void
  2180. gzfile_close(struct gzfile *gz, int closeflag)
  2181. {
  2182. VALUE io = gz->io;
  2183. gz->end(gz);
  2184. gz->io = Qnil;
  2185. gz->orig_name = Qnil;
  2186. gz->comment = Qnil;
  2187. if (closeflag && rb_respond_to(io, id_close)) {
  2188. rb_funcall(io, id_close, 0);
  2189. }
  2190. }
  2191. static void
  2192. gzfile_write_raw(struct gzfile *gz)
  2193. {
  2194. VALUE str;
  2195. if (ZSTREAM_BUF_FILLED(&gz->z) > 0) {
  2196. str = zstream_detach_buffer(&gz->z);
  2197. rb_funcall(gz->io, id_write, 1, str);
  2198. if ((gz->z.flags & GZFILE_FLAG_SYNC)
  2199. && rb_respond_to(gz->io, id_flush))
  2200. rb_funcall(gz->io, id_flush, 0);
  2201. }
  2202. }
  2203. static VALUE
  2204. gzfile_read_raw_partial(VALUE arg)
  2205. {
  2206. struct read_raw_arg *ra = (struct read_raw_arg *)arg;
  2207. VALUE str;
  2208. int argc = NIL_P(ra->as.argv[1]) ? 1 : 2;
  2209. str = rb_funcallv(ra->io, id_readpartial, argc, ra->as.argv);
  2210. Check_Type(str, T_STRING);
  2211. return str;
  2212. }
  2213. static VALUE
  2214. gzfile_read_raw_rescue(VALUE arg, VALUE _)
  2215. {
  2216. struct read_raw_arg *ra = (struct read_raw_arg *)arg;
  2217. VALUE str = Qnil;
  2218. if (rb_obj_is_kind_of(rb_errinfo(), rb_eNoMethodError)) {
  2219. int argc = NIL_P(ra->as.argv[1]) ? 1 : 2;
  2220. str = rb_funcallv(ra->io, id_read, argc, ra->as.argv);
  2221. if (!NIL_P(str)) {
  2222. Check_Type(str, T_STRING);
  2223. }
  2224. }
  2225. return str; /* return nil when EOFError */
  2226. }
  2227. static VALUE
  2228. gzfile_read_raw(struct gzfile *gz, VALUE outbuf)
  2229. {
  2230. struct read_raw_arg ra;
  2231. ra.io = gz->io;
  2232. ra.as.in.len = INT2FIX(GZFILE_READ_SIZE);
  2233. ra.as.in.buf = outbuf;
  2234. return rb_rescue2(gzfile_read_raw_partial, (VALUE)&ra,
  2235. gzfile_read_raw_rescue, (VALUE)&ra,
  2236. rb_eEOFError, rb_eNoMethodError, (VALUE)0);
  2237. }
  2238. static int
  2239. gzfile_read_raw_ensure(struct gzfile *gz, long size, VALUE outbuf)
  2240. {
  2241. VALUE str;
  2242. if (gz->io == Qundef) { /* Zlib.gunzip */
  2243. if (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size)
  2244. rb_raise(cGzError, "unexpected end of string");
  2245. }
  2246. while (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) {
  2247. str = gzfile_read_raw(gz, outbuf);
  2248. if (NIL_P(str)) return 0;
  2249. zstream_append_input2(&gz->z, str);
  2250. }
  2251. return 1;
  2252. }
  2253. static char *
  2254. gzfile_read_raw_until_zero(struct gzfile *gz, long offset)
  2255. {
  2256. VALUE str;
  2257. char *p;
  2258. for (;;) {
  2259. p = memchr(RSTRING_PTR(gz->z.input) + offset, '\0',
  2260. RSTRING_LEN(gz->z.input) - offset);
  2261. if (p) break;
  2262. str = gzfile_read_raw(gz, Qnil);
  2263. if (NIL_P(str)) {
  2264. rb_raise(cGzError, "unexpected end of file");
  2265. }
  2266. offset = RSTRING_LEN(gz->z.input);
  2267. zstream_append_input2(&gz->z, str);
  2268. }
  2269. return p;
  2270. }
  2271. static unsigned int
  2272. gzfile_get16(const unsigned char *src)
  2273. {
  2274. unsigned int n;
  2275. n = *(src++) & 0xff;
  2276. n |= (*(src++) & 0xff) << 8;
  2277. return n;
  2278. }
  2279. static unsigned long
  2280. gzfile_get32(const unsigned char *src)
  2281. {
  2282. unsigned long n;
  2283. n = *(src++) & 0xff;
  2284. n |= (*(src++) & 0xff) << 8;
  2285. n |= (*(src++) & 0xff) << 16;
  2286. n |= (*(src++) & 0xffU) << 24;
  2287. return n;
  2288. }
  2289. static void
  2290. gzfile_set32(unsigned long n, unsigned char *dst)
  2291. {
  2292. *(dst++) = n & 0xff;
  2293. *(dst++) = (n >> 8) & 0xff;
  2294. *(dst++) = (n >> 16) & 0xff;
  2295. *dst = (n >> 24) & 0xff;
  2296. }
  2297. static void
  2298. gzfile_raise(struct gzfile *gz, VALUE klass, const char *message)
  2299. {
  2300. VALUE exc = rb_exc_new2(klass, message);
  2301. if (!NIL_P(gz->z.input)) {
  2302. rb_ivar_set(exc, id_input, rb_str_resurrect(gz->z.input));
  2303. }
  2304. rb_exc_raise(exc);
  2305. }
  2306. /*
  2307. * Document-method: Zlib::GzipFile::Error#inspect
  2308. *
  2309. * Constructs a String of the GzipFile Error
  2310. */
  2311. static VALUE
  2312. gzfile_error_inspect(VALUE error)
  2313. {
  2314. VALUE str = rb_call_super(0, 0);
  2315. VALUE input = rb_attr_get(error, id_input);
  2316. if (!NIL_P(input)) {
  2317. rb_str_resize(str, RSTRING_LEN(str)-1);
  2318. rb_str_cat2(str, ", input=");
  2319. rb_str_append(str, rb_str_inspect(input));
  2320. rb_str_cat2(str, ">");
  2321. }
  2322. return str;
  2323. }
  2324. static void
  2325. gzfile_make_header(struct gzfile *gz)
  2326. {
  2327. Bytef buf[10]; /* the size of gzip header */
  2328. unsigned char flags = 0, extraflags = 0;
  2329. if (!NIL_P(gz->orig_name)) {
  2330. flags |= GZ_FLAG_ORIG_NAME;
  2331. }
  2332. if (!NIL_P(gz->comment)) {
  2333. flags |= GZ_FLAG_COMMENT;
  2334. }
  2335. if (!(gz->z.flags & GZFILE_FLAG_MTIME_IS_SET)) {
  2336. gz->mtime = time(0);
  2337. }
  2338. if (gz->level == Z_BEST_SPEED) {
  2339. extraflags |= GZ_EXTRAFLAG_FAST;
  2340. }
  2341. else if (gz->level == Z_BEST_COMPRESSION) {
  2342. extraflags |= GZ_EXTRAFLAG_SLOW;
  2343. }
  2344. buf[0] = GZ_MAGIC1;
  2345. buf[1] = GZ_MAGIC2;
  2346. buf[2] = GZ_METHOD_DEFLATE;
  2347. buf[3] = flags;
  2348. gzfile_set32((unsigned long)gz->mtime, &buf[4]);
  2349. buf[8] = extraflags;
  2350. buf[9] = gz->os_code;
  2351. zstream_append_buffer(&gz->z, buf, (long)sizeof(buf));
  2352. if (!NIL_P(gz->orig_name)) {
  2353. zstream_append_buffer2(&gz->z, gz->orig_name);
  2354. zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
  2355. }
  2356. if (!NIL_P(gz->comment)) {
  2357. zstream_append_buffer2(&gz->z, gz->comment);
  2358. zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
  2359. }
  2360. gz->z.flags |= GZFILE_FLAG_HEADER_FINISHED;
  2361. }
  2362. static void
  2363. gzfile_make_footer(struct gzfile *gz)
  2364. {
  2365. Bytef buf[8]; /* 8 is the size of gzip footer */
  2366. gzfile_set32(gz->crc, buf);
  2367. gzfile_set32(gz->z.stream.total_in, &buf[4]);
  2368. zstream_append_buffer(&gz->z, buf, (long)sizeof(buf));
  2369. gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
  2370. }
  2371. static void
  2372. gzfile_read_header(struct gzfile *gz, VALUE outbuf)
  2373. {
  2374. const unsigned char *head;
  2375. long len;
  2376. char flags, *p;
  2377. /* 10 is the size of gzip header */
  2378. if (!gzfile_read_raw_ensure(gz, 10, outbuf)) {
  2379. gzfile_raise(gz, cGzError, "not in gzip format");
  2380. }
  2381. head = (unsigned char*)RSTRING_PTR(gz->z.input);
  2382. if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {
  2383. gzfile_raise(gz, cGzError, "not in gzip format");
  2384. }
  2385. if (head[2] != GZ_METHOD_DEFLATE) {
  2386. rb_raise(cGzError, "unsupported compression method %d", head[2]);
  2387. }
  2388. flags = head[3];
  2389. if (flags & GZ_FLAG_MULTIPART) {
  2390. rb_raise(cGzError, "multi-part gzip file is not supported");
  2391. }
  2392. else if (flags & GZ_FLAG_ENCRYPT) {
  2393. rb_raise(cGzError, "encrypted gzip file is not supported");
  2394. }
  2395. else if (flags & GZ_FLAG_UNKNOWN_MASK) {
  2396. rb_raise(cGzError, "unknown flags 0x%02x", flags);
  2397. }
  2398. if (head[8] & GZ_EXTRAFLAG_FAST) {
  2399. gz->level = Z_BEST_SPEED;
  2400. }
  2401. else if (head[8] & GZ_EXTRAFLAG_SLOW) {
  2402. gz->level = Z_BEST_COMPRESSION;
  2403. }
  2404. else {
  2405. gz->level = Z_DEFAULT_COMPRESSION;
  2406. }
  2407. gz->mtime = gzfile_get32(&head[4]);
  2408. gz->os_code = head[9];
  2409. zstream_discard_input(&gz->z, 10);
  2410. if (flags & GZ_FLAG_EXTRA) {
  2411. if (!gzfile_read_raw_ensure(gz, 2, outbuf)) {
  2412. rb_raise(cGzError, "unexpected end of file");
  2413. }
  2414. len = gzfile_get16((Bytef*)RSTRING_PTR(gz->z.input));
  2415. if (!gzfile_read_raw_ensure(gz, 2 + len, outbuf)) {
  2416. rb_raise(cGzError, "unexpected end of file");
  2417. }
  2418. zstream_discard_input(&gz->z, 2 + len);
  2419. }
  2420. if (flags & GZ_FLAG_ORIG_NAME) {
  2421. if (!gzfile_read_raw_ensure(gz, 1, outbuf)) {
  2422. rb_raise(cGzError, "unexpected end of file");
  2423. }
  2424. p = gzfile_read_raw_until_zero(gz, 0);
  2425. len = p - RSTRING_PTR(gz->z.input);
  2426. gz->orig_name = rb_str_new(RSTRING_PTR(gz->z.input), len);
  2427. zstream_discard_input(&gz->z, len + 1);
  2428. }
  2429. if (flags & GZ_FLAG_COMMENT) {
  2430. if (!gzfile_read_raw_ensure(gz, 1, outbuf)) {
  2431. rb_raise(cGzError, "unexpected end of file");
  2432. }
  2433. p = gzfile_read_raw_until_zero(gz, 0);
  2434. len = p - RSTRING_PTR(gz->z.input);
  2435. gz->comment = rb_str_new(RSTRING_PTR(gz->z.input), len);
  2436. zstream_discard_input(&gz->z, len + 1);
  2437. }
  2438. if (gz->z.input != Qnil && RSTRING_LEN(gz->z.input) > 0) {
  2439. zstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);
  2440. }
  2441. }
  2442. static void
  2443. gzfile_check_footer(struct gzfile *gz, VALUE outbuf)
  2444. {
  2445. unsigned long crc, length;
  2446. gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
  2447. /* 8 is the size of gzip footer */
  2448. if (!gzfile_read_raw_ensure(gz, 8, outbuf)) {
  2449. gzfile_raise(gz, cNoFooter, "footer is not found");
  2450. }
  2451. crc = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input));
  2452. length = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input) + 4);
  2453. gz->z.stream.total_in += 8; /* to rewind correctly */
  2454. zstream_discard_input(&gz->z, 8);
  2455. if (gz->crc != crc) {
  2456. rb_raise(cCRCError, "invalid compressed data -- crc error");
  2457. }
  2458. if ((uint32_t)gz->z.stream.total_out != length) {
  2459. rb_raise(cLengthError, "invalid compressed data -- length error");
  2460. }
  2461. }
  2462. static void
  2463. gzfile_write(struct gzfile *gz, Bytef *str, long len)
  2464. {
  2465. if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
  2466. gzfile_make_header(gz);
  2467. }
  2468. if (len > 0 || (gz->z.flags & GZFILE_FLAG_SYNC)) {
  2469. gz->crc = checksum_long(crc32, gz->crc, str, len);
  2470. zstream_run(&gz->z, str, len, (gz->z.flags & GZFILE_FLAG_SYNC)
  2471. ? Z_SYNC_FLUSH : Z_NO_FLUSH);
  2472. }
  2473. gzfile_write_raw(gz);
  2474. }
  2475. static long
  2476. gzfile_read_more(struct gzfile *gz, VALUE outbuf)
  2477. {
  2478. VALUE str;
  2479. while (!ZSTREAM_IS_FINISHED(&gz->z)) {
  2480. str = gzfile_read_raw(gz, outbuf);
  2481. if (NIL_P(str)) {
  2482. if (!ZSTREAM_IS_FINISHED(&gz->z)) {
  2483. rb_raise(cGzError, "unexpected end of file");
  2484. }
  2485. break;
  2486. }
  2487. if (RSTRING_LEN(str) > 0) { /* prevent Z_BUF_ERROR */
  2488. zstream_run(&gz->z, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str),
  2489. Z_SYNC_FLUSH);
  2490. RB_GC_GUARD(str);
  2491. }
  2492. if (ZSTREAM_BUF_FILLED(&gz->z) > 0) break;
  2493. }
  2494. return ZSTREAM_BUF_FILLED(&gz->z);
  2495. }
  2496. static void
  2497. gzfile_calc_crc(struct gzfile *gz, VALUE str)
  2498. {
  2499. if (RSTRING_LEN(str) <= gz->ungetc) {
  2500. gz->ungetc -= RSTRING_LEN(str);
  2501. }
  2502. else {
  2503. gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
  2504. RSTRING_LEN(str) - gz->ungetc);
  2505. gz->ungetc = 0;
  2506. }
  2507. }
  2508. static VALUE
  2509. gzfile_newstr(struct gzfile *gz, VALUE str)
  2510. {
  2511. if (!gz->enc2) {
  2512. rb_enc_associate(str, gz->enc);
  2513. return str;
  2514. }
  2515. if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
  2516. str = rb_econv_str_convert(gz->ec, str, ECONV_PARTIAL_INPUT);
  2517. rb_enc_associate(str, gz->enc);
  2518. return str;
  2519. }
  2520. return rb_str_conv_enc_opts(str, gz->enc2, gz->enc,
  2521. gz->ecflags, gz->ecopts);
  2522. }
  2523. static long
  2524. gzfile_fill(struct gzfile *gz, long len)
  2525. {
  2526. if (len < 0)
  2527. rb_raise(rb_eArgError, "negative length %ld given", len);
  2528. if (len == 0)
  2529. return 0;
  2530. while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) < len) {
  2531. gzfile_read_more(gz, Qnil);
  2532. }
  2533. if (GZFILE_IS_FINISHED(gz)) {
  2534. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  2535. gzfile_check_footer(gz, Qnil);
  2536. }
  2537. return -1;
  2538. }
  2539. return len < ZSTREAM_BUF_FILLED(&gz->z) ? len : ZSTREAM_BUF_FILLED(&gz->z);
  2540. }
  2541. static VALUE
  2542. gzfile_read(struct gzfile *gz, long len)
  2543. {
  2544. VALUE dst;
  2545. len = gzfile_fill(gz, len);
  2546. if (len == 0) return rb_str_new(0, 0);
  2547. if (len < 0) return Qnil;
  2548. dst = zstream_shift_buffer(&gz->z, len);
  2549. if (!NIL_P(dst)) gzfile_calc_crc(gz, dst);
  2550. return dst;
  2551. }
  2552. static VALUE
  2553. gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
  2554. {
  2555. VALUE dst;
  2556. if (len < 0)
  2557. rb_raise(rb_eArgError, "negative length %ld given", len);
  2558. if (len == 0) {
  2559. if (NIL_P(outbuf))
  2560. return rb_str_new(0, 0);
  2561. else {
  2562. rb_str_resize(outbuf, 0);
  2563. return outbuf;
  2564. }
  2565. }
  2566. while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) {
  2567. gzfile_read_more(gz, outbuf);
  2568. }
  2569. if (GZFILE_IS_FINISHED(gz)) {
  2570. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  2571. gzfile_check_footer(gz, outbuf);
  2572. }
  2573. if (!NIL_P(outbuf))
  2574. rb_str_resize(outbuf, 0);
  2575. rb_raise(rb_eEOFError, "end of file reached");
  2576. }
  2577. dst = zstream_shift_buffer(&gz->z, len);
  2578. gzfile_calc_crc(gz, dst);
  2579. if (!NIL_P(outbuf)) {
  2580. rb_str_resize(outbuf, RSTRING_LEN(dst));
  2581. memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
  2582. rb_str_resize(dst, 0);
  2583. rb_gc_force_recycle(dst);
  2584. dst = outbuf;
  2585. }
  2586. return dst;
  2587. }
  2588. static VALUE
  2589. gzfile_read_all(struct gzfile *gz)
  2590. {
  2591. VALUE dst;
  2592. while (!ZSTREAM_IS_FINISHED(&gz->z)) {
  2593. gzfile_read_more(gz, Qnil);
  2594. }
  2595. if (GZFILE_IS_FINISHED(gz)) {
  2596. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  2597. gzfile_check_footer(gz, Qnil);
  2598. }
  2599. return rb_str_new(0, 0);
  2600. }
  2601. dst = zstream_detach_buffer(&gz->z);
  2602. if (NIL_P(dst)) return dst;
  2603. gzfile_calc_crc(gz, dst);
  2604. return gzfile_newstr(gz, dst);
  2605. }
  2606. static VALUE
  2607. gzfile_getc(struct gzfile *gz)
  2608. {
  2609. VALUE buf, dst = 0;
  2610. int len;
  2611. len = rb_enc_mbmaxlen(gz->enc);
  2612. while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) < len) {
  2613. gzfile_read_more(gz, Qnil);
  2614. }
  2615. if (GZFILE_IS_FINISHED(gz)) {
  2616. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  2617. gzfile_check_footer(gz, Qnil);
  2618. }
  2619. return Qnil;
  2620. }
  2621. if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
  2622. const unsigned char *ss, *sp, *se;
  2623. unsigned char *ds, *dp, *de;
  2624. VALUE cbuf = rb_enc_str_new(0, GZFILE_CBUF_CAPA, gz->enc);
  2625. ss = sp = (const unsigned char*)RSTRING_PTR(gz->z.buf);
  2626. se = sp + ZSTREAM_BUF_FILLED(&gz->z);
  2627. ds = dp = (unsigned char *)RSTRING_PTR(cbuf);
  2628. de = (unsigned char *)ds + GZFILE_CBUF_CAPA;
  2629. (void)rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
  2630. rb_econv_check_error(gz->ec);
  2631. dst = zstream_shift_buffer(&gz->z, sp - ss);
  2632. gzfile_calc_crc(gz, dst);
  2633. rb_str_resize(cbuf, dp - ds);
  2634. return cbuf;
  2635. }
  2636. else {
  2637. buf = gz->z.buf;
  2638. len = rb_enc_mbclen(RSTRING_PTR(buf), RSTRING_END(buf), gz->enc);
  2639. dst = gzfile_read(gz, len);
  2640. if (NIL_P(dst)) return dst;
  2641. return gzfile_newstr(gz, dst);
  2642. }
  2643. }
  2644. static void
  2645. gzfile_ungets(struct gzfile *gz, const Bytef *b, long len)
  2646. {
  2647. zstream_buffer_ungets(&gz->z, b, len);
  2648. gz->ungetc+=len;
  2649. }
  2650. static void
  2651. gzfile_ungetbyte(struct gzfile *gz, int c)
  2652. {
  2653. zstream_buffer_ungetbyte(&gz->z, c);
  2654. gz->ungetc++;
  2655. }
  2656. static VALUE
  2657. gzfile_writer_end_run(VALUE arg)
  2658. {
  2659. struct gzfile *gz = (struct gzfile *)arg;
  2660. if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
  2661. gzfile_make_header(gz);
  2662. }
  2663. zstream_run(&gz->z, (Bytef*)"", 0, Z_FINISH);
  2664. gzfile_make_footer(gz);
  2665. gzfile_write_raw(gz);
  2666. return Qnil;
  2667. }
  2668. static void
  2669. gzfile_writer_end(struct gzfile *gz)
  2670. {
  2671. if (ZSTREAM_IS_CLOSING(&gz->z)) return;
  2672. gz->z.flags |= ZSTREAM_FLAG_CLOSING;
  2673. rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_ensure_end, (VALUE)&gz->z);
  2674. }
  2675. static VALUE
  2676. gzfile_reader_end_run(VALUE arg)
  2677. {
  2678. struct gzfile *gz = (struct gzfile *)arg;
  2679. if (GZFILE_IS_FINISHED(gz)
  2680. && !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  2681. gzfile_check_footer(gz, Qnil);
  2682. }
  2683. return Qnil;
  2684. }
  2685. static void
  2686. gzfile_reader_end(struct gzfile *gz)
  2687. {
  2688. if (ZSTREAM_IS_CLOSING(&gz->z)) return;
  2689. gz->z.flags |= ZSTREAM_FLAG_CLOSING;
  2690. rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_ensure_end, (VALUE)&gz->z);
  2691. }
  2692. static void
  2693. gzfile_reader_rewind(struct gzfile *gz)
  2694. {
  2695. long n;
  2696. n = gz->z.stream.total_in;
  2697. if (!NIL_P(gz->z.input)) {
  2698. n += RSTRING_LEN(gz->z.input);
  2699. }
  2700. rb_funcall(gz->io, id_seek, 2, rb_int2inum(-n), INT2FIX(1));
  2701. gzfile_reset(gz);
  2702. }
  2703. static VALUE
  2704. gzfile_reader_get_unused(struct gzfile *gz)
  2705. {
  2706. VALUE str;
  2707. if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;
  2708. if (!GZFILE_IS_FINISHED(gz)) return Qnil;
  2709. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  2710. gzfile_check_footer(gz, Qnil);
  2711. }
  2712. if (NIL_P(gz->z.input)) return Qnil;
  2713. str = rb_str_resurrect(gz->z.input);
  2714. return str;
  2715. }
  2716. static struct gzfile *
  2717. get_gzfile(VALUE obj)
  2718. {
  2719. struct gzfile *gz;
  2720. TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
  2721. if (!ZSTREAM_IS_READY(&gz->z)) {
  2722. rb_raise(cGzError, "closed gzip stream");
  2723. }
  2724. return gz;
  2725. }
  2726. /* ------------------------------------------------------------------------- */
  2727. /*
  2728. * Document-class: Zlib::GzipFile
  2729. *
  2730. * Zlib::GzipFile is an abstract class for handling a gzip formatted
  2731. * compressed file. The operations are defined in the subclasses,
  2732. * Zlib::GzipReader for reading, and Zlib::GzipWriter for writing.
  2733. *
  2734. * GzipReader should be used by associating an IO, or IO-like, object.
  2735. *
  2736. * == Method Catalogue
  2737. *
  2738. * - ::wrap
  2739. * - ::open (Zlib::GzipReader::open and Zlib::GzipWriter::open)
  2740. * - #close
  2741. * - #closed?
  2742. * - #comment
  2743. * - comment= (Zlib::GzipWriter#comment=)
  2744. * - #crc
  2745. * - eof? (Zlib::GzipReader#eof?)
  2746. * - #finish
  2747. * - #level
  2748. * - lineno (Zlib::GzipReader#lineno)
  2749. * - lineno= (Zlib::GzipReader#lineno=)
  2750. * - #mtime
  2751. * - mtime= (Zlib::GzipWriter#mtime=)
  2752. * - #orig_name
  2753. * - orig_name (Zlib::GzipWriter#orig_name=)
  2754. * - #os_code
  2755. * - path (when the underlying IO supports #path)
  2756. * - #sync
  2757. * - #sync=
  2758. * - #to_io
  2759. *
  2760. * (due to internal structure, documentation may appear under Zlib::GzipReader
  2761. * or Zlib::GzipWriter)
  2762. */
  2763. typedef struct {
  2764. int argc;
  2765. VALUE *argv;
  2766. VALUE klass;
  2767. } new_wrap_arg_t;
  2768. static VALUE
  2769. new_wrap(VALUE tmp)
  2770. {
  2771. new_wrap_arg_t *arg = (new_wrap_arg_t *)tmp;
  2772. return rb_class_new_instance_kw(arg->argc, arg->argv, arg->klass, RB_PASS_CALLED_KEYWORDS);
  2773. }
  2774. static VALUE
  2775. gzfile_ensure_close(VALUE obj)
  2776. {
  2777. struct gzfile *gz;
  2778. TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
  2779. if (ZSTREAM_IS_READY(&gz->z)) {
  2780. gzfile_close(gz, 1);
  2781. }
  2782. return Qnil;
  2783. }
  2784. static VALUE
  2785. gzfile_wrap(int argc, VALUE *argv, VALUE klass, int close_io_on_error)
  2786. {
  2787. VALUE obj;
  2788. if (close_io_on_error) {
  2789. int state = 0;
  2790. new_wrap_arg_t arg;
  2791. arg.argc = argc;
  2792. arg.argv = argv;
  2793. arg.klass = klass;
  2794. obj = rb_protect(new_wrap, (VALUE)&arg, &state);
  2795. if (state) {
  2796. rb_io_close(argv[0]);
  2797. rb_jump_tag(state);
  2798. }
  2799. }
  2800. else {
  2801. obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
  2802. }
  2803. if (rb_block_given_p()) {
  2804. return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);
  2805. }
  2806. else {
  2807. return obj;
  2808. }
  2809. }
  2810. /*
  2811. * Document-method: Zlib::GzipFile.wrap
  2812. *
  2813. * call-seq:
  2814. * Zlib::GzipReader.wrap(io, ...) { |gz| ... }
  2815. * Zlib::GzipWriter.wrap(io, ...) { |gz| ... }
  2816. *
  2817. * Creates a GzipReader or GzipWriter associated with +io+, passing in any
  2818. * necessary extra options, and executes the block with the newly created
  2819. * object just like File.open.
  2820. *
  2821. * The GzipFile object will be closed automatically after executing the block.
  2822. * If you want to keep the associated IO object open, you may call
  2823. * Zlib::GzipFile#finish method in the block.
  2824. */
  2825. static VALUE
  2826. rb_gzfile_s_wrap(int argc, VALUE *argv, VALUE klass)
  2827. {
  2828. return gzfile_wrap(argc, argv, klass, 0);
  2829. }
  2830. /*
  2831. * Document-method: Zlib::GzipFile.open
  2832. *
  2833. * See Zlib::GzipReader#open and Zlib::GzipWriter#open.
  2834. */
  2835. static VALUE
  2836. gzfile_s_open(int argc, VALUE *argv, VALUE klass, const char *mode)
  2837. {
  2838. VALUE io, filename;
  2839. rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
  2840. filename = argv[0];
  2841. io = rb_file_open_str(filename, mode);
  2842. argv[0] = io;
  2843. return gzfile_wrap(argc, argv, klass, 1);
  2844. }
  2845. /*
  2846. * Document-method: Zlib::GzipFile#to_io
  2847. *
  2848. * Same as IO.
  2849. */
  2850. static VALUE
  2851. rb_gzfile_to_io(VALUE obj)
  2852. {
  2853. return get_gzfile(obj)->io;
  2854. }
  2855. /*
  2856. * Document-method: Zlib::GzipFile#crc
  2857. *
  2858. * Returns CRC value of the uncompressed data.
  2859. */
  2860. static VALUE
  2861. rb_gzfile_crc(VALUE obj)
  2862. {
  2863. return rb_uint2inum(get_gzfile(obj)->crc);
  2864. }
  2865. /*
  2866. * Document-method: Zlib::GzipFile#mtime
  2867. *
  2868. * Returns last modification time recorded in the gzip file header.
  2869. */
  2870. static VALUE
  2871. rb_gzfile_mtime(VALUE obj)
  2872. {
  2873. return rb_time_new(get_gzfile(obj)->mtime, (time_t)0);
  2874. }
  2875. /*
  2876. * Document-method: Zlib::GzipFile#level
  2877. *
  2878. * Returns compression level.
  2879. */
  2880. static VALUE
  2881. rb_gzfile_level(VALUE obj)
  2882. {
  2883. return INT2FIX(get_gzfile(obj)->level);
  2884. }
  2885. /*
  2886. * Document-method: Zlib::GzipFile#os_code
  2887. *
  2888. * Returns OS code number recorded in the gzip file header.
  2889. */
  2890. static VALUE
  2891. rb_gzfile_os_code(VALUE obj)
  2892. {
  2893. return INT2FIX(get_gzfile(obj)->os_code);
  2894. }
  2895. /*
  2896. * Document-method: Zlib::GzipFile#orig_name
  2897. *
  2898. * Returns original filename recorded in the gzip file header, or +nil+ if
  2899. * original filename is not present.
  2900. */
  2901. static VALUE
  2902. rb_gzfile_orig_name(VALUE obj)
  2903. {
  2904. VALUE str = get_gzfile(obj)->orig_name;
  2905. if (!NIL_P(str)) {
  2906. str = rb_str_dup(str);
  2907. }
  2908. return str;
  2909. }
  2910. /*
  2911. * Document-method: Zlib::GzipFile#comment
  2912. *
  2913. * Returns comments recorded in the gzip file header, or nil if the comments
  2914. * is not present.
  2915. */
  2916. static VALUE
  2917. rb_gzfile_comment(VALUE obj)
  2918. {
  2919. VALUE str = get_gzfile(obj)->comment;
  2920. if (!NIL_P(str)) {
  2921. str = rb_str_dup(str);
  2922. }
  2923. return str;
  2924. }
  2925. /*
  2926. * Document-method: Zlib::GzipFile#lineno
  2927. *
  2928. * The line number of the last row read from this file.
  2929. */
  2930. static VALUE
  2931. rb_gzfile_lineno(VALUE obj)
  2932. {
  2933. return INT2NUM(get_gzfile(obj)->lineno);
  2934. }
  2935. /*
  2936. * Document-method: Zlib::GzipReader#lineno=
  2937. *
  2938. * Specify line number of the last row read from this file.
  2939. */
  2940. static VALUE
  2941. rb_gzfile_set_lineno(VALUE obj, VALUE lineno)
  2942. {
  2943. struct gzfile *gz = get_gzfile(obj);
  2944. gz->lineno = NUM2INT(lineno);
  2945. return lineno;
  2946. }
  2947. /*
  2948. * Document-method: Zlib::GzipWriter#mtime=
  2949. *
  2950. * Specify the modification time (+mtime+) in the gzip header.
  2951. * Using an Integer.
  2952. *
  2953. * Setting the mtime in the gzip header does not effect the
  2954. * mtime of the file generated. Different utilities that
  2955. * expand the gzipped files may use the mtime
  2956. * header. For example the gunzip utility can use the `-N`
  2957. * flag which will set the resultant file's mtime to the
  2958. * value in the header. By default many tools will set
  2959. * the mtime of the expanded file to the mtime of the
  2960. * gzipped file, not the mtime in the header.
  2961. *
  2962. * If you do not set an mtime, the default value will be the time
  2963. * when compression started. Setting a value of 0 indicates
  2964. * no time stamp is available.
  2965. */
  2966. static VALUE
  2967. rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
  2968. {
  2969. struct gzfile *gz = get_gzfile(obj);
  2970. VALUE val;
  2971. if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
  2972. rb_raise(cGzError, "header is already written");
  2973. }
  2974. val = rb_Integer(mtime);
  2975. gz->mtime = NUM2UINT(val);
  2976. gz->z.flags |= GZFILE_FLAG_MTIME_IS_SET;
  2977. return mtime;
  2978. }
  2979. /*
  2980. * Document-method: Zlib::GzipFile#orig_name=
  2981. *
  2982. * Specify the original name (+str+) in the gzip header.
  2983. */
  2984. static VALUE
  2985. rb_gzfile_set_orig_name(VALUE obj, VALUE str)
  2986. {
  2987. struct gzfile *gz = get_gzfile(obj);
  2988. VALUE s;
  2989. char *p;
  2990. if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
  2991. rb_raise(cGzError, "header is already written");
  2992. }
  2993. s = rb_str_dup(rb_str_to_str(str));
  2994. p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
  2995. if (p) {
  2996. rb_str_resize(s, p - RSTRING_PTR(s));
  2997. }
  2998. gz->orig_name = s;
  2999. return str;
  3000. }
  3001. /*
  3002. * Document-method: Zlib::GzipFile#comment=
  3003. *
  3004. * Specify the comment (+str+) in the gzip header.
  3005. */
  3006. static VALUE
  3007. rb_gzfile_set_comment(VALUE obj, VALUE str)
  3008. {
  3009. struct gzfile *gz = get_gzfile(obj);
  3010. VALUE s;
  3011. char *p;
  3012. if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
  3013. rb_raise(cGzError, "header is already written");
  3014. }
  3015. s = rb_str_dup(rb_str_to_str(str));
  3016. p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
  3017. if (p) {
  3018. rb_str_resize(s, p - RSTRING_PTR(s));
  3019. }
  3020. gz->comment = s;
  3021. return str;
  3022. }
  3023. /*
  3024. * Document-method: Zlib::GzipFile#close
  3025. *
  3026. * Closes the GzipFile object. This method calls close method of the
  3027. * associated IO object. Returns the associated IO object.
  3028. */
  3029. static VALUE
  3030. rb_gzfile_close(VALUE obj)
  3031. {
  3032. struct gzfile *gz;
  3033. VALUE io;
  3034. TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
  3035. if (!ZSTREAM_IS_READY(&gz->z)) {
  3036. return Qnil;
  3037. }
  3038. io = gz->io;
  3039. gzfile_close(gz, 1);
  3040. return io;
  3041. }
  3042. /*
  3043. * Document-method: Zlib::GzipFile#finish
  3044. *
  3045. * Closes the GzipFile object. Unlike Zlib::GzipFile#close, this method never
  3046. * calls the close method of the associated IO object. Returns the associated IO
  3047. * object.
  3048. */
  3049. static VALUE
  3050. rb_gzfile_finish(VALUE obj)
  3051. {
  3052. struct gzfile *gz = get_gzfile(obj);
  3053. VALUE io;
  3054. io = gz->io;
  3055. gzfile_close(gz, 0);
  3056. return io;
  3057. }
  3058. /*
  3059. * Document-method: Zlib::GzipFile#closed?
  3060. *
  3061. * Same as IO#closed?
  3062. *
  3063. */
  3064. static VALUE
  3065. rb_gzfile_closed_p(VALUE obj)
  3066. {
  3067. struct gzfile *gz;
  3068. TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
  3069. return NIL_P(gz->io) ? Qtrue : Qfalse;
  3070. }
  3071. /*
  3072. * Document-method: Zlib::GzipFile#eof?
  3073. *
  3074. * Returns +true+ or +false+ whether the stream has reached the end.
  3075. */
  3076. static VALUE
  3077. rb_gzfile_eof_p(VALUE obj)
  3078. {
  3079. struct gzfile *gz = get_gzfile(obj);
  3080. return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
  3081. }
  3082. /*
  3083. * Document-method: Zlib::GzipFile#sync
  3084. *
  3085. * Same as IO#sync
  3086. *
  3087. */
  3088. static VALUE
  3089. rb_gzfile_sync(VALUE obj)
  3090. {
  3091. return (get_gzfile(obj)->z.flags & GZFILE_FLAG_SYNC) ? Qtrue : Qfalse;
  3092. }
  3093. /*
  3094. * Document-method: Zlib::GzipFile#sync=
  3095. *
  3096. * call-seq: sync = flag
  3097. *
  3098. * Same as IO. If flag is +true+, the associated IO object must respond to the
  3099. * +flush+ method. While +sync+ mode is +true+, the compression ratio
  3100. * decreases sharply.
  3101. */
  3102. static VALUE
  3103. rb_gzfile_set_sync(VALUE obj, VALUE mode)
  3104. {
  3105. struct gzfile *gz = get_gzfile(obj);
  3106. if (RTEST(mode)) {
  3107. gz->z.flags |= GZFILE_FLAG_SYNC;
  3108. }
  3109. else {
  3110. gz->z.flags &= ~GZFILE_FLAG_SYNC;
  3111. }
  3112. return mode;
  3113. }
  3114. /*
  3115. * Document-method: Zlib::GzipFile#total_in
  3116. *
  3117. * Total number of input bytes read so far.
  3118. */
  3119. static VALUE
  3120. rb_gzfile_total_in(VALUE obj)
  3121. {
  3122. return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
  3123. }
  3124. /*
  3125. * Document-method: Zlib::GzipFile#total_out
  3126. *
  3127. * Total number of output bytes output so far.
  3128. */
  3129. static VALUE
  3130. rb_gzfile_total_out(VALUE obj)
  3131. {
  3132. struct gzfile *gz = get_gzfile(obj);
  3133. uLong total_out = gz->z.stream.total_out;
  3134. long buf_filled = ZSTREAM_BUF_FILLED(&gz->z);
  3135. if (total_out >= (uLong)buf_filled) {
  3136. return rb_uint2inum(total_out - buf_filled);
  3137. } else {
  3138. return LONG2FIX(-(buf_filled - (long)total_out));
  3139. }
  3140. }
  3141. /*
  3142. * Document-method: Zlib::GzipFile#path
  3143. *
  3144. * call-seq: path
  3145. *
  3146. * Returns the path string of the associated IO-like object. This
  3147. * method is only defined when the IO-like object responds to #path().
  3148. */
  3149. static VALUE
  3150. rb_gzfile_path(VALUE obj)
  3151. {
  3152. struct gzfile *gz;
  3153. TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
  3154. return gz->path;
  3155. }
  3156. static VALUE
  3157. gzfile_initialize_path_partial(VALUE obj)
  3158. {
  3159. struct gzfile* gz;
  3160. TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
  3161. gz->path = rb_funcall(gz->io, id_path, 0);
  3162. rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
  3163. return Qnil;
  3164. }
  3165. static void
  3166. rb_gzfile_ecopts(struct gzfile *gz, VALUE opts)
  3167. {
  3168. if (!NIL_P(opts)) {
  3169. rb_io_extract_encoding_option(opts, &gz->enc, &gz->enc2, NULL);
  3170. }
  3171. if (gz->enc2) {
  3172. gz->ecflags = rb_econv_prepare_opts(opts, &opts);
  3173. gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
  3174. gz->ecflags, opts);
  3175. gz->ecopts = opts;
  3176. }
  3177. }
  3178. /* ------------------------------------------------------------------------- */
  3179. /*
  3180. * Document-class: Zlib::GzipWriter
  3181. *
  3182. * Zlib::GzipWriter is a class for writing gzipped files. GzipWriter should
  3183. * be used with an instance of IO, or IO-like, object.
  3184. *
  3185. * Following two example generate the same result.
  3186. *
  3187. * Zlib::GzipWriter.open('hoge.gz') do |gz|
  3188. * gz.write 'jugemu jugemu gokou no surikire...'
  3189. * end
  3190. *
  3191. * File.open('hoge.gz', 'w') do |f|
  3192. * gz = Zlib::GzipWriter.new(f)
  3193. * gz.write 'jugemu jugemu gokou no surikire...'
  3194. * gz.close
  3195. * end
  3196. *
  3197. * To make like gzip(1) does, run following:
  3198. *
  3199. * orig = 'hoge.txt'
  3200. * Zlib::GzipWriter.open('hoge.gz') do |gz|
  3201. * gz.mtime = File.mtime(orig)
  3202. * gz.orig_name = orig
  3203. * gz.write IO.binread(orig)
  3204. * end
  3205. *
  3206. * NOTE: Due to the limitation of Ruby's finalizer, you must explicitly close
  3207. * GzipWriter objects by Zlib::GzipWriter#close etc. Otherwise, GzipWriter
  3208. * will be not able to write the gzip footer and will generate a broken gzip
  3209. * file.
  3210. */
  3211. static VALUE
  3212. rb_gzwriter_s_allocate(VALUE klass)
  3213. {
  3214. return gzfile_writer_new(klass);
  3215. }
  3216. /*
  3217. * call-seq: Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... }
  3218. *
  3219. * Opens a file specified by +filename+ for writing gzip compressed data, and
  3220. * returns a GzipWriter object associated with that file. Further details of
  3221. * this method are found in Zlib::GzipWriter.new and Zlib::GzipFile.wrap.
  3222. */
  3223. static VALUE
  3224. rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
  3225. {
  3226. return gzfile_s_open(argc, argv, klass, "wb");
  3227. }
  3228. /*
  3229. * call-seq:
  3230. * Zlib::GzipWriter.new(io, level = nil, strategy = nil, options = {})
  3231. *
  3232. * Creates a GzipWriter object associated with +io+. +level+ and +strategy+
  3233. * should be the same as the arguments of Zlib::Deflate.new. The GzipWriter
  3234. * object writes gzipped data to +io+. +io+ must respond to the
  3235. * +write+ method that behaves the same as IO#write.
  3236. *
  3237. * The +options+ hash may be used to set the encoding of the data.
  3238. * +:external_encoding+, +:internal_encoding+ and +:encoding+ may be set as in
  3239. * IO::new.
  3240. */
  3241. static VALUE
  3242. rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
  3243. {
  3244. struct gzfile *gz;
  3245. VALUE io, level, strategy, opt = Qnil;
  3246. int err;
  3247. if (argc > 1) {
  3248. opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
  3249. if (!NIL_P(opt)) argc--;
  3250. }
  3251. rb_scan_args(argc, argv, "12", &io, &level, &strategy);
  3252. TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
  3253. /* this is undocumented feature of zlib */
  3254. gz->level = ARG_LEVEL(level);
  3255. err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
  3256. -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
  3257. if (err != Z_OK) {
  3258. raise_zlib_error(err, gz->z.stream.msg);
  3259. }
  3260. gz->io = io;
  3261. ZSTREAM_READY(&gz->z);
  3262. rb_gzfile_ecopts(gz, opt);
  3263. if (rb_respond_to(io, id_path)) {
  3264. /* File#path may raise IOError in case when a path is unavailable */
  3265. rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
  3266. }
  3267. return obj;
  3268. }
  3269. /*
  3270. * call-seq: flush(flush=nil)
  3271. *
  3272. * Flushes all the internal buffers of the GzipWriter object. The meaning of
  3273. * +flush+ is same as in Zlib::Deflate#deflate. <tt>Zlib::SYNC_FLUSH</tt> is used if
  3274. * +flush+ is omitted. It is no use giving flush <tt>Zlib::NO_FLUSH</tt>.
  3275. */
  3276. static VALUE
  3277. rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj)
  3278. {
  3279. struct gzfile *gz = get_gzfile(obj);
  3280. VALUE v_flush;
  3281. int flush;
  3282. rb_scan_args(argc, argv, "01", &v_flush);
  3283. flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
  3284. if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
  3285. zstream_run(&gz->z, (Bytef*)"", 0, flush);
  3286. }
  3287. gzfile_write_raw(gz);
  3288. if (rb_respond_to(gz->io, id_flush)) {
  3289. rb_funcall(gz->io, id_flush, 0);
  3290. }
  3291. return obj;
  3292. }
  3293. /*
  3294. * Same as IO.
  3295. */
  3296. static VALUE
  3297. rb_gzwriter_write(int argc, VALUE *argv, VALUE obj)
  3298. {
  3299. struct gzfile *gz = get_gzfile(obj);
  3300. size_t total = 0;
  3301. while (argc-- > 0) {
  3302. VALUE str = *argv++;
  3303. if (!RB_TYPE_P(str, T_STRING))
  3304. str = rb_obj_as_string(str);
  3305. if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
  3306. str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
  3307. }
  3308. gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
  3309. total += RSTRING_LEN(str);
  3310. RB_GC_GUARD(str);
  3311. }
  3312. return SIZET2NUM(total);
  3313. }
  3314. /*
  3315. * Same as IO.
  3316. */
  3317. static VALUE
  3318. rb_gzwriter_putc(VALUE obj, VALUE ch)
  3319. {
  3320. struct gzfile *gz = get_gzfile(obj);
  3321. char c = NUM2CHR(ch);
  3322. gzfile_write(gz, (Bytef*)&c, 1);
  3323. return ch;
  3324. }
  3325. /*
  3326. * Document-method: <<
  3327. * Same as IO.
  3328. */
  3329. #define rb_gzwriter_addstr rb_io_addstr
  3330. /*
  3331. * Document-method: printf
  3332. * Same as IO.
  3333. */
  3334. #define rb_gzwriter_printf rb_io_printf
  3335. /*
  3336. * Document-method: print
  3337. * Same as IO.
  3338. */
  3339. #define rb_gzwriter_print rb_io_print
  3340. /*
  3341. * Document-method: puts
  3342. * Same as IO.
  3343. */
  3344. #define rb_gzwriter_puts rb_io_puts
  3345. /* ------------------------------------------------------------------------- */
  3346. /*
  3347. * Document-class: Zlib::GzipReader
  3348. *
  3349. * Zlib::GzipReader is the class for reading a gzipped file. GzipReader should
  3350. * be used as an IO, or -IO-like, object.
  3351. *
  3352. * Zlib::GzipReader.open('hoge.gz') {|gz|
  3353. * print gz.read
  3354. * }
  3355. *
  3356. * File.open('hoge.gz') do |f|
  3357. * gz = Zlib::GzipReader.new(f)
  3358. * print gz.read
  3359. * gz.close
  3360. * end
  3361. *
  3362. * == Method Catalogue
  3363. *
  3364. * The following methods in Zlib::GzipReader are just like their counterparts
  3365. * in IO, but they raise Zlib::Error or Zlib::GzipFile::Error exception if an
  3366. * error was found in the gzip file.
  3367. * - #each
  3368. * - #each_line
  3369. * - #each_byte
  3370. * - #gets
  3371. * - #getc
  3372. * - #lineno
  3373. * - #lineno=
  3374. * - #read
  3375. * - #readchar
  3376. * - #readline
  3377. * - #readlines
  3378. * - #ungetc
  3379. *
  3380. * Be careful of the footer of the gzip file. A gzip file has the checksum of
  3381. * pre-compressed data in its footer. GzipReader checks all uncompressed data
  3382. * against that checksum at the following cases, and if it fails, raises
  3383. * <tt>Zlib::GzipFile::NoFooter</tt>, <tt>Zlib::GzipFile::CRCError</tt>, or
  3384. * <tt>Zlib::GzipFile::LengthError</tt> exception.
  3385. *
  3386. * - When an reading request is received beyond the end of file (the end of
  3387. * compressed data). That is, when Zlib::GzipReader#read,
  3388. * Zlib::GzipReader#gets, or some other methods for reading returns nil.
  3389. * - When Zlib::GzipFile#close method is called after the object reaches the
  3390. * end of file.
  3391. * - When Zlib::GzipReader#unused method is called after the object reaches
  3392. * the end of file.
  3393. *
  3394. * The rest of the methods are adequately described in their own
  3395. * documentation.
  3396. */
  3397. static VALUE
  3398. rb_gzreader_s_allocate(VALUE klass)
  3399. {
  3400. return gzfile_reader_new(klass);
  3401. }
  3402. /*
  3403. * Document-method: Zlib::GzipReader.open
  3404. *
  3405. * call-seq: Zlib::GzipReader.open(filename) {|gz| ... }
  3406. *
  3407. * Opens a file specified by +filename+ as a gzipped file, and returns a
  3408. * GzipReader object associated with that file. Further details of this method
  3409. * are in Zlib::GzipReader.new and ZLib::GzipFile.wrap.
  3410. */
  3411. static VALUE
  3412. rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
  3413. {
  3414. return gzfile_s_open(argc, argv, klass, "rb");
  3415. }
  3416. /*
  3417. * Document-method: Zlib::GzipReader.zcat
  3418. *
  3419. * call-seq:
  3420. * Zlib::GzipReader.zcat(io, options = {}, &block) => nil
  3421. * Zlib::GzipReader.zcat(io, options = {}) => string
  3422. *
  3423. * Decompresses all gzip data in the +io+, handling multiple gzip
  3424. * streams until the end of the +io+. There should not be any non-gzip
  3425. * data after the gzip streams.
  3426. *
  3427. * If a block is given, it is yielded strings of uncompressed data,
  3428. * and the method returns +nil+.
  3429. * If a block is not given, the method returns the concatenation of
  3430. * all uncompressed data in all gzip streams.
  3431. */
  3432. static VALUE
  3433. rb_gzreader_s_zcat(int argc, VALUE *argv, VALUE klass)
  3434. {
  3435. VALUE io, unused, obj, buf=0, tmpbuf;
  3436. long pos;
  3437. rb_check_arity(argc, 1, 2);
  3438. io = argv[0];
  3439. do {
  3440. obj = rb_funcallv(klass, rb_intern("new"), argc, argv);
  3441. if (rb_block_given_p()) {
  3442. rb_gzreader_each(0, 0, obj);
  3443. }
  3444. else {
  3445. if (!buf) {
  3446. buf = rb_str_new(0, 0);
  3447. }
  3448. tmpbuf = gzfile_read_all(get_gzfile(obj));
  3449. rb_str_cat(buf, RSTRING_PTR(tmpbuf), RSTRING_LEN(tmpbuf));
  3450. }
  3451. rb_gzreader_read(0, 0, obj);
  3452. pos = NUM2LONG(rb_funcall(io, rb_intern("pos"), 0));
  3453. unused = rb_gzreader_unused(obj);
  3454. rb_gzfile_finish(obj);
  3455. if (!NIL_P(unused)) {
  3456. pos -= NUM2LONG(rb_funcall(unused, rb_intern("length"), 0));
  3457. rb_funcall(io, rb_intern("pos="), 1, LONG2NUM(pos));
  3458. }
  3459. } while (pos < NUM2LONG(rb_funcall(io, rb_intern("size"), 0)));
  3460. if (rb_block_given_p()) {
  3461. return Qnil;
  3462. }
  3463. return buf;
  3464. }
  3465. /*
  3466. * Document-method: Zlib::GzipReader.new
  3467. *
  3468. * call-seq:
  3469. * Zlib::GzipReader.new(io, options = {})
  3470. *
  3471. * Creates a GzipReader object associated with +io+. The GzipReader object reads
  3472. * gzipped data from +io+, and parses/decompresses it. The +io+ must
  3473. * have a +read+ method that behaves same as the IO#read.
  3474. *
  3475. * The +options+ hash may be used to set the encoding of the data.
  3476. * +:external_encoding+, +:internal_encoding+ and +:encoding+ may be set as in
  3477. * IO::new.
  3478. *
  3479. * If the gzip file header is incorrect, raises an Zlib::GzipFile::Error
  3480. * exception.
  3481. */
  3482. static VALUE
  3483. rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
  3484. {
  3485. VALUE io, opt = Qnil;
  3486. struct gzfile *gz;
  3487. int err;
  3488. TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
  3489. rb_scan_args(argc, argv, "1:", &io, &opt);
  3490. /* this is undocumented feature of zlib */
  3491. err = inflateInit2(&gz->z.stream, -MAX_WBITS);
  3492. if (err != Z_OK) {
  3493. raise_zlib_error(err, gz->z.stream.msg);
  3494. }
  3495. gz->io = io;
  3496. ZSTREAM_READY(&gz->z);
  3497. gzfile_read_header(gz, Qnil);
  3498. rb_gzfile_ecopts(gz, opt);
  3499. if (rb_respond_to(io, id_path)) {
  3500. /* File#path may raise IOError in case when a path is unavailable */
  3501. rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
  3502. }
  3503. return obj;
  3504. }
  3505. /*
  3506. * Document-method: Zlib::GzipReader#rewind
  3507. *
  3508. * Resets the position of the file pointer to the point created the GzipReader
  3509. * object. The associated IO object needs to respond to the +seek+ method.
  3510. */
  3511. static VALUE
  3512. rb_gzreader_rewind(VALUE obj)
  3513. {
  3514. struct gzfile *gz = get_gzfile(obj);
  3515. gzfile_reader_rewind(gz);
  3516. return INT2FIX(0);
  3517. }
  3518. /*
  3519. * Document-method: Zlib::GzipReader#unused
  3520. *
  3521. * Returns the rest of the data which had read for parsing gzip format, or
  3522. * +nil+ if the whole gzip file is not parsed yet.
  3523. */
  3524. static VALUE
  3525. rb_gzreader_unused(VALUE obj)
  3526. {
  3527. struct gzfile *gz;
  3528. TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
  3529. return gzfile_reader_get_unused(gz);
  3530. }
  3531. /*
  3532. * Document-method: Zlib::GzipReader#read
  3533. *
  3534. * See Zlib::GzipReader documentation for a description.
  3535. */
  3536. static VALUE
  3537. rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
  3538. {
  3539. struct gzfile *gz = get_gzfile(obj);
  3540. VALUE vlen;
  3541. long len;
  3542. rb_scan_args(argc, argv, "01", &vlen);
  3543. if (NIL_P(vlen)) {
  3544. return gzfile_read_all(gz);
  3545. }
  3546. len = NUM2INT(vlen);
  3547. if (len < 0) {
  3548. rb_raise(rb_eArgError, "negative length %ld given", len);
  3549. }
  3550. return gzfile_read(gz, len);
  3551. }
  3552. /*
  3553. * Document-method: Zlib::GzipReader#readpartial
  3554. *
  3555. * call-seq:
  3556. * gzipreader.readpartial(maxlen [, outbuf]) => string, outbuf
  3557. *
  3558. * Reads at most <i>maxlen</i> bytes from the gziped stream but
  3559. * it blocks only if <em>gzipreader</em> has no data immediately available.
  3560. * If the optional <i>outbuf</i> argument is present,
  3561. * it must reference a String, which will receive the data.
  3562. * It raises <code>EOFError</code> on end of file.
  3563. */
  3564. static VALUE
  3565. rb_gzreader_readpartial(int argc, VALUE *argv, VALUE obj)
  3566. {
  3567. struct gzfile *gz = get_gzfile(obj);
  3568. VALUE vlen, outbuf;
  3569. long len;
  3570. rb_scan_args(argc, argv, "11", &vlen, &outbuf);
  3571. len = NUM2INT(vlen);
  3572. if (len < 0) {
  3573. rb_raise(rb_eArgError, "negative length %ld given", len);
  3574. }
  3575. if (!NIL_P(outbuf))
  3576. Check_Type(outbuf, T_STRING);
  3577. return gzfile_readpartial(gz, len, outbuf);
  3578. }
  3579. /*
  3580. * Document-method: Zlib::GzipReader#getc
  3581. *
  3582. * See Zlib::GzipReader documentation for a description.
  3583. */
  3584. static VALUE
  3585. rb_gzreader_getc(VALUE obj)
  3586. {
  3587. struct gzfile *gz = get_gzfile(obj);
  3588. return gzfile_getc(gz);
  3589. }
  3590. /*
  3591. * Document-method: Zlib::GzipReader#readchar
  3592. *
  3593. * See Zlib::GzipReader documentation for a description.
  3594. */
  3595. static VALUE
  3596. rb_gzreader_readchar(VALUE obj)
  3597. {
  3598. VALUE dst;
  3599. dst = rb_gzreader_getc(obj);
  3600. if (NIL_P(dst)) {
  3601. rb_raise(rb_eEOFError, "end of file reached");
  3602. }
  3603. return dst;
  3604. }
  3605. /*
  3606. * Document-method: Zlib::GzipReader#getbyte
  3607. *
  3608. * See Zlib::GzipReader documentation for a description.
  3609. */
  3610. static VALUE
  3611. rb_gzreader_getbyte(VALUE obj)
  3612. {
  3613. struct gzfile *gz = get_gzfile(obj);
  3614. VALUE dst;
  3615. dst = gzfile_read(gz, 1);
  3616. if (!NIL_P(dst)) {
  3617. dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
  3618. }
  3619. return dst;
  3620. }
  3621. /*
  3622. * Document-method: Zlib::GzipReader#readbyte
  3623. *
  3624. * See Zlib::GzipReader documentation for a description.
  3625. */
  3626. static VALUE
  3627. rb_gzreader_readbyte(VALUE obj)
  3628. {
  3629. VALUE dst;
  3630. dst = rb_gzreader_getbyte(obj);
  3631. if (NIL_P(dst)) {
  3632. rb_raise(rb_eEOFError, "end of file reached");
  3633. }
  3634. return dst;
  3635. }
  3636. /*
  3637. * Document-method: Zlib::GzipReader#each_char
  3638. *
  3639. * See Zlib::GzipReader documentation for a description.
  3640. */
  3641. static VALUE
  3642. rb_gzreader_each_char(VALUE obj)
  3643. {
  3644. VALUE c;
  3645. RETURN_ENUMERATOR(obj, 0, 0);
  3646. while (!NIL_P(c = rb_gzreader_getc(obj))) {
  3647. rb_yield(c);
  3648. }
  3649. return Qnil;
  3650. }
  3651. /*
  3652. * Document-method: Zlib::GzipReader#each_byte
  3653. *
  3654. * See Zlib::GzipReader documentation for a description.
  3655. */
  3656. static VALUE
  3657. rb_gzreader_each_byte(VALUE obj)
  3658. {
  3659. VALUE c;
  3660. RETURN_ENUMERATOR(obj, 0, 0);
  3661. while (!NIL_P(c = rb_gzreader_getbyte(obj))) {
  3662. rb_yield(c);
  3663. }
  3664. return Qnil;
  3665. }
  3666. /*
  3667. * Document-method: Zlib::GzipReader#ungetc
  3668. *
  3669. * See Zlib::GzipReader documentation for a description.
  3670. */
  3671. static VALUE
  3672. rb_gzreader_ungetc(VALUE obj, VALUE s)
  3673. {
  3674. struct gzfile *gz;
  3675. if (FIXNUM_P(s))
  3676. return rb_gzreader_ungetbyte(obj, s);
  3677. gz = get_gzfile(obj);
  3678. StringValue(s);
  3679. if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
  3680. s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2);
  3681. }
  3682. gzfile_ungets(gz, (const Bytef*)RSTRING_PTR(s), RSTRING_LEN(s));
  3683. RB_GC_GUARD(s);
  3684. return Qnil;
  3685. }
  3686. /*
  3687. * Document-method: Zlib::GzipReader#ungetbyte
  3688. *
  3689. * See Zlib::GzipReader documentation for a description.
  3690. */
  3691. static VALUE
  3692. rb_gzreader_ungetbyte(VALUE obj, VALUE ch)
  3693. {
  3694. struct gzfile *gz = get_gzfile(obj);
  3695. gzfile_ungetbyte(gz, NUM2CHR(ch));
  3696. return Qnil;
  3697. }
  3698. static void
  3699. gzreader_skip_linebreaks(struct gzfile *gz)
  3700. {
  3701. VALUE str;
  3702. char *p;
  3703. int n;
  3704. while (ZSTREAM_BUF_FILLED(&gz->z) == 0) {
  3705. if (GZFILE_IS_FINISHED(gz)) return;
  3706. gzfile_read_more(gz, Qnil);
  3707. }
  3708. n = 0;
  3709. p = RSTRING_PTR(gz->z.buf);
  3710. while (n++, *(p++) == '\n') {
  3711. if (n >= ZSTREAM_BUF_FILLED(&gz->z)) {
  3712. str = zstream_detach_buffer(&gz->z);
  3713. gzfile_calc_crc(gz, str);
  3714. while (ZSTREAM_BUF_FILLED(&gz->z) == 0) {
  3715. if (GZFILE_IS_FINISHED(gz)) return;
  3716. gzfile_read_more(gz, Qnil);
  3717. }
  3718. n = 0;
  3719. p = RSTRING_PTR(gz->z.buf);
  3720. }
  3721. }
  3722. str = zstream_shift_buffer(&gz->z, n - 1);
  3723. gzfile_calc_crc(gz, str);
  3724. }
  3725. static void
  3726. rscheck(const char *rsptr, long rslen, VALUE rs)
  3727. {
  3728. if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen)
  3729. rb_raise(rb_eRuntimeError, "rs modified");
  3730. }
  3731. static long
  3732. gzreader_charboundary(struct gzfile *gz, long n)
  3733. {
  3734. char *s = RSTRING_PTR(gz->z.buf);
  3735. char *e = s + ZSTREAM_BUF_FILLED(&gz->z);
  3736. char *p = rb_enc_left_char_head(s, s + n, e, gz->enc);
  3737. long l = p - s;
  3738. if (l < n) {
  3739. n = rb_enc_precise_mbclen(p, e, gz->enc);
  3740. if (MBCLEN_NEEDMORE_P(n)) {
  3741. if ((l = gzfile_fill(gz, l + MBCLEN_NEEDMORE_LEN(n))) > 0) {
  3742. return l;
  3743. }
  3744. }
  3745. else if (MBCLEN_CHARFOUND_P(n)) {
  3746. return l + MBCLEN_CHARFOUND_LEN(n);
  3747. }
  3748. }
  3749. return n;
  3750. }
  3751. static VALUE
  3752. gzreader_gets(int argc, VALUE *argv, VALUE obj)
  3753. {
  3754. struct gzfile *gz = get_gzfile(obj);
  3755. VALUE rs;
  3756. VALUE dst;
  3757. const char *rsptr;
  3758. char *p, *res;
  3759. long rslen, n, limit = -1;
  3760. int rspara;
  3761. rb_encoding *enc = gz->enc;
  3762. int maxlen = rb_enc_mbmaxlen(enc);
  3763. if (argc == 0) {
  3764. rs = rb_rs;
  3765. }
  3766. else {
  3767. VALUE lim, tmp;
  3768. rb_scan_args(argc, argv, "11", &rs, &lim);
  3769. if (!NIL_P(lim)) {
  3770. if (!NIL_P(rs)) StringValue(rs);
  3771. }
  3772. else if (!NIL_P(rs)) {
  3773. tmp = rb_check_string_type(rs);
  3774. if (NIL_P(tmp)) {
  3775. lim = rs;
  3776. rs = rb_rs;
  3777. }
  3778. else {
  3779. rs = tmp;
  3780. }
  3781. }
  3782. if (!NIL_P(lim)) {
  3783. limit = NUM2LONG(lim);
  3784. if (limit == 0) return rb_str_new(0,0);
  3785. }
  3786. }
  3787. if (NIL_P(rs)) {
  3788. if (limit < 0) {
  3789. dst = gzfile_read_all(gz);
  3790. if (RSTRING_LEN(dst) == 0) return Qnil;
  3791. }
  3792. else if ((n = gzfile_fill(gz, limit)) <= 0) {
  3793. return Qnil;
  3794. }
  3795. else {
  3796. if (maxlen > 1 && n >= limit && !GZFILE_IS_FINISHED(gz)) {
  3797. n = gzreader_charboundary(gz, n);
  3798. }
  3799. else {
  3800. n = limit;
  3801. }
  3802. dst = zstream_shift_buffer(&gz->z, n);
  3803. if (NIL_P(dst)) return dst;
  3804. gzfile_calc_crc(gz, dst);
  3805. dst = gzfile_newstr(gz, dst);
  3806. }
  3807. gz->lineno++;
  3808. return dst;
  3809. }
  3810. if (RSTRING_LEN(rs) == 0) {
  3811. rsptr = "\n\n";
  3812. rslen = 2;
  3813. rspara = 1;
  3814. }
  3815. else {
  3816. rsptr = RSTRING_PTR(rs);
  3817. rslen = RSTRING_LEN(rs);
  3818. rspara = 0;
  3819. }
  3820. if (rspara) {
  3821. gzreader_skip_linebreaks(gz);
  3822. }
  3823. while (ZSTREAM_BUF_FILLED(&gz->z) < rslen) {
  3824. if (ZSTREAM_IS_FINISHED(&gz->z)) {
  3825. if (ZSTREAM_BUF_FILLED(&gz->z) > 0) gz->lineno++;
  3826. return gzfile_read(gz, rslen);
  3827. }
  3828. gzfile_read_more(gz, Qnil);
  3829. }
  3830. p = RSTRING_PTR(gz->z.buf);
  3831. n = rslen;
  3832. for (;;) {
  3833. long filled;
  3834. if (n > ZSTREAM_BUF_FILLED(&gz->z)) {
  3835. if (ZSTREAM_IS_FINISHED(&gz->z)) break;
  3836. gzfile_read_more(gz, Qnil);
  3837. p = RSTRING_PTR(gz->z.buf) + n - rslen;
  3838. }
  3839. if (!rspara) rscheck(rsptr, rslen, rs);
  3840. filled = ZSTREAM_BUF_FILLED(&gz->z);
  3841. if (limit > 0 && filled >= limit) {
  3842. filled = limit;
  3843. }
  3844. res = memchr(p, rsptr[0], (filled - n + 1));
  3845. if (!res) {
  3846. n = filled;
  3847. if (limit > 0 && filled >= limit) break;
  3848. n++;
  3849. }
  3850. else {
  3851. n += (long)(res - p);
  3852. p = res;
  3853. if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
  3854. p++, n++;
  3855. }
  3856. }
  3857. if (maxlen > 1 && n == limit && (ZSTREAM_BUF_FILLED(&gz->z) > n || !ZSTREAM_IS_FINISHED(&gz->z))) {
  3858. n = gzreader_charboundary(gz, n);
  3859. }
  3860. gz->lineno++;
  3861. dst = gzfile_read(gz, n);
  3862. if (NIL_P(dst)) return dst;
  3863. if (rspara) {
  3864. gzreader_skip_linebreaks(gz);
  3865. }
  3866. RB_GC_GUARD(rs);
  3867. return gzfile_newstr(gz, dst);
  3868. }
  3869. /*
  3870. * Document-method: Zlib::GzipReader#gets
  3871. *
  3872. * See Zlib::GzipReader documentation for a description.
  3873. * However, note that this method can return +nil+ even if
  3874. * #eof? returns false, unlike the behavior of File#gets.
  3875. */
  3876. static VALUE
  3877. rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
  3878. {
  3879. VALUE dst;
  3880. dst = gzreader_gets(argc, argv, obj);
  3881. if (!NIL_P(dst)) {
  3882. rb_lastline_set(dst);
  3883. }
  3884. return dst;
  3885. }
  3886. /*
  3887. * Document-method: Zlib::GzipReader#readline
  3888. *
  3889. * See Zlib::GzipReader documentation for a description.
  3890. */
  3891. static VALUE
  3892. rb_gzreader_readline(int argc, VALUE *argv, VALUE obj)
  3893. {
  3894. VALUE dst;
  3895. dst = rb_gzreader_gets(argc, argv, obj);
  3896. if (NIL_P(dst)) {
  3897. rb_raise(rb_eEOFError, "end of file reached");
  3898. }
  3899. return dst;
  3900. }
  3901. /*
  3902. * Document-method: Zlib::GzipReader#each
  3903. *
  3904. * See Zlib::GzipReader documentation for a description.
  3905. */
  3906. static VALUE
  3907. rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
  3908. {
  3909. VALUE str;
  3910. RETURN_ENUMERATOR(obj, 0, 0);
  3911. while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
  3912. rb_yield(str);
  3913. }
  3914. return obj;
  3915. }
  3916. /*
  3917. * Document-method: Zlib::GzipReader#readlines
  3918. *
  3919. * See Zlib::GzipReader documentation for a description.
  3920. */
  3921. static VALUE
  3922. rb_gzreader_readlines(int argc, VALUE *argv, VALUE obj)
  3923. {
  3924. VALUE str, dst;
  3925. dst = rb_ary_new();
  3926. while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
  3927. rb_ary_push(dst, str);
  3928. }
  3929. return dst;
  3930. }
  3931. /*
  3932. * Document-method: Zlib::GzipReader#external_encoding
  3933. *
  3934. * See Zlib::GzipReader documentation for a description.
  3935. */
  3936. static VALUE
  3937. rb_gzreader_external_encoding(VALUE self)
  3938. {
  3939. return rb_enc_from_encoding(get_gzfile(self)->enc);
  3940. }
  3941. static VALUE
  3942. zlib_gzip_end_rescue(VALUE arg)
  3943. {
  3944. struct gzfile *gz = (struct gzfile *)arg;
  3945. gz->end(gz);
  3946. return Qnil;
  3947. }
  3948. static VALUE
  3949. zlib_gzip_ensure(VALUE arg)
  3950. {
  3951. return rb_rescue(zlib_gzip_end_rescue, arg, NULL, Qnil);
  3952. }
  3953. static void
  3954. zlib_gzip_end(struct gzfile *gz)
  3955. {
  3956. gz->z.flags |= ZSTREAM_FLAG_CLOSING;
  3957. zstream_run(&gz->z, (Bytef*)"", 0, Z_FINISH);
  3958. gzfile_make_footer(gz);
  3959. zstream_end(&gz->z);
  3960. }
  3961. static ID id_level, id_strategy;
  3962. static VALUE zlib_gzip_run(VALUE arg);
  3963. /*
  3964. * call-seq:
  3965. * Zlib.gzip(src, level: nil, strategy: nil) -> String
  3966. *
  3967. * Gzip the given +string+. Valid values of level are
  3968. * Zlib::NO_COMPRESSION, Zlib::BEST_SPEED, Zlib::BEST_COMPRESSION,
  3969. * Zlib::DEFAULT_COMPRESSION (default), or an integer from 0 to 9.
  3970. *
  3971. * This method is almost equivalent to the following code:
  3972. *
  3973. * def gzip(string, level: nil, strategy: nil)
  3974. * sio = StringIO.new
  3975. * sio.binmode
  3976. * gz = Zlib::GzipWriter.new(sio, level, strategy)
  3977. * gz.write(string)
  3978. * gz.close
  3979. * sio.string
  3980. * end
  3981. *
  3982. * See also Zlib.gunzip
  3983. *
  3984. */
  3985. static VALUE
  3986. zlib_s_gzip(int argc, VALUE *argv, VALUE klass)
  3987. {
  3988. struct gzfile gz0;
  3989. struct gzfile *gz = &gz0;
  3990. int err;
  3991. VALUE src, opts, level=Qnil, strategy=Qnil, args[2];
  3992. if (OPTHASH_GIVEN_P(opts)) {
  3993. ID keyword_ids[2];
  3994. VALUE kwargs[2];
  3995. keyword_ids[0] = id_level;
  3996. keyword_ids[1] = id_strategy;
  3997. rb_get_kwargs(opts, keyword_ids, 0, 2, kwargs);
  3998. if (kwargs[0] != Qundef) {
  3999. level = kwargs[0];
  4000. }
  4001. if (kwargs[1] != Qundef) {
  4002. strategy = kwargs[1];
  4003. }
  4004. }
  4005. rb_scan_args(argc, argv, "10", &src);
  4006. StringValue(src);
  4007. gzfile_init(gz, &deflate_funcs, zlib_gzip_end);
  4008. gz->level = ARG_LEVEL(level);
  4009. err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
  4010. -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
  4011. if (err != Z_OK) {
  4012. zlib_gzip_end(gz);
  4013. raise_zlib_error(err, gz->z.stream.msg);
  4014. }
  4015. ZSTREAM_READY(&gz->z);
  4016. args[0] = (VALUE)gz;
  4017. args[1] = src;
  4018. return rb_ensure(zlib_gzip_run, (VALUE)args, zlib_gzip_ensure, (VALUE)gz);
  4019. }
  4020. static VALUE
  4021. zlib_gzip_run(VALUE arg)
  4022. {
  4023. VALUE *args = (VALUE *)arg;
  4024. struct gzfile *gz = (struct gzfile *)args[0];
  4025. VALUE src = args[1];
  4026. long len;
  4027. gzfile_make_header(gz);
  4028. len = RSTRING_LEN(src);
  4029. if (len > 0) {
  4030. Bytef *ptr = (Bytef *)RSTRING_PTR(src);
  4031. gz->crc = checksum_long(crc32, gz->crc, ptr, len);
  4032. zstream_run(&gz->z, ptr, len, Z_NO_FLUSH);
  4033. }
  4034. gzfile_close(gz, 0);
  4035. return zstream_detach_buffer(&gz->z);
  4036. }
  4037. static void
  4038. zlib_gunzip_end(struct gzfile *gz)
  4039. {
  4040. gz->z.flags |= ZSTREAM_FLAG_CLOSING;
  4041. zstream_end(&gz->z);
  4042. }
  4043. static VALUE zlib_gunzip_run(VALUE arg);
  4044. /*
  4045. * call-seq:
  4046. * Zlib.gunzip(src) -> String
  4047. *
  4048. * Decode the given gzipped +string+.
  4049. *
  4050. * This method is almost equivalent to the following code:
  4051. *
  4052. * def gunzip(string)
  4053. * sio = StringIO.new(string)
  4054. * gz = Zlib::GzipReader.new(sio, encoding: Encoding::ASCII_8BIT)
  4055. * gz.read
  4056. * ensure
  4057. * gz&.close
  4058. * end
  4059. *
  4060. * See also Zlib.gzip
  4061. */
  4062. static VALUE
  4063. zlib_gunzip(VALUE klass, VALUE src)
  4064. {
  4065. struct gzfile gz0;
  4066. struct gzfile *gz = &gz0;
  4067. int err;
  4068. StringValue(src);
  4069. gzfile_init(gz, &inflate_funcs, zlib_gunzip_end);
  4070. err = inflateInit2(&gz->z.stream, -MAX_WBITS);
  4071. if (err != Z_OK) {
  4072. raise_zlib_error(err, gz->z.stream.msg);
  4073. }
  4074. gz->io = Qundef;
  4075. gz->z.input = src;
  4076. ZSTREAM_READY(&gz->z);
  4077. return rb_ensure(zlib_gunzip_run, (VALUE)gz, zlib_gzip_ensure, (VALUE)gz);
  4078. }
  4079. static VALUE
  4080. zlib_gunzip_run(VALUE arg)
  4081. {
  4082. struct gzfile *gz = (struct gzfile *)arg;
  4083. VALUE dst;
  4084. gzfile_read_header(gz, Qnil);
  4085. dst = zstream_detach_buffer(&gz->z);
  4086. gzfile_calc_crc(gz, dst);
  4087. if (!ZSTREAM_IS_FINISHED(&gz->z)) {
  4088. rb_raise(cGzError, "unexpected end of file");
  4089. }
  4090. if (NIL_P(gz->z.input)) {
  4091. rb_raise(cNoFooter, "footer is not found");
  4092. }
  4093. gzfile_check_footer(gz, Qnil);
  4094. return dst;
  4095. }
  4096. #endif /* GZIP_SUPPORT */
  4097. void
  4098. Init_zlib(void)
  4099. {
  4100. #ifdef HAVE_RB_EXT_RACTOR_SAFE
  4101. rb_ext_ractor_safe(true);
  4102. #endif
  4103. #undef rb_intern
  4104. VALUE mZlib, cZStream, cDeflate, cInflate;
  4105. #if GZIP_SUPPORT
  4106. VALUE cGzipFile, cGzipWriter, cGzipReader;
  4107. #endif
  4108. mZlib = rb_define_module("Zlib");
  4109. id_dictionaries = rb_intern("@dictionaries");
  4110. cZError = rb_define_class_under(mZlib, "Error", rb_eStandardError);
  4111. cStreamEnd = rb_define_class_under(mZlib, "StreamEnd", cZError);
  4112. cNeedDict = rb_define_class_under(mZlib, "NeedDict", cZError);
  4113. cDataError = rb_define_class_under(mZlib, "DataError", cZError);
  4114. cStreamError = rb_define_class_under(mZlib, "StreamError", cZError);
  4115. cMemError = rb_define_class_under(mZlib, "MemError", cZError);
  4116. cBufError = rb_define_class_under(mZlib, "BufError", cZError);
  4117. cVersionError = rb_define_class_under(mZlib, "VersionError", cZError);
  4118. rb_define_module_function(mZlib, "zlib_version", rb_zlib_version, 0);
  4119. rb_define_module_function(mZlib, "adler32", rb_zlib_adler32, -1);
  4120. rb_define_module_function(mZlib, "adler32_combine", rb_zlib_adler32_combine, 3);
  4121. rb_define_module_function(mZlib, "crc32", rb_zlib_crc32, -1);
  4122. rb_define_module_function(mZlib, "crc32_combine", rb_zlib_crc32_combine, 3);
  4123. rb_define_module_function(mZlib, "crc_table", rb_zlib_crc_table, 0);
  4124. /* The Ruby/zlib version string. */
  4125. rb_define_const(mZlib, "VERSION", rb_str_new2(RUBY_ZLIB_VERSION));
  4126. /* The string which represents the version of zlib.h */
  4127. rb_define_const(mZlib, "ZLIB_VERSION", rb_str_new2(ZLIB_VERSION));
  4128. cZStream = rb_define_class_under(mZlib, "ZStream", rb_cObject);
  4129. rb_undef_alloc_func(cZStream);
  4130. rb_define_method(cZStream, "avail_out", rb_zstream_avail_out, 0);
  4131. rb_define_method(cZStream, "avail_out=", rb_zstream_set_avail_out, 1);
  4132. rb_define_method(cZStream, "avail_in", rb_zstream_avail_in, 0);
  4133. rb_define_method(cZStream, "total_in", rb_zstream_total_in, 0);
  4134. rb_define_method(cZStream, "total_out", rb_zstream_total_out, 0);
  4135. rb_define_method(cZStream, "data_type", rb_zstream_data_type, 0);
  4136. rb_define_method(cZStream, "adler", rb_zstream_adler, 0);
  4137. rb_define_method(cZStream, "finished?", rb_zstream_finished_p, 0);
  4138. rb_define_method(cZStream, "stream_end?", rb_zstream_finished_p, 0);
  4139. rb_define_method(cZStream, "closed?", rb_zstream_closed_p, 0);
  4140. rb_define_method(cZStream, "ended?", rb_zstream_closed_p, 0);
  4141. rb_define_method(cZStream, "close", rb_zstream_end, 0);
  4142. rb_define_method(cZStream, "end", rb_zstream_end, 0);
  4143. rb_define_method(cZStream, "reset", rb_zstream_reset, 0);
  4144. rb_define_method(cZStream, "finish", rb_zstream_finish, 0);
  4145. rb_define_method(cZStream, "flush_next_in", rb_zstream_flush_next_in, 0);
  4146. rb_define_method(cZStream, "flush_next_out", rb_zstream_flush_next_out, 0);
  4147. /* Represents binary data as guessed by deflate.
  4148. *
  4149. * See Zlib::Deflate#data_type. */
  4150. rb_define_const(mZlib, "BINARY", INT2FIX(Z_BINARY));
  4151. /* Represents text data as guessed by deflate.
  4152. *
  4153. * NOTE: The underlying constant Z_ASCII was deprecated in favor of Z_TEXT
  4154. * in zlib 1.2.2. New applications should not use this constant.
  4155. *
  4156. * See Zlib::Deflate#data_type. */
  4157. rb_define_const(mZlib, "ASCII", INT2FIX(Z_ASCII));
  4158. #ifdef Z_TEXT
  4159. /* Represents text data as guessed by deflate.
  4160. *
  4161. * See Zlib::Deflate#data_type. */
  4162. rb_define_const(mZlib, "TEXT", INT2FIX(Z_TEXT));
  4163. #endif
  4164. /* Represents an unknown data type as guessed by deflate.
  4165. *
  4166. * See Zlib::Deflate#data_type. */
  4167. rb_define_const(mZlib, "UNKNOWN", INT2FIX(Z_UNKNOWN));
  4168. cDeflate = rb_define_class_under(mZlib, "Deflate", cZStream);
  4169. rb_define_singleton_method(cDeflate, "deflate", rb_deflate_s_deflate, -1);
  4170. rb_define_singleton_method(mZlib, "deflate", rb_deflate_s_deflate, -1);
  4171. rb_define_alloc_func(cDeflate, rb_deflate_s_allocate);
  4172. rb_define_method(cDeflate, "initialize", rb_deflate_initialize, -1);
  4173. rb_define_method(cDeflate, "initialize_copy", rb_deflate_init_copy, 1);
  4174. rb_define_method(cDeflate, "deflate", rb_deflate_deflate, -1);
  4175. rb_define_method(cDeflate, "<<", rb_deflate_addstr, 1);
  4176. rb_define_method(cDeflate, "flush", rb_deflate_flush, -1);
  4177. rb_define_method(cDeflate, "params", rb_deflate_params, 2);
  4178. rb_define_method(cDeflate, "set_dictionary", rb_deflate_set_dictionary, 1);
  4179. cInflate = rb_define_class_under(mZlib, "Inflate", cZStream);
  4180. rb_define_singleton_method(cInflate, "inflate", rb_inflate_s_inflate, 1);
  4181. rb_define_singleton_method(mZlib, "inflate", rb_inflate_s_inflate, 1);
  4182. rb_define_alloc_func(cInflate, rb_inflate_s_allocate);
  4183. rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1);
  4184. rb_define_method(cInflate, "add_dictionary", rb_inflate_add_dictionary, 1);
  4185. rb_define_method(cInflate, "inflate", rb_inflate_inflate, -1);
  4186. rb_define_method(cInflate, "<<", rb_inflate_addstr, 1);
  4187. rb_define_method(cInflate, "sync", rb_inflate_sync, 1);
  4188. rb_define_method(cInflate, "sync_point?", rb_inflate_sync_point_p, 0);
  4189. rb_define_method(cInflate, "set_dictionary", rb_inflate_set_dictionary, 1);
  4190. /* No compression, passes through data untouched. Use this for appending
  4191. * pre-compressed data to a deflate stream.
  4192. */
  4193. rb_define_const(mZlib, "NO_COMPRESSION", INT2FIX(Z_NO_COMPRESSION));
  4194. /* Fastest compression level, but with the lowest space savings. */
  4195. rb_define_const(mZlib, "BEST_SPEED", INT2FIX(Z_BEST_SPEED));
  4196. /* Slowest compression level, but with the best space savings. */
  4197. rb_define_const(mZlib, "BEST_COMPRESSION", INT2FIX(Z_BEST_COMPRESSION));
  4198. /* Default compression level which is a good trade-off between space and
  4199. * time
  4200. */
  4201. rb_define_const(mZlib, "DEFAULT_COMPRESSION",
  4202. INT2FIX(Z_DEFAULT_COMPRESSION));
  4203. /* Deflate strategy for data produced by a filter (or predictor). The
  4204. * effect of FILTERED is to force more Huffman codes and less string
  4205. * matching; it is somewhat intermediate between DEFAULT_STRATEGY and
  4206. * HUFFMAN_ONLY. Filtered data consists mostly of small values with a
  4207. * somewhat random distribution.
  4208. */
  4209. rb_define_const(mZlib, "FILTERED", INT2FIX(Z_FILTERED));
  4210. /* Deflate strategy which uses Huffman codes only (no string matching). */
  4211. rb_define_const(mZlib, "HUFFMAN_ONLY", INT2FIX(Z_HUFFMAN_ONLY));
  4212. #ifdef Z_RLE
  4213. /* Deflate compression strategy designed to be almost as fast as
  4214. * HUFFMAN_ONLY, but give better compression for PNG image data.
  4215. */
  4216. rb_define_const(mZlib, "RLE", INT2FIX(Z_RLE));
  4217. #endif
  4218. #ifdef Z_FIXED
  4219. /* Deflate strategy which prevents the use of dynamic Huffman codes,
  4220. * allowing for a simpler decoder for specialized applications.
  4221. */
  4222. rb_define_const(mZlib, "FIXED", INT2FIX(Z_FIXED));
  4223. #endif
  4224. /* Default deflate strategy which is used for normal data. */
  4225. rb_define_const(mZlib, "DEFAULT_STRATEGY", INT2FIX(Z_DEFAULT_STRATEGY));
  4226. /* The maximum size of the zlib history buffer. Note that zlib allows
  4227. * larger values to enable different inflate modes. See Zlib::Inflate.new
  4228. * for details.
  4229. */
  4230. rb_define_const(mZlib, "MAX_WBITS", INT2FIX(MAX_WBITS));
  4231. /* The default memory level for allocating zlib deflate compression state.
  4232. */
  4233. rb_define_const(mZlib, "DEF_MEM_LEVEL", INT2FIX(DEF_MEM_LEVEL));
  4234. /* The maximum memory level for allocating zlib deflate compression state.
  4235. */
  4236. rb_define_const(mZlib, "MAX_MEM_LEVEL", INT2FIX(MAX_MEM_LEVEL));
  4237. /* NO_FLUSH is the default flush method and allows deflate to decide how
  4238. * much data to accumulate before producing output in order to maximize
  4239. * compression.
  4240. */
  4241. rb_define_const(mZlib, "NO_FLUSH", INT2FIX(Z_NO_FLUSH));
  4242. /* The SYNC_FLUSH method flushes all pending output to the output buffer
  4243. * and the output is aligned on a byte boundary. Flushing may degrade
  4244. * compression so it should be used only when necessary, such as at a
  4245. * request or response boundary for a network stream.
  4246. */
  4247. rb_define_const(mZlib, "SYNC_FLUSH", INT2FIX(Z_SYNC_FLUSH));
  4248. /* Flushes all output as with SYNC_FLUSH, and the compression state is
  4249. * reset so that decompression can restart from this point if previous
  4250. * compressed data has been damaged or if random access is desired. Like
  4251. * SYNC_FLUSH, using FULL_FLUSH too often can seriously degrade
  4252. * compression.
  4253. */
  4254. rb_define_const(mZlib, "FULL_FLUSH", INT2FIX(Z_FULL_FLUSH));
  4255. /* Processes all pending input and flushes pending output. */
  4256. rb_define_const(mZlib, "FINISH", INT2FIX(Z_FINISH));
  4257. #if GZIP_SUPPORT
  4258. id_write = rb_intern("write");
  4259. id_read = rb_intern("read");
  4260. id_readpartial = rb_intern("readpartial");
  4261. id_flush = rb_intern("flush");
  4262. id_seek = rb_intern("seek");
  4263. id_close = rb_intern("close");
  4264. id_path = rb_intern("path");
  4265. id_input = rb_intern("@input");
  4266. cGzipFile = rb_define_class_under(mZlib, "GzipFile", rb_cObject);
  4267. cGzError = rb_define_class_under(cGzipFile, "Error", cZError);
  4268. /* input gzipped string */
  4269. rb_define_attr(cGzError, "input", 1, 0);
  4270. rb_define_method(cGzError, "inspect", gzfile_error_inspect, 0);
  4271. cNoFooter = rb_define_class_under(cGzipFile, "NoFooter", cGzError);
  4272. cCRCError = rb_define_class_under(cGzipFile, "CRCError", cGzError);
  4273. cLengthError = rb_define_class_under(cGzipFile,"LengthError",cGzError);
  4274. cGzipWriter = rb_define_class_under(mZlib, "GzipWriter", cGzipFile);
  4275. cGzipReader = rb_define_class_under(mZlib, "GzipReader", cGzipFile);
  4276. rb_include_module(cGzipReader, rb_mEnumerable);
  4277. rb_define_singleton_method(cGzipFile, "wrap", rb_gzfile_s_wrap, -1);
  4278. rb_undef_alloc_func(cGzipFile);
  4279. rb_define_method(cGzipFile, "to_io", rb_gzfile_to_io, 0);
  4280. rb_define_method(cGzipFile, "crc", rb_gzfile_crc, 0);
  4281. rb_define_method(cGzipFile, "mtime", rb_gzfile_mtime, 0);
  4282. rb_define_method(cGzipFile, "level", rb_gzfile_level, 0);
  4283. rb_define_method(cGzipFile, "os_code", rb_gzfile_os_code, 0);
  4284. rb_define_method(cGzipFile, "orig_name", rb_gzfile_orig_name, 0);
  4285. rb_define_method(cGzipFile, "comment", rb_gzfile_comment, 0);
  4286. rb_define_method(cGzipReader, "lineno", rb_gzfile_lineno, 0);
  4287. rb_define_method(cGzipReader, "lineno=", rb_gzfile_set_lineno, 1);
  4288. rb_define_method(cGzipWriter, "mtime=", rb_gzfile_set_mtime, 1);
  4289. rb_define_method(cGzipWriter, "orig_name=", rb_gzfile_set_orig_name,1);
  4290. rb_define_method(cGzipWriter, "comment=", rb_gzfile_set_comment, 1);
  4291. rb_define_method(cGzipFile, "close", rb_gzfile_close, 0);
  4292. rb_define_method(cGzipFile, "finish", rb_gzfile_finish, 0);
  4293. rb_define_method(cGzipFile, "closed?", rb_gzfile_closed_p, 0);
  4294. rb_define_method(cGzipReader, "eof", rb_gzfile_eof_p, 0);
  4295. rb_define_method(cGzipReader, "eof?", rb_gzfile_eof_p, 0);
  4296. rb_define_method(cGzipFile, "sync", rb_gzfile_sync, 0);
  4297. rb_define_method(cGzipFile, "sync=", rb_gzfile_set_sync, 1);
  4298. rb_define_method(cGzipReader, "pos", rb_gzfile_total_out, 0);
  4299. rb_define_method(cGzipWriter, "pos", rb_gzfile_total_in, 0);
  4300. rb_define_method(cGzipReader, "tell", rb_gzfile_total_out, 0);
  4301. rb_define_method(cGzipWriter, "tell", rb_gzfile_total_in, 0);
  4302. rb_define_singleton_method(cGzipWriter, "open", rb_gzwriter_s_open,-1);
  4303. rb_define_alloc_func(cGzipWriter, rb_gzwriter_s_allocate);
  4304. rb_define_method(cGzipWriter, "initialize", rb_gzwriter_initialize,-1);
  4305. rb_define_method(cGzipWriter, "flush", rb_gzwriter_flush, -1);
  4306. rb_define_method(cGzipWriter, "write", rb_gzwriter_write, -1);
  4307. rb_define_method(cGzipWriter, "putc", rb_gzwriter_putc, 1);
  4308. rb_define_method(cGzipWriter, "<<", rb_gzwriter_addstr, 1);
  4309. rb_define_method(cGzipWriter, "printf", rb_gzwriter_printf, -1);
  4310. rb_define_method(cGzipWriter, "print", rb_gzwriter_print, -1);
  4311. rb_define_method(cGzipWriter, "puts", rb_gzwriter_puts, -1);
  4312. rb_define_singleton_method(cGzipReader, "open", rb_gzreader_s_open,-1);
  4313. rb_define_singleton_method(cGzipReader, "zcat", rb_gzreader_s_zcat, -1);
  4314. rb_define_alloc_func(cGzipReader, rb_gzreader_s_allocate);
  4315. rb_define_method(cGzipReader, "initialize", rb_gzreader_initialize, -1);
  4316. rb_define_method(cGzipReader, "rewind", rb_gzreader_rewind, 0);
  4317. rb_define_method(cGzipReader, "unused", rb_gzreader_unused, 0);
  4318. rb_define_method(cGzipReader, "read", rb_gzreader_read, -1);
  4319. rb_define_method(cGzipReader, "readpartial", rb_gzreader_readpartial, -1);
  4320. rb_define_method(cGzipReader, "getc", rb_gzreader_getc, 0);
  4321. rb_define_method(cGzipReader, "getbyte", rb_gzreader_getbyte, 0);
  4322. rb_define_method(cGzipReader, "readchar", rb_gzreader_readchar, 0);
  4323. rb_define_method(cGzipReader, "readbyte", rb_gzreader_readbyte, 0);
  4324. rb_define_method(cGzipReader, "each_byte", rb_gzreader_each_byte, 0);
  4325. rb_define_method(cGzipReader, "each_char", rb_gzreader_each_char, 0);
  4326. rb_define_method(cGzipReader, "ungetc", rb_gzreader_ungetc, 1);
  4327. rb_define_method(cGzipReader, "ungetbyte", rb_gzreader_ungetbyte, 1);
  4328. rb_define_method(cGzipReader, "gets", rb_gzreader_gets, -1);
  4329. rb_define_method(cGzipReader, "readline", rb_gzreader_readline, -1);
  4330. rb_define_method(cGzipReader, "each", rb_gzreader_each, -1);
  4331. rb_define_method(cGzipReader, "each_line", rb_gzreader_each, -1);
  4332. rb_define_method(cGzipReader, "readlines", rb_gzreader_readlines, -1);
  4333. rb_define_method(cGzipReader, "external_encoding", rb_gzreader_external_encoding, 0);
  4334. rb_define_singleton_method(mZlib, "gzip", zlib_s_gzip, -1);
  4335. rb_define_singleton_method(mZlib, "gunzip", zlib_gunzip, 1);
  4336. /* The OS code of current host */
  4337. rb_define_const(mZlib, "OS_CODE", INT2FIX(OS_CODE));
  4338. /* OS code for MSDOS hosts */
  4339. rb_define_const(mZlib, "OS_MSDOS", INT2FIX(OS_MSDOS));
  4340. /* OS code for Amiga hosts */
  4341. rb_define_const(mZlib, "OS_AMIGA", INT2FIX(OS_AMIGA));
  4342. /* OS code for VMS hosts */
  4343. rb_define_const(mZlib, "OS_VMS", INT2FIX(OS_VMS));
  4344. /* OS code for UNIX hosts */
  4345. rb_define_const(mZlib, "OS_UNIX", INT2FIX(OS_UNIX));
  4346. /* OS code for Atari hosts */
  4347. rb_define_const(mZlib, "OS_ATARI", INT2FIX(OS_ATARI));
  4348. /* OS code for OS2 hosts */
  4349. rb_define_const(mZlib, "OS_OS2", INT2FIX(OS_OS2));
  4350. /* OS code for Mac OS hosts */
  4351. rb_define_const(mZlib, "OS_MACOS", INT2FIX(OS_MACOS));
  4352. /* OS code for TOPS-20 hosts */
  4353. rb_define_const(mZlib, "OS_TOPS20", INT2FIX(OS_TOPS20));
  4354. /* OS code for Win32 hosts */
  4355. rb_define_const(mZlib, "OS_WIN32", INT2FIX(OS_WIN32));
  4356. /* OS code for VM OS hosts */
  4357. rb_define_const(mZlib, "OS_VMCMS", INT2FIX(OS_VMCMS));
  4358. /* OS code for Z-System hosts */
  4359. rb_define_const(mZlib, "OS_ZSYSTEM", INT2FIX(OS_ZSYSTEM));
  4360. /* OS code for CP/M hosts */
  4361. rb_define_const(mZlib, "OS_CPM", INT2FIX(OS_CPM));
  4362. /* OS code for QDOS hosts */
  4363. rb_define_const(mZlib, "OS_QDOS", INT2FIX(OS_QDOS));
  4364. /* OS code for RISC OS hosts */
  4365. rb_define_const(mZlib, "OS_RISCOS", INT2FIX(OS_RISCOS));
  4366. /* OS code for unknown hosts */
  4367. rb_define_const(mZlib, "OS_UNKNOWN", INT2FIX(OS_UNKNOWN));
  4368. id_level = rb_intern("level");
  4369. id_strategy = rb_intern("strategy");
  4370. id_buffer = rb_intern("buffer");
  4371. #endif /* GZIP_SUPPORT */
  4372. }
  4373. /* Document error classes. */
  4374. /*
  4375. * Document-class: Zlib::Error
  4376. *
  4377. * The superclass for all exceptions raised by Ruby/zlib.
  4378. *
  4379. * The following exceptions are defined as subclasses of Zlib::Error. These
  4380. * exceptions are raised when zlib library functions return with an error
  4381. * status.
  4382. *
  4383. * - Zlib::StreamEnd
  4384. * - Zlib::NeedDict
  4385. * - Zlib::DataError
  4386. * - Zlib::StreamError
  4387. * - Zlib::MemError
  4388. * - Zlib::BufError
  4389. * - Zlib::VersionError
  4390. *
  4391. */
  4392. /*
  4393. * Document-class: Zlib::StreamEnd
  4394. *
  4395. * Subclass of Zlib::Error
  4396. *
  4397. * When zlib returns a Z_STREAM_END
  4398. * is return if the end of the compressed data has been reached
  4399. * and all uncompressed out put has been produced.
  4400. *
  4401. */
  4402. /*
  4403. * Document-class: Zlib::NeedDict
  4404. *
  4405. * Subclass of Zlib::Error
  4406. *
  4407. * When zlib returns a Z_NEED_DICT
  4408. * if a preset dictionary is needed at this point.
  4409. *
  4410. * Used by Zlib::Inflate.inflate and <tt>Zlib.inflate</tt>
  4411. */
  4412. /*
  4413. * Document-class: Zlib::VersionError
  4414. *
  4415. * Subclass of Zlib::Error
  4416. *
  4417. * When zlib returns a Z_VERSION_ERROR,
  4418. * usually if the zlib library version is incompatible with the
  4419. * version assumed by the caller.
  4420. *
  4421. */
  4422. /*
  4423. * Document-class: Zlib::MemError
  4424. *
  4425. * Subclass of Zlib::Error
  4426. *
  4427. * When zlib returns a Z_MEM_ERROR,
  4428. * usually if there was not enough memory.
  4429. *
  4430. */
  4431. /*
  4432. * Document-class: Zlib::StreamError
  4433. *
  4434. * Subclass of Zlib::Error
  4435. *
  4436. * When zlib returns a Z_STREAM_ERROR,
  4437. * usually if the stream state was inconsistent.
  4438. *
  4439. */
  4440. /*
  4441. * Document-class: Zlib::BufError
  4442. *
  4443. * Subclass of Zlib::Error when zlib returns a Z_BUF_ERROR.
  4444. *
  4445. * Usually if no progress is possible.
  4446. *
  4447. */
  4448. /*
  4449. * Document-class: Zlib::DataError
  4450. *
  4451. * Subclass of Zlib::Error when zlib returns a Z_DATA_ERROR.
  4452. *
  4453. * Usually if a stream was prematurely freed.
  4454. *
  4455. */
  4456. /*
  4457. * Document-class: Zlib::GzipFile::Error
  4458. *
  4459. * Base class of errors that occur when processing GZIP files.
  4460. */
  4461. /*
  4462. * Document-class: Zlib::GzipFile::NoFooter
  4463. *
  4464. * Raised when gzip file footer is not found.
  4465. */
  4466. /*
  4467. * Document-class: Zlib::GzipFile::CRCError
  4468. *
  4469. * Raised when the CRC checksum recorded in gzip file footer is not equivalent
  4470. * to the CRC checksum of the actual uncompressed data.
  4471. */
  4472. /*
  4473. * Document-class: Zlib::GzipFile::LengthError
  4474. *
  4475. * Raised when the data length recorded in the gzip file footer is not equivalent
  4476. * to the length of the actual uncompressed data.
  4477. */