diff libinterp/corefcn/oct-stream.cc @ 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 175b392e91fe
children 775e7874b38d fdd27f68b011
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc
+++ b/libinterp/corefcn/oct-stream.cc
@@ -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