Mercurial > octave-nkf
diff libinterp/corefcn/oct-stream.cc @ 18515:bc31d9359cf9
maint: Periodic merge of gui-release to default.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 21 Feb 2014 18:20:35 -0500 |
parents | 775e7874b38d fdd27f68b011 |
children | f958e8cd6348 |
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc Thu Feb 20 14:08:53 2014 -0800 +++ b/libinterp/corefcn/oct-stream.cc Fri Feb 21 18:20:35 2014 -0500 @@ -3275,6 +3275,14 @@ while (is && ! is.eof () && (read_to_eof || count < elts_to_read)) { + if (! read_to_eof) + { + octave_idx_type remaining_elts = elts_to_read - count; + + if (remaining_elts < input_buf_elts) + input_buf_size = remaining_elts * input_elt_size; + } + char *input_buf = new char [input_buf_size]; is.read (input_buf, input_buf_size); @@ -3283,15 +3291,35 @@ char_count += gcount; - count += gcount / input_elt_size; + size_t nel = gcount / input_elt_size; + + count += nel; input_buf_list.push_back (input_buf); - if (is && skip != 0 && count == block_size) + if (is && skip != 0 && nel == block_size) { - int seek_status = seek (skip, SEEK_CUR); - - if (seek_status < 0) + // Seek to skip. If skip would move past EOF, + // position at EOF. + + off_t orig_pos = tell (); + + seek (0, SEEK_END); + + off_t eof_pos = tell (); + + // Is it possible for this to fail to return us to + // the original position? + seek (orig_pos, SEEK_SET); + + size_t remaining = eof_pos - orig_pos; + + if (remaining < skip) + seek (0, SEEK_END); + else + seek (skip, SEEK_CUR); + + if (! is) break; } }