PageRenderTime 75ms CodeModel.GetById 29ms 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

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

  1. /*
  2. * zlib.c - An interface for zlib.
  3. *
  4. * Copyright (C) UENO Katsuhiro 2000-2003
  5. *
  6. * $Id$
  7. */
  8. #include <ruby.h>
  9. #include <zlib.h>
  10. #include <time.h>
  11. #include <ruby/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;

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