Mercurial > hg > octave-nkf
changeset 18580:fdd27f68b011 stable
handle fread skip parameter correctly (bug #41648)
* oct-stream.cc (octave_stream::read): Decide whether to skip based on
current number of elements read, not total. Correctly handle case of
reading partial blocks when there is a repeat cound. Skip to EOF if
the full skip is beyond EOF.
* io.tst: New test.
author | Rik <rik@octave.org> and John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 21 Feb 2014 15:28:02 -0500 |
parents | bcc88f8f071d |
children | 39fbe4aba560 0bdecd41b2dd |
files | libinterp/corefcn/oct-stream.cc test/io.tst |
diffstat | 2 files changed, 55 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc +++ b/libinterp/corefcn/oct-stream.cc @@ -3260,6 +3260,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); @@ -3268,15 +3276,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; } }
--- a/test/io.tst +++ b/test/io.tst @@ -547,3 +547,25 @@ %! assert (data, [25185, 26213; 25699, 0]); %! assert (count, 3); %! fclose (id); + +%!test +%! id = tmpfile (); +%! fwrite (id, char (0:15)); +%! frewind (id); +%! [data, count] = fread (id, inf, "2*uint8", 2); +%! assert (data, [0; 1; 4; 5; 8; 9; 12; 13]); +%! assert (count, 8); +%! frewind (id); +%! [data, count] = fread (id, 3, "2*uint8", 3); +%! assert (data, [0; 1; 5]); +%! assert (count, 3); +%! [data, count] = fread (id, 3, "2*uint8", 3); +%! assert (data, [6; 7; 11]); +%! assert (count, 3); +%! [data, count] = fread (id, 3, "2*uint8", 3); +%! assert (data, [12; 13]); +%! assert (count, 2); +%! [data, count] = fread (id, 3, "2*uint8", 3); +%! assert (data, []); +%! assert (count, 0); +%! fclose (id);