Mercurial > hg > octave-nkf
changeset 4944:44046bbaa52c
[project @ 2004-08-31 05:30:46 by jwe]
author | jwe |
---|---|
date | Tue, 31 Aug 2004 05:30:47 +0000 |
parents | 1a499d0c58f5 |
children | 4bd917f8a4a7 |
files | liboctave/CNDArray.h liboctave/ChangeLog liboctave/boolNDArray.h liboctave/byte-swap.h liboctave/chNDArray.h liboctave/dMatrix.cc liboctave/dMatrix.h liboctave/dNDArray.h liboctave/data-conv.cc liboctave/data-conv.h src/ChangeLog src/file-io.cc src/ls-mat4.cc src/ls-mat5.cc src/ls-oct-binary.cc src/oct-stream.cc src/oct-stream.h src/ov-base-int.cc src/ov-base.cc src/ov-base.h src/ov-bool-mat.cc src/ov-bool.cc src/ov-cell.cc src/ov-complex.cc src/ov-complex.h src/ov-cx-mat.cc src/ov-cx-mat.h src/ov-intx.h src/ov-list.cc src/ov-range.cc src/ov-re-mat.cc src/ov-re-mat.h src/ov-scalar.cc src/ov-scalar.h src/ov-str-mat.cc src/ov-str-mat.h src/ov-struct.cc src/ov.cc src/ov.h |
diffstat | 39 files changed, 1452 insertions(+), 863 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/CNDArray.h +++ b/liboctave/CNDArray.h @@ -33,9 +33,6 @@ #include "mx-defs.h" #include "mx-op-defs.h" -#include "data-conv.h" -#include "mach-info.h" - class ComplexNDArray : public MArrayN<Complex> {
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,23 @@ +2004-08-31 John W. Eaton <jwe@octave.org> + + * data-conv.h (oct_data_conv::data_type): Include sized types. + Explicitly number enum elements. + + * data-conv.cc (oct_data_conv::string_to_data_type (const + std::string&, int&, oct_data_conv::data_type&, + oct_data_conv::data_type&)): New function. + (oct_data_conv::string_to_data_type (const std::string&, int&, + oct_data_conv::data_type&)): New function. + (oct_data_conv::data_type_as_string): New function. + + * dMatrix.cc (read_int, do_read, Matrix::read): Delete. + (write_int, do_write, Matrix::write): Delete. + * dMatrix.h (Matrix::read, Matrix::write): Delete decls. + + * byte-swap.h: Use template functions and specialization. + Change all uses. + (swap_2_bytes, swap_4_bytes, swap_8_bytes): Delete. + 2004-08-30 John W. Eaton <jwe@octave.org> * oct-inttypes.h (octave_int_fit_to_range): Use template
--- a/liboctave/boolNDArray.h +++ b/liboctave/boolNDArray.h @@ -33,9 +33,6 @@ #include "mx-defs.h" #include "mx-op-defs.h" -#include "data-conv.h" -#include "mach-info.h" - #include "boolMatrix.h" class
--- a/liboctave/byte-swap.h +++ b/liboctave/byte-swap.h @@ -36,68 +36,62 @@ t[j] = tmp; } -static inline void -swap_2_bytes (volatile void *ptr) +template <int n> +void +swap_bytes (volatile void *ptr) { - volatile char *t = static_cast<volatile char *> (ptr); + for (size_t i = 0; i < n/2; i++) + swap_bytes (ptr, i, n-1-i); +} - swap_bytes (t, 0, 1); +template <> +inline void +swap_bytes <1> (volatile void *) +{ +} + +template <> +inline void +swap_bytes <2> (volatile void *ptr) +{ + swap_bytes (ptr, 0, 1); } -static inline void -swap_4_bytes (volatile void *ptr) +template <> +inline void +swap_bytes <4> (volatile void *ptr) { - volatile char *t = static_cast<volatile char *> (ptr); - - swap_bytes (t, 0, 3); - swap_bytes (t, 1, 2); + swap_bytes (ptr, 0, 3); + swap_bytes (ptr, 1, 2); } -static inline void -swap_8_bytes (volatile void *ptr) +template <> +inline void +swap_bytes <8> (volatile void *ptr) { - volatile char *t = static_cast<volatile char *> (ptr); - - swap_bytes (t, 0, 7); - swap_bytes (t, 1, 6); - swap_bytes (t, 2, 5); - swap_bytes (t, 3, 4); + swap_bytes (ptr, 0, 7); + swap_bytes (ptr, 1, 6); + swap_bytes (ptr, 2, 5); + swap_bytes (ptr, 3, 4); } -static inline void -swap_2_bytes (volatile void *ptr, int len) +template <int n> +void +swap_bytes (volatile void *ptr, int len) { volatile char *t = static_cast<volatile char *> (ptr); for (int i = 0; i < len; i++) { - swap_2_bytes (t); - t += 2; + swap_bytes<n> (t); + t += n; } } -static inline void -swap_4_bytes (volatile void *ptr, int len) +template <> +inline void +swap_bytes<1> (volatile void *, int) { - volatile char *t = static_cast<volatile char *> (ptr); - - for (int i = 0; i < len; i++) - { - swap_4_bytes (t); - t += 4; - } -} - -static inline void -swap_8_bytes (volatile void *ptr, int len) -{ - volatile char *t = static_cast<volatile char *> (ptr); - - for (int i = 0; i < len; i++) - { - swap_8_bytes (t); - t += 8; - } } #endif
--- a/liboctave/chNDArray.h +++ b/liboctave/chNDArray.h @@ -33,9 +33,6 @@ #include "mx-defs.h" #include "mx-op-defs.h" -#include "data-conv.h" -#include "mach-info.h" - class charNDArray : public MArrayN<char> {
--- a/liboctave/dMatrix.cc +++ b/liboctave/dMatrix.cc @@ -2500,497 +2500,6 @@ return is; } -template <class T> -void -read_int (std::istream& is, bool swap_bytes, T& val) -{ - is.read (X_CAST (char *, &val), sizeof (T)); - - int t = sizeof (T); - - if (swap_bytes && t > 1) - { - switch (t) - { - case 2: - swap_2_bytes (X_CAST (char *, &val)); - break; - - case 4: - swap_4_bytes (X_CAST (char *, &val)); - break; - - case 8: - swap_8_bytes (X_CAST (char *, &val)); - break; - - default: - (*current_liboctave_error_handler) - ("read_int: unrecognized data format!"); - } - } -} - -template void read_int (std::istream&, bool, char&); -template void read_int (std::istream&, bool, signed char&); -template void read_int (std::istream&, bool, unsigned char&); -template void read_int (std::istream&, bool, short&); -template void read_int (std::istream&, bool, unsigned short&); -template void read_int (std::istream&, bool, int&); -template void read_int (std::istream&, bool, unsigned int&); -template void read_int (std::istream&, bool, long&); -template void read_int (std::istream&, bool, unsigned long&); - -static inline bool -do_read (std::istream& is, oct_data_conv::data_type dt, - oct_mach_info::float_format flt_fmt, bool swap_bytes, - bool do_float_conversion, double& val) -{ - bool retval = true; - - switch (dt) - { - case oct_data_conv::dt_char: - { - char tmp; - read_int (is, swap_bytes, tmp); - val = tmp; - } - break; - - case oct_data_conv::dt_schar: - { - signed char tmp; - read_int (is, swap_bytes, tmp); - val = tmp; - } - break; - - case oct_data_conv::dt_uchar: - { - unsigned char tmp; - read_int (is, swap_bytes, tmp); - val = tmp; - } - break; - - case oct_data_conv::dt_short: - { - short tmp; - read_int (is, swap_bytes, tmp); - val = tmp; - } - break; - - case oct_data_conv::dt_ushort: - { - unsigned short tmp; - read_int (is, swap_bytes, tmp); - val = tmp; - } - break; - - case oct_data_conv::dt_int: - { - int tmp; - read_int (is, swap_bytes, tmp); - val = tmp; - } - break; - - case oct_data_conv::dt_uint: - { - unsigned int tmp; - read_int (is, swap_bytes, tmp); - val = tmp; - } - break; - - case oct_data_conv::dt_long: - { - long tmp; - read_int (is, swap_bytes, tmp); - val = tmp; - } - break; - - case oct_data_conv::dt_ulong: - { - unsigned long tmp; - read_int (is, swap_bytes, tmp); - val = tmp; - } - break; - - case oct_data_conv::dt_float: - { - float f; - - is.read (X_CAST (char *, &f), sizeof (float)); - - if (do_float_conversion) - do_float_format_conversion (&f, 1, flt_fmt); - - val = f; - } - break; - - case oct_data_conv::dt_double: - { - is.read (X_CAST (char *, &val), sizeof (double)); - - if (do_float_conversion) - do_double_format_conversion (&val, 1, flt_fmt); - } - break; - - default: - retval = false; - (*current_liboctave_error_handler) - ("read: invalid type specification"); - break; - } - - return retval; -} - -int -Matrix::read (std::istream& is, int nr, int nc, - oct_data_conv::data_type dt, int skip, - oct_mach_info::float_format flt_fmt) -{ - if (nr == 0 || nc == 0) - { - if (nr >= 0 && nc >= 0) - resize (nr, nc); - else - resize (0, 0); - - return 0; - } - - int retval = -1; - - bool ok = true; - - int count = 0; - - double *dat = 0; - int max_size = 0; - - int final_nr = 0; - int final_nc = 0; - - if (nr > 0) - { - if (nc > 0) - { - resize (nr, nc, 0.0); - dat = fortran_vec (); - max_size = nr * nc; - } - else - { - resize (nr, 32, 0.0); - dat = fortran_vec (); - max_size = nr * 32; - } - } - else - { - resize (32, 1, 0.0); - dat = fortran_vec (); - max_size = 32; - } - - oct_mach_info::float_format native_flt_fmt - = oct_mach_info::float_format (); - - bool do_float_conversion = (flt_fmt != native_flt_fmt); - - // XXX FIXME XXX -- byte order for Cray? - - bool swap_bytes = false; - - if (oct_mach_info::words_big_endian ()) - swap_bytes = (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian - || flt_fmt == oct_mach_info::flt_fmt_vax_g - || flt_fmt == oct_mach_info::flt_fmt_vax_g); - else - swap_bytes = (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); - - for (;;) - { - // XXX FIXME XXX -- maybe there should be a special case for - // skip == 0. - - if (is) - { - if (nr > 0 && nc > 0 && count == max_size) - { - final_nr = nr; - final_nc = nc; - - break; - } - - double tmp = 0.0; - - ok = do_read (is, dt, flt_fmt, swap_bytes, do_float_conversion, tmp); - - if (ok) - { - if (is) - { - if (count == max_size) - { - max_size *= 2; - - if (nr > 0) - resize (nr, max_size / nr, 0.0); - else - resize (max_size, 1, 0.0); - - dat = fortran_vec (); - } - - dat[count++] = tmp; - } - - if (skip != 0) - is.seekg (skip, std::ios::cur); - - if (is.eof ()) - { - if (nr > 0) - { - if (count > nr) - { - final_nr = nr; - final_nc = (count - 1) / nr + 1; - } - else - { - final_nr = count; - final_nc = 1; - } - } - else - { - final_nr = count; - final_nc = 1; - } - - break; - } - } - else - { - ok = false; - break; - } - } - else - { - ok = false; - break; - } - } - - if (ok) - { - resize (final_nr, final_nc, 0.0); - - retval = count; - } - - return retval; -} - -template <class T> -void -write_int (std::ostream& os, bool swap_bytes, T val) -{ - int t = sizeof (T); - - if (swap_bytes && t > 1) - { - switch (t) - { - case 2: - swap_2_bytes (X_CAST (char *, &val)); - break; - - case 4: - swap_4_bytes (X_CAST (char *, &val)); - break; - - case 8: - swap_8_bytes (X_CAST (char *, &val)); - break; - - default: - (*current_liboctave_error_handler) - ("write_int: unrecognized data format!"); - } - } - - os.write (X_CAST (char *, &val), sizeof (T)); -} - -template void write_int (std::ostream&, bool, char); -template void write_int (std::ostream&, bool, signed char); -template void write_int (std::ostream&, bool, unsigned char); -template void write_int (std::ostream&, bool, short); -template void write_int (std::ostream&, bool, unsigned short); -template void write_int (std::ostream&, bool, int); -template void write_int (std::ostream&, bool, unsigned int); -template void write_int (std::ostream&, bool, long); -template void write_int (std::ostream&, bool, unsigned long); - -static inline bool -do_write (std::ostream& os, double d, oct_data_conv::data_type dt, - oct_mach_info::float_format flt_fmt, bool swap_bytes, - bool do_float_conversion) -{ - bool retval = true; - - switch (dt) - { - case oct_data_conv::dt_char: - write_int (os, swap_bytes, X_CAST (char, d)); - break; - - case oct_data_conv::dt_schar: - write_int (os, swap_bytes, X_CAST (signed char, d)); - break; - - case oct_data_conv::dt_uchar: - write_int (os, swap_bytes, X_CAST (unsigned char, d)); - break; - - case oct_data_conv::dt_short: - write_int (os, swap_bytes, X_CAST (short, d)); - break; - - case oct_data_conv::dt_ushort: - write_int (os, swap_bytes, X_CAST (unsigned short, d)); - break; - - case oct_data_conv::dt_int: - write_int (os, swap_bytes, X_CAST (int, d)); - break; - - case oct_data_conv::dt_uint: - write_int (os, swap_bytes, X_CAST (unsigned int, d)); - break; - - case oct_data_conv::dt_long: - write_int (os, swap_bytes, X_CAST (long, d)); - break; - - case oct_data_conv::dt_ulong: - write_int (os, swap_bytes, X_CAST (unsigned long, d)); - break; - - case oct_data_conv::dt_float: - { - float f = d; - - if (do_float_conversion) - do_float_format_conversion (&f, 1, flt_fmt); - - os.write (X_CAST (char *, &f), sizeof (float)); - } - break; - - case oct_data_conv::dt_double: - { - if (do_float_conversion) - do_double_format_conversion (&d, 1, flt_fmt); - - os.write (X_CAST (char *, &d), sizeof (double)); - } - break; - - default: - retval = false; - (*current_liboctave_error_handler) - ("write: invalid type specification"); - break; - } - - return retval; -} - -int -Matrix::write (std::ostream& os, oct_data_conv::data_type dt, int skip, - oct_mach_info::float_format flt_fmt) -{ - int retval = -1; - - bool ok = true; - - int count = 0; - - const double *d = data (); - - int n = length (); - - oct_mach_info::float_format native_flt_fmt - = oct_mach_info::float_format (); - - bool do_float_conversion = (flt_fmt != native_flt_fmt); - - // XXX FIXME XXX -- byte order for Cray? - - bool swap_bytes = false; - - if (oct_mach_info::words_big_endian ()) - swap_bytes = (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian - || flt_fmt == oct_mach_info::flt_fmt_vax_g - || flt_fmt == oct_mach_info::flt_fmt_vax_g); - else - swap_bytes = (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); - - for (int i = 0; i < n; i++) - { - if (os) - { - if (skip != 0) - os.seekp (skip, std::ios::cur); - - if (os) - { - ok = do_write (os, d[i], dt, flt_fmt, swap_bytes, - do_float_conversion); - - if (os && ok) - count++; - else - break; - } - else - { - ok = false; - break; - } - } - else - { - ok = false; - break; - } - } - - if (ok) - retval = count; - - return retval; -} - - - Matrix Givens (double x, double y) {
--- a/liboctave/dMatrix.h +++ b/liboctave/dMatrix.h @@ -33,9 +33,6 @@ #include "mx-defs.h" #include "mx-op-defs.h" -#include "data-conv.h" -#include "mach-info.h" - class Matrix : public MArray2<double> { @@ -230,12 +227,6 @@ friend std::ostream& operator << (std::ostream& os, const Matrix& a); friend std::istream& operator >> (std::istream& is, Matrix& a); - int read (std::istream& is, int nr, int nc, oct_data_conv::data_type dt, - int skip, oct_mach_info::float_format flt_fmt); - - int write (std::ostream& os, oct_data_conv::data_type dt, int skip, - oct_mach_info::float_format flt_fmt); - static double resize_fill_value (void) { return 0; } private:
--- a/liboctave/dNDArray.h +++ b/liboctave/dNDArray.h @@ -34,9 +34,6 @@ #include "mx-defs.h" #include "mx-op-defs.h" -#include "data-conv.h" -#include "mach-info.h" - class NDArray : public MArrayN<double> {
--- a/liboctave/data-conv.cc +++ b/liboctave/data-conv.cc @@ -32,6 +32,26 @@ #include "data-conv.h" #include "lo-error.h" +#if defined HAVE_LONG_LONG_INT +#define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \ + do \ + { \ + int sz = BITS / CHAR_BIT; \ + if (sizeof (TQ char) == sz) \ + VAL = oct_data_conv::dt_ ## Q ## char; \ + else if (sizeof (TQ short) == sz) \ + VAL = oct_data_conv::dt_ ## Q ## short; \ + else if (sizeof (TQ int) == sz) \ + VAL = oct_data_conv::dt_ ## Q ## int; \ + else if (sizeof (TQ long) == sz) \ + VAL = oct_data_conv::dt_ ## Q ## long; \ + else if (sizeof (TQ long long) == sz) \ + VAL = oct_data_conv::dt_ ## Q ## longlong; \ + else \ + VAL = oct_data_conv::dt_unknown; \ + } \ + while (0) +#else #define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \ do \ { \ @@ -48,6 +68,7 @@ VAL = oct_data_conv::dt_unknown; \ } \ while (0) +#endif #define FIND_SIZED_FLOAT_TYPE(VAL, BITS) \ do \ @@ -101,6 +122,52 @@ } } +static std::string +strip_spaces (const std::string& str) +{ + int n = str.length (); + + int k = 0; + + std::string s (n, ' '); + + for (int i = 0; i < n; i++) + if (! isspace (str[i])) + s[k++] = tolower (str[i]); + + s.resize (k); + + return s; +} + +#define GET_SIZED_INT_TYPE(T, U) \ + do \ + { \ + switch (sizeof (T)) \ + { \ + case 1: \ + retval = dt_ ## U ## int8; \ + break; \ + \ + case 2: \ + retval = dt_ ## U ## int16; \ + break; \ + \ + case 4: \ + retval = dt_ ## U ## int32; \ + break; \ + \ + case 8: \ + retval = dt_ ## U ## int64; \ + break; \ + \ + default: \ + retval = dt_unknown; \ + break; \ + } \ + } \ + while (0) + oct_data_conv::data_type oct_data_conv::string_to_data_type (const std::string& str) { @@ -117,62 +184,57 @@ initialized = true; } - // XXX FIXME XXX -- finish implementing this. - - int n = str.length (); - - int k = 0; - - std::string s (n, ' '); + std::string s = strip_spaces (str); - for (int i = 0; i < n; i++) - if (! isspace (str[i])) - s[k++] = tolower (str[i]); - - s.resize (k); - - if (s == "char") + if (s == "int8" || s == "integer*1") + retval = dt_int8; + else if (s == "uint8") + retval = dt_uint8; + else if (s == "int16" || s == "integer*2") + retval = dt_int16; + else if (s == "uint16") + retval = dt_uint16; + else if (s == "int32" || s == "integer*4") + retval = dt_int32; + else if (s == "uint32") + retval = dt_uint32; + else if (s == "int64" || s == "integer*8") + retval = dt_int64; + else if (s == "uint64") + retval = dt_uint64; + else if (s == "single" || s == "float32" || s == "real*4") + retval = dt_single; + else if (s == "double" || s == "float64" || s == "real*8") + retval = dt_double; + else if (s == "char" || s == "char*1") retval = dt_char; else if (s == "schar" || s == "signedchar") retval = dt_schar; else if (s == "uchar" || s == "unsignedchar") retval = dt_uchar; else if (s == "short") - retval = dt_short; + GET_SIZED_INT_TYPE (short, ); else if (s == "ushort" || s == "unsignedshort") - retval = dt_ushort; + GET_SIZED_INT_TYPE (unsigned short, u); else if (s == "int") - retval = dt_int; + GET_SIZED_INT_TYPE (int, ); else if (s == "uint" || s == "unsignedint") - retval = dt_uint; + GET_SIZED_INT_TYPE (unsigned int, u); else if (s == "long") - retval = dt_long; + GET_SIZED_INT_TYPE (long, ); else if (s == "ulong" || s == "unsignedlong") - retval = dt_ulong; + GET_SIZED_INT_TYPE (unsigned long, u); + else if (s == "longlong") + GET_SIZED_INT_TYPE (long long, ); + else if (s == "ulonglong" || s == "unsignedlonglong") + GET_SIZED_INT_TYPE (unsigned long long, u); else if (s == "float") - retval = dt_float; - else if (s == "double") - retval = dt_double; - else if (s == "int8" || s == "char*1" || s == "integer*1") - retval = sized_type_table[0][0]; - else if (s == "int16" || s == "integer*2") - retval = sized_type_table[0][1]; - else if (s == "int32" || s == "integer*4") - retval = sized_type_table[0][2]; - else if (s == "int64" || s == "integer*8") - retval = sized_type_table[0][3]; - else if (s == "uint8") - retval = sized_type_table[1][0]; - else if (s == "uint16") - retval = sized_type_table[1][1]; - else if (s == "uint32") - retval = sized_type_table[1][2]; - else if (s == "uint64") - retval = sized_type_table[1][3]; - else if (s == "float32" || s == "real*4") - retval = sized_type_table[2][2]; - else if (s == "float64" || s == "real*8") - retval = sized_type_table[2][3]; + { + if (sizeof (float) == sizeof (double)) + retval = dt_double; + else + retval = dt_single; + } else (*current_liboctave_error_handler) ("invalid data type specified"); @@ -183,7 +245,217 @@ return retval; } -#define swap_1_bytes(x, y) +void +oct_data_conv::string_to_data_type + (const std::string& str, int& block_size, + oct_data_conv::data_type& input_type, + oct_data_conv::data_type& output_type) +{ + block_size = 1; + input_type = dt_uchar; + output_type = dt_double; + + bool input_is_output = false; + + std::string s = strip_spaces (str); + + size_t pos = 0; + + if (s[0] == '*') + input_is_output = true; + else + { + size_t len = s.length (); + + while (pos < len && isdigit (s[pos])) + pos++; + + if (pos > 0) + { + if (s[pos] == '*') + { + block_size = atoi (s.c_str ()); + s = s.substr (pos+1); + } + else + { + (*current_liboctave_error_handler) + ("invalid repeat count in `%s'", str.c_str ()); + + return; + } + } + } + + pos = s.find ('='); + + if (pos != std::string::npos) + { + if (s[pos+1] == '>') + { + if (input_is_output) + { + input_is_output = false; + + (*current_liboctave_warning_handler) + ("warning: ignoring leading * in fread precision"); + } + + input_type = string_to_data_type (s.substr (0, pos)); + output_type = string_to_data_type (s.substr (pos+2)); + } + else + (*current_liboctave_error_handler) + ("fread: invalid precision specified"); + } + else + { + input_type = string_to_data_type (s); + + if (input_is_output) + output_type = input_type; + } +} + +void +oct_data_conv::string_to_data_type + (const std::string& str, int& block_size, + oct_data_conv::data_type& output_type) +{ + block_size = 1; + output_type = dt_double; + + std::string s = strip_spaces (str); + + size_t pos = 0; + + size_t len = s.length (); + + while (pos < len && isdigit (s[pos])) + pos++; + + if (pos > 0) + { + if (s[pos] == '*') + { + block_size = atoi (s.c_str ()); + s = s.substr (pos+1); + } + else + { + (*current_liboctave_error_handler) + ("invalid repeat count in `%s'", str.c_str ()); + + return; + } + } + + output_type = string_to_data_type (s); +} + +std::string +oct_data_conv::data_type_as_string (oct_data_conv::data_type dt) +{ + std::string retval; + + switch (dt) + { + case oct_data_conv::dt_int8: + retval = "int8"; + break; + + case oct_data_conv::dt_uint8: + retval = "uint8"; + break; + + case oct_data_conv::dt_int16: + retval = "int16"; + break; + + case oct_data_conv::dt_uint16: + retval = "uint16"; + break; + + case oct_data_conv::dt_int32: + retval = "int32"; + break; + + case oct_data_conv::dt_uint32: + retval = "uint32"; + break; + + case oct_data_conv::dt_int64: + retval = "int64"; + break; + + case oct_data_conv::dt_uint64: + retval = "uint64"; + break; + + case oct_data_conv::dt_single: + retval = "single"; + break; + + case oct_data_conv::dt_double: + retval = "double"; + break; + + case oct_data_conv::dt_char: + retval = "char"; + break; + + case oct_data_conv::dt_schar: + retval = "signed char"; + break; + + case oct_data_conv::dt_uchar: + retval = "usigned char"; + break; + + case oct_data_conv::dt_short: + retval = "short"; + break; + + case oct_data_conv::dt_ushort: + retval = "unsigned short"; + break; + + case oct_data_conv::dt_int: + retval = "int"; + break; + + case oct_data_conv::dt_uint: + retval = "usigned int"; + break; + + case oct_data_conv::dt_long: + retval = "long"; + break; + + case oct_data_conv::dt_ulong: + retval = "usigned long"; + break; + + case oct_data_conv::dt_longlong: + retval = "long long"; + break; + + case oct_data_conv::dt_ulonglong: + retval = "unsigned long long"; + break; + + case oct_data_conv::dt_float: + retval = "float"; + break; + + case oct_data_conv::dt_unknown: + default: + retval = "unknown"; + break; + } + + return retval; +} #define LS_DO_READ(TYPE, swap, data, size, len, stream) \ do \ @@ -193,7 +465,7 @@ volatile TYPE *ptr = X_CAST (volatile TYPE *, data); \ stream.read (X_CAST (char *, ptr), size * len); \ if (swap) \ - swap_ ## size ## _bytes (ptr, len); \ + swap_bytes< size > (ptr, len); \ TYPE tmp = ptr[0]; \ for (int i = len - 1; i > 0; i--) \ data[i] = ptr[i]; \ @@ -247,205 +519,206 @@ // XXX FIXME XXX -- assumes sizeof (float) == 4 static void -IEEE_big_double_to_IEEE_little_double (double *d, int len) +IEEE_big_double_to_IEEE_little_double (void *d, int len) { - swap_8_bytes (d, len); + swap_bytes<8> (d, len); } static void -VAX_D_double_to_IEEE_little_double (double * /* d */, int /* len */) +VAX_D_double_to_IEEE_little_double (void * /* d */, int /* len */) { gripe_data_conversion ("VAX D float", "IEEE little endian format"); } static void -VAX_G_double_to_IEEE_little_double (double * /* d */, int /* len */) +VAX_G_double_to_IEEE_little_double (void * /* d */, int /* len */) { gripe_data_conversion ("VAX G float", "IEEE little endian format"); } static void -Cray_to_IEEE_little_double (double * /* d */, int /* len */) +Cray_to_IEEE_little_double (void * /* d */, int /* len */) { gripe_data_conversion ("Cray", "IEEE little endian format"); } static void -IEEE_big_float_to_IEEE_little_float (float *d, int len) +IEEE_big_float_to_IEEE_little_float (void *d, int len) { - swap_4_bytes (d, len); + swap_bytes<4> (d, len); } static void -VAX_D_float_to_IEEE_little_float (float * /* d */, int /* len */) +VAX_D_float_to_IEEE_little_float (void * /* d */, int /* len */) { gripe_data_conversion ("VAX D float", "IEEE little endian format"); } static void -VAX_G_float_to_IEEE_little_float (float * /* d */, int /* len */) +VAX_G_float_to_IEEE_little_float (void * /* d */, int /* len */) { gripe_data_conversion ("VAX G float", "IEEE little endian format"); } static void -Cray_to_IEEE_little_float (float * /* d */, int /* len */) +Cray_to_IEEE_little_float (void * /* d */, int /* len */) { gripe_data_conversion ("Cray", "IEEE little endian format"); } static void -IEEE_little_double_to_IEEE_big_double (double *d, int len) +IEEE_little_double_to_IEEE_big_double (void *d, int len) { - swap_8_bytes (d, len); + swap_bytes<8> (d, len); } static void -VAX_D_double_to_IEEE_big_double (double * /* d */, int /* len */) +VAX_D_double_to_IEEE_big_double (void * /* d */, int /* len */) { gripe_data_conversion ("VAX D float", "IEEE big endian format"); } static void -VAX_G_double_to_IEEE_big_double (double * /* d */, int /* len */) +VAX_G_double_to_IEEE_big_double (void * /* d */, int /* len */) { gripe_data_conversion ("VAX G float", "IEEE big endian format"); } static void -Cray_to_IEEE_big_double (double * /* d */, int /* len */) +Cray_to_IEEE_big_double (void * /* d */, int /* len */) { gripe_data_conversion ("Cray", "IEEE big endian format"); } static void -IEEE_little_float_to_IEEE_big_float (float *d, int len) +IEEE_little_float_to_IEEE_big_float (void *d, int len) { - swap_4_bytes (d, len); + swap_bytes<4> (d, len); } static void -VAX_D_float_to_IEEE_big_float (float * /* d */, int /* len */) +VAX_D_float_to_IEEE_big_float (void * /* d */, int /* len */) { gripe_data_conversion ("VAX D float", "IEEE big endian format"); } static void -VAX_G_float_to_IEEE_big_float (float * /* d */, int /* len */) +VAX_G_float_to_IEEE_big_float (void * /* d */, int /* len */) { gripe_data_conversion ("VAX G float", "IEEE big endian format"); } static void -Cray_to_IEEE_big_float (float * /* d */, int /* len */) +Cray_to_IEEE_big_float (void * /* d */, int /* len */) { gripe_data_conversion ("Cray", "IEEE big endian format"); } static void -IEEE_little_double_to_VAX_D_double (double * /* d */, int /* len */) +IEEE_little_double_to_VAX_D_double (void * /* d */, int /* len */) { gripe_data_conversion ("IEEE little endian", "VAX D"); } static void -IEEE_big_double_to_VAX_D_double (double * /* d */, int /* len */) +IEEE_big_double_to_VAX_D_double (void * /* d */, int /* len */) { gripe_data_conversion ("IEEE big endian", "VAX D"); } static void -VAX_G_double_to_VAX_D_double (double * /* d */, int /* len */) +VAX_G_double_to_VAX_D_double (void * /* d */, int /* len */) { gripe_data_conversion ("VAX G float", "VAX D"); } static void -Cray_to_VAX_D_double (double * /* d */, int /* len */) +Cray_to_VAX_D_double (void * /* d */, int /* len */) { gripe_data_conversion ("Cray", "VAX D"); } static void -IEEE_little_float_to_VAX_D_float (float * /* d */, int /* len */) +IEEE_little_float_to_VAX_D_float (void * /* d */, int /* len */) { gripe_data_conversion ("IEEE little endian", "VAX D"); } static void -IEEE_big_float_to_VAX_D_float (float * /* d */, int /* len */) +IEEE_big_float_to_VAX_D_float (void * /* d */, int /* len */) { gripe_data_conversion ("IEEE big endian", "VAX D"); } static void -VAX_G_float_to_VAX_D_float (float * /* d */, int /* len */) +VAX_G_float_to_VAX_D_float (void * /* d */, int /* len */) { gripe_data_conversion ("VAX G float", "VAX D"); } static void -Cray_to_VAX_D_float (float * /* d */, int /* len */) +Cray_to_VAX_D_float (void * /* d */, int /* len */) { gripe_data_conversion ("Cray", "VAX D"); } static void -IEEE_little_double_to_VAX_G_double (double * /* d */, int /* len */) +IEEE_little_double_to_VAX_G_double (void * /* d */, int /* len */) { gripe_data_conversion ("IEEE little endian", "VAX G"); } static void -IEEE_big_double_to_VAX_G_double (double * /* d */, int /* len */) +IEEE_big_double_to_VAX_G_double (void * /* d */, int /* len */) { gripe_data_conversion ("IEEE big endian", "VAX G"); } static void -VAX_D_double_to_VAX_G_double (double * /* d */, int /* len */) +VAX_D_double_to_VAX_G_double (void * /* d */, int /* len */) { gripe_data_conversion ("VAX D float", "VAX G"); } static void -Cray_to_VAX_G_double (double * /* d */, int /* len */) +Cray_to_VAX_G_double (void * /* d */, int /* len */) { gripe_data_conversion ("VAX G float", "VAX G"); } static void -IEEE_little_float_to_VAX_G_float (float * /* d */, int /* len */) +IEEE_little_float_to_VAX_G_float (void * /* d */, int /* len */) { gripe_data_conversion ("IEEE little endian", "VAX G"); } static void -IEEE_big_float_to_VAX_G_float (float * /* d */, int /* len */) +IEEE_big_float_to_VAX_G_float (void * /* d */, int /* len */) { gripe_data_conversion ("IEEE big endian", "VAX G"); } static void -VAX_D_float_to_VAX_G_float (float * /* d */, int /* len */) +VAX_D_float_to_VAX_G_float (void * /* d */, int /* len */) { gripe_data_conversion ("VAX D float", "VAX G"); } static void -Cray_to_VAX_G_float (float * /* d */, int /* len */) +Cray_to_VAX_G_float (void * /* d */, int /* len */) { gripe_data_conversion ("VAX G float", "VAX G"); } void -do_double_format_conversion (double *data, int len, - oct_mach_info::float_format fmt) +do_double_format_conversion (void *data, int len, + oct_mach_info::float_format from_fmt, + oct_mach_info::float_format to_fmt) { - switch (oct_mach_info::native_float_format ()) + switch (to_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: - switch (fmt) + switch (from_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: break; @@ -473,7 +746,7 @@ break; case oct_mach_info::flt_fmt_ieee_big_endian: - switch (fmt) + switch (from_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: IEEE_little_double_to_IEEE_big_double (data, len); @@ -501,7 +774,7 @@ break; case oct_mach_info::flt_fmt_vax_d: - switch (fmt) + switch (from_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: IEEE_little_double_to_VAX_D_double (data, len); @@ -529,7 +802,7 @@ break; case oct_mach_info::flt_fmt_vax_g: - switch (fmt) + switch (from_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: IEEE_little_double_to_VAX_G_double (data, len); @@ -565,13 +838,14 @@ } void -do_float_format_conversion (float *data, int len, - oct_mach_info::float_format fmt) +do_float_format_conversion (void *data, int len, + oct_mach_info::float_format from_fmt, + oct_mach_info::float_format to_fmt) { - switch (oct_mach_info::native_float_format ()) + switch (to_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: - switch (fmt) + switch (from_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: break; @@ -599,7 +873,7 @@ break; case oct_mach_info::flt_fmt_ieee_big_endian: - switch (fmt) + switch (from_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: IEEE_little_float_to_IEEE_big_float (data, len); @@ -627,7 +901,7 @@ break; case oct_mach_info::flt_fmt_vax_d: - switch (fmt) + switch (from_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: IEEE_little_float_to_VAX_D_float (data, len); @@ -655,7 +929,7 @@ break; case oct_mach_info::flt_fmt_vax_g: - switch (fmt) + switch (from_fmt) { case oct_mach_info::flt_fmt_ieee_little_endian: IEEE_little_float_to_VAX_G_float (data, len); @@ -691,8 +965,32 @@ } void +do_float_format_conversion (void *data, size_t sz, int len, + oct_mach_info::float_format from_fmt, + oct_mach_info::float_format to_fmt) +{ + switch (sz) + { + case sizeof (float): + do_float_format_conversion (data, len, from_fmt, to_fmt); + break; + + case sizeof (double): + do_double_format_conversion (data, len, from_fmt, to_fmt); + break; + + default: + (*current_liboctave_error_handler) + ("impossible state reached in file `%s' at line %d", + __FILE__, __LINE__); + break; + } +} + + +void read_doubles (std::istream& is, double *data, save_type type, int len, - int swap, oct_mach_info::float_format fmt) + bool swap, oct_mach_info::float_format fmt) { switch (type) { @@ -724,7 +1022,7 @@ { volatile float *ptr = X_CAST (float *, data); is.read (X_CAST (char *, data), 4 * len); - do_float_format_conversion (X_CAST (float *, data), len, fmt); + do_float_format_conversion (data, len, fmt); float tmp = ptr[0]; for (int i = len - 1; i > 0; i--) data[i] = ptr[i];
--- a/liboctave/data-conv.h +++ b/liboctave/data-conv.h @@ -66,23 +66,41 @@ enum data_type { - dt_unknown, - dt_char, - dt_schar, - dt_uchar, - dt_short, - dt_ushort, - dt_int, - dt_uint, - dt_long, - dt_ulong, - dt_float, - dt_double, - dt_float_complex, - dt_double_complex + dt_int8 = 0, + dt_uint8 = 1, + dt_int16 = 2, + dt_uint16 = 3, + dt_int32 = 4, + dt_uint32 = 5, + dt_int64 = 6, + dt_uint64 = 7, + dt_single = 8, + dt_double = 9, + dt_char = 10, + dt_schar = 11, + dt_uchar = 12, + dt_short = 13, + dt_ushort = 14, + dt_int = 15, + dt_uint = 16, + dt_long = 17, + dt_ulong = 18, + dt_longlong = 19, + dt_ulonglong = 20, + dt_float = 21, + dt_unknown = 22 // Must be last, have largest value! }; static data_type string_to_data_type (const std::string& s); + + static void string_to_data_type (const std::string& s, int& block_size, + data_type& input_type, + data_type& output_type); + + static void string_to_data_type (const std::string& s, int& block_size, + data_type& output_type); + + static std::string data_type_as_string (data_type dt); }; // Add new entries to the end of this enum, otherwise Octave will not @@ -104,16 +122,26 @@ }; extern void -do_double_format_conversion (double *data, int len, - oct_mach_info::float_format fmt); +do_double_format_conversion (void *data, int len, + oct_mach_info::float_format from_fmt, + oct_mach_info::float_format to_fmt + = oct_mach_info::native_float_format ()); extern void -do_float_format_conversion (float *data, int len, - oct_mach_info::float_format fmt); +do_float_format_conversion (void *data, int len, + oct_mach_info::float_format from_fmt, + oct_mach_info::float_format to_fmt + = oct_mach_info::native_float_format ()); + +extern void +do_float_format_conversion (void *data, size_t sz, int len, + oct_mach_info::float_format from_fmt, + oct_mach_info::float_format to_fmt + = oct_mach_info::native_float_format ()); extern void read_doubles (std::istream& is, double *data, save_type type, int len, - int swap, oct_mach_info::float_format fmt); + bool swap, oct_mach_info::float_format fmt); extern void write_doubles (std::ostream& os, const double *data, save_type type, int len);
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,38 @@ +2004-08-31 John W. Eaton <jwe@octave.org> + + * ls-mat5.cc (read_int): New function. + + * oct-stream.cc (octave_base_stream::do_read, + octave_base_stream::read, octave_base_stream::write): Delete. + * oct-stream.h: Delete decls. + + * oct-stream.cc (octave_stream::read): Handle block_size and + separate input/output types. + (octave_stream::write): Handle block_size and various input types. + (octave_type_traits, octave_array_type_traits): New traits classes. + (do_read): New templates to read data and perform type conversion. + (octave_stream::write (const Array<T>&, int, + oct_data_conv::data_type, int, oct_mach_info::float_format), + do_write, write_int): + New templates to write ints and perform type conversion. + Instantiate for various Octave types. + + * ov.cc (octave_value::write): New function. + * ov.h: Provide decl. + * ov-base.cc (octave_base_value::write): New function. + * ov-base.h: Provide decl. + * ov-complex.h (octave_complex::write): New function. + * ov-cx-mat.h (octave_complex_matrix::write): New function. + * ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::write): New function. + (OCTAVE_VALUE_INT_SCALAR_T::write): New function. + * ov-re-mat.h (octave_matrix::write): New function. + * ov-scalar.h (octave_scalar::write): New function. + * ov-str-mat.h (octave_char_matrix_str::write): New function. + + * file-io.cc (Ffread): Handle block size, to/from format in + precision argument. + (Ffwrite): Handle block size in precision argument. + 2004-08-25 David Bateman <dbateman@free.fr> * ov-cell.cc (octave_cell::subsasgn): Delete elements of cell array
--- a/src/file-io.cc +++ b/src/file-io.cc @@ -1129,8 +1129,12 @@ if (! error_state) { - oct_data_conv::data_type dt - = oct_data_conv::string_to_data_type (prec); + int block_size = 1; + oct_data_conv::data_type input_type; + oct_data_conv::data_type output_type; + + oct_data_conv::string_to_data_type (prec, block_size, + input_type, output_type); if (! error_state) { @@ -1146,7 +1150,8 @@ = oct_mach_info::string_to_float_format (arch); if (! error_state) - retval = os.read (size, dt, skip, flt_fmt, count); + retval = os.read (size, block_size, input_type, + output_type, skip, flt_fmt, count); } else ::error ("fread: architecture type must be a string"); @@ -1200,73 +1205,113 @@ data to read and may be one of\n\ \n\ @table @code\n\ -@item \"char\"\n\ -@itemx \"char*1\"\n\ -@itemx \"integer*1\"\n\ -@itemx \"int8\"\n\ -Single character.\n\ -\n\ -@item \"signed char\"\n\ -@itemx \"schar\"\n\ +@item \"schar\"\n\ +@itemx \"signed char\"\n\ Signed character.\n\ \n\ -@item \"unsigned char\"\n\ -@itemx \"uchar\"\n\ -@itemx \"uint8\"\n\ +@item \"uchar\"\n\ +@itemx \"unsigned char\"\n\ Unsigned character.\n\ \n\ -@item \"short\"\n\ -Short integer.\n\ +@item \"int8\"\n\ +@itemx \"integer*1\"\n\ +\n\ +8-bit signed integer.\n\ \n\ -@item \"unsigned short\"\n\ -@itemx \"ushort\"\n\ -Unsigned short integer.\n\ +@item \"int16\"\n\ +@itemx \"integer*2\"\n\ +16-bit signed integer.\n\ \n\ -@item \"int\"\n\ -Integer.\n\ +@item \"int32\"\n\ +@itemx \"integer*4\"\n\ +32-bit signed integer.\n\ \n\ -@item \"unsigned int\"\n\ -@itemx \"uint\"\n\ -Unsigned integer.\n\ +@item \"int64\"\n\ +@itemx \"integer*8\"\n\ +64-bit signed integer.\n\ +\n\ +@item \"uint8\"\n\ +8-bit unsigned integer.\n\ \n\ -@item \"long\"\n\ -Long integer.\n\ +@item \"uint16\"\n\ +16-bit unsigned integer.\n\ \n\ -@item \"unsigned long\"\n\ -@itemx \"ulong\"\n\ -Unsigned long integer.\n\ +@item \"uint32\"\n\ +32-bit unsigned integer.\n\ \n\ -@item \"float\"\n\ +@item \"uint64\"\n\ +64-bit unsigned integer.\n\ +\n\ +@item \"single\"\n\ @itemx \"float32\"\n\ @itemx \"real*4\"\n\ -Single precision float.\n\ +32-bit floating point number.\n\ \n\ @item \"double\"\n\ @itemx \"float64\"\n\ @itemx \"real*8\"\n\ -Double precision float.\n\ +64-bit floating point number.\n\ +\n\ +@item \"char\"\n\ +@itemx \"char*1\"\n\ +Single character.\n\ \n\ -@item \"integer*2\"\n\ -@itemx \"int16\"\n\ -Two byte signed integer.\n\ +@item \"short\"\n\ +Short integer (size is platform dependent).\n\ +\n\ +@item \"int\"\n\ +Integer (size is platform dependent).\n\ +\n\ +@item \"long\"\n\ +Long integer (size is platform dependent).\n\ \n\ -@item \"integer*4\"\n\ -@itemx \"int32\"\n\ -Four byte signed integer.\n\ +@item \"ushort\"\n\ +@itemx \"unsigned short\"\n\ +Unsigned short integer (size is platform dependent).\n\ \n\ -@item \"uint16\"\n\ -Two byte unsigned integer.\n\ +@item \"uint\"\n\ +@itemx \"unsigned int\"\n\ +Unsigned integer (size is platform dependent).\n\ \n\ -@item \"uint32\"\n\ -Four byte unsigned integer.\n\ +@item \"ulong\"\n\ +@itemx \"unsigned long\"\n\ +Unsigned long integer (size is platform dependent).\n\ +\n\ +@item \"float\"\n\ +Single precision floating point number (size is platform dependent).\n\ @end table\n\ \n\ @noindent\n\ The default precision is @code{\"uchar\"}.\n\ \n\ +The @var{precision} argument may also specify an optional repeat\n\ +count. For example, @samp{32*single} causes @code{fread} to read\n\ +a block of 32 single precision floating point numbers. Reading in\n\ +blocks is useful in combination with the @var{skip} argument.\n\ +\n\ +The @var{precision} argument may also specify a type conversion.\n\ +For example, @samp{int16=>int32} causes @code{fread} to read 16-bit\n\ +integer values and return an array of 32-bit integer values. By\n\ +default, @code{fread} returns a double precision array. The special\n\ +form @samp{*TYPE} is shorthand for @samp{TYPE=>TYPE}.\n\ +\n\ +The conversion and repeat counts may be combined. For example,\n\ +@samp{32*single=>single} causes @code{fread} to read blocks of single\n\ +precision floating point values and return an array of single precision\n\ +values instead of the default array of double precision values.\n\ +\n\ The optional argument @var{skip} specifies the number of bytes to skip\n\ -after each element is read. If it is not specified, a value of 0 is\n\ -assumed.\n\ +after each element (or block of elements) is read. If it is not\n\ +specified, a value of 0 is assumed. If the final block read is not\n\ +complete, the final skip is omitted. For example,\n\ +\n\ +@example\n\ +fread (f, 10, \"3*single=>single\", 8)\n\ +@end example\n\ +\n\ +@noindent\n\ +will omit the final 8-byte skip because the last read will not be\n\ +a complete block of 3 values.\n\ \n\ The optional argument @var{arch} is a string specifying the data format\n\ for the file. Valid values are\n\ @@ -1356,8 +1401,10 @@ if (! error_state) { - oct_data_conv::data_type dt - = oct_data_conv::string_to_data_type (prec); + int block_size = 1; + oct_data_conv::data_type output_type; + + oct_data_conv::string_to_data_type (prec, block_size, output_type); if (! error_state) { @@ -1373,7 +1420,8 @@ = oct_mach_info::string_to_float_format (arch); if (! error_state) - retval = os.write (data, dt, skip, flt_fmt); + retval = os.write (data, block_size, output_type, + skip, flt_fmt); } else ::error ("fwrite: architecture type must be a string");
--- a/src/ls-mat4.cc +++ b/src/ls-mat4.cc @@ -155,11 +155,11 @@ if (swap) { - swap_4_bytes (X_CAST (char *, &mopt)); - swap_4_bytes (X_CAST (char *, &nr)); - swap_4_bytes (X_CAST (char *, &nc)); - swap_4_bytes (X_CAST (char *, &imag)); - swap_4_bytes (X_CAST (char *, &len)); + swap_bytes<4> (&mopt); + swap_bytes<4> (&nr); + swap_bytes<4> (&nc); + swap_bytes<4> (&imag); + swap_bytes<4> (&len); } if (mopt > 9999 || mopt < 0 || imag > 1 || imag < 0)
--- a/src/ls-mat5.cc +++ b/src/ls-mat5.cc @@ -172,7 +172,7 @@ goto data_read_error; if (swap) - swap_4_bytes ((char *)&temp); + swap_bytes<4> (&temp); upper = (temp >> 16) & 0xffff; type = temp & 0xffff; @@ -187,7 +187,7 @@ if (! is.read (X_CAST (char *, &temp), 4 )) goto data_read_error; if (swap) - swap_4_bytes ((char *)&temp); + swap_bytes<4> (&temp); bytes = temp; } @@ -197,6 +197,15 @@ return 1; } +static void +read_int (std::istream& is, bool swap, FOUR_BYTE_INT& val) +{ + is.read (reinterpret_cast<char *> (&val), 4); + + if (swap) + swap_bytes<4> (&val); +} + // Extract one data element (scalar, matrix, string, etc.) from stream // IS and place it in TC, returning the name of the variable. // @@ -378,7 +387,7 @@ goto data_read_error; if (swap) - swap_4_bytes ((char *)&field_name_length); + swap_bytes<4> (&field_name_length); // field name subelement. The length of this subelement tells // us how many fields there are.
--- a/src/ls-oct-binary.cc +++ b/src/ls-oct-binary.cc @@ -153,7 +153,7 @@ if (! is) return retval; if (swap) - swap_4_bytes (X_CAST (char *, &name_len)); + swap_bytes<4> (&name_len); { OCTAVE_LOCAL_BUFFER (char, name, name_len+1); @@ -167,7 +167,7 @@ if (! is) goto data_read_error; if (swap) - swap_4_bytes (X_CAST (char *, &doc_len)); + swap_bytes<4> (&doc_len); { OCTAVE_LOCAL_BUFFER (char, tdoc, doc_len+1); @@ -213,7 +213,7 @@ if (! is.read (X_CAST (char *, &len), 4)) goto data_read_error; if (swap) - swap_4_bytes (X_CAST (char *, &len)); + swap_bytes<4> (&len); OCTAVE_LOCAL_BUFFER (char, s, len+1); if (! is.read (X_CAST (char *, s), len)) goto data_read_error; @@ -240,7 +240,7 @@ if (! is.read (X_CAST (char *, &len), 4)) goto data_read_error; if (swap) - swap_4_bytes (X_CAST (char *, &len)); + swap_bytes<4> (&len); OCTAVE_LOCAL_BUFFER (char, s, len+1); if (! is.read (X_CAST (char *, s), len)) goto data_read_error;
--- a/src/oct-stream.cc +++ b/src/oct-stream.cc @@ -31,6 +31,13 @@ #include <fstream> #include <string> +#include <Array.h> +#include <Array2.h> +#include <Array3.h> + +#include <Array.cc> + +#include "byte-swap.h" #include "lo-ieee.h" #include "lo-mappers.h" #include "lo-sstream.h" @@ -1032,48 +1039,6 @@ return do_gets (max_len, err, false, who); } -octave_value -octave_base_stream::read (const Array<double>& size, - oct_data_conv::data_type dt, int skip, - oct_mach_info::float_format ffmt, - int& char_count) -{ - Matrix retval; - - char_count = 0; - - std::istream *isp = input_stream (); - - if (isp) - { - std::istream& is = *isp; - - int nr = -1; - int nc = -1; - - bool ignore; - - get_size (size, nr, nc, ignore, "fread"); - - if (! error_state) - { - if (ffmt == oct_mach_info::flt_fmt_unknown) - ffmt = float_format (); - - int tmp = retval.read (is, nr, nc, dt, skip, ffmt); - - if (tmp < 0) - error ("fread: read error"); - else - char_count = tmp; - } - } - else - invalid_operation ("fread", "reading"); - - return retval; -} - #if defined (__GNUG__) && ! defined (CXX_ISO_COMPLIANT_LIBRARY) #define OCTAVE_SCAN(is, fmt, arg) is.scan ((fmt).text, arg) @@ -2092,49 +2057,6 @@ return retval; } -int -octave_base_stream::write (const octave_value& data, - oct_data_conv::data_type dt, int skip, - oct_mach_info::float_format ffmt) -{ - int retval = -1; - - std::ostream *osp = output_stream (); - - if (osp) - { - std::ostream& os = *osp; - - int status = 0; - - // XXX FIXME XXX -- the octave_value class should probably have - // a write method that would handle the dispatch for us? - // - // If DATA is a character matrix, then it is a bit of a kluge to - // force it to be a double matrix and then write it out as uchar - // data, but this is the quick fix... - - Matrix mval = data.matrix_value (true); - - if (! error_state) - { - if (ffmt == oct_mach_info::flt_fmt_unknown) - ffmt = float_format (); - - status = mval.write (os, dt, skip, ffmt); - - if (status < 0) - error ("fwrite: write error"); - else - retval = status; - } - } - else - invalid_operation ("fwrite", "writing"); - - return retval; -} - class printf_value_cache { @@ -2848,32 +2770,646 @@ rep->close (); } +// XXX FIXME XXX -- these trait classes probably belong somehwere else... + +template <typename T> +class +octave_type_traits +{ +public: + typedef T val_type; +}; + +#define OCTAVE_TYPE_TRAIT(T, VAL_T) \ + template <> \ + class \ + octave_type_traits<T> \ + { \ + public: \ + typedef VAL_T val_type; \ + } + +OCTAVE_TYPE_TRAIT (octave_int8, octave_int8::val_type); +OCTAVE_TYPE_TRAIT (octave_uint8, octave_uint8::val_type); +OCTAVE_TYPE_TRAIT (octave_int16, octave_int16::val_type); +OCTAVE_TYPE_TRAIT (octave_uint16, octave_uint16::val_type); +OCTAVE_TYPE_TRAIT (octave_int32, octave_int32::val_type); +OCTAVE_TYPE_TRAIT (octave_uint32, octave_uint32::val_type); +OCTAVE_TYPE_TRAIT (octave_int64, octave_int64::val_type); +OCTAVE_TYPE_TRAIT (octave_uint64, octave_uint64::val_type); + +template <typename T> +class octave_array_type_traits +{ +public: + typedef T element_type; +}; + +#define OCTAVE_ARRAY_TYPE_TRAIT(T, ELT_T) \ + template <> \ + class \ + octave_array_type_traits<T> \ + { \ + public: \ + typedef ELT_T element_type; \ + } + +OCTAVE_ARRAY_TYPE_TRAIT (charNDArray, char); +OCTAVE_ARRAY_TYPE_TRAIT (int8NDArray, octave_int8); +OCTAVE_ARRAY_TYPE_TRAIT (uint8NDArray, octave_uint8); +OCTAVE_ARRAY_TYPE_TRAIT (int16NDArray, octave_int16); +OCTAVE_ARRAY_TYPE_TRAIT (uint16NDArray, octave_uint16); +OCTAVE_ARRAY_TYPE_TRAIT (int32NDArray, octave_int32); +OCTAVE_ARRAY_TYPE_TRAIT (uint32NDArray, octave_uint32); +OCTAVE_ARRAY_TYPE_TRAIT (int64NDArray, octave_int64); +OCTAVE_ARRAY_TYPE_TRAIT (uint64NDArray, octave_uint64); +OCTAVE_ARRAY_TYPE_TRAIT (NDArray, double); + +template <class RET_T, class READ_T> octave_value -octave_stream::read (const Array<double>& size, - oct_data_conv::data_type dt, int skip, - oct_mach_info::float_format flt_fmt, int& count) +do_read (octave_stream& strm, int nr, int nc, int block_size, + int skip, bool do_float_fmt_conv, + oct_mach_info::float_format from_flt_fmt, int& count) { octave_value retval; + RET_T nda; + + bool ok = true; + + count = 0; + + typename octave_array_type_traits<RET_T>::element_type elt_zero + = typename octave_array_type_traits<RET_T>::element_type (); + + typename octave_array_type_traits<RET_T>::element_type *dat = 0; + + int max_size = 0; + + int final_nr = 0; + int final_nc = 0; + + if (nr > 0) + { + if (nc > 0) + { + nda.resize (dim_vector (nr, nc), elt_zero); + dat = nda.fortran_vec (); + max_size = nr * nc; + } + else + { + nda.resize (dim_vector (nr, 32), elt_zero); + dat = nda.fortran_vec (); + max_size = nr * 32; + } + } + else + { + nda.resize (dim_vector (32, 1), elt_zero); + dat = nda.fortran_vec (); + max_size = 32; + } + + // XXX FIXME XXX -- byte order for Cray? + + bool swap = false; + + if (oct_mach_info::words_big_endian ()) + swap = (from_flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian + || from_flt_fmt == oct_mach_info::flt_fmt_vax_g + || from_flt_fmt == oct_mach_info::flt_fmt_vax_g); + else + swap = (from_flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); + + union + { + char buf[sizeof (typename octave_type_traits<READ_T>::val_type)]; + typename octave_type_traits<READ_T>::val_type val; + } u; + + std::istream *isp = strm.input_stream (); + + if (isp) + { + std::istream& is = *isp; + + int elts_read = 0; + + for (;;) + { + // XXX FIXME XXX -- maybe there should be a special case for + // skip == 0. + + if (is) + { + if (nr > 0 && nc > 0 && count == max_size) + { + final_nr = nr; + final_nc = nc; + + break; + } + + is.read (u.buf, sizeof (typename octave_type_traits<READ_T>::val_type)); + + // We only swap bytes for integer types. For float + // types, the format conversion will also handle byte + // swapping. + + if (swap) + swap_bytes<sizeof (typename octave_type_traits<READ_T>::val_type)> (u.buf); + else if (do_float_fmt_conv) + do_float_format_conversion + (u.buf, + sizeof (typename octave_type_traits<READ_T>::val_type), + 1, from_flt_fmt, oct_mach_info::float_format ()); + + typename octave_array_type_traits<RET_T>::element_type tmp + = static_cast <typename octave_array_type_traits<RET_T>::element_type> (u.val); + + if (ok) + { + if (is) + { + if (count == max_size) + { + max_size *= 2; + + if (nr > 0) + nda.resize (dim_vector (nr, max_size / nr), + elt_zero); + else + nda.resize (dim_vector (max_size, 1), elt_zero); + + dat = nda.fortran_vec (); + } + + dat[count++] = tmp; + + elts_read++; + } + + if (skip != 0 && elts_read == block_size) + { + strm.seek (skip, SEEK_CUR); + elts_read = 0; + } + + if (is.eof ()) + { + if (nr > 0) + { + if (count > nr) + { + final_nr = nr; + final_nc = (count - 1) / nr + 1; + } + else + { + final_nr = count; + final_nc = 1; + } + } + else + { + final_nr = count; + final_nc = 1; + } + + break; + } + } + else + { + ok = false; + break; + } + } + else + { + ok = false; + break; + } + } + } + + if (ok) + { + nda.resize (dim_vector (final_nr, final_nc), elt_zero); + + retval = nda; + } + + return retval; +} + +#define DO_READ_VAL_TEMPLATE(RET_T, READ_T) \ + template octave_value \ + do_read<RET_T, READ_T> (octave_stream&, int, int, int, int, bool, \ + oct_mach_info::float_format, int&) + +// XXX FIXME XXX -- should we only have float if it is a different +// size from double? + +#define INSTANTIATE_DO_READ(VAL_T) \ + DO_READ_VAL_TEMPLATE (VAL_T, octave_int8); \ + DO_READ_VAL_TEMPLATE (VAL_T, octave_uint8); \ + DO_READ_VAL_TEMPLATE (VAL_T, octave_int16); \ + DO_READ_VAL_TEMPLATE (VAL_T, octave_uint16); \ + DO_READ_VAL_TEMPLATE (VAL_T, octave_int32); \ + DO_READ_VAL_TEMPLATE (VAL_T, octave_uint32); \ + DO_READ_VAL_TEMPLATE (VAL_T, octave_int64); \ + DO_READ_VAL_TEMPLATE (VAL_T, octave_uint64); \ + DO_READ_VAL_TEMPLATE (VAL_T, float); \ + DO_READ_VAL_TEMPLATE (VAL_T, double); \ + DO_READ_VAL_TEMPLATE (VAL_T, char); \ + DO_READ_VAL_TEMPLATE (VAL_T, signed char); \ + DO_READ_VAL_TEMPLATE (VAL_T, unsigned char) + +INSTANTIATE_DO_READ(int8NDArray); +INSTANTIATE_DO_READ(uint8NDArray); +INSTANTIATE_DO_READ(int16NDArray); +INSTANTIATE_DO_READ(uint16NDArray); +INSTANTIATE_DO_READ(int32NDArray); +INSTANTIATE_DO_READ(uint32NDArray); +INSTANTIATE_DO_READ(int64NDArray); +INSTANTIATE_DO_READ(uint64NDArray); +// INSTANTIATE_DO_READ(floatNDArray); +INSTANTIATE_DO_READ(NDArray); +INSTANTIATE_DO_READ(charNDArray); + +typedef octave_value (*read_fptr) (octave_stream&, int, int, int, int, bool, + oct_mach_info::float_format ffmt, int&); + +INSTANTIATE_ARRAY (read_fptr); +template class Array2<read_fptr>; + +#define FILL_TABLE_ROW(R, VAL_T) \ + read_fptr_table(R,oct_data_conv::dt_int8) = do_read<VAL_T, octave_int8>; \ + read_fptr_table(R,oct_data_conv::dt_uint8) = do_read<VAL_T, octave_uint8>; \ + read_fptr_table(R,oct_data_conv::dt_int16) = do_read<VAL_T, octave_int16>; \ + read_fptr_table(R,oct_data_conv::dt_uint16) = do_read<VAL_T, octave_uint16>; \ + read_fptr_table(R,oct_data_conv::dt_int32) = do_read<VAL_T, octave_int32>; \ + read_fptr_table(R,oct_data_conv::dt_uint32) = do_read<VAL_T, octave_uint32>; \ + read_fptr_table(R,oct_data_conv::dt_int64) = do_read<VAL_T, octave_int64>; \ + read_fptr_table(R,oct_data_conv::dt_uint64) = do_read<VAL_T, octave_uint64>; \ + read_fptr_table(R,oct_data_conv::dt_single) = do_read<VAL_T, float>; \ + read_fptr_table(R,oct_data_conv::dt_double) = do_read<VAL_T, double>; \ + read_fptr_table(R,oct_data_conv::dt_char) = do_read<VAL_T, char>; \ + read_fptr_table(R,oct_data_conv::dt_schar) = do_read<VAL_T, signed char>; \ + read_fptr_table(R,oct_data_conv::dt_uchar) = do_read<VAL_T, unsigned char> + +octave_value +octave_stream::read (const Array<double>& size, int block_size, + oct_data_conv::data_type input_type, + oct_data_conv::data_type output_type, + int skip, oct_mach_info::float_format ffmt, + int& char_count) +{ + static bool initialized = false; + + // Table function pointers for return types x read types. + + static Array2<read_fptr> read_fptr_table (oct_data_conv::dt_unknown, 13, 0); + + if (! initialized) + { + FILL_TABLE_ROW (oct_data_conv::dt_int8, int8NDArray); + FILL_TABLE_ROW (oct_data_conv::dt_uint8, uint8NDArray); + FILL_TABLE_ROW (oct_data_conv::dt_int16, int16NDArray); + FILL_TABLE_ROW (oct_data_conv::dt_uint16, uint16NDArray); + FILL_TABLE_ROW (oct_data_conv::dt_int32, int32NDArray); + FILL_TABLE_ROW (oct_data_conv::dt_uint32, uint32NDArray); + FILL_TABLE_ROW (oct_data_conv::dt_int64, int64NDArray); + FILL_TABLE_ROW (oct_data_conv::dt_uint64, uint64NDArray); + FILL_TABLE_ROW (oct_data_conv::dt_double, NDArray); + FILL_TABLE_ROW (oct_data_conv::dt_char, charNDArray); + FILL_TABLE_ROW (oct_data_conv::dt_schar, charNDArray); + FILL_TABLE_ROW (oct_data_conv::dt_uchar, charNDArray); + + initialized = true; + } + + octave_value retval; + if (stream_ok ("fread")) - retval = rep->read (size, dt, skip, flt_fmt, count); + { + // XXX FIXME XXX -- we may eventually want to make this extensible. + + // XXX FIXME XXX -- we need a better way to ensure that this + // numbering stays consistent with the order of the elements in the + // data_type enum in the oct_data_conv class. + + char_count = 0; + + int nr = -1; + int nc = -1; + + bool ignore; + + get_size (size, nr, nc, ignore, "fread"); + + if (! error_state) + { + if (nr == 0 || nc == 0) + retval = Matrix (nr, nc); + else + { + if (ffmt == oct_mach_info::flt_fmt_unknown) + ffmt = float_format (); + + read_fptr fcn = read_fptr_table (output_type, input_type); + + bool do_float_fmt_conv = ((input_type == oct_data_conv::dt_double + || input_type == oct_data_conv::dt_single) + && ffmt != float_format ()); + + if (fcn) + { + retval = (*fcn) (*this, nr, nc, block_size, skip, + do_float_fmt_conv, ffmt, char_count); + + // XXX FIXME XXX -- kluge! + + if (! error_state + && (output_type == oct_data_conv::dt_char + || output_type == oct_data_conv::dt_schar + || output_type == oct_data_conv::dt_uchar)) + retval = octave_value (retval.char_matrix_value (), true); + } + else + error ("fread: unable to read and convert requested types"); + } + } + else + invalid_operation ("fread", "reading"); + } return retval; } int -octave_stream::write (const octave_value& data, - oct_data_conv::data_type dt, int skip, +octave_stream::write (const octave_value& data, int block_size, + oct_data_conv::data_type output_type, int skip, oct_mach_info::float_format flt_fmt) { int retval = -1; if (stream_ok ("fwrite")) - retval = rep->write (data, dt, skip, flt_fmt); + { + if (! error_state) + { + if (flt_fmt == oct_mach_info::flt_fmt_unknown) + flt_fmt = float_format (); + + int status = data.write (*this, block_size, output_type, + skip, flt_fmt); + + if (status < 0) + error ("fwrite: write error"); + else + retval = status; + } + else + invalid_operation ("fwrite", "writing"); + } return retval; } +template <class T> +void +write_int (std::ostream& os, bool swap, const T& val) +{ + typename octave_type_traits<T>::val_type tmp = val.value (); + + if (swap) + swap_bytes<sizeof (typename octave_type_traits<T>::val_type)> (&tmp); + + os.write (reinterpret_cast<const char *> (&tmp), + sizeof (typename octave_type_traits<T>::val_type)); +} + +template void write_int (std::ostream&, bool, const octave_int8&); +template void write_int (std::ostream&, bool, const octave_uint8&); +template void write_int (std::ostream&, bool, const octave_int16&); +template void write_int (std::ostream&, bool, const octave_uint16&); +template void write_int (std::ostream&, bool, const octave_int32&); +template void write_int (std::ostream&, bool, const octave_uint32&); +template void write_int (std::ostream&, bool, const octave_int64&); +template void write_int (std::ostream&, bool, const octave_uint64&); + +template <class T> +static inline bool +do_write (std::ostream& os, const T& val, oct_data_conv::data_type output_type, + oct_mach_info::float_format flt_fmt, bool swap, + bool do_float_conversion) +{ + bool retval = true; + + // For compatibility, Octave converts to the output type, then + // writes. This means that truncation happens on the conversion. + // For example, the following program prints 0: + // + // x = int8 (-1) + // f = fopen ("foo.dat", "w"); + // fwrite (f, x, "unsigned char"); + // fclose (f); + // f = fopen ("foo.dat", "r"); + // y = fread (f, 1, "unsigned char"); + // printf ("%d\n", y); + + switch (output_type) + { + case oct_data_conv::dt_char: + case oct_data_conv::dt_schar: + case oct_data_conv::dt_int8: + write_int (os, swap, octave_int8 (val)); + break; + + case oct_data_conv::dt_uchar: + case oct_data_conv::dt_uint8: + write_int (os, swap, octave_uint8 (val)); + break; + + case oct_data_conv::dt_int16: + write_int (os, swap, octave_int16 (val)); + break; + + case oct_data_conv::dt_uint16: + write_int (os, swap, octave_uint16 (val)); + break; + + case oct_data_conv::dt_int32: + write_int (os, swap, octave_int32 (val)); + break; + + case oct_data_conv::dt_uint32: + write_int (os, swap, octave_uint32 (val)); + break; + + case oct_data_conv::dt_int64: + write_int (os, swap, octave_int64 (val)); + break; + + case oct_data_conv::dt_uint64: + write_int (os, swap, octave_uint64 (val)); + break; + + case oct_data_conv::dt_single: + { + float f = static_cast<float> (val); + + if (do_float_conversion) + do_float_format_conversion (&f, 1, flt_fmt); + + os.write (reinterpret_cast<const char *> (&f), sizeof (float)); + } + break; + + case oct_data_conv::dt_double: + { + double d = static_cast<double> (val); + if (do_float_conversion) + do_double_format_conversion (&d, 1, flt_fmt); + + os.write (reinterpret_cast<const char *> (&d), sizeof (double)); + } + break; + + default: + retval = false; + (*current_liboctave_error_handler) + ("write: invalid type specification"); + break; + } + + return retval; +} + +template <class T> +int +octave_stream::write (const Array<T>& data, int block_size, + oct_data_conv::data_type output_type, + int skip, oct_mach_info::float_format flt_fmt) +{ + int retval = -1; + + bool status = true; + + int count = 0; + + const T *d = data.data (); + + int n = data.length (); + + oct_mach_info::float_format native_flt_fmt + = oct_mach_info::float_format (); + + bool do_float_conversion = (flt_fmt != native_flt_fmt); + + // XXX FIXME XXX -- byte order for Cray? + + bool swap = false; + + if (oct_mach_info::words_big_endian ()) + swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian + || flt_fmt == oct_mach_info::flt_fmt_vax_g + || flt_fmt == oct_mach_info::flt_fmt_vax_g); + else + swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); + + for (int i = 0; i < n; i++) + { + std::ostream *osp = output_stream (); + + if (osp) + { + std::ostream& os = *osp; + + if (skip != 0 && (i % block_size) == 0) + seek (skip, SEEK_CUR); + + if (os) + { + status = do_write (os, d[i], output_type, flt_fmt, swap, + do_float_conversion); + + if (os && status) + count++; + else + break; + } + else + { + status = false; + break; + } + } + else + { + status = false; + break; + } + } + + if (status) + retval = count; + + return retval; +} + +template int +octave_stream::write (const Array<char>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + +template int +octave_stream::write (const Array<double>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + +template int +octave_stream::write (const Array<octave_int8>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + +template int +octave_stream::write (const Array<octave_uint8>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + +template int +octave_stream::write (const Array<octave_int16>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + +template int +octave_stream::write (const Array<octave_uint16>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + +template int +octave_stream::write (const Array<octave_int32>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + +template int +octave_stream::write (const Array<octave_uint32>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + +template int +octave_stream::write (const Array<octave_int64>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + +template int +octave_stream::write (const Array<octave_uint64>&, int, + oct_data_conv::data_type, + int, oct_mach_info::float_format); + octave_value octave_stream::scanf (const std::string& fmt, const Array<double>& size, int& count, const std::string& who)
--- a/src/oct-stream.h +++ b/src/oct-stream.h @@ -432,14 +432,6 @@ std::string getl (int max_len, bool& err, const std::string& who /* = "getl" */); std::string gets (int max_len, bool& err, const std::string& who /* = "gets" */); - octave_value do_read (int nr, int nc, oct_data_conv::data_type dt, - int skip, oct_mach_info::float_format flt_fmt, - int& count); - - octave_value read (const Array<double>& size, oct_data_conv::data_type dt, - int skip, oct_mach_info::float_format flt_fmt, - int& count); - octave_value do_scanf (scanf_format_list& fmt_list, int nr, int nc, bool one_elt_size_spec, int& count, const std::string& who /* = "scanf" */); @@ -458,9 +450,6 @@ int flush (void); - int write (const octave_value& data, oct_data_conv::data_type dt, - int skip, oct_mach_info::float_format flt_fmt); - int do_printf (printf_format_list& fmt_list, const octave_value_list& args, const std::string& who /* = "printf" */); @@ -517,11 +506,19 @@ void close (void); - octave_value read (const Array<double>& size, oct_data_conv::data_type dt, + octave_value read (const Array<double>& size, int block_size, + oct_data_conv::data_type input_type, + oct_data_conv::data_type output_type, int skip, oct_mach_info::float_format flt_fmt, int& count); - int write (const octave_value& data, oct_data_conv::data_type dt, + int write (const octave_value& data, int block_size, + oct_data_conv::data_type output_type, + int skip, oct_mach_info::float_format flt_fmt); + + template <class T> + int write (const Array<T>&, int block_size, + oct_data_conv::data_type output_type, int skip, oct_mach_info::float_format flt_fmt); octave_value scanf (const std::string& fmt, const Array<double>& size, @@ -602,6 +599,12 @@ return retval; } + + void invalid_operation (const std::string& who, const char *rw) + { + if (rep) + rep->invalid_operation (who, rw); + } }; class
--- a/src/ov-base-int.cc +++ b/src/ov-base-int.cc @@ -42,6 +42,7 @@ #include "gripes.h" #include "oct-obj.h" #include "oct-lvalue.h" +#include "oct-stream.h" #include "ops.h" #include "ov-base.h" #include "ov-base-mat.h" @@ -158,7 +159,7 @@ if (! is.read (X_CAST (char *, &mdims), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &mdims)); + swap_bytes<4> (&mdims); if (mdims >= 0) return false; @@ -172,7 +173,7 @@ if (! is.read (X_CAST (char *, &di), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &di)); + swap_bytes<4> (&di); dv(i) = di; } @@ -189,13 +190,13 @@ switch (bytes) { case 8: - swap_8_bytes (X_CAST (char *, &m(i))); + swap_bytes<8> (&m(i)); break; case 4: - swap_4_bytes (X_CAST (char *, &m(i))); + swap_bytes<4> (&m(i)); break; case 2: - swap_2_bytes (X_CAST (char *, &m(i))); + swap_bytes<2> (&m(i)); break; case 1: default: @@ -361,13 +362,13 @@ switch (this->byte_size()) { case 8: - swap_8_bytes (X_CAST (char *, &tmp)); + swap_bytes<8> (&tmp); break; case 4: - swap_4_bytes (X_CAST (char *, &tmp)); + swap_bytes<4> (&tmp); break; case 2: - swap_2_bytes (X_CAST (char *, &tmp)); + swap_bytes<2> (&tmp); break; case 1: default: @@ -378,6 +379,7 @@ } #if defined (HAVE_HDF5) + template <class T> bool octave_base_int_scalar<T>::save_hdf5 (hid_t loc_id, const char *name, bool) @@ -438,6 +440,7 @@ return true; } + #endif /*
--- a/src/ov-base.cc +++ b/src/ov-base.cc @@ -725,6 +725,7 @@ } #if defined (HAVE_HDF5) + bool octave_base_value::save_hdf5 (hid_t, const char *, bool) { @@ -740,8 +741,18 @@ return false; } + #endif +int +octave_base_value::write (octave_stream&, int, oct_data_conv::data_type, + int, oct_mach_info::float_format) const +{ + gripe_wrong_type_arg ("octave_base_value::write()", type_name ()); + + return false; +} + CONVDECLX (matrix_conv) { return new octave_matrix ();
--- a/src/ov-base.h +++ b/src/ov-base.h @@ -308,6 +308,10 @@ bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug); #endif + int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const; + private: DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
--- a/src/ov-bool-mat.cc +++ b/src/ov-bool-mat.cc @@ -304,7 +304,7 @@ if (! is.read (X_CAST (char *, &mdims), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &mdims)); + swap_bytes<4> (&mdims); if (mdims >= 0) return false; @@ -321,7 +321,7 @@ if (! is.read (X_CAST (char *, &di), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &di)); + swap_bytes<4> (&di); dv(i) = di; } @@ -339,6 +339,7 @@ } #if defined (HAVE_HDF5) + bool octave_bool_matrix::save_hdf5 (hid_t loc_id, const char *name, bool /* save_as_floats */) @@ -447,6 +448,7 @@ return retval; } + #endif /*
--- a/src/ov-bool.cc +++ b/src/ov-bool.cc @@ -162,6 +162,7 @@ } #if defined (HAVE_HDF5) + bool octave_bool::save_hdf5 (hid_t loc_id, const char *name, bool /* save_as_floats */) @@ -220,6 +221,7 @@ return true; } + #endif /*
--- a/src/ov-cell.cc +++ b/src/ov-cell.cc @@ -634,7 +634,7 @@ if (! is.read (X_CAST (char *, &mdims), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &mdims)); + swap_bytes<4> (&mdims); if (mdims >= 0) return false; @@ -648,7 +648,7 @@ if (! is.read (X_CAST (char *, &di), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &di)); + swap_bytes<4> (&di); dv(i) = di; }
--- a/src/ov-complex.cc +++ b/src/ov-complex.cc @@ -33,6 +33,7 @@ #include "lo-ieee.h" #include "oct-obj.h" +#include "oct-stream.h" #include "ops.h" #include "ov-complex.h" #include "ov-base.h" @@ -236,6 +237,7 @@ } #if defined (HAVE_HDF5) + bool octave_complex::save_hdf5 (hid_t loc_id, const char *name, bool /* save_as_floats */) @@ -317,6 +319,7 @@ return retval; } + #endif /*
--- a/src/ov-complex.h +++ b/src/ov-complex.h @@ -96,7 +96,14 @@ NDArray array_value (bool = false) const; octave_value resize (const dim_vector& dv) const - { ComplexNDArray retval (dv); if (dv.numel()) retval(0) = scalar; return retval; } + { + ComplexNDArray retval (dv); + + if (dv.numel ()) + retval(0) = scalar; + + return retval; + } Complex complex_value (bool = false) const; @@ -124,6 +131,15 @@ bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug); #endif + int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const + { + // Yes, for compatibility, we drop the imaginary part here. + return os.write (array_value (true), block_size, output_type, + skip, flt_fmt); + } + private: DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-cx-mat.cc +++ b/src/ov-cx-mat.cc @@ -31,11 +31,14 @@ #include <iostream> #include <vector> +#include "data-conv.h" #include "lo-ieee.h" #include "mx-base.h" +#include "mach-info.h" #include "gripes.h" #include "oct-obj.h" +#include "oct-stream.h" #include "ops.h" #include "ov-base.h" #include "ov-base-mat.h" @@ -392,7 +395,7 @@ if (! is.read (X_CAST (char *, &mdims), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &mdims)); + swap_bytes<4> (&mdims); if (mdims < 0) { mdims = - mdims; @@ -405,7 +408,7 @@ if (! is.read (X_CAST (char *, &di), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &di)); + swap_bytes<4> (&di); dv(i) = di; } @@ -427,7 +430,7 @@ if (! is.read (X_CAST (char *, &nc), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &nc)); + swap_bytes<4> (&nc); if (! is.read (X_CAST (char *, &tmp), 1)) return false; ComplexMatrix m (nr, nc); @@ -443,6 +446,7 @@ } #if defined (HAVE_HDF5) + bool octave_complex_matrix::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats) @@ -598,6 +602,7 @@ return retval; } + #endif void
--- a/src/ov-cx-mat.h +++ b/src/ov-cx-mat.h @@ -37,6 +37,7 @@ #include "str-vec.h" #include "error.h" +#include "oct-stream.h" #include "ov-base.h" #include "ov-base-mat.h" #include "ov-typeinfo.h" @@ -127,6 +128,15 @@ bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug); #endif + int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const + { + // Yes, for compatibility, we drop the imaginary part here. + return os.write (matrix_value (true), block_size, output_type, + skip, flt_fmt); + } + void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const; private:
--- a/src/ov-intx.h +++ b/src/ov-intx.h @@ -31,6 +31,7 @@ #include "str-vec.h" #include "error.h" +#include "oct-stream.h" #include "ov-base.h" #include "ov-base-int.h" #include "ov-typeinfo.h" @@ -73,6 +74,11 @@ idx_vector index_vector (void) const { return idx_vector (matrix); } + int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const + { return os.write (matrix, block_size, output_type, skip, flt_fmt); } + private: DECLARE_OCTAVE_ALLOCATOR @@ -123,6 +129,14 @@ idx_vector index_vector (void) const { return idx_vector (scalar); } + int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const + { + return os.write (OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION (), + block_size, output_type, skip, flt_fmt); + } + private: DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-list.cc +++ b/src/ov-list.cc @@ -623,7 +623,7 @@ if (! is.read (X_CAST (char *, &len), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &len)); + swap_bytes<4> (&len); if (len > 0) { @@ -663,6 +663,7 @@ } #if defined (HAVE_HDF5) + bool octave_list::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats) { @@ -727,6 +728,7 @@ return retval; } + #endif /*
--- a/src/ov-range.cc +++ b/src/ov-range.cc @@ -342,21 +342,22 @@ if (! is.read (X_CAST (char *, &bas), 8)) return false; if (swap) - swap_8_bytes (X_CAST (char *, &bas)); + swap_bytes<8> (&bas); if (! is.read (X_CAST (char *, &lim), 8)) return false; if (swap) - swap_8_bytes (X_CAST (char *, &lim)); + swap_bytes<8> (&lim); if (! is.read (X_CAST (char *, &inc), 8)) return false; if (swap) - swap_8_bytes (X_CAST (char *, &inc)); + swap_bytes<8> (&inc); Range r (bas, lim, inc); range = r; return true; } #if defined (HAVE_HDF5) + // The following subroutines creates an HDF5 representation of the way // we will store Octave range types (triplets of floating-point numbers). // NUM_TYPE is the HDF5 numeric type to use for storage (e.g. @@ -461,6 +462,7 @@ return retval; } + #endif /*
--- a/src/ov-re-mat.cc +++ b/src/ov-re-mat.cc @@ -33,8 +33,10 @@ #include <iostream> #include <vector> +#include "data-conv.h" #include "lo-ieee.h" #include "lo-utils.h" +#include "mach-info.h" #include "mx-base.h" #include "quit.h" @@ -42,6 +44,7 @@ #include "gripes.h" #include "oct-obj.h" #include "oct-lvalue.h" +#include "oct-stream.h" #include "ops.h" #include "ov-base.h" #include "ov-base-mat.h" @@ -446,7 +449,7 @@ if (! is.read (X_CAST (char *, &mdims), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &mdims)); + swap_bytes<4> (&mdims); if (mdims < 0) { mdims = - mdims; @@ -459,7 +462,7 @@ if (! is.read (X_CAST (char *, &di), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &di)); + swap_bytes<4> (&di); dv(i) = di; } @@ -480,7 +483,7 @@ if (! is.read (X_CAST (char *, &nc), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &nc)); + swap_bytes<4> (&nc); if (! is.read (X_CAST (char *, &tmp), 1)) return false; Matrix m (nr, nc); @@ -495,6 +498,7 @@ } #if defined (HAVE_HDF5) + bool octave_matrix::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats) { @@ -618,6 +622,7 @@ return retval; } + #endif void
--- a/src/ov-re-mat.h +++ b/src/ov-re-mat.h @@ -38,6 +38,7 @@ #include "str-vec.h" #include "error.h" +#include "oct-stream.h" #include "ov-base.h" #include "ov-base-mat.h" #include "ov-typeinfo.h" @@ -136,6 +137,11 @@ bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug); #endif + int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const + { return os.write (matrix, block_size, output_type, skip, flt_fmt); } + private: DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-scalar.cc +++ b/src/ov-scalar.cc @@ -30,9 +30,13 @@ #include <iostream> +#include "data-conv.h" +#include "mach-info.h" + #include "defun.h" #include "gripes.h" #include "oct-obj.h" +#include "oct-stream.h" #include "ov-scalar.h" #include "ov-base.h" #include "ov-base-scalar.h" @@ -208,6 +212,7 @@ } #if defined (HAVE_HDF5) + bool octave_scalar::save_hdf5 (hid_t loc_id, const char *name, bool /* save_as_floats */) @@ -266,6 +271,7 @@ return true; } + #endif /*
--- a/src/ov-scalar.h +++ b/src/ov-scalar.h @@ -98,7 +98,14 @@ { return NDArray (dim_vector (1, 1), scalar); } octave_value resize (const dim_vector& dv) const - { NDArray retval (dv); if (dv.numel()) retval(0) = scalar; return retval; } + { + NDArray retval (dv); + + if (dv.numel ()) + retval(0) = scalar; + + return retval; + } Complex complex_value (bool = false) const { return scalar; } @@ -134,6 +141,14 @@ bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug); #endif + int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const + { + return os.write (array_value (), block_size, output_type, + skip, flt_fmt); + } + private: DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-str-mat.cc +++ b/src/ov-str-mat.cc @@ -31,10 +31,13 @@ #include <iostream> #include <vector> +#include "data-conv.h" #include "lo-ieee.h" +#include "mach-info.h" #include "mx-base.h" #include "oct-obj.h" +#include "oct-stream.h" #include "ops.h" #include "ov-re-mat.h" #include "ov-str-mat.h" @@ -438,7 +441,7 @@ if (! is.read (X_CAST (char *, &elements), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &elements)); + swap_bytes<4> (&elements); if (elements < 0) { @@ -452,7 +455,7 @@ if (! is.read (X_CAST (char *, &di), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &di)); + swap_bytes<4> (&di); dv(i) = di; } @@ -474,7 +477,7 @@ if (! is.read (X_CAST (char *, &len), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &len)); + swap_bytes<4> (&len); OCTAVE_LOCAL_BUFFER (char, btmp, len+1); if (! is.read (X_CAST (char *, btmp), len)) return false; @@ -492,6 +495,7 @@ } #if defined (HAVE_HDF5) + bool octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name, bool /* save_as_floats */) @@ -703,6 +707,7 @@ return retval; } + #endif /*
--- a/src/ov-str-mat.h +++ b/src/ov-str-mat.h @@ -36,6 +36,7 @@ #include "str-vec.h" #include "error.h" +#include "oct-stream.h" #include "ov.h" #include "ov-ch-mat.h" #include "ov-typeinfo.h" @@ -140,6 +141,11 @@ bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug); #endif + int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const + { return os.write (matrix, block_size, output_type, skip, flt_fmt); } + private: DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-struct.cc +++ b/src/ov-struct.cc @@ -1083,7 +1083,7 @@ if (! is.read (X_CAST (char *, &len), 4)) return false; if (swap) - swap_4_bytes (X_CAST (char *, &len)); + swap_bytes<4> (&len); if (len > 0) {
--- a/src/ov.cc +++ b/src/ov.cc @@ -33,6 +33,7 @@ #include "quit.h" #include "oct-obj.h" +#include "oct-stream.h" #include "ov.h" #include "ov-base.h" #include "ov-bool.h" @@ -1450,6 +1451,14 @@ tn2.c_str (), tn1.c_str ()); } +int +octave_value::write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const +{ + return rep->write (os, block_size, output_type, skip, flt_fmt); +} + octave_value octave_value::numeric_assign (const std::string& type, const std::list<octave_value_list>& idx,
--- a/src/ov.h +++ b/src/ov.h @@ -748,6 +748,10 @@ { return rep->load_hdf5 (loc_id, name, have_h5giterate_bug); } #endif + virtual int write (octave_stream& os, int block_size, + oct_data_conv::data_type output_type, int skip, + oct_mach_info::float_format flt_fmt) const; + octave_value *internal_rep (void) const { return rep; } protected: