PageRenderTime 85ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/ext/zlib/zlib.c

https://github.com/fizx/ruby
C | 3736 lines | 2514 code | 453 blank | 769 comment | 328 complexity | d6a7e2b59d47a2f93f79529f119b3fd8 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0, 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/encoding.h>
  12. #define RUBY_ZLIB_VERSION "0.6.0"
  13. #define OBJ_IS_FREED(val) (RBASIC(val)->flags == 0)
  14. #ifndef GZIP_SUPPORT
  15. #define GZIP_SUPPORT 1
  16. #endif
  17. /* from zutil.h */
  18. #ifndef DEF_MEM_LEVEL
  19. #if MAX_MEM_LEVEL >= 8
  20. #define DEF_MEM_LEVEL 8
  21. #else
  22. #define DEF_MEM_LEVEL MAX_MEM_LEVEL
  23. #endif
  24. #endif
  25. /*--------- Prototypes --------*/
  26. static NORETURN(void raise_zlib_error(int, const char*));
  27. static VALUE rb_zlib_version(VALUE);
  28. static VALUE do_checksum(int, VALUE*, uLong (*)(uLong, const Bytef*, uInt));
  29. static VALUE rb_zlib_adler32(int, VALUE*, VALUE);
  30. static VALUE rb_zlib_crc32(int, VALUE*, VALUE);
  31. static VALUE rb_zlib_crc_table(VALUE);
  32. static voidpf zlib_mem_alloc(voidpf, uInt, uInt);
  33. static void zlib_mem_free(voidpf, voidpf);
  34. static void finalizer_warn(const char*);
  35. struct zstream;
  36. struct zstream_funcs;
  37. static void zstream_init(struct zstream*, const struct zstream_funcs*);
  38. static void zstream_expand_buffer(struct zstream*);
  39. static void zstream_expand_buffer_into(struct zstream*, int);
  40. static void zstream_append_buffer(struct zstream*, const Bytef*, int);
  41. static VALUE zstream_detach_buffer(struct zstream*);
  42. static VALUE zstream_shift_buffer(struct zstream*, int);
  43. static void zstream_buffer_ungets(struct zstream*, const Bytef*, int);
  44. static void zstream_buffer_ungetbyte(struct zstream*, int);
  45. static void zstream_append_input(struct zstream*, const Bytef*, unsigned int);
  46. static void zstream_discard_input(struct zstream*, unsigned int);
  47. static void zstream_reset_input(struct zstream*);
  48. static void zstream_passthrough_input(struct zstream*);
  49. static VALUE zstream_detach_input(struct zstream*);
  50. static void zstream_reset(struct zstream*);
  51. static VALUE zstream_end(struct zstream*);
  52. static void zstream_run(struct zstream*, Bytef*, uInt, int);
  53. static VALUE zstream_sync(struct zstream*, Bytef*, uInt);
  54. static void zstream_mark(struct zstream*);
  55. static void zstream_free(struct zstream*);
  56. static VALUE zstream_new(VALUE, const struct zstream_funcs*);
  57. static struct zstream *get_zstream(VALUE);
  58. static void zstream_finalize(struct zstream*);
  59. static VALUE rb_zstream_end(VALUE);
  60. static VALUE rb_zstream_reset(VALUE);
  61. static VALUE rb_zstream_finish(VALUE);
  62. static VALUE rb_zstream_flush_next_in(VALUE);
  63. static VALUE rb_zstream_flush_next_out(VALUE);
  64. static VALUE rb_zstream_avail_out(VALUE);
  65. static VALUE rb_zstream_set_avail_out(VALUE, VALUE);
  66. static VALUE rb_zstream_avail_in(VALUE);
  67. static VALUE rb_zstream_total_in(VALUE);
  68. static VALUE rb_zstream_total_out(VALUE);
  69. static VALUE rb_zstream_data_type(VALUE);
  70. static VALUE rb_zstream_adler(VALUE);
  71. static VALUE rb_zstream_finished_p(VALUE);
  72. static VALUE rb_zstream_closed_p(VALUE);
  73. static VALUE rb_deflate_s_allocate(VALUE);
  74. static VALUE rb_deflate_initialize(int, VALUE*, VALUE);
  75. static VALUE rb_deflate_init_copy(VALUE, VALUE);
  76. static VALUE deflate_run(VALUE);
  77. static VALUE rb_deflate_s_deflate(int, VALUE*, VALUE);
  78. static void do_deflate(struct zstream*, VALUE, int);
  79. static VALUE rb_deflate_deflate(int, VALUE*, VALUE);
  80. static VALUE rb_deflate_addstr(VALUE, VALUE);
  81. static VALUE rb_deflate_flush(int, VALUE*, VALUE);
  82. static VALUE rb_deflate_params(VALUE, VALUE, VALUE);
  83. static VALUE rb_deflate_set_dictionary(VALUE, VALUE);
  84. static VALUE inflate_run(VALUE);
  85. static VALUE rb_inflate_s_allocate(VALUE);
  86. static VALUE rb_inflate_initialize(int, VALUE*, VALUE);
  87. static VALUE rb_inflate_s_inflate(VALUE, VALUE);
  88. static void do_inflate(struct zstream*, VALUE);
  89. static VALUE rb_inflate_inflate(VALUE, VALUE);
  90. static VALUE rb_inflate_addstr(VALUE, VALUE);
  91. static VALUE rb_inflate_sync(VALUE, VALUE);
  92. static VALUE rb_inflate_sync_point_p(VALUE);
  93. static VALUE rb_inflate_set_dictionary(VALUE, VALUE);
  94. #if GZIP_SUPPORT
  95. struct gzfile;
  96. static void gzfile_mark(struct gzfile*);
  97. static void gzfile_free(struct gzfile*);
  98. static VALUE gzfile_new(VALUE, const struct zstream_funcs*, void (*) _((struct gzfile*)));
  99. static void gzfile_reset(struct gzfile*);
  100. static void gzfile_close(struct gzfile*, int);
  101. static void gzfile_write_raw(struct gzfile*);
  102. static VALUE gzfile_read_raw_partial(VALUE);
  103. static VALUE gzfile_read_raw_rescue(VALUE);
  104. static VALUE gzfile_read_raw(struct gzfile*);
  105. static int gzfile_read_raw_ensure(struct gzfile*, int);
  106. static char *gzfile_read_raw_until_zero(struct gzfile*, long);
  107. static unsigned int gzfile_get16(const unsigned char*);
  108. static unsigned long gzfile_get32(const unsigned char*);
  109. static void gzfile_set32(unsigned long n, unsigned char*);
  110. static void gzfile_make_header(struct gzfile*);
  111. static void gzfile_make_footer(struct gzfile*);
  112. static void gzfile_read_header(struct gzfile*);
  113. static void gzfile_check_footer(struct gzfile*);
  114. static void gzfile_write(struct gzfile*, Bytef*, uInt);
  115. static long gzfile_read_more(struct gzfile*);
  116. static void gzfile_calc_crc(struct gzfile*, VALUE);
  117. static VALUE gzfile_read(struct gzfile*, int);
  118. static VALUE gzfile_read_all(struct gzfile*);
  119. static void gzfile_ungets(struct gzfile*, const Bytef*, int);
  120. static void gzfile_ungetbyte(struct gzfile*, int);
  121. static VALUE gzfile_writer_end_run(VALUE);
  122. static void gzfile_writer_end(struct gzfile*);
  123. static VALUE gzfile_reader_end_run(VALUE);
  124. static void gzfile_reader_end(struct gzfile*);
  125. static void gzfile_reader_rewind(struct gzfile*);
  126. static VALUE gzfile_reader_get_unused(struct gzfile*);
  127. static struct gzfile *get_gzfile(VALUE);
  128. static VALUE gzfile_ensure_close(VALUE);
  129. static VALUE rb_gzfile_s_wrap(int, VALUE*, VALUE);
  130. static VALUE gzfile_s_open(int, VALUE*, VALUE, const char*);
  131. static VALUE rb_gzfile_to_io(VALUE);
  132. static VALUE rb_gzfile_crc(VALUE);
  133. static VALUE rb_gzfile_mtime(VALUE);
  134. static VALUE rb_gzfile_level(VALUE);
  135. static VALUE rb_gzfile_os_code(VALUE);
  136. static VALUE rb_gzfile_orig_name(VALUE);
  137. static VALUE rb_gzfile_comment(VALUE);
  138. static VALUE rb_gzfile_lineno(VALUE);
  139. static VALUE rb_gzfile_set_lineno(VALUE, VALUE);
  140. static VALUE rb_gzfile_set_mtime(VALUE, VALUE);
  141. static VALUE rb_gzfile_set_orig_name(VALUE, VALUE);
  142. static VALUE rb_gzfile_set_comment(VALUE, VALUE);
  143. static VALUE rb_gzfile_close(VALUE);
  144. static VALUE rb_gzfile_finish(VALUE);
  145. static VALUE rb_gzfile_closed_p(VALUE);
  146. static VALUE rb_gzfile_eof_p(VALUE);
  147. static VALUE rb_gzfile_sync(VALUE);
  148. static VALUE rb_gzfile_set_sync(VALUE, VALUE);
  149. static VALUE rb_gzfile_total_in(VALUE);
  150. static VALUE rb_gzfile_total_out(VALUE);
  151. static VALUE rb_gzfile_path(VALUE);
  152. static VALUE rb_gzwriter_s_allocate(VALUE);
  153. static VALUE rb_gzwriter_s_open(int, VALUE*, VALUE);
  154. static VALUE rb_gzwriter_initialize(int, VALUE*, VALUE);
  155. static VALUE rb_gzwriter_flush(int, VALUE*, VALUE);
  156. static VALUE rb_gzwriter_write(VALUE, VALUE);
  157. static VALUE rb_gzwriter_putc(VALUE, VALUE);
  158. static VALUE rb_gzreader_s_allocate(VALUE);
  159. static VALUE rb_gzreader_s_open(int, VALUE*, VALUE);
  160. static VALUE rb_gzreader_initialize(int, VALUE*, VALUE);
  161. static VALUE rb_gzreader_rewind(VALUE);
  162. static VALUE rb_gzreader_unused(VALUE);
  163. static VALUE rb_gzreader_read(int, VALUE*, VALUE);
  164. static VALUE rb_gzreader_getc(VALUE);
  165. static VALUE rb_gzreader_readchar(VALUE);
  166. static VALUE rb_gzreader_each_byte(VALUE);
  167. static VALUE rb_gzreader_ungetc(VALUE, VALUE);
  168. static VALUE rb_gzreader_ungetbyte(VALUE, VALUE);
  169. static void gzreader_skip_linebreaks(struct gzfile*);
  170. static VALUE gzreader_gets(int, VALUE*, VALUE);
  171. static VALUE rb_gzreader_gets(int, VALUE*, VALUE);
  172. static VALUE rb_gzreader_readline(int, VALUE*, VALUE);
  173. static VALUE rb_gzreader_each(int, VALUE*, VALUE);
  174. static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
  175. #endif /* GZIP_SUPPORT */
  176. void Init_zlib(void);
  177. int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p);
  178. VALUE rb_str_conv_enc_opts(VALUE, rb_encoding*, rb_encoding*, int, VALUE);
  179. /*--------- Exceptions --------*/
  180. static VALUE cZError, cStreamEnd, cNeedDict;
  181. static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError;
  182. static void
  183. raise_zlib_error(int err, const char *msg)
  184. {
  185. VALUE exc;
  186. if (!msg) {
  187. msg = zError(err);
  188. }
  189. switch(err) {
  190. case Z_STREAM_END:
  191. exc = rb_exc_new2(cStreamEnd, msg);
  192. break;
  193. case Z_NEED_DICT:
  194. exc = rb_exc_new2(cNeedDict, msg);
  195. break;
  196. case Z_STREAM_ERROR:
  197. exc = rb_exc_new2(cStreamError, msg);
  198. break;
  199. case Z_DATA_ERROR:
  200. exc = rb_exc_new2(cDataError, msg);
  201. break;
  202. case Z_BUF_ERROR:
  203. exc = rb_exc_new2(cBufError, msg);
  204. break;
  205. case Z_VERSION_ERROR:
  206. exc = rb_exc_new2(cVersionError, msg);
  207. break;
  208. case Z_MEM_ERROR:
  209. exc = rb_exc_new2(cMemError, msg);
  210. break;
  211. case Z_ERRNO:
  212. rb_sys_fail(msg);
  213. /* no return */
  214. default:
  215. {
  216. char buf[BUFSIZ];
  217. snprintf(buf, BUFSIZ, "unknown zlib error %d: %s", err, msg);
  218. exc = rb_exc_new2(cZError, buf);
  219. }
  220. }
  221. rb_exc_raise(exc);
  222. }
  223. /*--- Warning (in finalizer) ---*/
  224. static void
  225. finalizer_warn(const char *msg)
  226. {
  227. fprintf(stderr, "zlib(finalizer): %s\n", msg);
  228. }
  229. /*-------- module Zlib --------*/
  230. /*
  231. * Returns the string which represents the version of zlib library.
  232. */
  233. static VALUE
  234. rb_zlib_version(VALUE klass)
  235. {
  236. VALUE str;
  237. str = rb_str_new2(zlibVersion());
  238. OBJ_TAINT(str); /* for safe */
  239. return str;
  240. }
  241. static VALUE
  242. do_checksum(argc, argv, func)
  243. int argc;
  244. VALUE *argv;
  245. uLong (*func)(uLong, const Bytef*, uInt);
  246. {
  247. VALUE str, vsum;
  248. unsigned long sum;
  249. rb_scan_args(argc, argv, "02", &str, &vsum);
  250. if (!NIL_P(vsum)) {
  251. sum = NUM2ULONG(vsum);
  252. }
  253. else if (NIL_P(str)) {
  254. sum = 0;
  255. }
  256. else {
  257. sum = func(0, Z_NULL, 0);
  258. }
  259. if (NIL_P(str)) {
  260. sum = func(sum, Z_NULL, 0);
  261. }
  262. else {
  263. StringValue(str);
  264. sum = func(sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
  265. }
  266. return rb_uint2inum(sum);
  267. }
  268. /*
  269. * call-seq: Zlib.adler32(string, adler)
  270. *
  271. * Calculates Adler-32 checksum for +string+, and returns updated value of
  272. * +adler+. If +string+ is omitted, it returns the Adler-32 initial value. If
  273. * +adler+ is omitted, it assumes that the initial value is given to +adler+.
  274. *
  275. * FIXME: expression.
  276. */
  277. static VALUE
  278. rb_zlib_adler32(int argc, VALUE *argv, VALUE klass)
  279. {
  280. return do_checksum(argc, argv, adler32);
  281. }
  282. #ifdef HAVE_ADLER32_COMBINE
  283. /*
  284. * call-seq: Zlib.adler32_combine(adler1, adler2, len2)
  285. *
  286. * Combine two Adler-32 check values in to one. +alder1+ is the first Adler-32
  287. * value, +adler2+ is the second Adler-32 value. +len2+ is the length of the
  288. * string used to generate +adler2+.
  289. *
  290. */
  291. static VALUE
  292. rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
  293. {
  294. return ULONG2NUM(
  295. adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
  296. }
  297. #else
  298. #define rb_zlib_adler32_combine rb_f_notimplement
  299. #endif
  300. /*
  301. * call-seq: Zlib.crc32(string, adler)
  302. *
  303. * Calculates CRC checksum for +string+, and returns updated value of +crc+. If
  304. * +string+ is omitted, it returns the CRC initial value. If +crc+ is omitted, it
  305. * assumes that the initial value is given to +crc+.
  306. *
  307. * FIXME: expression.
  308. */
  309. static VALUE
  310. rb_zlib_crc32(int argc, VALUE *argv, VALUE klass)
  311. {
  312. return do_checksum(argc, argv, crc32);
  313. }
  314. #ifdef HAVE_CRC32_COMBINE
  315. /*
  316. * call-seq: Zlib.crc32_combine(crc1, crc2, len2)
  317. *
  318. * Combine two CRC-32 check values in to one. +crc1+ is the first CRC-32
  319. * value, +crc2+ is the second CRC-32 value. +len2+ is the length of the
  320. * string used to generate +crc2+.
  321. *
  322. */
  323. static VALUE
  324. rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
  325. {
  326. return ULONG2NUM(
  327. crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
  328. }
  329. #else
  330. #define rb_zlib_crc32_combine rb_f_notimplement
  331. #endif
  332. /*
  333. * Returns the table for calculating CRC checksum as an array.
  334. */
  335. static VALUE
  336. rb_zlib_crc_table(VALUE obj)
  337. {
  338. const unsigned long *crctbl;
  339. VALUE dst;
  340. int i;
  341. crctbl = get_crc_table();
  342. dst = rb_ary_new2(256);
  343. for (i = 0; i < 256; i++) {
  344. rb_ary_push(dst, rb_uint2inum(crctbl[i]));
  345. }
  346. return dst;
  347. }
  348. /*-------- zstream - internal APIs --------*/
  349. struct zstream {
  350. unsigned long flags;
  351. VALUE buf;
  352. long buf_filled;
  353. VALUE input;
  354. z_stream stream;
  355. const struct zstream_funcs {
  356. int (*reset)(z_streamp);
  357. int (*end)(z_streamp);
  358. int (*run)(z_streamp, int);
  359. } *func;
  360. };
  361. #define ZSTREAM_FLAG_READY 0x1
  362. #define ZSTREAM_FLAG_IN_STREAM 0x2
  363. #define ZSTREAM_FLAG_FINISHED 0x4
  364. #define ZSTREAM_FLAG_CLOSING 0x8
  365. #define ZSTREAM_FLAG_UNUSED 0x10
  366. #define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
  367. #define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
  368. #define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)
  369. #define ZSTREAM_IS_CLOSING(z) ((z)->flags & ZSTREAM_FLAG_CLOSING)
  370. /* I think that more better value should be found,
  371. but I gave up finding it. B) */
  372. #define ZSTREAM_INITIAL_BUFSIZE 1024
  373. #define ZSTREAM_AVAIL_OUT_STEP_MAX 16384
  374. #define ZSTREAM_AVAIL_OUT_STEP_MIN 2048
  375. static const struct zstream_funcs deflate_funcs = {
  376. deflateReset, deflateEnd, deflate,
  377. };
  378. static const struct zstream_funcs inflate_funcs = {
  379. inflateReset, inflateEnd, inflate,
  380. };
  381. static voidpf
  382. zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
  383. {
  384. return xmalloc(items * size);
  385. }
  386. static void
  387. zlib_mem_free(voidpf opaque, voidpf address)
  388. {
  389. xfree(address);
  390. }
  391. static void
  392. zstream_init(struct zstream *z, const struct zstream_funcs *func)
  393. {
  394. z->flags = 0;
  395. z->buf = Qnil;
  396. z->buf_filled = 0;
  397. z->input = Qnil;
  398. z->stream.zalloc = zlib_mem_alloc;
  399. z->stream.zfree = zlib_mem_free;
  400. z->stream.opaque = Z_NULL;
  401. z->stream.msg = Z_NULL;
  402. z->stream.next_in = Z_NULL;
  403. z->stream.avail_in = 0;
  404. z->stream.next_out = Z_NULL;
  405. z->stream.avail_out = 0;
  406. z->func = func;
  407. }
  408. #define zstream_init_deflate(z) zstream_init((z), &deflate_funcs)
  409. #define zstream_init_inflate(z) zstream_init((z), &inflate_funcs)
  410. static void
  411. zstream_expand_buffer(struct zstream *z)
  412. {
  413. long inc;
  414. if (NIL_P(z->buf)) {
  415. /* I uses rb_str_new here not rb_str_buf_new because
  416. rb_str_buf_new makes a zero-length string. */
  417. z->buf = rb_str_new(0, ZSTREAM_INITIAL_BUFSIZE);
  418. z->buf_filled = 0;
  419. z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
  420. z->stream.avail_out = ZSTREAM_INITIAL_BUFSIZE;
  421. RBASIC(z->buf)->klass = 0;
  422. return;
  423. }
  424. if (RSTRING_LEN(z->buf) - z->buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
  425. /* to keep other threads from freezing */
  426. z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
  427. }
  428. else {
  429. inc = z->buf_filled / 2;
  430. if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
  431. inc = ZSTREAM_AVAIL_OUT_STEP_MIN;
  432. }
  433. rb_str_resize(z->buf, z->buf_filled + inc);
  434. z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
  435. inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
  436. }
  437. z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
  438. }
  439. static void
  440. zstream_expand_buffer_into(struct zstream *z, int size)
  441. {
  442. if (NIL_P(z->buf)) {
  443. /* I uses rb_str_new here not rb_str_buf_new because
  444. rb_str_buf_new makes a zero-length string. */
  445. z->buf = rb_str_new(0, size);
  446. z->buf_filled = 0;
  447. z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
  448. z->stream.avail_out = size;
  449. RBASIC(z->buf)->klass = 0;
  450. }
  451. else if (z->stream.avail_out != size) {
  452. rb_str_resize(z->buf, z->buf_filled + size);
  453. z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
  454. z->stream.avail_out = size;
  455. }
  456. }
  457. static void
  458. zstream_append_buffer(struct zstream *z, const Bytef *src, int len)
  459. {
  460. if (NIL_P(z->buf)) {
  461. z->buf = rb_str_buf_new(len);
  462. rb_str_buf_cat(z->buf, (const char*)src, len);
  463. z->buf_filled = len;
  464. z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
  465. z->stream.avail_out = 0;
  466. RBASIC(z->buf)->klass = 0;
  467. return;
  468. }
  469. if (RSTRING_LEN(z->buf) < z->buf_filled + len) {
  470. rb_str_resize(z->buf, z->buf_filled + len);
  471. z->stream.avail_out = 0;
  472. }
  473. else {
  474. if (z->stream.avail_out >= (uInt)len) {
  475. z->stream.avail_out -= len;
  476. }
  477. else {
  478. z->stream.avail_out = 0;
  479. }
  480. }
  481. memcpy(RSTRING_PTR(z->buf) + z->buf_filled, src, len);
  482. z->buf_filled += len;
  483. z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
  484. }
  485. #define zstream_append_buffer2(z,v) \
  486. zstream_append_buffer((z),(Bytef*)RSTRING_PTR(v),RSTRING_LEN(v))
  487. static VALUE
  488. zstream_detach_buffer(struct zstream *z)
  489. {
  490. VALUE dst;
  491. if (NIL_P(z->buf)) {
  492. dst = rb_str_new(0, 0);
  493. }
  494. else {
  495. dst = z->buf;
  496. rb_str_resize(dst, z->buf_filled);
  497. RBASIC(dst)->klass = rb_cString;
  498. }
  499. z->buf = Qnil;
  500. z->buf_filled = 0;
  501. z->stream.next_out = 0;
  502. z->stream.avail_out = 0;
  503. return dst;
  504. }
  505. static VALUE
  506. zstream_shift_buffer(struct zstream *z, int len)
  507. {
  508. VALUE dst;
  509. if (z->buf_filled <= len) {
  510. return zstream_detach_buffer(z);
  511. }
  512. dst = rb_str_subseq(z->buf, 0, len);
  513. RBASIC(dst)->klass = rb_cString;
  514. z->buf_filled -= len;
  515. memmove(RSTRING_PTR(z->buf), RSTRING_PTR(z->buf) + len,
  516. z->buf_filled);
  517. z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
  518. z->stream.avail_out = RSTRING_LEN(z->buf) - z->buf_filled;
  519. if (z->stream.avail_out > ZSTREAM_AVAIL_OUT_STEP_MAX) {
  520. z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
  521. }
  522. return dst;
  523. }
  524. static void
  525. zstream_buffer_ungets(struct zstream *z, const Bytef *b, int len)
  526. {
  527. if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
  528. zstream_expand_buffer_into(z, len);
  529. }
  530. memmove(RSTRING_PTR(z->buf) + len, RSTRING_PTR(z->buf), z->buf_filled);
  531. memmove(RSTRING_PTR(z->buf), b, len);
  532. z->buf_filled+=len;
  533. if (z->stream.avail_out > 0) {
  534. z->stream.next_out+=len;
  535. z->stream.avail_out-=len;
  536. }
  537. }
  538. static void
  539. zstream_buffer_ungetbyte(struct zstream *z, int c)
  540. {
  541. if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
  542. zstream_expand_buffer(z);
  543. }
  544. memmove(RSTRING_PTR(z->buf) + 1, RSTRING_PTR(z->buf), z->buf_filled);
  545. RSTRING_PTR(z->buf)[0] = (char)c;
  546. z->buf_filled++;
  547. if (z->stream.avail_out > 0) {
  548. z->stream.next_out++;
  549. z->stream.avail_out--;
  550. }
  551. }
  552. static void
  553. zstream_append_input(struct zstream *z, const Bytef *src, unsigned int len)
  554. {
  555. if (len <= 0) return;
  556. if (NIL_P(z->input)) {
  557. z->input = rb_str_buf_new(len);
  558. rb_str_buf_cat(z->input, (const char*)src, len);
  559. RBASIC(z->input)->klass = 0;
  560. }
  561. else {
  562. rb_str_buf_cat(z->input, (const char*)src, len);
  563. }
  564. }
  565. #define zstream_append_input2(z,v)\
  566. zstream_append_input((z), (Bytef*)RSTRING_PTR(v), RSTRING_LEN(v))
  567. static void
  568. zstream_discard_input(struct zstream *z, unsigned int len)
  569. {
  570. if (NIL_P(z->input) || (unsigned int)RSTRING_LEN(z->input) <= len) {
  571. z->input = Qnil;
  572. }
  573. else {
  574. memmove(RSTRING_PTR(z->input), RSTRING_PTR(z->input) + len,
  575. RSTRING_LEN(z->input) - len);
  576. rb_str_resize(z->input, RSTRING_LEN(z->input) - len);
  577. }
  578. }
  579. static void
  580. zstream_reset_input(struct zstream *z)
  581. {
  582. z->input = Qnil;
  583. }
  584. static void
  585. zstream_passthrough_input(struct zstream *z)
  586. {
  587. if (!NIL_P(z->input)) {
  588. zstream_append_buffer2(z, z->input);
  589. z->input = Qnil;
  590. }
  591. }
  592. static VALUE
  593. zstream_detach_input(struct zstream *z)
  594. {
  595. VALUE dst;
  596. if (NIL_P(z->input)) {
  597. dst = rb_str_new(0, 0);
  598. }
  599. else {
  600. dst = z->input;
  601. RBASIC(dst)->klass = rb_cString;
  602. }
  603. z->input = Qnil;
  604. RBASIC(dst)->klass = rb_cString;
  605. return dst;
  606. }
  607. static void
  608. zstream_reset(struct zstream *z)
  609. {
  610. int err;
  611. err = z->func->reset(&z->stream);
  612. if (err != Z_OK) {
  613. raise_zlib_error(err, z->stream.msg);
  614. }
  615. z->flags = ZSTREAM_FLAG_READY;
  616. z->buf = Qnil;
  617. z->buf_filled = 0;
  618. z->stream.next_out = 0;
  619. z->stream.avail_out = 0;
  620. zstream_reset_input(z);
  621. }
  622. static VALUE
  623. zstream_end(struct zstream *z)
  624. {
  625. int err;
  626. if (!ZSTREAM_IS_READY(z)) {
  627. rb_warning("attempt to close uninitialized zstream; ignored.");
  628. return Qnil;
  629. }
  630. if (z->flags & ZSTREAM_FLAG_IN_STREAM) {
  631. rb_warning("attempt to close unfinished zstream; reset forced.");
  632. zstream_reset(z);
  633. }
  634. zstream_reset_input(z);
  635. err = z->func->end(&z->stream);
  636. if (err != Z_OK) {
  637. raise_zlib_error(err, z->stream.msg);
  638. }
  639. z->flags = 0;
  640. return Qnil;
  641. }
  642. static void
  643. zstream_run(struct zstream *z, Bytef *src, uInt len, int flush)
  644. {
  645. uInt n;
  646. int err;
  647. volatile VALUE guard = Qnil;
  648. if (NIL_P(z->input) && len == 0) {
  649. z->stream.next_in = (Bytef*)"";
  650. z->stream.avail_in = 0;
  651. }
  652. else {
  653. zstream_append_input(z, src, len);
  654. z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
  655. z->stream.avail_in = RSTRING_LEN(z->input);
  656. /* keep reference to `z->input' so as not to be garbage collected
  657. after zstream_reset_input() and prevent `z->stream.next_in'
  658. from dangling. */
  659. guard = z->input;
  660. }
  661. if (z->stream.avail_out == 0) {
  662. zstream_expand_buffer(z);
  663. }
  664. for (;;) {
  665. /* VC allocates err and guard to same address. accessing err and guard
  666. in same scope prevents it. */
  667. RB_GC_GUARD(guard);
  668. n = z->stream.avail_out;
  669. err = z->func->run(&z->stream, flush);
  670. z->buf_filled += n - z->stream.avail_out;
  671. rb_thread_schedule();
  672. if (err == Z_STREAM_END) {
  673. z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
  674. z->flags |= ZSTREAM_FLAG_FINISHED;
  675. break;
  676. }
  677. if (err != Z_OK) {
  678. if (flush != Z_FINISH && err == Z_BUF_ERROR
  679. && z->stream.avail_out > 0) {
  680. z->flags |= ZSTREAM_FLAG_IN_STREAM;
  681. break;
  682. }
  683. zstream_reset_input(z);
  684. if (z->stream.avail_in > 0) {
  685. zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
  686. }
  687. raise_zlib_error(err, z->stream.msg);
  688. }
  689. if (z->stream.avail_out > 0) {
  690. z->flags |= ZSTREAM_FLAG_IN_STREAM;
  691. break;
  692. }
  693. zstream_expand_buffer(z);
  694. }
  695. zstream_reset_input(z);
  696. if (z->stream.avail_in > 0) {
  697. zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
  698. guard = Qnil; /* prevent tail call to make guard effective */
  699. }
  700. }
  701. static VALUE
  702. zstream_sync(struct zstream *z, Bytef *src, uInt len)
  703. {
  704. VALUE rest;
  705. int err;
  706. if (!NIL_P(z->input)) {
  707. z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
  708. z->stream.avail_in = RSTRING_LEN(z->input);
  709. err = inflateSync(&z->stream);
  710. if (err == Z_OK) {
  711. zstream_discard_input(z,
  712. RSTRING_LEN(z->input) - z->stream.avail_in);
  713. zstream_append_input(z, src, len);
  714. return Qtrue;
  715. }
  716. zstream_reset_input(z);
  717. if (err != Z_DATA_ERROR) {
  718. rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in);
  719. raise_zlib_error(err, z->stream.msg);
  720. }
  721. }
  722. if (len <= 0) return Qfalse;
  723. z->stream.next_in = src;
  724. z->stream.avail_in = len;
  725. err = inflateSync(&z->stream);
  726. if (err == Z_OK) {
  727. zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
  728. return Qtrue;
  729. }
  730. if (err != Z_DATA_ERROR) {
  731. rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in);
  732. raise_zlib_error(err, z->stream.msg);
  733. }
  734. return Qfalse;
  735. }
  736. static void
  737. zstream_mark(struct zstream *z)
  738. {
  739. rb_gc_mark(z->buf);
  740. rb_gc_mark(z->input);
  741. }
  742. static void
  743. zstream_finalize(struct zstream *z)
  744. {
  745. int err = z->func->end(&z->stream);
  746. if (err == Z_STREAM_ERROR)
  747. finalizer_warn("the stream state was inconsistent.");
  748. if (err == Z_DATA_ERROR)
  749. finalizer_warn("the stream was freed prematurely.");
  750. }
  751. static void
  752. zstream_free(struct zstream *z)
  753. {
  754. if (ZSTREAM_IS_READY(z)) {
  755. zstream_finalize(z);
  756. }
  757. xfree(z);
  758. }
  759. static VALUE
  760. zstream_new(VALUE klass, const struct zstream_funcs *funcs)
  761. {
  762. VALUE obj;
  763. struct zstream *z;
  764. obj = Data_Make_Struct(klass, struct zstream,
  765. zstream_mark, zstream_free, z);
  766. zstream_init(z, funcs);
  767. return obj;
  768. }
  769. #define zstream_deflate_new(klass) zstream_new((klass), &deflate_funcs)
  770. #define zstream_inflate_new(klass) zstream_new((klass), &inflate_funcs)
  771. static struct zstream *
  772. get_zstream(VALUE obj)
  773. {
  774. struct zstream *z;
  775. Data_Get_Struct(obj, struct zstream, z);
  776. if (!ZSTREAM_IS_READY(z)) {
  777. rb_raise(cZError, "stream is not ready");
  778. }
  779. return z;
  780. }
  781. /* ------------------------------------------------------------------------- */
  782. /*
  783. * Document-class: Zlib::ZStream
  784. *
  785. * Zlib::ZStream is the abstract class for the stream which handles the
  786. * compressed data. The operations are defined in the subclasses:
  787. * Zlib::Deflate for compression, and Zlib::Inflate for decompression.
  788. *
  789. * An instance of Zlib::ZStream has one stream (struct zstream in the source)
  790. * and two variable-length buffers which associated to the input (next_in) of
  791. * the stream and the output (next_out) of the stream. In this document,
  792. * "input buffer" means the buffer for input, and "output buffer" means the
  793. * buffer for output.
  794. *
  795. * Data input into an instance of Zlib::ZStream are temporally stored into
  796. * the end of input buffer, and then data in input buffer are processed from
  797. * the beginning of the buffer until no more output from the stream is
  798. * produced (i.e. until avail_out > 0 after processing). During processing,
  799. * output buffer is allocated and expanded automatically to hold all output
  800. * data.
  801. *
  802. * Some particular instance methods consume the data in output buffer and
  803. * return them as a String.
  804. *
  805. * Here is an ascii art for describing above:
  806. *
  807. * +================ an instance of Zlib::ZStream ================+
  808. * || ||
  809. * || +--------+ +-------+ +--------+ ||
  810. * || +--| output |<---------|zstream|<---------| input |<--+ ||
  811. * || | | buffer | next_out+-------+next_in | buffer | | ||
  812. * || | +--------+ +--------+ | ||
  813. * || | | ||
  814. * +===|======================================================|===+
  815. * | |
  816. * v |
  817. * "output data" "input data"
  818. *
  819. * If an error occurs during processing input buffer, an exception which is a
  820. * subclass of Zlib::Error is raised. At that time, both input and output
  821. * buffer keep their conditions at the time when the error occurs.
  822. *
  823. * == Method Catalogue
  824. *
  825. * Many of the methods in this class are fairly low-level and unlikely to be
  826. * of interest to users. In fact, users are unlikely to use this class
  827. * directly; rather they will be interested in Zlib::Inflate and
  828. * Zlib::Deflate.
  829. *
  830. * The higher level methods are listed below.
  831. *
  832. * - #total_in
  833. * - #total_out
  834. * - #data_type
  835. * - #adler
  836. * - #reset
  837. * - #finish
  838. * - #finished?
  839. * - #close
  840. * - #closed?
  841. */
  842. /*
  843. * Closes the stream. All operations on the closed stream will raise an
  844. * exception.
  845. */
  846. static VALUE
  847. rb_zstream_end(VALUE obj)
  848. {
  849. zstream_end(get_zstream(obj));
  850. return Qnil;
  851. }
  852. /*
  853. * Resets and initializes the stream. All data in both input and output buffer
  854. * are discarded.
  855. */
  856. static VALUE
  857. rb_zstream_reset(VALUE obj)
  858. {
  859. zstream_reset(get_zstream(obj));
  860. return Qnil;
  861. }
  862. /*
  863. * Finishes the stream and flushes output buffer. See Zlib::Deflate#finish and
  864. * Zlib::Inflate#finish for details of this behavior.
  865. */
  866. static VALUE
  867. rb_zstream_finish(VALUE obj)
  868. {
  869. struct zstream *z = get_zstream(obj);
  870. VALUE dst;
  871. zstream_run(z, (Bytef*)"", 0, Z_FINISH);
  872. dst = zstream_detach_buffer(z);
  873. OBJ_INFECT(dst, obj);
  874. return dst;
  875. }
  876. /*
  877. * Flushes input buffer and returns all data in that buffer.
  878. */
  879. static VALUE
  880. rb_zstream_flush_next_in(VALUE obj)
  881. {
  882. struct zstream *z;
  883. VALUE dst;
  884. Data_Get_Struct(obj, struct zstream, z);
  885. dst = zstream_detach_input(z);
  886. OBJ_INFECT(dst, obj);
  887. return dst;
  888. }
  889. /*
  890. * Flushes output buffer and returns all data in that buffer.
  891. */
  892. static VALUE
  893. rb_zstream_flush_next_out(VALUE obj)
  894. {
  895. struct zstream *z;
  896. VALUE dst;
  897. Data_Get_Struct(obj, struct zstream, z);
  898. dst = zstream_detach_buffer(z);
  899. OBJ_INFECT(dst, obj);
  900. return dst;
  901. }
  902. /*
  903. * Returns number of bytes of free spaces in output buffer. Because the free
  904. * space is allocated automatically, this method returns 0 normally.
  905. */
  906. static VALUE
  907. rb_zstream_avail_out(VALUE obj)
  908. {
  909. struct zstream *z;
  910. Data_Get_Struct(obj, struct zstream, z);
  911. return rb_uint2inum(z->stream.avail_out);
  912. }
  913. /*
  914. * Allocates +size+ bytes of free space in the output buffer. If there are more
  915. * than +size+ bytes already in the buffer, the buffer is truncated. Because
  916. * free space is allocated automatically, you usually don't need to use this
  917. * method.
  918. */
  919. static VALUE
  920. rb_zstream_set_avail_out(VALUE obj, VALUE size)
  921. {
  922. struct zstream *z = get_zstream(obj);
  923. Check_Type(size, T_FIXNUM);
  924. zstream_expand_buffer_into(z, FIX2INT(size));
  925. return size;
  926. }
  927. /*
  928. * Returns bytes of data in the input buffer. Normally, returns 0.
  929. */
  930. static VALUE
  931. rb_zstream_avail_in(VALUE obj)
  932. {
  933. struct zstream *z;
  934. Data_Get_Struct(obj, struct zstream, z);
  935. return INT2FIX(NIL_P(z->input) ? 0 : (int)(RSTRING_LEN(z->input)));
  936. }
  937. /*
  938. * Returns the total bytes of the input data to the stream. FIXME
  939. */
  940. static VALUE
  941. rb_zstream_total_in(VALUE obj)
  942. {
  943. return rb_uint2inum(get_zstream(obj)->stream.total_in);
  944. }
  945. /*
  946. * Returns the total bytes of the output data from the stream. FIXME
  947. */
  948. static VALUE
  949. rb_zstream_total_out(VALUE obj)
  950. {
  951. return rb_uint2inum(get_zstream(obj)->stream.total_out);
  952. }
  953. /*
  954. * Guesses the type of the data which have been inputed into the stream. The
  955. * returned value is either <tt>Zlib::BINARY</tt>, <tt>Zlib::ASCII</tt>, or
  956. * <tt>Zlib::UNKNOWN</tt>.
  957. */
  958. static VALUE
  959. rb_zstream_data_type(VALUE obj)
  960. {
  961. return INT2FIX(get_zstream(obj)->stream.data_type);
  962. }
  963. /*
  964. * Returns the adler-32 checksum.
  965. */
  966. static VALUE
  967. rb_zstream_adler(VALUE obj)
  968. {
  969. return rb_uint2inum(get_zstream(obj)->stream.adler);
  970. }
  971. /*
  972. * Returns true if the stream is finished.
  973. */
  974. static VALUE
  975. rb_zstream_finished_p(VALUE obj)
  976. {
  977. return ZSTREAM_IS_FINISHED(get_zstream(obj)) ? Qtrue : Qfalse;
  978. }
  979. /*
  980. * Returns true if the stream is closed.
  981. */
  982. static VALUE
  983. rb_zstream_closed_p(VALUE obj)
  984. {
  985. struct zstream *z;
  986. Data_Get_Struct(obj, struct zstream, z);
  987. return ZSTREAM_IS_READY(z) ? Qfalse : Qtrue;
  988. }
  989. /* ------------------------------------------------------------------------- */
  990. /*
  991. * Document-class: Zlib::Deflate
  992. *
  993. * Zlib::Deflate is the class for compressing data. See Zlib::Stream for more
  994. * information.
  995. */
  996. #define FIXNUMARG(val, ifnil) \
  997. (NIL_P((val)) ? (ifnil) \
  998. : ((void)Check_Type((val), T_FIXNUM), FIX2INT((val))))
  999. #define ARG_LEVEL(val) FIXNUMARG((val), Z_DEFAULT_COMPRESSION)
  1000. #define ARG_WBITS(val) FIXNUMARG((val), MAX_WBITS)
  1001. #define ARG_MEMLEVEL(val) FIXNUMARG((val), DEF_MEM_LEVEL)
  1002. #define ARG_STRATEGY(val) FIXNUMARG((val), Z_DEFAULT_STRATEGY)
  1003. #define ARG_FLUSH(val) FIXNUMARG((val), Z_NO_FLUSH)
  1004. static VALUE
  1005. rb_deflate_s_allocate(VALUE klass)
  1006. {
  1007. return zstream_deflate_new(klass);
  1008. }
  1009. /*
  1010. * call-seq: Zlib::Deflate.new(level=nil, windowBits=nil, memlevel=nil, strategy=nil)
  1011. *
  1012. * Creates a new deflate stream for compression. See zlib.h for details of
  1013. * each argument. If an argument is nil, the default value of that argument is
  1014. * used.
  1015. *
  1016. * TODO: document better!
  1017. */
  1018. static VALUE
  1019. rb_deflate_initialize(int argc, VALUE *argv, VALUE obj)
  1020. {
  1021. struct zstream *z;
  1022. VALUE level, wbits, memlevel, strategy;
  1023. int err;
  1024. rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy);
  1025. Data_Get_Struct(obj, struct zstream, z);
  1026. err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
  1027. ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
  1028. ARG_STRATEGY(strategy));
  1029. if (err != Z_OK) {
  1030. raise_zlib_error(err, z->stream.msg);
  1031. }
  1032. ZSTREAM_READY(z);
  1033. return obj;
  1034. }
  1035. /*
  1036. * Duplicates the deflate stream.
  1037. */
  1038. static VALUE
  1039. rb_deflate_init_copy(VALUE self, VALUE orig)
  1040. {
  1041. struct zstream *z1, *z2;
  1042. int err;
  1043. Data_Get_Struct(self, struct zstream, z1);
  1044. z2 = get_zstream(orig);
  1045. err = deflateCopy(&z1->stream, &z2->stream);
  1046. if (err != Z_OK) {
  1047. raise_zlib_error(err, 0);
  1048. }
  1049. z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input);
  1050. z1->buf = NIL_P(z2->buf) ? Qnil : rb_str_dup(z2->buf);
  1051. z1->buf_filled = z2->buf_filled;
  1052. z1->flags = z2->flags;
  1053. return self;
  1054. }
  1055. static VALUE
  1056. deflate_run(VALUE args)
  1057. {
  1058. struct zstream *z = (struct zstream*)((VALUE*)args)[0];
  1059. VALUE src = ((VALUE*)args)[1];
  1060. zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_FINISH);
  1061. return zstream_detach_buffer(z);
  1062. }
  1063. /*
  1064. * call-seq: Zlib::Deflate.deflate(string[, level])
  1065. *
  1066. * Compresses the given +string+. Valid values of level are
  1067. * <tt>Zlib::NO_COMPRESSION</tt>, <tt>Zlib::BEST_SPEED</tt>,
  1068. * <tt>Zlib::BEST_COMPRESSION</tt>, <tt>Zlib::DEFAULT_COMPRESSION</tt>, and an
  1069. * integer from 0 to 9.
  1070. *
  1071. * This method is almost equivalent to the following code:
  1072. *
  1073. * def deflate(string, level)
  1074. * z = Zlib::Deflate.new(level)
  1075. * dst = z.deflate(string, Zlib::FINISH)
  1076. * z.close
  1077. * dst
  1078. * end
  1079. *
  1080. * TODO: what's default value of +level+?
  1081. *
  1082. */
  1083. static VALUE
  1084. rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
  1085. {
  1086. struct zstream z;
  1087. VALUE src, level, dst, args[2];
  1088. int err, lev;
  1089. rb_scan_args(argc, argv, "11", &src, &level);
  1090. lev = ARG_LEVEL(level);
  1091. StringValue(src);
  1092. zstream_init_deflate(&z);
  1093. err = deflateInit(&z.stream, lev);
  1094. if (err != Z_OK) {
  1095. raise_zlib_error(err, z.stream.msg);
  1096. }
  1097. ZSTREAM_READY(&z);
  1098. args[0] = (VALUE)&z;
  1099. args[1] = src;
  1100. dst = rb_ensure(deflate_run, (VALUE)args, zstream_end, (VALUE)&z);
  1101. OBJ_INFECT(dst, src);
  1102. return dst;
  1103. }
  1104. static void
  1105. do_deflate(struct zstream *z, VALUE src, int flush)
  1106. {
  1107. if (NIL_P(src)) {
  1108. zstream_run(z, (Bytef*)"", 0, Z_FINISH);
  1109. return;
  1110. }
  1111. StringValue(src);
  1112. if (flush != Z_NO_FLUSH || RSTRING_LEN(src) > 0) { /* prevent BUF_ERROR */
  1113. zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), flush);
  1114. }
  1115. }
  1116. /*
  1117. * call-seq: deflate(string[, flush])
  1118. *
  1119. * Inputs +string+ into the deflate stream and returns the output from the
  1120. * stream. On calling this method, both the input and the output buffers of
  1121. * the stream are flushed. If +string+ is nil, this method finishes the
  1122. * stream, just like Zlib::ZStream#finish.
  1123. *
  1124. * The value of +flush+ should be either <tt>Zlib::NO_FLUSH</tt>,
  1125. * <tt>Zlib::SYNC_FLUSH</tt>, <tt>Zlib::FULL_FLUSH</tt>, or
  1126. * <tt>Zlib::FINISH</tt>. See zlib.h for details.
  1127. *
  1128. * TODO: document better!
  1129. */
  1130. static VALUE
  1131. rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
  1132. {
  1133. struct zstream *z = get_zstream(obj);
  1134. VALUE src, flush, dst;
  1135. rb_scan_args(argc, argv, "11", &src, &flush);
  1136. OBJ_INFECT(obj, src);
  1137. do_deflate(z, src, ARG_FLUSH(flush));
  1138. dst = zstream_detach_buffer(z);
  1139. OBJ_INFECT(dst, obj);
  1140. return dst;
  1141. }
  1142. /*
  1143. * call-seq: << string
  1144. *
  1145. * Inputs +string+ into the deflate stream just like Zlib::Deflate#deflate, but
  1146. * returns the Zlib::Deflate object itself. The output from the stream is
  1147. * preserved in output buffer.
  1148. */
  1149. static VALUE
  1150. rb_deflate_addstr(VALUE obj, VALUE src)
  1151. {
  1152. OBJ_INFECT(obj, src);
  1153. do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
  1154. return obj;
  1155. }
  1156. /*
  1157. * call-seq: flush(flush)
  1158. *
  1159. * This method is equivalent to <tt>deflate('', flush)</tt>. If flush is omitted,
  1160. * <tt>Zlib::SYNC_FLUSH</tt> is used as flush. This method is just provided
  1161. * to improve the readability of your Ruby program.
  1162. *
  1163. * TODO: document better!
  1164. */
  1165. static VALUE
  1166. rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
  1167. {
  1168. struct zstream *z = get_zstream(obj);
  1169. VALUE v_flush, dst;
  1170. int flush;
  1171. rb_scan_args(argc, argv, "01", &v_flush);
  1172. flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
  1173. if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
  1174. zstream_run(z, (Bytef*)"", 0, flush);
  1175. }
  1176. dst = zstream_detach_buffer(z);
  1177. OBJ_INFECT(dst, obj);
  1178. return dst;
  1179. }
  1180. /*
  1181. * call-seq: params(level, strategy)
  1182. *
  1183. * Changes the parameters of the deflate stream. See zlib.h for details. The
  1184. * output from the stream by changing the params is preserved in output
  1185. * buffer.
  1186. *
  1187. * TODO: document better!
  1188. */
  1189. static VALUE
  1190. rb_deflate_params(VALUE obj, VALUE v_level, VALUE v_strategy)
  1191. {
  1192. struct zstream *z = get_zstream(obj);
  1193. int level, strategy;
  1194. int err;
  1195. level = ARG_LEVEL(v_level);
  1196. strategy = ARG_STRATEGY(v_strategy);
  1197. zstream_run(z, (Bytef*)"", 0, Z_SYNC_FLUSH);
  1198. err = deflateParams(&z->stream, level, strategy);
  1199. while (err == Z_BUF_ERROR) {
  1200. rb_warning("deflateParams() returned Z_BUF_ERROR");
  1201. zstream_expand_buffer(z);
  1202. err = deflateParams(&z->stream, level, strategy);
  1203. }
  1204. if (err != Z_OK) {
  1205. raise_zlib_error(err, z->stream.msg);
  1206. }
  1207. return Qnil;
  1208. }
  1209. /*
  1210. * call-seq: set_dictionary(string)
  1211. *
  1212. * Sets the preset dictionary and returns +string+. This method is available
  1213. * just only after Zlib::Deflate.new or Zlib::ZStream#reset method was called.
  1214. * See zlib.h for details.
  1215. *
  1216. * TODO: document better!
  1217. */
  1218. static VALUE
  1219. rb_deflate_set_dictionary(VALUE obj, VALUE dic)
  1220. {
  1221. struct zstream *z = get_zstream(obj);
  1222. VALUE src = dic;
  1223. int err;
  1224. OBJ_INFECT(obj, dic);
  1225. StringValue(src);
  1226. err = deflateSetDictionary(&z->stream,
  1227. (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src));
  1228. if (err != Z_OK) {
  1229. raise_zlib_error(err, z->stream.msg);
  1230. }
  1231. return dic;
  1232. }
  1233. /* ------------------------------------------------------------------------- */
  1234. /*
  1235. * Document-class: Zlib::Inflate
  1236. *
  1237. * Zlib:Inflate is the class for decompressing compressed data. Unlike
  1238. * Zlib::Deflate, an instance of this class is not able to duplicate (clone,
  1239. * dup) itself.
  1240. */
  1241. static VALUE
  1242. rb_inflate_s_allocate(VALUE klass)
  1243. {
  1244. return zstream_inflate_new(klass);
  1245. }
  1246. /*
  1247. * call-seq: Zlib::Inflate.new(window_bits)
  1248. *
  1249. * Creates a new inflate stream for decompression. See zlib.h for details
  1250. * of the argument. If +window_bits+ is +nil+, the default value is used.
  1251. *
  1252. * TODO: document better!
  1253. */
  1254. static VALUE
  1255. rb_inflate_initialize(int argc, VALUE *argv, VALUE obj)
  1256. {
  1257. struct zstream *z;
  1258. VALUE wbits;
  1259. int err;
  1260. rb_scan_args(argc, argv, "01", &wbits);
  1261. Data_Get_Struct(obj, struct zstream, z);
  1262. err = inflateInit2(&z->stream, ARG_WBITS(wbits));
  1263. if (err != Z_OK) {
  1264. raise_zlib_error(err, z->stream.msg);
  1265. }
  1266. ZSTREAM_READY(z);
  1267. return obj;
  1268. }
  1269. static VALUE
  1270. inflate_run(VALUE args)
  1271. {
  1272. struct zstream *z = (struct zstream*)((VALUE*)args)[0];
  1273. VALUE src = ((VALUE*)args)[1];
  1274. zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
  1275. zstream_run(z, (Bytef*)"", 0, Z_FINISH); /* for checking errors */
  1276. return zstream_detach_buffer(z);
  1277. }
  1278. /*
  1279. * call-seq: Zlib::Inflate.inflate(string)
  1280. *
  1281. * Decompresses +string+. Raises a Zlib::NeedDict exception if a preset
  1282. * dictionary is needed for decompression.
  1283. *
  1284. * This method is almost equivalent to the following code:
  1285. *
  1286. * def inflate(string)
  1287. * zstream = Zlib::Inflate.new
  1288. * buf = zstream.inflate(string)
  1289. * zstream.finish
  1290. * zstream.close
  1291. * buf
  1292. * end
  1293. *
  1294. */
  1295. static VALUE
  1296. rb_inflate_s_inflate(VALUE obj, VALUE src)
  1297. {
  1298. struct zstream z;
  1299. VALUE dst, args[2];
  1300. int err;
  1301. StringValue(src);
  1302. zstream_init_inflate(&z);
  1303. err = inflateInit(&z.stream);
  1304. if (err != Z_OK) {
  1305. raise_zlib_error(err, z.stream.msg);
  1306. }
  1307. ZSTREAM_READY(&z);
  1308. args[0] = (VALUE)&z;
  1309. args[1] = src;
  1310. dst = rb_ensure(inflate_run, (VALUE)args, zstream_end, (VALUE)&z);
  1311. OBJ_INFECT(dst, src);
  1312. return dst;
  1313. }
  1314. static void
  1315. do_inflate(struct zstream *z, VALUE src)
  1316. {
  1317. if (NIL_P(src)) {
  1318. zstream_run(z, (Bytef*)"", 0, Z_FINISH);
  1319. return;
  1320. }
  1321. StringValue(src);
  1322. if (RSTRING_LEN(src) > 0) { /* prevent Z_BUF_ERROR */
  1323. zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
  1324. }
  1325. }
  1326. /*
  1327. * call-seq: inflate(string)
  1328. *
  1329. * Inputs +string+ into the inflate stream and returns the output from the
  1330. * stream. Calling this method, both the input and the output buffer of the
  1331. * stream are flushed. If string is +nil+, this method finishes the stream,
  1332. * just like Zlib::ZStream#finish.
  1333. *
  1334. * Raises a Zlib::NeedDict exception if a preset dictionary is needed to
  1335. * decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
  1336. * call this method again with an empty string. (<i>???</i>)
  1337. *
  1338. * TODO: document better!
  1339. */
  1340. static VALUE
  1341. rb_inflate_inflate(VALUE obj, VALUE src)
  1342. {
  1343. struct zstream *z = get_zstream(obj);
  1344. VALUE dst;
  1345. OBJ_INFECT(obj, src);
  1346. if (ZSTREAM_IS_FINISHED(z)) {
  1347. if (NIL_P(src)) {
  1348. dst = zstream_detach_buffer(z);
  1349. }
  1350. else {
  1351. StringValue(src);
  1352. zstream_append_buffer2(z, src);
  1353. dst = rb_str_new(0, 0);
  1354. }
  1355. }
  1356. else {
  1357. do_inflate(z, src);
  1358. dst = zstream_detach_buffer(z);
  1359. if (ZSTREAM_IS_FINISHED(z)) {
  1360. zstream_passthrough_input(z);
  1361. }
  1362. }
  1363. OBJ_INFECT(dst, obj);
  1364. return dst;
  1365. }
  1366. /*
  1367. * call-seq: << string
  1368. *
  1369. * Inputs +string+ into the inflate stream just like Zlib::Inflate#inflate, but
  1370. * returns the Zlib::Inflate object itself. The output from the stream is
  1371. * preserved in output buffer.
  1372. */
  1373. static VALUE
  1374. rb_inflate_addstr(VALUE obj, VALUE src)
  1375. {
  1376. struct zstream *z = get_zstream(obj);
  1377. OBJ_INFECT(obj, src);
  1378. if (ZSTREAM_IS_FINISHED(z)) {
  1379. if (!NIL_P(src)) {
  1380. StringValue(src);
  1381. zstream_append_buffer2(z, src);
  1382. }
  1383. }
  1384. else {
  1385. do_inflate(z, src);
  1386. if (ZSTREAM_IS_FINISHED(z)) {
  1387. zstream_passthrough_input(z);
  1388. }
  1389. }
  1390. return obj;
  1391. }
  1392. /*
  1393. * call-seq: sync(string)
  1394. *
  1395. * Inputs +string+ into the end of input buffer and skips data until a full
  1396. * flush point can be found. If the point is found in the buffer, this method
  1397. * flushes the buffer and returns false. Otherwise it returns +true+ and the
  1398. * following data of full flush point is preserved in the buffer.
  1399. */
  1400. static VALUE
  1401. rb_inflate_sync(VALUE obj, VALUE src)
  1402. {
  1403. struct zstream *z = get_zstream(obj);
  1404. OBJ_INFECT(obj, src);
  1405. StringValue(src);
  1406. return zstream_sync(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src));
  1407. }
  1408. /*
  1409. * Quoted verbatim from original documentation:
  1410. *
  1411. * What is this?
  1412. *
  1413. * <tt>:)</tt>
  1414. */
  1415. static VALUE
  1416. rb_inflate_sync_point_p(VALUE obj)
  1417. {
  1418. struct zstream *z = get_zstream(obj);
  1419. int err;
  1420. err = inflateSyncPoint(&z->stream);
  1421. if (err == 1) {
  1422. return Qtrue;
  1423. }
  1424. if (err != Z_OK) {
  1425. raise_zlib_error(err, z->stream.msg);
  1426. }
  1427. return Qfalse;
  1428. }
  1429. /*
  1430. * Sets the preset dictionary and returns +string+. This method is available just
  1431. * only after a Zlib::NeedDict exception was raised. See zlib.h for details.
  1432. *
  1433. * TODO: document better!
  1434. */
  1435. static VALUE
  1436. rb_inflate_set_dictionary(VALUE obj, VALUE dic)
  1437. {
  1438. struct zstream *z = get_zstream(obj);
  1439. VALUE src = dic;
  1440. int err;
  1441. OBJ_INFECT(obj, dic);
  1442. StringValue(src);
  1443. err = inflateSetDictionary(&z->stream,
  1444. (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src));
  1445. if (err != Z_OK) {
  1446. raise_zlib_error(err, z->stream.msg);
  1447. }
  1448. return dic;
  1449. }
  1450. #if GZIP_SUPPORT
  1451. /* NOTE: Features for gzip files of Ruby/zlib are written from scratch
  1452. * and using undocumented feature of zlib, negative wbits.
  1453. * I don't think gzFile APIs of zlib are good for Ruby.
  1454. */
  1455. /*------- .gz file header --------*/
  1456. #define GZ_MAGIC1 0x1f
  1457. #define GZ_MAGIC2 0x8b
  1458. #define GZ_METHOD_DEFLATE 8
  1459. #define GZ_FLAG_MULTIPART 0x2
  1460. #define GZ_FLAG_EXTRA 0x4
  1461. #define GZ_FLAG_ORIG_NAME 0x8
  1462. #define GZ_FLAG_COMMENT 0x10
  1463. #define GZ_FLAG_ENCRYPT 0x20
  1464. #define GZ_FLAG_UNKNOWN_MASK 0xc0
  1465. #define GZ_EXTRAFLAG_FAST 0x4
  1466. #define GZ_EXTRAFLAG_SLOW 0x2
  1467. /* from zutil.h */
  1468. #define OS_MSDOS 0x00
  1469. #define OS_AMIGA 0x01
  1470. #define OS_VMS 0x02
  1471. #define OS_UNIX 0x03
  1472. #define OS_ATARI 0x05
  1473. #define OS_OS2 0x06
  1474. #define OS_MACOS 0x07
  1475. #define OS_TOPS20 0x0a
  1476. #define OS_WIN32 0x0b
  1477. #define OS_VMCMS 0x04
  1478. #define OS_ZSYSTEM 0x08
  1479. #define OS_CPM 0x09
  1480. #define OS_QDOS 0x0c
  1481. #define OS_RISCOS 0x0d
  1482. #define OS_UNKNOWN 0xff
  1483. #ifndef OS_CODE
  1484. #define OS_CODE OS_UNIX
  1485. #endif
  1486. static ID id_write, id_read, id_readpartial, id_flush, id_seek, id_close, id_path;
  1487. static VALUE cGzError, cNoFooter, cCRCError, cLengthError;
  1488. /*-------- gzfile internal APIs --------*/
  1489. struct gzfile {
  1490. struct zstream z;
  1491. VALUE io;
  1492. int level;
  1493. time_t mtime; /* for header */
  1494. int os_code; /* for header */
  1495. VALUE orig_name; /* for header; must be a String */
  1496. VALUE comment; /* for header; must be a String */
  1497. unsigned long crc;
  1498. int lineno;
  1499. int ungetc;
  1500. void (*end)(struct gzfile *);
  1501. rb_encoding *enc;
  1502. rb_encoding *enc2;
  1503. rb_econv_t *ec;
  1504. int ecflags;
  1505. VALUE ecopts;
  1506. char *cbuf;
  1507. VALUE path;
  1508. };
  1509. #define GZFILE_CBUF_CAPA 10
  1510. #define GZFILE_FLAG_SYNC ZSTREAM_FLAG_UNUSED
  1511. #define GZFILE_FLAG_HEADER_FINISHED (ZSTREAM_FLAG_UNUSED << 1)
  1512. #define GZFILE_FLAG_FOOTER_FINISHED (ZSTREAM_FLAG_UNUSED << 2)
  1513. #define GZFILE_IS_FINISHED(gz) \
  1514. (ZSTREAM_IS_FINISHED(&gz->z) && (gz)->z.buf_filled == 0)
  1515. #define GZFILE_READ_SIZE 2048
  1516. static void
  1517. gzfile_mark(struct gzfile *gz)
  1518. {
  1519. rb_gc_mark(gz->io);
  1520. rb_gc_mark(gz->orig_name);
  1521. rb_gc_mark(gz->comment);
  1522. zstream_mark(&gz->z);
  1523. rb_gc_mark(gz->ecopts);
  1524. rb_gc_mark(gz->path);
  1525. }
  1526. static void
  1527. gzfile_free(struct gzfile *gz)
  1528. {
  1529. struct zstream *z = &gz->z;
  1530. if (ZSTREAM_IS_READY(z)) {
  1531. if (z->func == &deflate_funcs) {
  1532. finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
  1533. }
  1534. zstream_finalize(z);
  1535. }
  1536. if (gz->cbuf) {
  1537. xfree(gz->cbuf);
  1538. }
  1539. xfree(gz);
  1540. }
  1541. static VALUE
  1542. gzfile_new(klass, funcs, endfunc)
  1543. VALUE klass;
  1544. const struct zstream_funcs *funcs;
  1545. void (*endfunc)(struct gzfile *);
  1546. {
  1547. VALUE obj;
  1548. struct gzfile *gz;
  1549. obj = Data_Make_Struct(klass, struct gzfile, gzfile_mark, gzfile_free, gz);
  1550. zstream_init(&gz->z, funcs);
  1551. gz->io = Qnil;
  1552. gz->level = 0;
  1553. gz->mtime = 0;
  1554. gz->os_code = OS_CODE;
  1555. gz->orig_name = Qnil;
  1556. gz->comment = Qnil;
  1557. gz->crc = crc32(0, Z_NULL, 0);
  1558. gz->lineno = 0;
  1559. gz->ungetc = 0;
  1560. gz->end = endfunc;
  1561. gz->enc = rb_default_external_encoding();
  1562. gz->enc2 = 0;
  1563. gz->ec = NULL;
  1564. gz->ecflags = 0;
  1565. gz->ecopts = Qnil;
  1566. gz->cbuf = 0;
  1567. gz->path = Qnil;
  1568. return obj;
  1569. }
  1570. #define gzfile_writer_new(gz) gzfile_new((gz),&deflate_funcs,gzfile_writer_end)
  1571. #define gzfile_reader_new(gz) gzfile_new((gz),&inflate_funcs,gzfile_reader_end)
  1572. static void
  1573. gzfile_reset(struct gzfile *gz)
  1574. {
  1575. zstream_reset(&gz->z);
  1576. gz->crc = crc32(0, Z_NULL, 0);
  1577. gz->lineno = 0;
  1578. gz->ungetc = 0;
  1579. if (gz->ec) {
  1580. rb_econv_close(gz->ec);
  1581. gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
  1582. gz->ecflags, gz->ecopts);
  1583. }
  1584. }
  1585. static void
  1586. gzfile_close(struct gzfile *gz, int closeflag)
  1587. {
  1588. VALUE io = gz->io;
  1589. gz->end(gz);
  1590. gz->io = Qnil;
  1591. gz->orig_name = Qnil;
  1592. gz->comment = Qnil;
  1593. if (closeflag && rb_respond_to(io, id_close)) {
  1594. rb_funcall(io, id_close, 0);
  1595. }
  1596. }
  1597. static void
  1598. gzfile_write_raw(struct gzfile *gz)
  1599. {
  1600. VALUE str;
  1601. if (gz->z.buf_filled > 0) {
  1602. str = zstream_detach_buffer(&gz->z);
  1603. OBJ_TAINT(str); /* for safe */
  1604. rb_funcall(gz->io, id_write, 1, str);
  1605. if ((gz->z.flags & GZFILE_FLAG_SYNC)
  1606. && rb_respond_to(gz->io, id_flush))
  1607. rb_funcall(gz->io, id_flush, 0);
  1608. }
  1609. }
  1610. static VALUE
  1611. gzfile_read_raw_partial(VALUE arg)
  1612. {
  1613. struct gzfile *gz = (struct gzfile*)arg;
  1614. VALUE str;
  1615. str = rb_funcall(gz->io, id_readpartial, 1, INT2FIX(GZFILE_READ_SIZE));
  1616. Check_Type(str, T_STRING);
  1617. return str;
  1618. }
  1619. static VALUE
  1620. gzfile_read_raw_rescue(VALUE arg)
  1621. {
  1622. struct gzfile *gz = (struct gzfile*)arg;
  1623. VALUE str = Qnil;
  1624. if (rb_obj_is_kind_of(rb_errinfo(), rb_eNoMethodError)) {
  1625. str = rb_funcall(gz->io, id_read, 1, INT2FIX(GZFILE_READ_SIZE));
  1626. if (!NIL_P(str)) {
  1627. Check_Type(str, T_STRING);
  1628. }
  1629. }
  1630. return str; /* return nil when EOFError */
  1631. }
  1632. static VALUE
  1633. gzfile_read_raw(struct gzfile *gz)
  1634. {
  1635. return rb_rescue2(gzfile_read_raw_partial, (VALUE)gz,
  1636. gzfile_read_raw_rescue, (VALUE)gz,
  1637. rb_eEOFError, rb_eNoMethodError, (VALUE)0);
  1638. }
  1639. static int
  1640. gzfile_read_raw_ensure(struct gzfile *gz, int size)
  1641. {
  1642. VALUE str;
  1643. while (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) {
  1644. str = gzfile_read_raw(gz);
  1645. if (NIL_P(str)) return Qfalse;
  1646. zstream_append_input2(&gz->z, str);
  1647. }
  1648. return Qtrue;
  1649. }
  1650. static char *
  1651. gzfile_read_raw_until_zero(struct gzfile *gz, long offset)
  1652. {
  1653. VALUE str;
  1654. char *p;
  1655. for (;;) {
  1656. p = memchr(RSTRING_PTR(gz->z.input) + offset, '\0',
  1657. RSTRING_LEN(gz->z.input) - offset);
  1658. if (p) break;
  1659. str = gzfile_read_raw(gz);
  1660. if (NIL_P(str)) {
  1661. rb_raise(cGzError, "unexpected end of file");
  1662. }
  1663. offset = RSTRING_LEN(gz->z.input);
  1664. zstream_append_input2(&gz->z, str);
  1665. }
  1666. return p;
  1667. }
  1668. static unsigned int
  1669. gzfile_get16(const unsigned char *src)
  1670. {
  1671. unsigned int n;
  1672. n = *(src++) & 0xff;
  1673. n |= (*(src++) & 0xff) << 8;
  1674. return n;
  1675. }
  1676. static unsigned long
  1677. gzfile_get32(const unsigned char *src)
  1678. {
  1679. unsigned long n;
  1680. n = *(src++) & 0xff;
  1681. n |= (*(src++) & 0xff) << 8;
  1682. n |= (*(src++) & 0xff) << 16;
  1683. n |= (*(src++) & 0xffU) << 24;
  1684. return n;
  1685. }
  1686. static void
  1687. gzfile_set32(unsigned long n, unsigned char *dst)
  1688. {
  1689. *(dst++) = n & 0xff;
  1690. *(dst++) = (n >> 8) & 0xff;
  1691. *(dst++) = (n >> 16) & 0xff;
  1692. *dst = (n >> 24) & 0xff;
  1693. }
  1694. static void
  1695. gzfile_make_header(struct gzfile *gz)
  1696. {
  1697. Bytef buf[10]; /* the size of gzip header */
  1698. unsigned char flags = 0, extraflags = 0;
  1699. if (!NIL_P(gz->orig_name)) {
  1700. flags |= GZ_FLAG_ORIG_NAME;
  1701. }
  1702. if (!NIL_P(gz->comment)) {
  1703. flags |= GZ_FLAG_COMMENT;
  1704. }
  1705. if (gz->mtime == 0) {
  1706. gz->mtime = time(0);
  1707. }
  1708. if (gz->level == Z_BEST_SPEED) {
  1709. extraflags |= GZ_EXTRAFLAG_FAST;
  1710. }
  1711. else if (gz->level == Z_BEST_COMPRESSION) {
  1712. extraflags |= GZ_EXTRAFLAG_SLOW;
  1713. }
  1714. buf[0] = GZ_MAGIC1;
  1715. buf[1] = GZ_MAGIC2;
  1716. buf[2] = GZ_METHOD_DEFLATE;
  1717. buf[3] = flags;
  1718. gzfile_set32((unsigned long)gz->mtime, &buf[4]);
  1719. buf[8] = extraflags;
  1720. buf[9] = gz->os_code;
  1721. zstream_append_buffer(&gz->z, buf, sizeof(buf));
  1722. if (!NIL_P(gz->orig_name)) {
  1723. zstream_append_buffer2(&gz->z, gz->orig_name);
  1724. zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
  1725. }
  1726. if (!NIL_P(gz->comment)) {
  1727. zstream_append_buffer2(&gz->z, gz->comment);
  1728. zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
  1729. }
  1730. gz->z.flags |= GZFILE_FLAG_HEADER_FINISHED;
  1731. }
  1732. static void
  1733. gzfile_make_footer(struct gzfile *gz)
  1734. {
  1735. Bytef buf[8]; /* 8 is the size of gzip footer */
  1736. gzfile_set32(gz->crc, buf);
  1737. gzfile_set32(gz->z.stream.total_in, &buf[4]);
  1738. zstream_append_buffer(&gz->z, buf, sizeof(buf));
  1739. gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
  1740. }
  1741. static void
  1742. gzfile_read_header(struct gzfile *gz)
  1743. {
  1744. const unsigned char *head;
  1745. long len;
  1746. char flags, *p;
  1747. if (!gzfile_read_raw_ensure(gz, 10)) { /* 10 is the size of gzip header */
  1748. rb_raise(cGzError, "not in gzip format");
  1749. }
  1750. head = (unsigned char*)RSTRING_PTR(gz->z.input);
  1751. if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {
  1752. rb_raise(cGzError, "not in gzip format");
  1753. }
  1754. if (head[2] != GZ_METHOD_DEFLATE) {
  1755. rb_raise(cGzError, "unsupported compression method %d", head[2]);
  1756. }
  1757. flags = head[3];
  1758. if (flags & GZ_FLAG_MULTIPART) {
  1759. rb_raise(cGzError, "multi-part gzip file is not supported");
  1760. }
  1761. else if (flags & GZ_FLAG_ENCRYPT) {
  1762. rb_raise(cGzError, "encrypted gzip file is not supported");
  1763. }
  1764. else if (flags & GZ_FLAG_UNKNOWN_MASK) {
  1765. rb_raise(cGzError, "unknown flags 0x%02x", flags);
  1766. }
  1767. if (head[8] & GZ_EXTRAFLAG_FAST) {
  1768. gz->level = Z_BEST_SPEED;
  1769. }
  1770. else if (head[8] & GZ_EXTRAFLAG_SLOW) {
  1771. gz->level = Z_BEST_COMPRESSION;
  1772. }
  1773. else {
  1774. gz->level = Z_DEFAULT_COMPRESSION;
  1775. }
  1776. gz->mtime = gzfile_get32(&head[4]);
  1777. gz->os_code = head[9];
  1778. zstream_discard_input(&gz->z, 10);
  1779. if (flags & GZ_FLAG_EXTRA) {
  1780. if (!gzfile_read_raw_ensure(gz, 2)) {
  1781. rb_raise(cGzError, "unexpected end of file");
  1782. }
  1783. len = gzfile_get16((Bytef*)RSTRING_PTR(gz->z.input));
  1784. if (!gzfile_read_raw_ensure(gz, 2 + len)) {
  1785. rb_raise(cGzError, "unexpected end of file");
  1786. }
  1787. zstream_discard_input(&gz->z, 2 + len);
  1788. }
  1789. if (flags & GZ_FLAG_ORIG_NAME) {
  1790. p = gzfile_read_raw_until_zero(gz, 0);
  1791. len = p - RSTRING_PTR(gz->z.input);
  1792. gz->orig_name = rb_str_new(RSTRING_PTR(gz->z.input), len);
  1793. OBJ_TAINT(gz->orig_name); /* for safe */
  1794. zstream_discard_input(&gz->z, len + 1);
  1795. }
  1796. if (flags & GZ_FLAG_COMMENT) {
  1797. p = gzfile_read_raw_until_zero(gz, 0);
  1798. len = p - RSTRING_PTR(gz->z.input);
  1799. gz->comment = rb_str_new(RSTRING_PTR(gz->z.input), len);
  1800. OBJ_TAINT(gz->comment); /* for safe */
  1801. zstream_discard_input(&gz->z, len + 1);
  1802. }
  1803. if (gz->z.input != Qnil && RSTRING_LEN(gz->z.input) > 0) {
  1804. zstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);
  1805. }
  1806. }
  1807. static void
  1808. gzfile_check_footer(struct gzfile *gz)
  1809. {
  1810. unsigned long crc, length;
  1811. gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
  1812. if (!gzfile_read_raw_ensure(gz, 8)) { /* 8 is the size of gzip footer */
  1813. rb_raise(cNoFooter, "footer is not found");
  1814. }
  1815. crc = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input));
  1816. length = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input) + 4);
  1817. gz->z.stream.total_in += 8; /* to rewind correctly */
  1818. zstream_discard_input(&gz->z, 8);
  1819. if (gz->crc != crc) {
  1820. rb_raise(cCRCError, "invalid compressed data -- crc error");
  1821. }
  1822. if (gz->z.stream.total_out != length) {
  1823. rb_raise(cLengthError, "invalid compressed data -- length error");
  1824. }
  1825. }
  1826. static void
  1827. gzfile_write(struct gzfile *gz, Bytef *str, uInt len)
  1828. {
  1829. if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
  1830. gzfile_make_header(gz);
  1831. }
  1832. if (len > 0 || (gz->z.flags & GZFILE_FLAG_SYNC)) {
  1833. gz->crc = crc32(gz->crc, str, len);
  1834. zstream_run(&gz->z, str, len, (gz->z.flags & GZFILE_FLAG_SYNC)
  1835. ? Z_SYNC_FLUSH : Z_NO_FLUSH);
  1836. }
  1837. gzfile_write_raw(gz);
  1838. }
  1839. static long
  1840. gzfile_read_more(struct gzfile *gz)
  1841. {
  1842. volatile VALUE str;
  1843. while (!ZSTREAM_IS_FINISHED(&gz->z)) {
  1844. str = gzfile_read_raw(gz);
  1845. if (NIL_P(str)) {
  1846. if (!ZSTREAM_IS_FINISHED(&gz->z)) {
  1847. rb_raise(cGzError, "unexpected end of file");
  1848. }
  1849. break;
  1850. }
  1851. if (RSTRING_LEN(str) > 0) { /* prevent Z_BUF_ERROR */
  1852. zstream_run(&gz->z, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str),
  1853. Z_SYNC_FLUSH);
  1854. }
  1855. if (gz->z.buf_filled > 0) break;
  1856. }
  1857. return gz->z.buf_filled;
  1858. }
  1859. static void
  1860. gzfile_calc_crc(struct gzfile *gz, VALUE str)
  1861. {
  1862. if (RSTRING_LEN(str) <= gz->ungetc) {
  1863. gz->ungetc -= RSTRING_LEN(str);
  1864. }
  1865. else {
  1866. gz->crc = crc32(gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
  1867. RSTRING_LEN(str) - gz->ungetc);
  1868. gz->ungetc = 0;
  1869. }
  1870. }
  1871. static VALUE
  1872. gzfile_newstr(struct gzfile *gz, VALUE str)
  1873. {
  1874. if (!gz->enc2) {
  1875. rb_enc_associate(str, gz->enc);
  1876. OBJ_TAINT(str); /* for safe */
  1877. return str;
  1878. }
  1879. if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
  1880. str = rb_econv_str_convert(gz->ec, str, ECONV_PARTIAL_INPUT);
  1881. rb_enc_associate(str, gz->enc);
  1882. OBJ_TAINT(str);
  1883. return str;
  1884. }
  1885. return rb_str_conv_enc_opts(str, gz->enc2, gz->enc,
  1886. gz->ecflags, gz->ecopts);
  1887. }
  1888. static VALUE
  1889. gzfile_read(struct gzfile *gz, int len)
  1890. {
  1891. VALUE dst;
  1892. if (len < 0)
  1893. rb_raise(rb_eArgError, "negative length %d given", len);
  1894. if (len == 0)
  1895. return rb_str_new(0, 0);
  1896. while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
  1897. gzfile_read_more(gz);
  1898. }
  1899. if (GZFILE_IS_FINISHED(gz)) {
  1900. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  1901. gzfile_check_footer(gz);
  1902. }
  1903. return Qnil;
  1904. }
  1905. dst = zstream_shift_buffer(&gz->z, len);
  1906. gzfile_calc_crc(gz, dst);
  1907. return dst;
  1908. }
  1909. static VALUE
  1910. gzfile_readpartial(struct gzfile *gz, int len, VALUE outbuf)
  1911. {
  1912. VALUE dst;
  1913. if (len < 0)
  1914. rb_raise(rb_eArgError, "negative length %d given", len);
  1915. if (!NIL_P(outbuf))
  1916. OBJ_TAINT(outbuf);
  1917. if (len == 0) {
  1918. if (NIL_P(outbuf))
  1919. return rb_str_new(0, 0);
  1920. else {
  1921. rb_str_resize(outbuf, 0);
  1922. return outbuf;
  1923. }
  1924. }
  1925. while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled == 0) {
  1926. gzfile_read_more(gz);
  1927. }
  1928. if (GZFILE_IS_FINISHED(gz)) {
  1929. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  1930. gzfile_check_footer(gz);
  1931. }
  1932. if (!NIL_P(outbuf))
  1933. rb_str_resize(outbuf, 0);
  1934. rb_raise(rb_eEOFError, "end of file reached");
  1935. }
  1936. dst = zstream_shift_buffer(&gz->z, len);
  1937. gzfile_calc_crc(gz, dst);
  1938. if (!NIL_P(outbuf)) {
  1939. rb_str_resize(outbuf, RSTRING_LEN(dst));
  1940. memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
  1941. dst = outbuf;
  1942. }
  1943. OBJ_TAINT(dst); /* for safe */
  1944. return dst;
  1945. }
  1946. static VALUE
  1947. gzfile_read_all(struct gzfile *gz)
  1948. {
  1949. VALUE dst;
  1950. while (!ZSTREAM_IS_FINISHED(&gz->z)) {
  1951. gzfile_read_more(gz);
  1952. }
  1953. if (GZFILE_IS_FINISHED(gz)) {
  1954. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  1955. gzfile_check_footer(gz);
  1956. }
  1957. return rb_str_new(0, 0);
  1958. }
  1959. dst = zstream_detach_buffer(&gz->z);
  1960. gzfile_calc_crc(gz, dst);
  1961. OBJ_TAINT(dst);
  1962. return gzfile_newstr(gz, dst);
  1963. }
  1964. static VALUE
  1965. gzfile_getc(struct gzfile *gz)
  1966. {
  1967. VALUE buf, dst = 0;
  1968. int len;
  1969. len = rb_enc_mbmaxlen(gz->enc);
  1970. while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
  1971. gzfile_read_more(gz);
  1972. }
  1973. if (GZFILE_IS_FINISHED(gz)) {
  1974. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  1975. gzfile_check_footer(gz);
  1976. }
  1977. return Qnil;
  1978. }
  1979. if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
  1980. const unsigned char *ss, *sp, *se;
  1981. unsigned char *ds, *dp, *de;
  1982. rb_econv_result_t res;
  1983. if (!gz->cbuf) {
  1984. gz->cbuf = ALLOC_N(char, GZFILE_CBUF_CAPA);
  1985. }
  1986. ss = sp = (const unsigned char*)RSTRING_PTR(gz->z.buf);
  1987. se = sp + gz->z.buf_filled;
  1988. ds = dp = (unsigned char *)gz->cbuf;
  1989. de = (unsigned char *)ds + GZFILE_CBUF_CAPA;
  1990. res = rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
  1991. rb_econv_check_error(gz->ec);
  1992. dst = zstream_shift_buffer(&gz->z, sp - ss);
  1993. gzfile_calc_crc(gz, dst);
  1994. dst = rb_str_new(gz->cbuf, dp - ds);
  1995. rb_enc_associate(dst, gz->enc);
  1996. OBJ_TAINT(dst);
  1997. return dst;
  1998. }
  1999. else {
  2000. buf = gz->z.buf;
  2001. len = rb_enc_mbclen(RSTRING_PTR(buf), RSTRING_END(buf), gz->enc);
  2002. dst = gzfile_read(gz, len);
  2003. return gzfile_newstr(gz, dst);
  2004. }
  2005. }
  2006. static void
  2007. gzfile_ungets(struct gzfile *gz, const Bytef *b, int len)
  2008. {
  2009. zstream_buffer_ungets(&gz->z, b, len);
  2010. gz->ungetc+=len;
  2011. }
  2012. static void
  2013. gzfile_ungetbyte(struct gzfile *gz, int c)
  2014. {
  2015. zstream_buffer_ungetbyte(&gz->z, c);
  2016. gz->ungetc++;
  2017. }
  2018. static VALUE
  2019. gzfile_writer_end_run(VALUE arg)
  2020. {
  2021. struct gzfile *gz = (struct gzfile *)arg;
  2022. if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
  2023. gzfile_make_header(gz);
  2024. }
  2025. zstream_run(&gz->z, (Bytef*)"", 0, Z_FINISH);
  2026. gzfile_make_footer(gz);
  2027. gzfile_write_raw(gz);
  2028. return Qnil;
  2029. }
  2030. static void
  2031. gzfile_writer_end(struct gzfile *gz)
  2032. {
  2033. if (ZSTREAM_IS_CLOSING(&gz->z)) return;
  2034. gz->z.flags |= ZSTREAM_FLAG_CLOSING;
  2035. rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
  2036. }
  2037. static VALUE
  2038. gzfile_reader_end_run(VALUE arg)
  2039. {
  2040. struct gzfile *gz = (struct gzfile *)arg;
  2041. if (GZFILE_IS_FINISHED(gz)
  2042. && !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  2043. gzfile_check_footer(gz);
  2044. }
  2045. return Qnil;
  2046. }
  2047. static void
  2048. gzfile_reader_end(struct gzfile *gz)
  2049. {
  2050. if (ZSTREAM_IS_CLOSING(&gz->z)) return;
  2051. gz->z.flags |= ZSTREAM_FLAG_CLOSING;
  2052. rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
  2053. }
  2054. static void
  2055. gzfile_reader_rewind(struct gzfile *gz)
  2056. {
  2057. long n;
  2058. n = gz->z.stream.total_in;
  2059. if (!NIL_P(gz->z.input)) {
  2060. n += RSTRING_LEN(gz->z.input);
  2061. }
  2062. rb_funcall(gz->io, id_seek, 2, rb_int2inum(-n), INT2FIX(1));
  2063. gzfile_reset(gz);
  2064. }
  2065. static VALUE
  2066. gzfile_reader_get_unused(struct gzfile *gz)
  2067. {
  2068. VALUE str;
  2069. if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;
  2070. if (!GZFILE_IS_FINISHED(gz)) return Qnil;
  2071. if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
  2072. gzfile_check_footer(gz);
  2073. }
  2074. if (NIL_P(gz->z.input)) return Qnil;
  2075. str = rb_str_dup(gz->z.input);
  2076. OBJ_TAINT(str); /* for safe */
  2077. return str;
  2078. }
  2079. static struct gzfile *
  2080. get_gzfile(VALUE obj)
  2081. {
  2082. struct gzfile *gz;
  2083. Data_Get_Struct(obj, struct gzfile, gz);
  2084. if (!ZSTREAM_IS_READY(&gz->z)) {
  2085. rb_raise(cGzError, "closed gzip stream");
  2086. }
  2087. return gz;
  2088. }
  2089. /* ------------------------------------------------------------------------- */
  2090. /*
  2091. * Document-class: Zlib::GzipFile
  2092. *
  2093. * Zlib::GzipFile is an abstract class for handling a gzip formatted
  2094. * compressed file. The operations are defined in the subclasses,
  2095. * Zlib::GzipReader for reading, and Zlib::GzipWriter for writing.
  2096. *
  2097. * GzipReader should be used by associating an IO, or IO-like, object.
  2098. */
  2099. static VALUE
  2100. gzfile_ensure_close(VALUE obj)
  2101. {
  2102. struct gzfile *gz;
  2103. Data_Get_Struct(obj, struct gzfile, gz);
  2104. if (ZSTREAM_IS_READY(&gz->z)) {
  2105. gzfile_close(gz, 1);
  2106. }
  2107. return Qnil;
  2108. }
  2109. /*
  2110. * call-seq: Zlib::GzipFile.wrap(io) { |gz| ... }
  2111. *
  2112. * Creates a GzipFile object associated with +io+, and
  2113. * executes the block with the newly created GzipFile object,
  2114. * just like File.open. The GzipFile object will be closed
  2115. * automatically after executing the block. If you want to keep
  2116. * the associated IO object opening, you may call
  2117. * +Zlib::GzipFile#finish+ method in the block.
  2118. */
  2119. static VALUE
  2120. rb_gzfile_s_wrap(int argc, VALUE *argv, VALUE klass)
  2121. {
  2122. VALUE obj = rb_class_new_instance(argc, argv, klass);
  2123. if (rb_block_given_p()) {
  2124. return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);
  2125. }
  2126. else {
  2127. return obj;
  2128. }
  2129. }
  2130. /*
  2131. * See Zlib::GzipReader#open and Zlib::GzipWriter#open.
  2132. */
  2133. static VALUE
  2134. gzfile_s_open(int argc, VALUE *argv, VALUE klass, const char *mode)
  2135. {
  2136. VALUE io, filename;
  2137. if (argc < 1) {
  2138. rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
  2139. }
  2140. filename = argv[0];
  2141. io = rb_file_open_str(filename, mode);
  2142. argv[0] = io;
  2143. return rb_gzfile_s_wrap(argc, argv, klass);
  2144. }
  2145. /*
  2146. * Same as IO.
  2147. */
  2148. static VALUE
  2149. rb_gzfile_to_io(VALUE obj)
  2150. {
  2151. return get_gzfile(obj)->io;
  2152. }
  2153. /*
  2154. * Returns CRC value of the uncompressed data.
  2155. */
  2156. static VALUE
  2157. rb_gzfile_crc(VALUE obj)
  2158. {
  2159. return rb_uint2inum(get_gzfile(obj)->crc);
  2160. }
  2161. /*
  2162. * Returns last modification time recorded in the gzip file header.
  2163. */
  2164. static VALUE
  2165. rb_gzfile_mtime(VALUE obj)
  2166. {
  2167. return rb_time_new(get_gzfile(obj)->mtime, (time_t)0);
  2168. }
  2169. /*
  2170. * Returns compression level.
  2171. */
  2172. static VALUE
  2173. rb_gzfile_level(VALUE obj)
  2174. {
  2175. return INT2FIX(get_gzfile(obj)->level);
  2176. }
  2177. /*
  2178. * Returns OS code number recorded in the gzip file header.
  2179. */
  2180. static VALUE
  2181. rb_gzfile_os_code(VALUE obj)
  2182. {
  2183. return INT2FIX(get_gzfile(obj)->os_code);
  2184. }
  2185. /*
  2186. * Returns original filename recorded in the gzip file header, or +nil+ if
  2187. * original filename is not present.
  2188. */
  2189. static VALUE
  2190. rb_gzfile_orig_name(VALUE obj)
  2191. {
  2192. VALUE str = get_gzfile(obj)->orig_name;
  2193. if (!NIL_P(str)) {
  2194. str = rb_str_dup(str);
  2195. }
  2196. OBJ_TAINT(str); /* for safe */
  2197. return str;
  2198. }
  2199. /*
  2200. * Returns comments recorded in the gzip file header, or nil if the comments
  2201. * is not present.
  2202. */
  2203. static VALUE
  2204. rb_gzfile_comment(VALUE obj)
  2205. {
  2206. VALUE str = get_gzfile(obj)->comment;
  2207. if (!NIL_P(str)) {
  2208. str = rb_str_dup(str);
  2209. }
  2210. OBJ_TAINT(str); /* for safe */
  2211. return str;
  2212. }
  2213. /*
  2214. * ???
  2215. */
  2216. static VALUE
  2217. rb_gzfile_lineno(VALUE obj)
  2218. {
  2219. return INT2NUM(get_gzfile(obj)->lineno);
  2220. }
  2221. /*
  2222. * ???
  2223. */
  2224. static VALUE
  2225. rb_gzfile_set_lineno(VALUE obj, VALUE lineno)
  2226. {
  2227. struct gzfile *gz = get_gzfile(obj);
  2228. gz->lineno = NUM2INT(lineno);
  2229. return lineno;
  2230. }
  2231. /*
  2232. * ???
  2233. */
  2234. static VALUE
  2235. rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
  2236. {
  2237. struct gzfile *gz = get_gzfile(obj);
  2238. VALUE val;
  2239. if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
  2240. rb_raise(cGzError, "header is already written");
  2241. }
  2242. if (FIXNUM_P(mtime)) {
  2243. gz->mtime = FIX2INT(mtime);
  2244. }
  2245. else {
  2246. val = rb_Integer(mtime);
  2247. gz->mtime = FIXNUM_P(val) ? FIX2INT(val) : rb_big2ulong(val);
  2248. }
  2249. return mtime;
  2250. }
  2251. /*
  2252. * ???
  2253. */
  2254. static VALUE
  2255. rb_gzfile_set_orig_name(VALUE obj, VALUE str)
  2256. {
  2257. struct gzfile *gz = get_gzfile(obj);
  2258. VALUE s;
  2259. char *p;
  2260. if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
  2261. rb_raise(cGzError, "header is already written");
  2262. }
  2263. s = rb_str_dup(rb_str_to_str(str));
  2264. p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
  2265. if (p) {
  2266. rb_str_resize(s, p - RSTRING_PTR(s));
  2267. }
  2268. gz->orig_name = s;
  2269. return str;
  2270. }
  2271. /*
  2272. * ???
  2273. */
  2274. static VALUE
  2275. rb_gzfile_set_comment(VALUE obj, VALUE str)
  2276. {
  2277. struct gzfile *gz = get_gzfile(obj);
  2278. VALUE s;
  2279. char *p;
  2280. if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
  2281. rb_raise(cGzError, "header is already written");
  2282. }
  2283. s = rb_str_dup(rb_str_to_str(str));
  2284. p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
  2285. if (p) {
  2286. rb_str_resize(s, p - RSTRING_PTR(s));
  2287. }
  2288. gz->comment = s;
  2289. return str;
  2290. }
  2291. /*
  2292. * Closes the GzipFile object. This method calls close method of the
  2293. * associated IO object. Returns the associated IO object.
  2294. */
  2295. static VALUE
  2296. rb_gzfile_close(VALUE obj)
  2297. {
  2298. struct gzfile *gz = get_gzfile(obj);
  2299. VALUE io;
  2300. io = gz->io;
  2301. gzfile_close(gz, 1);
  2302. return io;
  2303. }
  2304. /*
  2305. * Closes the GzipFile object. Unlike Zlib::GzipFile#close, this method never
  2306. * calls the close method of the associated IO object. Returns the associated IO
  2307. * object.
  2308. */
  2309. static VALUE
  2310. rb_gzfile_finish(VALUE obj)
  2311. {
  2312. struct gzfile *gz = get_gzfile(obj);
  2313. VALUE io;
  2314. io = gz->io;
  2315. gzfile_close(gz, 0);
  2316. return io;
  2317. }
  2318. /*
  2319. * Same as IO.
  2320. */
  2321. static VALUE
  2322. rb_gzfile_closed_p(VALUE obj)
  2323. {
  2324. struct gzfile *gz;
  2325. Data_Get_Struct(obj, struct gzfile, gz);
  2326. return NIL_P(gz->io) ? Qtrue : Qfalse;
  2327. }
  2328. /*
  2329. * ???
  2330. */
  2331. static VALUE
  2332. rb_gzfile_eof_p(VALUE obj)
  2333. {
  2334. struct gzfile *gz = get_gzfile(obj);
  2335. return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
  2336. }
  2337. /*
  2338. * Same as IO.
  2339. */
  2340. static VALUE
  2341. rb_gzfile_sync(VALUE obj)
  2342. {
  2343. return (get_gzfile(obj)->z.flags & GZFILE_FLAG_SYNC) ? Qtrue : Qfalse;
  2344. }
  2345. /*
  2346. * call-seq: sync = flag
  2347. *
  2348. * Same as IO. If flag is +true+, the associated IO object must respond to the
  2349. * +flush+ method. While +sync+ mode is +true+, the compression ratio
  2350. * decreases sharply.
  2351. */
  2352. static VALUE
  2353. rb_gzfile_set_sync(VALUE obj, VALUE mode)
  2354. {
  2355. struct gzfile *gz = get_gzfile(obj);
  2356. if (RTEST(mode)) {
  2357. gz->z.flags |= GZFILE_FLAG_SYNC;
  2358. }
  2359. else {
  2360. gz->z.flags &= ~GZFILE_FLAG_SYNC;
  2361. }
  2362. return mode;
  2363. }
  2364. /*
  2365. * ???
  2366. */
  2367. static VALUE
  2368. rb_gzfile_total_in(VALUE obj)
  2369. {
  2370. return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
  2371. }
  2372. /*
  2373. * ???
  2374. */
  2375. static VALUE
  2376. rb_gzfile_total_out(VALUE obj)
  2377. {
  2378. struct gzfile *gz = get_gzfile(obj);
  2379. return rb_uint2inum(gz->z.stream.total_out - gz->z.buf_filled);
  2380. }
  2381. /*
  2382. * Document-method: path
  2383. *
  2384. * call-seq: path
  2385. *
  2386. * Returns the path string of the associated IO-like object. This
  2387. * method is only defined when the IO-like object responds to #path().
  2388. */
  2389. static VALUE
  2390. rb_gzfile_path(VALUE obj)
  2391. {
  2392. struct gzfile *gz;
  2393. Data_Get_Struct(obj, struct gzfile, gz);
  2394. return gz->path;
  2395. }
  2396. static void
  2397. rb_gzfile_ecopts(struct gzfile *gz, VALUE opts)
  2398. {
  2399. if (!NIL_P(opts)) {
  2400. rb_io_extract_encoding_option(opts, &gz->enc, &gz->enc2);
  2401. }
  2402. if (gz->enc2) {
  2403. gz->ecflags = rb_econv_prepare_opts(opts, &opts);
  2404. gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
  2405. gz->ecflags, opts);
  2406. gz->ecopts = opts;
  2407. }
  2408. }
  2409. /* ------------------------------------------------------------------------- */
  2410. /*
  2411. * Document-class: Zlib::GzipWriter
  2412. *
  2413. * Zlib::GzipWriter is a class for writing gzipped files. GzipWriter should
  2414. * be used with an instance of IO, or IO-like, object.
  2415. *
  2416. * For example:
  2417. *
  2418. * Zlib::GzipWriter.open('hoge.gz') do |gz|
  2419. * gz.write 'jugemu jugemu gokou no surikire...'
  2420. * end
  2421. *
  2422. * File.open('hoge.gz', 'w') do |f|
  2423. * gz = Zlib::GzipWriter.new(f)
  2424. * gz.write 'jugemu jugemu gokou no surikire...'
  2425. * gz.close
  2426. * end
  2427. *
  2428. * # TODO: test these. Are they equivalent? Can GzipWriter.new take a
  2429. * # block?
  2430. *
  2431. * NOTE: Due to the limitation of Ruby's finalizer, you must explicitly close
  2432. * GzipWriter objects by Zlib::GzipWriter#close etc. Otherwise, GzipWriter
  2433. * will be not able to write the gzip footer and will generate a broken gzip
  2434. * file.
  2435. */
  2436. static VALUE
  2437. rb_gzwriter_s_allocate(VALUE klass)
  2438. {
  2439. return gzfile_writer_new(klass);
  2440. }
  2441. /*
  2442. * call-seq: Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... }
  2443. *
  2444. * Opens a file specified by +filename+ for writing gzip compressed data, and
  2445. * returns a GzipWriter object associated with that file. Further details of
  2446. * this method are found in Zlib::GzipWriter.new and Zlib::GzipFile.wrap.
  2447. */
  2448. static VALUE
  2449. rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
  2450. {
  2451. return gzfile_s_open(argc, argv, klass, "wb");
  2452. }
  2453. /*
  2454. * call-seq: Zlib::GzipWriter.new(io, level, strategy)
  2455. *
  2456. * Creates a GzipWriter object associated with +io+. +level+ and +strategy+
  2457. * should be the same as the arguments of Zlib::Deflate.new. The GzipWriter
  2458. * object writes gzipped data to +io+. At least, +io+ must respond to the
  2459. * +write+ method that behaves same as write method in IO class.
  2460. */
  2461. static VALUE
  2462. rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
  2463. {
  2464. struct gzfile *gz;
  2465. VALUE io, level, strategy, opt = Qnil;
  2466. int err;
  2467. if (argc > 1) {
  2468. opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
  2469. if (!NIL_P(opt)) argc--;
  2470. }
  2471. rb_scan_args(argc, argv, "12", &io, &level, &strategy);
  2472. Data_Get_Struct(obj, struct gzfile, gz);
  2473. /* this is undocumented feature of zlib */
  2474. gz->level = ARG_LEVEL(level);
  2475. err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
  2476. -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
  2477. if (err != Z_OK) {
  2478. raise_zlib_error(err, gz->z.stream.msg);
  2479. }
  2480. gz->io = io;
  2481. ZSTREAM_READY(&gz->z);
  2482. rb_gzfile_ecopts(gz, opt);
  2483. if (rb_respond_to(io, id_path)) {
  2484. gz->path = rb_funcall(gz->io, id_path, 0);
  2485. rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
  2486. }
  2487. return obj;
  2488. }
  2489. /*
  2490. * call-seq: flush(flush=nil)
  2491. *
  2492. * Flushes all the internal buffers of the GzipWriter object. The meaning of
  2493. * +flush+ is same as in Zlib::Deflate#deflate. <tt>Zlib::SYNC_FLUSH</tt> is used if
  2494. * +flush+ is omitted. It is no use giving flush <tt>Zlib::NO_FLUSH</tt>.
  2495. */
  2496. static VALUE
  2497. rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj)
  2498. {
  2499. struct gzfile *gz = get_gzfile(obj);
  2500. VALUE v_flush;
  2501. int flush;
  2502. rb_scan_args(argc, argv, "01", &v_flush);
  2503. flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
  2504. if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
  2505. zstream_run(&gz->z, (Bytef*)"", 0, flush);
  2506. }
  2507. gzfile_write_raw(gz);
  2508. if (rb_respond_to(gz->io, id_flush)) {
  2509. rb_funcall(gz->io, id_flush, 0);
  2510. }
  2511. return obj;
  2512. }
  2513. /*
  2514. * Same as IO.
  2515. */
  2516. static VALUE
  2517. rb_gzwriter_write(VALUE obj, VALUE str)
  2518. {
  2519. struct gzfile *gz = get_gzfile(obj);
  2520. if (TYPE(str) != T_STRING)
  2521. str = rb_obj_as_string(str);
  2522. if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
  2523. str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
  2524. }
  2525. gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
  2526. return INT2FIX(RSTRING_LEN(str));
  2527. }
  2528. /*
  2529. * Same as IO.
  2530. */
  2531. static VALUE
  2532. rb_gzwriter_putc(VALUE obj, VALUE ch)
  2533. {
  2534. struct gzfile *gz = get_gzfile(obj);
  2535. char c = NUM2CHR(ch);
  2536. gzfile_write(gz, (Bytef*)&c, 1);
  2537. return ch;
  2538. }
  2539. /*
  2540. * Document-method: <<
  2541. * Same as IO.
  2542. */
  2543. #define rb_gzwriter_addstr rb_io_addstr
  2544. /*
  2545. * Document-method: printf
  2546. * Same as IO.
  2547. */
  2548. #define rb_gzwriter_printf rb_io_printf
  2549. /*
  2550. * Document-method: print
  2551. * Same as IO.
  2552. */
  2553. #define rb_gzwriter_print rb_io_print
  2554. /*
  2555. * Document-method: puts
  2556. * Same as IO.
  2557. */
  2558. #define rb_gzwriter_puts rb_io_puts
  2559. /* ------------------------------------------------------------------------- */
  2560. /*
  2561. * Document-class: Zlib::GzipReader
  2562. *
  2563. * Zlib::GzipReader is the class for reading a gzipped file. GzipReader should
  2564. * be used an IO, or -IO-lie, object.
  2565. *
  2566. * Zlib::GzipReader.open('hoge.gz') {|gz|
  2567. * print gz.read
  2568. * }
  2569. *
  2570. * File.open('hoge.gz') do |f|
  2571. * gz = Zlib::GzipReader.new(f)
  2572. * print gz.read
  2573. * gz.close
  2574. * end
  2575. *
  2576. * # TODO: test these. Are they equivalent? Can GzipReader.new take a
  2577. * # block?
  2578. *
  2579. * == Method Catalogue
  2580. *
  2581. * The following methods in Zlib::GzipReader are just like their counterparts
  2582. * in IO, but they raise Zlib::Error or Zlib::GzipFile::Error exception if an
  2583. * error was found in the gzip file.
  2584. * - #each
  2585. * - #each_line
  2586. * - #each_byte
  2587. * - #gets
  2588. * - #getc
  2589. * - #lineno
  2590. * - #lineno=
  2591. * - #read
  2592. * - #readchar
  2593. * - #readline
  2594. * - #readlines
  2595. * - #ungetc
  2596. *
  2597. * Be careful of the footer of the gzip file. A gzip file has the checksum of
  2598. * pre-compressed data in its footer. GzipReader checks all uncompressed data
  2599. * against that checksum at the following cases, and if it fails, raises
  2600. * <tt>Zlib::GzipFile::NoFooter</tt>, <tt>Zlib::GzipFile::CRCError</tt>, or
  2601. * <tt>Zlib::GzipFile::LengthError</tt> exception.
  2602. *
  2603. * - When an reading request is received beyond the end of file (the end of
  2604. * compressed data). That is, when Zlib::GzipReader#read,
  2605. * Zlib::GzipReader#gets, or some other methods for reading returns nil.
  2606. * - When Zlib::GzipFile#close method is called after the object reaches the
  2607. * end of file.
  2608. * - When Zlib::GzipReader#unused method is called after the object reaches
  2609. * the end of file.
  2610. *
  2611. * The rest of the methods are adequately described in their own
  2612. * documentation.
  2613. */
  2614. static VALUE
  2615. rb_gzreader_s_allocate(VALUE klass)
  2616. {
  2617. return gzfile_reader_new(klass);
  2618. }
  2619. /*
  2620. * call-seq: Zlib::GzipReader.open(filename) {|gz| ... }
  2621. *
  2622. * Opens a file specified by +filename+ as a gzipped file, and returns a
  2623. * GzipReader object associated with that file. Further details of this method
  2624. * are in Zlib::GzipReader.new and ZLib::GzipFile.wrap.
  2625. */
  2626. static VALUE
  2627. rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
  2628. {
  2629. return gzfile_s_open(argc, argv, klass, "rb");
  2630. }
  2631. /*
  2632. * call-seq: Zlib::GzipReader.new(io)
  2633. *
  2634. * Creates a GzipReader object associated with +io+. The GzipReader object reads
  2635. * gzipped data from +io+, and parses/decompresses them. At least, +io+ must have
  2636. * a +read+ method that behaves same as the +read+ method in IO class.
  2637. *
  2638. * If the gzip file header is incorrect, raises an Zlib::GzipFile::Error
  2639. * exception.
  2640. */
  2641. static VALUE
  2642. rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
  2643. {
  2644. VALUE io, opt = Qnil;
  2645. struct gzfile *gz;
  2646. int err;
  2647. Data_Get_Struct(obj, struct gzfile, gz);
  2648. if (argc > 1) {
  2649. opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
  2650. if (!NIL_P(opt)) argc--;
  2651. }
  2652. rb_scan_args(argc, argv, "1", &io);
  2653. /* this is undocumented feature of zlib */
  2654. err = inflateInit2(&gz->z.stream, -MAX_WBITS);
  2655. if (err != Z_OK) {
  2656. raise_zlib_error(err, gz->z.stream.msg);
  2657. }
  2658. gz->io = io;
  2659. ZSTREAM_READY(&gz->z);
  2660. gzfile_read_header(gz);
  2661. rb_gzfile_ecopts(gz, opt);
  2662. if (rb_respond_to(io, id_path)) {
  2663. gz->path = rb_funcall(gz->io, id_path, 0);
  2664. rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
  2665. }
  2666. return obj;
  2667. }
  2668. /*
  2669. * Resets the position of the file pointer to the point created the GzipReader
  2670. * object. The associated IO object needs to respond to the +seek+ method.
  2671. */
  2672. static VALUE
  2673. rb_gzreader_rewind(VALUE obj)
  2674. {
  2675. struct gzfile *gz = get_gzfile(obj);
  2676. gzfile_reader_rewind(gz);
  2677. return INT2FIX(0);
  2678. }
  2679. /*
  2680. * Returns the rest of the data which had read for parsing gzip format, or
  2681. * +nil+ if the whole gzip file is not parsed yet.
  2682. */
  2683. static VALUE
  2684. rb_gzreader_unused(VALUE obj)
  2685. {
  2686. struct gzfile *gz;
  2687. Data_Get_Struct(obj, struct gzfile, gz);
  2688. return gzfile_reader_get_unused(gz);
  2689. }
  2690. /*
  2691. * See Zlib::GzipReader documentation for a description.
  2692. */
  2693. static VALUE
  2694. rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
  2695. {
  2696. struct gzfile *gz = get_gzfile(obj);
  2697. VALUE vlen;
  2698. int len;
  2699. rb_scan_args(argc, argv, "01", &vlen);
  2700. if (NIL_P(vlen)) {
  2701. return gzfile_read_all(gz);
  2702. }
  2703. len = NUM2INT(vlen);
  2704. if (len < 0) {
  2705. rb_raise(rb_eArgError, "negative length %d given", len);
  2706. }
  2707. return gzfile_read(gz, len);
  2708. }
  2709. /*
  2710. * call-seq:
  2711. * gzipreader.readpartial(maxlen [, outbuf]) => string, outbuf
  2712. *
  2713. * Reads at most <i>maxlen</i> bytes from the gziped stream but
  2714. * it blocks only if <em>gzipreader</em> has no data immediately available.
  2715. * If the optional <i>outbuf</i> argument is present,
  2716. * it must reference a String, which will receive the data.
  2717. * It raises <code>EOFError</code> on end of file.
  2718. */
  2719. static VALUE
  2720. rb_gzreader_readpartial(int argc, VALUE *argv, VALUE obj)
  2721. {
  2722. struct gzfile *gz = get_gzfile(obj);
  2723. VALUE vlen, outbuf;
  2724. int len;
  2725. rb_scan_args(argc, argv, "11", &vlen, &outbuf);
  2726. len = NUM2INT(vlen);
  2727. if (len < 0) {
  2728. rb_raise(rb_eArgError, "negative length %d given", len);
  2729. }
  2730. if (!NIL_P(outbuf))
  2731. Check_Type(outbuf, T_STRING);
  2732. return gzfile_readpartial(gz, len, outbuf);
  2733. }
  2734. /*
  2735. * See Zlib::GzipReader documentation for a description.
  2736. */
  2737. static VALUE
  2738. rb_gzreader_getc(VALUE obj)
  2739. {
  2740. struct gzfile *gz = get_gzfile(obj);
  2741. return gzfile_getc(gz);
  2742. }
  2743. /*
  2744. * See Zlib::GzipReader documentation for a description.
  2745. */
  2746. static VALUE
  2747. rb_gzreader_readchar(VALUE obj)
  2748. {
  2749. VALUE dst;
  2750. dst = rb_gzreader_getc(obj);
  2751. if (NIL_P(dst)) {
  2752. rb_raise(rb_eEOFError, "end of file reached");
  2753. }
  2754. return dst;
  2755. }
  2756. /*
  2757. * See Zlib::GzipReader documentation for a description.
  2758. */
  2759. static VALUE
  2760. rb_gzreader_getbyte(VALUE obj)
  2761. {
  2762. struct gzfile *gz = get_gzfile(obj);
  2763. VALUE dst;
  2764. dst = gzfile_read(gz, 1);
  2765. if (!NIL_P(dst)) {
  2766. dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
  2767. }
  2768. return dst;
  2769. }
  2770. /*
  2771. * See Zlib::GzipReader documentation for a description.
  2772. */
  2773. static VALUE
  2774. rb_gzreader_readbyte(VALUE obj)
  2775. {
  2776. VALUE dst;
  2777. dst = rb_gzreader_getbyte(obj);
  2778. if (NIL_P(dst)) {
  2779. rb_raise(rb_eEOFError, "end of file reached");
  2780. }
  2781. return dst;
  2782. }
  2783. /*
  2784. * See Zlib::GzipReader documentation for a description.
  2785. */
  2786. static VALUE
  2787. rb_gzreader_each_char(VALUE obj)
  2788. {
  2789. VALUE c;
  2790. RETURN_ENUMERATOR(obj, 0, 0);
  2791. while (!NIL_P(c = rb_gzreader_getc(obj))) {
  2792. rb_yield(c);
  2793. }
  2794. return Qnil;
  2795. }
  2796. /*
  2797. * See Zlib::GzipReader documentation for a description.
  2798. */
  2799. static VALUE
  2800. rb_gzreader_each_byte(VALUE obj)
  2801. {
  2802. VALUE c;
  2803. RETURN_ENUMERATOR(obj, 0, 0);
  2804. while (!NIL_P(c = rb_gzreader_getbyte(obj))) {
  2805. rb_yield(c);
  2806. }
  2807. return Qnil;
  2808. }
  2809. /*
  2810. * See Zlib::GzipReader documentation for a description.
  2811. */
  2812. static VALUE
  2813. rb_gzreader_ungetc(VALUE obj, VALUE s)
  2814. {
  2815. struct gzfile *gz;
  2816. if (FIXNUM_P(s))
  2817. return rb_gzreader_ungetbyte(obj, s);
  2818. gz = get_gzfile(obj);
  2819. StringValue(s);
  2820. if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
  2821. s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2);
  2822. }
  2823. gzfile_ungets(gz, (const Bytef*)RSTRING_PTR(s), RSTRING_LEN(s));
  2824. return Qnil;
  2825. }
  2826. /*
  2827. * See Zlib::GzipReader documentation for a description.
  2828. */
  2829. static VALUE
  2830. rb_gzreader_ungetbyte(VALUE obj, VALUE ch)
  2831. {
  2832. struct gzfile *gz = get_gzfile(obj);
  2833. gzfile_ungetbyte(gz, NUM2CHR(ch));
  2834. return Qnil;
  2835. }
  2836. static void
  2837. gzreader_skip_linebreaks(struct gzfile *gz)
  2838. {
  2839. VALUE str;
  2840. char *p;
  2841. int n;
  2842. while (gz->z.buf_filled == 0) {
  2843. if (GZFILE_IS_FINISHED(gz)) return;
  2844. gzfile_read_more(gz);
  2845. }
  2846. n = 0;
  2847. p = RSTRING_PTR(gz->z.buf);
  2848. while (n++, *(p++) == '\n') {
  2849. if (n >= gz->z.buf_filled) {
  2850. str = zstream_detach_buffer(&gz->z);
  2851. gzfile_calc_crc(gz, str);
  2852. while (gz->z.buf_filled == 0) {
  2853. if (GZFILE_IS_FINISHED(gz)) return;
  2854. gzfile_read_more(gz);
  2855. }
  2856. n = 0;
  2857. p = RSTRING_PTR(gz->z.buf);
  2858. }
  2859. }
  2860. str = zstream_shift_buffer(&gz->z, n - 1);
  2861. gzfile_calc_crc(gz, str);
  2862. }
  2863. static void
  2864. rscheck(const char *rsptr, long rslen, VALUE rs)
  2865. {
  2866. if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen)
  2867. rb_raise(rb_eRuntimeError, "rs modified");
  2868. }
  2869. static VALUE
  2870. gzreader_gets(int argc, VALUE *argv, VALUE obj)
  2871. {
  2872. struct gzfile *gz = get_gzfile(obj);
  2873. volatile VALUE rs;
  2874. VALUE dst;
  2875. const char *rsptr;
  2876. char *p, *res;
  2877. long rslen, n;
  2878. int rspara;
  2879. if (argc == 0) {
  2880. rs = rb_rs;
  2881. }
  2882. else {
  2883. rb_scan_args(argc, argv, "1", &rs);
  2884. if (!NIL_P(rs)) {
  2885. Check_Type(rs, T_STRING);
  2886. }
  2887. }
  2888. if (NIL_P(rs)) {
  2889. dst = gzfile_read_all(gz);
  2890. if (RSTRING_LEN(dst) != 0) gz->lineno++;
  2891. else
  2892. return Qnil;
  2893. return dst;
  2894. }
  2895. if (RSTRING_LEN(rs) == 0) {
  2896. rsptr = "\n\n";
  2897. rslen = 2;
  2898. rspara = 1;
  2899. } else {
  2900. rsptr = RSTRING_PTR(rs);
  2901. rslen = RSTRING_LEN(rs);
  2902. rspara = 0;
  2903. }
  2904. if (rspara) {
  2905. gzreader_skip_linebreaks(gz);
  2906. }
  2907. while (gz->z.buf_filled < rslen) {
  2908. if (ZSTREAM_IS_FINISHED(&gz->z)) {
  2909. if (gz->z.buf_filled > 0) gz->lineno++;
  2910. return gzfile_read(gz, rslen);
  2911. }
  2912. gzfile_read_more(gz);
  2913. }
  2914. p = RSTRING_PTR(gz->z.buf);
  2915. n = rslen;
  2916. for (;;) {
  2917. if (n > gz->z.buf_filled) {
  2918. if (ZSTREAM_IS_FINISHED(&gz->z)) break;
  2919. gzfile_read_more(gz);
  2920. p = RSTRING_PTR(gz->z.buf) + n - rslen;
  2921. }
  2922. if (!rspara) rscheck(rsptr, rslen, rs);
  2923. res = memchr(p, rsptr[0], (gz->z.buf_filled - n + 1));
  2924. if (!res) {
  2925. n = gz->z.buf_filled + 1;
  2926. } else {
  2927. n += (long)(res - p);
  2928. p = res;
  2929. if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
  2930. p++, n++;
  2931. }
  2932. }
  2933. gz->lineno++;
  2934. dst = gzfile_read(gz, n);
  2935. if (rspara) {
  2936. gzreader_skip_linebreaks(gz);
  2937. }
  2938. return gzfile_newstr(gz, dst);
  2939. }
  2940. /*
  2941. * See Zlib::GzipReader documentation for a description.
  2942. */
  2943. static VALUE
  2944. rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
  2945. {
  2946. VALUE dst;
  2947. dst = gzreader_gets(argc, argv, obj);
  2948. if (!NIL_P(dst)) {
  2949. rb_lastline_set(dst);
  2950. }
  2951. return dst;
  2952. }
  2953. /*
  2954. * See Zlib::GzipReader documentation for a description.
  2955. */
  2956. static VALUE
  2957. rb_gzreader_readline(int argc, VALUE *argv, VALUE obj)
  2958. {
  2959. VALUE dst;
  2960. dst = rb_gzreader_gets(argc, argv, obj);
  2961. if (NIL_P(dst)) {
  2962. rb_raise(rb_eEOFError, "end of file reached");
  2963. }
  2964. return dst;
  2965. }
  2966. /*
  2967. * See Zlib::GzipReader documentation for a description.
  2968. */
  2969. static VALUE
  2970. rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
  2971. {
  2972. VALUE str;
  2973. RETURN_ENUMERATOR(obj, 0, 0);
  2974. while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
  2975. rb_yield(str);
  2976. }
  2977. return obj;
  2978. }
  2979. /*
  2980. * See Zlib::GzipReader documentation for a description.
  2981. */
  2982. static VALUE
  2983. rb_gzreader_readlines(int argc, VALUE *argv, VALUE obj)
  2984. {
  2985. VALUE str, dst;
  2986. dst = rb_ary_new();
  2987. while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
  2988. rb_ary_push(dst, str);
  2989. }
  2990. return dst;
  2991. }
  2992. #endif /* GZIP_SUPPORT */
  2993. /*
  2994. * The Zlib module contains several classes for compressing and decompressing
  2995. * streams, and for working with "gzip" files.
  2996. *
  2997. * == Classes
  2998. *
  2999. * Following are the classes that are most likely to be of interest to the
  3000. * user:
  3001. * Zlib::Inflate
  3002. * Zlib::Deflate
  3003. * Zlib::GzipReader
  3004. * Zlib::GzipWriter
  3005. *
  3006. * There are two important base classes for the classes above: Zlib::ZStream
  3007. * and Zlib::GzipFile. Everything else is an error class.
  3008. *
  3009. * == Constants
  3010. *
  3011. * Here's a list.
  3012. *
  3013. * Zlib::VERSION
  3014. * The Ruby/zlib version string.
  3015. *
  3016. * Zlib::ZLIB_VERSION
  3017. * The string which represents the version of zlib.h.
  3018. *
  3019. * Zlib::BINARY
  3020. * Zlib::ASCII
  3021. * Zlib::UNKNOWN
  3022. * The integers representing data types which Zlib::ZStream#data_type
  3023. * method returns.
  3024. *
  3025. * Zlib::NO_COMPRESSION
  3026. * Zlib::BEST_SPEED
  3027. * Zlib::BEST_COMPRESSION
  3028. * Zlib::DEFAULT_COMPRESSION
  3029. * The integers representing compression levels which are an argument
  3030. * for Zlib::Deflate.new, Zlib::Deflate#deflate, and so on.
  3031. *
  3032. * Zlib::FILTERED
  3033. * Zlib::HUFFMAN_ONLY
  3034. * Zlib::DEFAULT_STRATEGY
  3035. * The integers representing compression methods which are an argument
  3036. * for Zlib::Deflate.new and Zlib::Deflate#params.
  3037. *
  3038. * Zlib::DEF_MEM_LEVEL
  3039. * Zlib::MAX_MEM_LEVEL
  3040. * The integers representing memory levels which are an argument for
  3041. * Zlib::Deflate.new, Zlib::Deflate#params, and so on.
  3042. *
  3043. * Zlib::MAX_WBITS
  3044. * The default value of windowBits which is an argument for
  3045. * Zlib::Deflate.new and Zlib::Inflate.new.
  3046. *
  3047. * Zlib::NO_FLUSH
  3048. * Zlib::SYNC_FLUSH
  3049. * Zlib::FULL_FLUSH
  3050. * Zlib::FINISH
  3051. * The integers to control the output of the deflate stream, which are
  3052. * an argument for Zlib::Deflate#deflate and so on.
  3053. *
  3054. * Zlib::OS_CODE
  3055. * Zlib::OS_MSDOS
  3056. * Zlib::OS_AMIGA
  3057. * Zlib::OS_VMS
  3058. * Zlib::OS_UNIX
  3059. * Zlib::OS_VMCMS
  3060. * Zlib::OS_ATARI
  3061. * Zlib::OS_OS2
  3062. * Zlib::OS_MACOS
  3063. * Zlib::OS_ZSYSTEM
  3064. * Zlib::OS_CPM
  3065. * Zlib::OS_TOPS20
  3066. * Zlib::OS_WIN32
  3067. * Zlib::OS_QDOS
  3068. * Zlib::OS_RISCOS
  3069. * Zlib::OS_UNKNOWN
  3070. * The return values of Zlib::GzipFile#os_code method.
  3071. */
  3072. void
  3073. Init_zlib()
  3074. {
  3075. VALUE mZlib, cZStream, cDeflate, cInflate;
  3076. #if GZIP_SUPPORT
  3077. VALUE cGzipFile, cGzipWriter, cGzipReader;
  3078. #endif
  3079. mZlib = rb_define_module("Zlib");
  3080. cZError = rb_define_class_under(mZlib, "Error", rb_eStandardError);
  3081. cStreamEnd = rb_define_class_under(mZlib, "StreamEnd", cZError);
  3082. cNeedDict = rb_define_class_under(mZlib, "NeedDict", cZError);
  3083. cDataError = rb_define_class_under(mZlib, "DataError", cZError);
  3084. cStreamError = rb_define_class_under(mZlib, "StreamError", cZError);
  3085. cMemError = rb_define_class_under(mZlib, "MemError", cZError);
  3086. cBufError = rb_define_class_under(mZlib, "BufError", cZError);
  3087. cVersionError = rb_define_class_under(mZlib, "VersionError", cZError);
  3088. rb_define_module_function(mZlib, "zlib_version", rb_zlib_version, 0);
  3089. rb_define_module_function(mZlib, "adler32", rb_zlib_adler32, -1);
  3090. rb_define_module_function(mZlib, "adler32_combine", rb_zlib_adler32_combine, 3);
  3091. rb_define_module_function(mZlib, "crc32", rb_zlib_crc32, -1);
  3092. rb_define_module_function(mZlib, "crc32_combine", rb_zlib_crc32_combine, 3);
  3093. rb_define_module_function(mZlib, "crc_table", rb_zlib_crc_table, 0);
  3094. rb_define_const(mZlib, "VERSION", rb_str_new2(RUBY_ZLIB_VERSION));
  3095. rb_define_const(mZlib, "ZLIB_VERSION", rb_str_new2(ZLIB_VERSION));
  3096. cZStream = rb_define_class_under(mZlib, "ZStream", rb_cObject);
  3097. rb_undef_alloc_func(cZStream);
  3098. rb_define_method(cZStream, "avail_out", rb_zstream_avail_out, 0);
  3099. rb_define_method(cZStream, "avail_out=", rb_zstream_set_avail_out, 1);
  3100. rb_define_method(cZStream, "avail_in", rb_zstream_avail_in, 0);
  3101. rb_define_method(cZStream, "total_in", rb_zstream_total_in, 0);
  3102. rb_define_method(cZStream, "total_out", rb_zstream_total_out, 0);
  3103. rb_define_method(cZStream, "data_type", rb_zstream_data_type, 0);
  3104. rb_define_method(cZStream, "adler", rb_zstream_adler, 0);
  3105. rb_define_method(cZStream, "finished?", rb_zstream_finished_p, 0);
  3106. rb_define_method(cZStream, "stream_end?", rb_zstream_finished_p, 0);
  3107. rb_define_method(cZStream, "closed?", rb_zstream_closed_p, 0);
  3108. rb_define_method(cZStream, "ended?", rb_zstream_closed_p, 0);
  3109. rb_define_method(cZStream, "close", rb_zstream_end, 0);
  3110. rb_define_method(cZStream, "end", rb_zstream_end, 0);
  3111. rb_define_method(cZStream, "reset", rb_zstream_reset, 0);
  3112. rb_define_method(cZStream, "finish", rb_zstream_finish, 0);
  3113. rb_define_method(cZStream, "flush_next_in", rb_zstream_flush_next_in, 0);
  3114. rb_define_method(cZStream, "flush_next_out", rb_zstream_flush_next_out, 0);
  3115. rb_define_const(mZlib, "BINARY", INT2FIX(Z_BINARY));
  3116. rb_define_const(mZlib, "ASCII", INT2FIX(Z_ASCII));
  3117. rb_define_const(mZlib, "UNKNOWN", INT2FIX(Z_UNKNOWN));
  3118. cDeflate = rb_define_class_under(mZlib, "Deflate", cZStream);
  3119. rb_define_singleton_method(cDeflate, "deflate", rb_deflate_s_deflate, -1);
  3120. rb_define_alloc_func(cDeflate, rb_deflate_s_allocate);
  3121. rb_define_method(cDeflate, "initialize", rb_deflate_initialize, -1);
  3122. rb_define_method(cDeflate, "initialize_copy", rb_deflate_init_copy, 1);
  3123. rb_define_method(cDeflate, "deflate", rb_deflate_deflate, -1);
  3124. rb_define_method(cDeflate, "<<", rb_deflate_addstr, 1);
  3125. rb_define_method(cDeflate, "flush", rb_deflate_flush, -1);
  3126. rb_define_method(cDeflate, "params", rb_deflate_params, 2);
  3127. rb_define_method(cDeflate, "set_dictionary", rb_deflate_set_dictionary, 1);
  3128. cInflate = rb_define_class_under(mZlib, "Inflate", cZStream);
  3129. rb_define_singleton_method(cInflate, "inflate", rb_inflate_s_inflate, 1);
  3130. rb_define_alloc_func(cInflate, rb_inflate_s_allocate);
  3131. rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1);
  3132. rb_define_method(cInflate, "inflate", rb_inflate_inflate, 1);
  3133. rb_define_method(cInflate, "<<", rb_inflate_addstr, 1);
  3134. rb_define_method(cInflate, "sync", rb_inflate_sync, 1);
  3135. rb_define_method(cInflate, "sync_point?", rb_inflate_sync_point_p, 0);
  3136. rb_define_method(cInflate, "set_dictionary", rb_inflate_set_dictionary, 1);
  3137. rb_define_const(mZlib, "NO_COMPRESSION", INT2FIX(Z_NO_COMPRESSION));
  3138. rb_define_const(mZlib, "BEST_SPEED", INT2FIX(Z_BEST_SPEED));
  3139. rb_define_const(mZlib, "BEST_COMPRESSION", INT2FIX(Z_BEST_COMPRESSION));
  3140. rb_define_const(mZlib, "DEFAULT_COMPRESSION",
  3141. INT2FIX(Z_DEFAULT_COMPRESSION));
  3142. rb_define_const(mZlib, "FILTERED", INT2FIX(Z_FILTERED));
  3143. rb_define_const(mZlib, "HUFFMAN_ONLY", INT2FIX(Z_HUFFMAN_ONLY));
  3144. rb_define_const(mZlib, "DEFAULT_STRATEGY", INT2FIX(Z_DEFAULT_STRATEGY));
  3145. rb_define_const(mZlib, "MAX_WBITS", INT2FIX(MAX_WBITS));
  3146. rb_define_const(mZlib, "DEF_MEM_LEVEL", INT2FIX(DEF_MEM_LEVEL));
  3147. rb_define_const(mZlib, "MAX_MEM_LEVEL", INT2FIX(MAX_MEM_LEVEL));
  3148. rb_define_const(mZlib, "NO_FLUSH", INT2FIX(Z_NO_FLUSH));
  3149. rb_define_const(mZlib, "SYNC_FLUSH", INT2FIX(Z_SYNC_FLUSH));
  3150. rb_define_const(mZlib, "FULL_FLUSH", INT2FIX(Z_FULL_FLUSH));
  3151. rb_define_const(mZlib, "FINISH", INT2FIX(Z_FINISH));
  3152. #if GZIP_SUPPORT
  3153. id_write = rb_intern("write");
  3154. id_read = rb_intern("read");
  3155. id_readpartial = rb_intern("readpartial");
  3156. id_flush = rb_intern("flush");
  3157. id_seek = rb_intern("seek");
  3158. id_close = rb_intern("close");
  3159. id_path = rb_intern("path");
  3160. cGzipFile = rb_define_class_under(mZlib, "GzipFile", rb_cObject);
  3161. cGzError = rb_define_class_under(cGzipFile, "Error", cZError);
  3162. cNoFooter = rb_define_class_under(cGzipFile, "NoFooter", cGzError);
  3163. cCRCError = rb_define_class_under(cGzipFile, "CRCError", cGzError);
  3164. cLengthError = rb_define_class_under(cGzipFile,"LengthError",cGzError);
  3165. cGzipWriter = rb_define_class_under(mZlib, "GzipWriter", cGzipFile);
  3166. cGzipReader = rb_define_class_under(mZlib, "GzipReader", cGzipFile);
  3167. rb_include_module(cGzipReader, rb_mEnumerable);
  3168. rb_define_singleton_method(cGzipFile, "wrap", rb_gzfile_s_wrap, -1);
  3169. rb_undef_alloc_func(cGzipFile);
  3170. rb_define_method(cGzipFile, "to_io", rb_gzfile_to_io, 0);
  3171. rb_define_method(cGzipFile, "crc", rb_gzfile_crc, 0);
  3172. rb_define_method(cGzipFile, "mtime", rb_gzfile_mtime, 0);
  3173. rb_define_method(cGzipFile, "level", rb_gzfile_level, 0);
  3174. rb_define_method(cGzipFile, "os_code", rb_gzfile_os_code, 0);
  3175. rb_define_method(cGzipFile, "orig_name", rb_gzfile_orig_name, 0);
  3176. rb_define_method(cGzipFile, "comment", rb_gzfile_comment, 0);
  3177. rb_define_method(cGzipReader, "lineno", rb_gzfile_lineno, 0);
  3178. rb_define_method(cGzipReader, "lineno=", rb_gzfile_set_lineno, 1);
  3179. rb_define_method(cGzipWriter, "mtime=", rb_gzfile_set_mtime, 1);
  3180. rb_define_method(cGzipWriter, "orig_name=", rb_gzfile_set_orig_name,1);
  3181. rb_define_method(cGzipWriter, "comment=", rb_gzfile_set_comment, 1);
  3182. rb_define_method(cGzipFile, "close", rb_gzfile_close, 0);
  3183. rb_define_method(cGzipFile, "finish", rb_gzfile_finish, 0);
  3184. rb_define_method(cGzipFile, "closed?", rb_gzfile_closed_p, 0);
  3185. rb_define_method(cGzipReader, "eof", rb_gzfile_eof_p, 0);
  3186. rb_define_method(cGzipReader, "eof?", rb_gzfile_eof_p, 0);
  3187. rb_define_method(cGzipFile, "sync", rb_gzfile_sync, 0);
  3188. rb_define_method(cGzipFile, "sync=", rb_gzfile_set_sync, 1);
  3189. rb_define_method(cGzipReader, "pos", rb_gzfile_total_out, 0);
  3190. rb_define_method(cGzipWriter, "pos", rb_gzfile_total_in, 0);
  3191. rb_define_method(cGzipReader, "tell", rb_gzfile_total_out, 0);
  3192. rb_define_method(cGzipWriter, "tell", rb_gzfile_total_in, 0);
  3193. rb_define_singleton_method(cGzipWriter, "open", rb_gzwriter_s_open,-1);
  3194. rb_define_alloc_func(cGzipWriter, rb_gzwriter_s_allocate);
  3195. rb_define_method(cGzipWriter, "initialize", rb_gzwriter_initialize,-1);
  3196. rb_define_method(cGzipWriter, "flush", rb_gzwriter_flush, -1);
  3197. rb_define_method(cGzipWriter, "write", rb_gzwriter_write, 1);
  3198. rb_define_method(cGzipWriter, "putc", rb_gzwriter_putc, 1);
  3199. rb_define_method(cGzipWriter, "<<", rb_gzwriter_addstr, 1);
  3200. rb_define_method(cGzipWriter, "printf", rb_gzwriter_printf, -1);
  3201. rb_define_method(cGzipWriter, "print", rb_gzwriter_print, -1);
  3202. rb_define_method(cGzipWriter, "puts", rb_gzwriter_puts, -1);
  3203. rb_define_singleton_method(cGzipReader, "open", rb_gzreader_s_open,-1);
  3204. rb_define_alloc_func(cGzipReader, rb_gzreader_s_allocate);
  3205. rb_define_method(cGzipReader, "initialize", rb_gzreader_initialize, -1);
  3206. rb_define_method(cGzipReader, "rewind", rb_gzreader_rewind, 0);
  3207. rb_define_method(cGzipReader, "unused", rb_gzreader_unused, 0);
  3208. rb_define_method(cGzipReader, "read", rb_gzreader_read, -1);
  3209. rb_define_method(cGzipReader, "readpartial", rb_gzreader_readpartial, -1);
  3210. rb_define_method(cGzipReader, "getc", rb_gzreader_getc, 0);
  3211. rb_define_method(cGzipReader, "getbyte", rb_gzreader_getbyte, 0);
  3212. rb_define_method(cGzipReader, "readchar", rb_gzreader_readchar, 0);
  3213. rb_define_method(cGzipReader, "readbyte", rb_gzreader_readbyte, 0);
  3214. rb_define_method(cGzipReader, "each_byte", rb_gzreader_each_byte, 0);
  3215. rb_define_method(cGzipReader, "each_char", rb_gzreader_each_char, 0);
  3216. rb_define_method(cGzipReader, "bytes", rb_gzreader_each_byte, 0);
  3217. rb_define_method(cGzipReader, "ungetc", rb_gzreader_ungetc, 1);
  3218. rb_define_method(cGzipReader, "ungetbyte", rb_gzreader_ungetbyte, 1);
  3219. rb_define_method(cGzipReader, "gets", rb_gzreader_gets, -1);
  3220. rb_define_method(cGzipReader, "readline", rb_gzreader_readline, -1);
  3221. rb_define_method(cGzipReader, "each", rb_gzreader_each, -1);
  3222. rb_define_method(cGzipReader, "each_line", rb_gzreader_each, -1);
  3223. rb_define_method(cGzipReader, "lines", rb_gzreader_each, -1);
  3224. rb_define_method(cGzipReader, "readlines", rb_gzreader_readlines, -1);
  3225. rb_define_const(mZlib, "OS_CODE", INT2FIX(OS_CODE));
  3226. rb_define_const(mZlib, "OS_MSDOS", INT2FIX(OS_MSDOS));
  3227. rb_define_const(mZlib, "OS_AMIGA", INT2FIX(OS_AMIGA));
  3228. rb_define_const(mZlib, "OS_VMS", INT2FIX(OS_VMS));
  3229. rb_define_const(mZlib, "OS_UNIX", INT2FIX(OS_UNIX));
  3230. rb_define_const(mZlib, "OS_ATARI", INT2FIX(OS_ATARI));
  3231. rb_define_const(mZlib, "OS_OS2", INT2FIX(OS_OS2));
  3232. rb_define_const(mZlib, "OS_MACOS", INT2FIX(OS_MACOS));
  3233. rb_define_const(mZlib, "OS_TOPS20", INT2FIX(OS_TOPS20));
  3234. rb_define_const(mZlib, "OS_WIN32", INT2FIX(OS_WIN32));
  3235. rb_define_const(mZlib, "OS_VMCMS", INT2FIX(OS_VMCMS));
  3236. rb_define_const(mZlib, "OS_ZSYSTEM", INT2FIX(OS_ZSYSTEM));
  3237. rb_define_const(mZlib, "OS_CPM", INT2FIX(OS_CPM));
  3238. rb_define_const(mZlib, "OS_QDOS", INT2FIX(OS_QDOS));
  3239. rb_define_const(mZlib, "OS_RISCOS", INT2FIX(OS_RISCOS));
  3240. rb_define_const(mZlib, "OS_UNKNOWN", INT2FIX(OS_UNKNOWN));
  3241. #endif /* GZIP_SUPPORT */
  3242. }
  3243. /* Document error classes. */
  3244. /*
  3245. * Document-class: Zlib::Error
  3246. *
  3247. * The superclass for all exceptions raised by Ruby/zlib.
  3248. *
  3249. * The following exceptions are defined as subclasses of Zlib::Error. These
  3250. * exceptions are raised when zlib library functions return with an error
  3251. * status.
  3252. *
  3253. * - Zlib::StreamEnd
  3254. * - Zlib::NeedDict
  3255. * - Zlib::DataError
  3256. * - Zlib::StreamError
  3257. * - Zlib::MemError
  3258. * - Zlib::BufError
  3259. * - Zlib::VersionError
  3260. *
  3261. */
  3262. /*
  3263. * Document-class: Zlib::GzipFile::Error
  3264. *
  3265. * Base class of errors that occur when processing GZIP files.
  3266. */
  3267. /*
  3268. * Document-class: Zlib::GzipFile::NoFooter
  3269. *
  3270. * Raised when gzip file footer is not found.
  3271. */
  3272. /*
  3273. * Document-class: Zlib::GzipFile::CRCError
  3274. *
  3275. * Raised when the CRC checksum recorded in gzip file footer is not equivalent
  3276. * to the CRC checksum of the actual uncompressed data.
  3277. */
  3278. /*
  3279. * Document-class: Zlib::GzipFile::LengthError
  3280. *
  3281. * Raised when the data length recorded in the gzip file footer is not equivalent
  3282. * to the length of the actual uncompressed data.
  3283. */