Revision: 4480 http://trac.macosforge.org/projects/ruby/changeset/4480 Author: lsansonetti@apple.com Date: 2010-08-30 22:02:24 -0700 (Mon, 30 Aug 2010) Log Message: ----------- when reading all, try to determine the input's remaining data length before actually reading it in chunks Modified Paths: -------------- MacRuby/trunk/io.c Modified: MacRuby/trunk/io.c =================================================================== --- MacRuby/trunk/io.c 2010-08-31 02:04:11 UTC (rev 4479) +++ MacRuby/trunk/io.c 2010-08-31 05:02:24 UTC (rev 4480) @@ -1011,16 +1011,26 @@ static VALUE rb_io_read_all(rb_io_t *io_struct, VALUE outbuf) { + struct stat st; + long bufsize = 512; + if (fstat(io_struct->read_fd, &st) == 0 && S_ISREG(st.st_mode)) { + const off_t pos = lseek(io_struct->read_fd, 0, SEEK_CUR); + if (st.st_size >= pos && pos >= 0) { + bufsize = st.st_size - pos; + if (bufsize > LONG_MAX) { + rb_raise(rb_eIOError, "file too big for single read"); + } + } + } + outbuf = rb_str_bstr(outbuf); - - const long BUFSIZE = 512; long bytes_read = 0; const long original_position = rb_bstr_length(outbuf); while (true) { - rb_bstr_resize(outbuf, original_position + bytes_read + BUFSIZE); + rb_bstr_resize(outbuf, original_position + bytes_read + bufsize); uint8_t *bytes = rb_bstr_bytes(outbuf) + original_position + bytes_read; - const long last_read = rb_io_read_internal(io_struct, bytes, BUFSIZE); + const long last_read = rb_io_read_internal(io_struct, bytes, bufsize); bytes_read += last_read; if (last_read == 0) { break;