changeset 18209:a0abcf377ec5 stable

return elements read, not bytes in fread second output (bug #41091) * oct-stream.cc (octave_stream::read): Rename char_count arg to be count. Make char_count a local variable. Use count instead of elts_read. Correctly truncate size of result matrix if fewer elements are read than requested.
author John W. Eaton <jwe@octave.org>
date Fri, 03 Jan 2014 17:29:08 -0500
parents 1c1236fd179a
children 77fa327a956d 8d7e45ea11fa
files libinterp/corefcn/oct-stream.cc test/io.tst
diffstat 2 files changed, 49 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc	Fri Jan 03 23:15:34 2014 +0100
+++ b/libinterp/corefcn/oct-stream.cc	Fri Jan 03 17:29:08 2014 -0500
@@ -3164,7 +3164,7 @@
                      oct_data_conv::data_type input_type,
                      oct_data_conv::data_type output_type,
                      octave_idx_type skip, oct_mach_info::float_format ffmt,
-                     octave_idx_type& char_count)
+                     octave_idx_type& count)
 {
   octave_value retval;
 
@@ -3181,7 +3181,10 @@
       // numbering stays consistent with the order of the elements in the
       // data_type enum in the oct_data_conv class.
 
-      char_count = 0;
+      // Expose this in a future version?
+      octave_idx_type char_count = 0;
+
+      count = 0;
 
       get_size (size, nr, nc, one_elt_size_spec, "fread");
 
@@ -3254,24 +3257,22 @@
 
               std::list <void *> input_buf_list;
 
-              octave_idx_type elts_read = 0;
-
               while (is && ! is.eof ()
-                     && (read_to_eof || elts_read < elts_to_read))
+                     && (read_to_eof || count < elts_to_read))
                 {
                   char *input_buf = new char [input_buf_size];
 
                   is.read (input_buf, input_buf_size);
 
-                  size_t count = is.gcount ();
-
-                  char_count += count;
-
-                  elts_read += count / input_elt_size;
+                  size_t gcount = is.gcount ();
+
+                  char_count += gcount;
+
+                  count += gcount / input_elt_size;
 
                   input_buf_list.push_back (input_buf);
 
-                  if (is && skip != 0 && elts_read == block_size)
+                  if (is && skip != 0 && count == block_size)
                     {
                       int seek_status = seek (skip, SEEK_CUR);
 
@@ -3283,12 +3284,25 @@
               if (read_to_eof)
                 {
                   if (nc < 0)
-                    nc = elts_read / nr + 1;
+                    nc = count / nr + 1;
                   else
-                    nr = elts_read;
+                    nr = count;
+                }
+              else if (count == 0)
+                {
+                  nr = 0;
+                  nc = 0;
                 }
-
-              retval = finalize_read (input_buf_list, input_buf_elts, elts_read,
+              else if (count != nr * nc)
+                {
+                  if (count % nr != 0)
+                    nc = count / nr + 1;
+
+                  if (count < nr)
+                    nr = count;
+                }
+
+              retval = finalize_read (input_buf_list, input_buf_elts, count,
                                       nr, nc, input_type, output_type, ffmt);
             }
           else
--- a/test/io.tst	Fri Jan 03 23:15:34 2014 +0100
+++ b/test/io.tst	Fri Jan 03 17:29:08 2014 -0500
@@ -527,3 +527,23 @@
 %!error <Invalid call to frewind> frewind (1, 2)
 %!error frewind ("foo")
 
+%!test
+%! id = tmpfile ();
+%! fwrite (id, "abcdefg");
+%! frewind (id);
+%! [data, count] = fread (id);
+%! assert (data, [97; 98; 99; 100; 101; 102; 103]);
+%! assert (count, 7);
+%! frewind (id);
+%! [data, count] = fread (id, 'int16');
+%! assert (data, [25185; 25699; 26213]);
+%! assert (count, 3);
+%! frewind (id);
+%! [data, count] = fread (id, [10, 2], 'int16');
+%! assert (data, [25185; 25699; 26213]);
+%! assert (count, 3);
+%! frewind (id);
+%! [data, count] = fread (id, [2, 10], 'int16');
+%! assert (data, [25185, 26213; 25699, 0]);
+%! assert (count, 3);
+%! fclose (id);