PageRenderTime 76ms CodeModel.GetById 24ms 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

Large files files are truncated, but you can click here to view the full file

  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 str…

Large files files are truncated, but you can click here to view the full file