Mercurial > octave-libgccjit
changeset 18616:aa861a98d84d stable
fwrite: don't convert to octave_int for char output types
* oct-stream.cc (convert_chars): New template function.
(ultimate_element_type): New traits class and specialization.
(convert_data): Handle conversion to char types differently from
single byte integer types.
* io.tst: New test.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 03 Apr 2014 19:50:14 -0400 |
parents | ef7bb00d8167 |
children | c644cfa9cb3b |
files | libinterp/corefcn/oct-stream.cc test/io.tst |
diffstat | 2 files changed, 52 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc Tue Apr 01 15:49:23 2014 +0200 +++ b/libinterp/corefcn/oct-stream.cc Thu Apr 03 19:50:14 2014 -0400 @@ -3379,6 +3379,18 @@ template <class T, class V> static void +convert_chars (const void *data, void *conv_data, octave_idx_type n_elts) +{ + const T *tt_data = static_cast<const T *> (data); + + V *vt_data = static_cast<V *> (conv_data); + + for (octave_idx_type i = 0; i < n_elts; i++) + vt_data[i] = tt_data[i]; +} + +template <class T, class V> +static void convert_ints (const T *data, void *conv_data, octave_idx_type n_elts, bool swap) { @@ -3388,6 +3400,9 @@ for (octave_idx_type i = 0; i < n_elts; i++) { + // Yes, we want saturation semantics when converting to an integer + // type. + V val (data[i]); vt_data[i] = val.value (); @@ -3398,6 +3413,20 @@ } template <class T> +class ultimate_element_type +{ +public: + typedef T type; +}; + +template <class T> +class ultimate_element_type<octave_int<T> > +{ +public: + typedef T type; +}; + +template <class T> static bool convert_data (const T *data, void *conv_data, octave_idx_type n_elts, oct_data_conv::data_type output_type, @@ -3412,18 +3441,26 @@ bool do_float_conversion = flt_fmt != oct_mach_info::float_format (); - // We use octave_intN classes here instead of converting directly to - // intN_t so that we get integer saturation semantics. + typedef typename ultimate_element_type<T>::type ult_elt_type; switch (output_type) { case oct_data_conv::dt_char: + convert_chars<ult_elt_type, char> (data, conv_data, n_elts); + break; + case oct_data_conv::dt_schar: + convert_chars<ult_elt_type, signed char> (data, conv_data, n_elts); + break; + + case oct_data_conv::dt_uchar: + convert_chars<ult_elt_type, unsigned char> (data, conv_data, n_elts); + break; + case oct_data_conv::dt_int8: convert_ints<T, octave_int8> (data, conv_data, n_elts, swap); break; - case oct_data_conv::dt_uchar: case oct_data_conv::dt_uint8: convert_ints<T, octave_uint8> (data, conv_data, n_elts, swap); break;
--- a/test/io.tst Tue Apr 01 15:49:23 2014 +0200 +++ b/test/io.tst Thu Apr 03 19:50:14 2014 -0400 @@ -434,6 +434,18 @@ %! assert (__prog_output_assert__ ("ok")); %!test +%! x = char (128:255)'; +%! nm = tmpnam (); +%! id = fopen (nm, "wb"); +%! fwrite (id, x); +%! fclose (id); +%! id = fopen (nm, "rb"); +%! y = fread (id, Inf, "uchar=>char"); +%! fclose (id); +%! unlink (nm); +%! assert (x, y); + +%!test %! nm = tmpnam (); %! id = fopen (nm, "wb"); %! if (id > 0)