comparison 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
comparison
equal deleted inserted replaced
18208:1c1236fd179a 18209:a0abcf377ec5
3162 octave_value 3162 octave_value
3163 octave_stream::read (const Array<double>& size, octave_idx_type block_size, 3163 octave_stream::read (const Array<double>& size, octave_idx_type block_size,
3164 oct_data_conv::data_type input_type, 3164 oct_data_conv::data_type input_type,
3165 oct_data_conv::data_type output_type, 3165 oct_data_conv::data_type output_type,
3166 octave_idx_type skip, oct_mach_info::float_format ffmt, 3166 octave_idx_type skip, oct_mach_info::float_format ffmt,
3167 octave_idx_type& char_count) 3167 octave_idx_type& count)
3168 { 3168 {
3169 octave_value retval; 3169 octave_value retval;
3170 3170
3171 octave_idx_type nr = -1; 3171 octave_idx_type nr = -1;
3172 octave_idx_type nc = -1; 3172 octave_idx_type nc = -1;
3179 3179
3180 // FIXME: we need a better way to ensure that this 3180 // FIXME: we need a better way to ensure that this
3181 // numbering stays consistent with the order of the elements in the 3181 // numbering stays consistent with the order of the elements in the
3182 // data_type enum in the oct_data_conv class. 3182 // data_type enum in the oct_data_conv class.
3183 3183
3184 char_count = 0; 3184 // Expose this in a future version?
3185 octave_idx_type char_count = 0;
3186
3187 count = 0;
3185 3188
3186 get_size (size, nr, nc, one_elt_size_spec, "fread"); 3189 get_size (size, nr, nc, one_elt_size_spec, "fread");
3187 3190
3188 if (! error_state) 3191 if (! error_state)
3189 { 3192 {
3252 { 3255 {
3253 std::istream& is = *isp; 3256 std::istream& is = *isp;
3254 3257
3255 std::list <void *> input_buf_list; 3258 std::list <void *> input_buf_list;
3256 3259
3257 octave_idx_type elts_read = 0;
3258
3259 while (is && ! is.eof () 3260 while (is && ! is.eof ()
3260 && (read_to_eof || elts_read < elts_to_read)) 3261 && (read_to_eof || count < elts_to_read))
3261 { 3262 {
3262 char *input_buf = new char [input_buf_size]; 3263 char *input_buf = new char [input_buf_size];
3263 3264
3264 is.read (input_buf, input_buf_size); 3265 is.read (input_buf, input_buf_size);
3265 3266
3266 size_t count = is.gcount (); 3267 size_t gcount = is.gcount ();
3267 3268
3268 char_count += count; 3269 char_count += gcount;
3269 3270
3270 elts_read += count / input_elt_size; 3271 count += gcount / input_elt_size;
3271 3272
3272 input_buf_list.push_back (input_buf); 3273 input_buf_list.push_back (input_buf);
3273 3274
3274 if (is && skip != 0 && elts_read == block_size) 3275 if (is && skip != 0 && count == block_size)
3275 { 3276 {
3276 int seek_status = seek (skip, SEEK_CUR); 3277 int seek_status = seek (skip, SEEK_CUR);
3277 3278
3278 if (seek_status < 0) 3279 if (seek_status < 0)
3279 break; 3280 break;
3281 } 3282 }
3282 3283
3283 if (read_to_eof) 3284 if (read_to_eof)
3284 { 3285 {
3285 if (nc < 0) 3286 if (nc < 0)
3286 nc = elts_read / nr + 1; 3287 nc = count / nr + 1;
3287 else 3288 else
3288 nr = elts_read; 3289 nr = count;
3289 } 3290 }
3290 3291 else if (count == 0)
3291 retval = finalize_read (input_buf_list, input_buf_elts, elts_read, 3292 {
3293 nr = 0;
3294 nc = 0;
3295 }
3296 else if (count != nr * nc)
3297 {
3298 if (count % nr != 0)
3299 nc = count / nr + 1;
3300
3301 if (count < nr)
3302 nr = count;
3303 }
3304
3305 retval = finalize_read (input_buf_list, input_buf_elts, count,
3292 nr, nc, input_type, output_type, ffmt); 3306 nr, nc, input_type, output_type, ffmt);
3293 } 3307 }
3294 else 3308 else
3295 error ("fread: invalid input stream"); 3309 error ("fread: invalid input stream");
3296 } 3310 }