diff options
author | Jeremy Evans <code@jeremyevans.net> | 2020-10-28 10:58:28 -0700 |
---|---|---|
committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2020-12-04 19:12:20 +0900 |
commit | bc63ec57e7f965796479f68f6f687187c089bd40 (patch) | |
tree | 7d75a8642f27705e9aa6f3adb4bdb30adaf52e85 /ext/zlib | |
parent | a60dfff43470583bbb4474594efde8607f889e8b (diff) |
[ruby/zlib] Allow Zlib.crc32 and .adler32 to accept IO instance
This reads from the IO in 8192 byte chunks, so you don't need to
have the entire string in memory.
Fixes #16
https://github.com/ruby/zlib/commit/ba9793c550
Diffstat (limited to 'ext/zlib')
-rw-r--r-- | ext/zlib/zlib.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index c540d4c5a1..fa2112f6b8 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -56,7 +56,7 @@ max_uint(long n) #define MAX_UINT(n) (uInt)(n) #endif -static ID id_dictionaries; +static ID id_dictionaries, id_read; /*--------- Prototypes --------*/ @@ -407,6 +407,15 @@ do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt)) if (NIL_P(str)) { sum = func(sum, Z_NULL, 0); } + else if (rb_obj_is_kind_of(str, rb_cIO)) { + VALUE buf; + VALUE buflen = INT2NUM(8192); + + while (!NIL_P(buf = rb_funcall(str, id_read, 1, buflen))) { + StringValue(buf); + sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(buf), RSTRING_LEN(buf)); + } + } else { StringValue(str); sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str)); @@ -422,6 +431,8 @@ do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt)) * Calculates Adler-32 checksum for +string+, and returns updated value of * +adler+. If +string+ is omitted, it returns the Adler-32 initial value. If * +adler+ is omitted, it assumes that the initial value is given to +adler+. + * If +string+ is an IO instance, reads from the IO until the IO returns nil + * and returns Adler-32 of all read data. * * Example usage: * @@ -466,7 +477,9 @@ rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2) * * Calculates CRC checksum for +string+, and returns updated value of +crc+. If * +string+ is omitted, it returns the CRC initial value. If +crc+ is omitted, it - * assumes that the initial value is given to +crc+. + * assumes that the initial value is given to +crc+. If +string+ is an IO instance, + * reads from the IO until the IO returns nil and returns CRC checksum of all read + * data. * * FIXME: expression. */ @@ -2198,7 +2211,7 @@ rb_inflate_set_dictionary(VALUE obj, VALUE dic) #define OS_CODE OS_UNIX #endif -static ID id_write, id_read, id_readpartial, id_flush, id_seek, id_close, id_path, id_input; +static ID id_write, id_readpartial, id_flush, id_seek, id_close, id_path, id_input; static VALUE cGzError, cNoFooter, cCRCError, cLengthError; |