# HG changeset patch # User jwe # Date 1102046765 0 # Node ID 3db2b2762491494e3afc60b2fc19fde8b116fd80 # Parent 7830f271a53f3796e1e77fe56631f0ceb5cb759c [project @ 2004-12-03 04:06:05 by jwe] diff -r 7830f271a53f -r 3db2b2762491 src/ChangeLog --- a/src/ChangeLog Wed Dec 01 19:54:45 2004 +0000 +++ b/src/ChangeLog Fri Dec 03 04:06:05 2004 +0000 @@ -1,3 +1,19 @@ +2004-12-02 David Bateman + + * ls-mat5.cc (arrayclasstype): Add mxINT64_CLASS, mxUINT64_CLASS, + mxFUNCTION_CLASS enum values. + (read_mat5_integer_data): New template function. + (OCTAVE_MAT5_INTEGER_READ): New macro. + (read_mat5_binary_element): Handle reading integer types. + Eliminate automatic conversion from int to double. + (write_mat5_integer_data): New template function. + Instantiate it for the 8 integer data types + (save_mat5_binary_element): Handle integer data types. + + * load-save.cc (Fload): Check file existence here. + If file does not exist, append ".mat" to name and try again. + (get_file_format): Delete check for file existence. + 2004-11-30 John W. Eaton * Makefile.in (oct-gperf.h): Use -L C++ instead of -L ANSI_C. diff -r 7830f271a53f -r 3db2b2762491 src/load-save.cc --- a/src/load-save.cc Wed Dec 01 19:54:45 2004 +0000 +++ b/src/load-save.cc Fri Dec 03 04:06:05 2004 +0000 @@ -306,16 +306,6 @@ { load_save_format retval = LS_UNKNOWN; - // If the file doesn't exist do nothing - std::ifstream file_exist (fname.c_str ()); - if (file_exist) - file_exist.close (); - else - { - error ("load: nonexistent file `%s'", fname.c_str ()); - return LS_UNKNOWN; - } - #ifdef HAVE_HDF5 // check this before we open the file if (H5Fis_hdf5 (fname.c_str ()) > 0) @@ -724,6 +714,24 @@ { std::string fname = file_ops::tilde_expand (argv[i]); + // Check if file exists, if it doesn't then also check with a + // .mat extension + std::ifstream file_exist (fname.c_str ()); + if (file_exist) + file_exist.close (); + else + { + fname.append (".mat"); + std::ifstream file_mat_exist (fname.c_str ()); + if (file_mat_exist) + file_mat_exist.close (); + else + { + error ("load: nonexistent file: `%s'", orig_fname.c_str ()); + return retval; + } + } + if (format == LS_UNKNOWN) format = get_file_format (fname, orig_fname); @@ -732,28 +740,19 @@ { i++; - // If the file doesn't exist do nothing - std::ifstream file (fname.c_str (), std::ios::in); - if (file) - { - file.close (); - - hdf5_ifstream hdf5_file (fname.c_str ()); + hdf5_ifstream hdf5_file (fname.c_str ()); - if (hdf5_file.file_id >= 0) - { - retval = do_load (hdf5_file, orig_fname, force, format, - flt_fmt, list_only, swap, verbose, - argv, i, argc, nargout); + if (hdf5_file.file_id >= 0) + { + retval = do_load (hdf5_file, orig_fname, force, format, + flt_fmt, list_only, swap, verbose, + argv, i, argc, nargout); - hdf5_file.close (); - } - else - error ("load: couldn't open input file `%s'", - orig_fname.c_str ()); + hdf5_file.close (); } else - error ("load: nonexistent file `%s'", orig_fname.c_str ()); + error ("load: couldn't open input file `%s'", + orig_fname.c_str ()); } else #endif /* HAVE_HDF5 */ @@ -803,8 +802,6 @@ error ("load: couldn't open input file `%s'", orig_fname.c_str ()); } - else - error ("load: nonexistent file: `%s'", orig_fname.c_str ()); } return retval; diff -r 7830f271a53f -r 3db2b2762491 src/ls-mat5.cc --- a/src/ls-mat5.cc Wed Dec 01 19:54:45 2004 +0000 +++ b/src/ls-mat5.cc Fri Dec 03 04:06:05 2004 +0000 @@ -86,7 +86,10 @@ mxINT16_CLASS, // 16 bit signed integer mxUINT16_CLASS, // 16 bit unsigned integer mxINT32_CLASS, // 32 bit signed integer - mxUINT32_CLASS // 32 bit unsigned integer + mxUINT32_CLASS, // 32 bit unsigned integer + mxINT64_CLASS, // 64 bit signed integer + mxUINT64_CLASS, // 64 bit unsigned integer + mxFUNCTION_CLASS // Function handle }; // Read COUNT elements of data from IS in the format specified by TYPE, @@ -159,6 +162,175 @@ } } +template +void +read_mat5_integer_data (std::istream& is, T &m, int count, bool swap, + mat5_data_type type) +{ + +#define READ_INTEGER_DATA(TYPE, swap, data, size, len, stream) \ + do \ + { \ + if (len > 0) \ + { \ + volatile TYPE *ptr = X_CAST (volatile TYPE *, data); \ + stream.read (X_CAST (char *, ptr), size * len); \ + if (swap) \ + swap_bytes< size > (ptr, len); \ + TYPE tmp = ptr[0]; \ + for (int i = len - 1; i > 0; i--) \ + data[i] = ptr[i]; \ + data[0] = tmp; \ + } \ + } \ + while (0) + + switch (type) + { + case miINT8: + READ_INTEGER_DATA (signed char, swap, m.fortran_vec (), 1, + count, is); + break; + + case miUINT8: + READ_INTEGER_DATA (unsigned char, swap, m.fortran_vec (), 1, + count, is); + break; + + case miINT16: + READ_INTEGER_DATA (signed TWO_BYTE_INT, swap, m.fortran_vec (), 2, + count, is); + break; + + case miUINT16: + READ_INTEGER_DATA (unsigned TWO_BYTE_INT, swap, m.fortran_vec (), 2, + count, is); + break; + + case miINT32: + READ_INTEGER_DATA (signed FOUR_BYTE_INT, swap, m.fortran_vec (), 4, + count, is); + break; + + case miUINT32: + READ_INTEGER_DATA (unsigned FOUR_BYTE_INT, swap, m.fortran_vec (), 4, + count, is); + break; + + case miSINGLE: + case miRESERVE1: + case miDOUBLE: + case miRESERVE2: + case miRESERVE3: + break; + + case miINT64: +#ifdef EIGHT_BYTE_INT + READ_INTEGER_DATA (signed EIGHT_BYTE_INT, swap, m.fortran_vec (), 8, + count, is); +#endif + break; + + case miUINT64: +#ifdef EIGHT_BYTE_INT + READ_INTEGER_DATA (unsigned EIGHT_BYTE_INT, swap, m.fortran_vec (), 8, + count, is); +#endif + break; + + case miMATRIX: + default: + break; + } + +#undef READ_INTEGER_DATA + +} + +template void read_mat5_integer_data (std::istream& is, int8NDArray &m, + int count, bool swap, + mat5_data_type type); +template void read_mat5_integer_data (std::istream& is, int16NDArray &m, + int count, bool swap, + mat5_data_type type); +template void read_mat5_integer_data (std::istream& is, int32NDArray &m, + int count, bool swap, + mat5_data_type type); +template void read_mat5_integer_data (std::istream& is, int64NDArray &m, + int count, bool swap, + mat5_data_type type); +template void read_mat5_integer_data (std::istream& is, uint8NDArray &m, + int count, bool swap, + mat5_data_type type); +template void read_mat5_integer_data (std::istream& is, uint16NDArray &m, + int count, bool swap, + mat5_data_type type); +template void read_mat5_integer_data (std::istream& is, uint32NDArray &m, + int count, bool swap, + mat5_data_type type); +template void read_mat5_integer_data (std::istream& is, uint64NDArray &m, + int count, bool swap, + mat5_data_type type); + +#define OCTAVE_MAT5_INTEGER_READ(TYP) \ + { \ + TYP re (dims); \ + \ + std::streampos tmp_pos; \ + \ + if (read_mat5_tag (is, swap, type, len)) \ + { \ + error ("load: reading matrix data for `%s'", retval.c_str ()); \ + goto data_read_error; \ + } \ + \ + int n = re.length (); \ + tmp_pos = is.tellg (); \ + read_mat5_integer_data (is, re, n, swap, \ + (enum mat5_data_type) type); \ + \ + if (! is || error_state) \ + { \ + error ("load: reading matrix data for `%s'", retval.c_str ()); \ + goto data_read_error; \ + } \ + \ + is.seekg (tmp_pos + static_cast (PAD (len))); \ + \ + if (imag) \ + { \ + /* We don't handle imag integer types, convert to an array */ \ + NDArray im (dims); \ + \ + if (read_mat5_tag (is, swap, type, len)) \ + { \ + error ("load: reading matrix data for `%s'", \ + retval.c_str ()); \ + goto data_read_error; \ + } \ + \ + n = im.length (); \ + read_mat5_binary_data (is, im.fortran_vec (), n, swap, \ + (enum mat5_data_type) type, flt_fmt); \ + \ + if (! is || error_state) \ + { \ + error ("load: reading imaginary matrix data for `%s'", \ + retval.c_str ()); \ + goto data_read_error; \ + } \ + \ + ComplexNDArray ctmp (dims); \ + \ + for (int i = 0; i < n; i++) \ + ctmp(i) = Complex (double (re(i)), im(i)); \ + \ + tc = ctmp; \ + } \ + else \ + tc = re; \ + } + // Read one element tag from stream IS, // place the type code in TYPE and the byte count in BYTES // return nonzero on error @@ -224,7 +396,6 @@ // first used to avoid errors from gcc about goto crossing // initialization of variable. - NDArray re; oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown; int type = 0; bool imag; @@ -297,7 +468,6 @@ read_int (is, swap, n); dims(i) = n; } - re.resize (dims); std::streampos tmp_pos = is.tellg (); is.seekg (tmp_pos + static_cast (PAD (dim_len) - dim_len)); @@ -364,6 +534,10 @@ warning ("load: sparse arrays are not implemented"); goto skip_ahead; + case mxFUNCTION_CLASS: + warning ("load: function handles are not implemented"); + goto skip_ahead; + case mxSTRUCT_CLASS: { Octave_map m; @@ -446,24 +620,51 @@ } break; + case mxINT8_CLASS: + OCTAVE_MAT5_INTEGER_READ (int8NDArray); + break; + + case mxUINT8_CLASS: + OCTAVE_MAT5_INTEGER_READ (uint8NDArray); + break; + + case mxINT16_CLASS: + OCTAVE_MAT5_INTEGER_READ (int16NDArray); + break; + + case mxUINT16_CLASS: + OCTAVE_MAT5_INTEGER_READ (uint16NDArray); + break; + + case mxINT32_CLASS: + OCTAVE_MAT5_INTEGER_READ (int32NDArray); + break; + + case mxUINT32_CLASS: + OCTAVE_MAT5_INTEGER_READ (uint32NDArray); + break; + + case mxINT64_CLASS: + OCTAVE_MAT5_INTEGER_READ (int64NDArray); + break; + + case mxUINT64_CLASS: + OCTAVE_MAT5_INTEGER_READ (uint64NDArray); + break; + case mxCHAR_CLASS: // handle as a numerical array to start with case mxDOUBLE_CLASS: case mxSINGLE_CLASS: - case mxINT8_CLASS: - case mxUINT8_CLASS: - case mxINT16_CLASS: - case mxUINT16_CLASS: - case mxINT32_CLASS: - case mxUINT32_CLASS: default: - // handle all these numerical formats as double arrays + { + NDArray re (dims); - // real data subelement - { + // real data subelement + std::streampos tmp_pos; - + if (read_mat5_tag (is, swap, type, len)) { error ("load: reading matrix data for `%s'", retval.c_str ()); @@ -482,42 +683,42 @@ } is.seekg (tmp_pos + static_cast (PAD (len))); - } - - // imaginary data subelement - if (imag) - { - NDArray im (dims); + + // imaginary data subelement + if (imag) + { + NDArray im (dims); - if (read_mat5_tag (is, swap, type, len)) - { - error ("load: reading matrix data for `%s'", retval.c_str ()); - goto data_read_error; - } + if (read_mat5_tag (is, swap, type, len)) + { + error ("load: reading matrix data for `%s'", retval.c_str ()); + goto data_read_error; + } - int n = im.length (); - read_mat5_binary_data (is, im.fortran_vec (), n, swap, - (enum mat5_data_type) type, flt_fmt); + n = im.length (); + read_mat5_binary_data (is, im.fortran_vec (), n, swap, + (enum mat5_data_type) type, flt_fmt); - if (! is || error_state) - { - error ("load: reading imaginary matrix data for `%s'", - retval.c_str ()); - goto data_read_error; - } + if (! is || error_state) + { + error ("load: reading imaginary matrix data for `%s'", + retval.c_str ()); + goto data_read_error; + } - ComplexNDArray ctmp (dims); + ComplexNDArray ctmp (dims); - for (int i = 0; i < n; i++) - ctmp(i) = Complex (re(i), im(i)); + for (int i = 0; i < n; i++) + ctmp(i) = Complex (re(i), im(i)); - tc = ctmp; - } - else - tc = re; + tc = ctmp; + } + else + tc = re; - if (arrayclass == mxCHAR_CLASS) - tc = tc.convert_to_str (false, true); + if (arrayclass == mxCHAR_CLASS) + tc = tc.convert_to_str (false, true); + } } is.seekg (pos + static_cast (element_length)); @@ -710,6 +911,76 @@ } } +template +void +write_mat5_integer_data (std::ostream& os, const T& m, int size) +{ + int nel = m.nelem (); + mat5_data_type mst; + unsigned len; + + switch (size) + { + case 1: + mst = miUINT8; + break; + case 2: + mst = miUINT16; + break; + case 3: + mst = miUINT32; + break; + case 4: + mst = miUINT64; + break; + case -1: + mst = miINT8; + size = - size; + break; + case -2: + mst = miINT16; + size = - size; + break; + case -3: + mst = miINT32; + size = - size; + break; + case -4: + default: + mst = miINT64; + size = - size; + break; + } + + len = nel*size; + write_mat5_tag (os, mst, len); + + os.write (X_CAST(char *, m.data ()), len); + + if (PAD (len) > len) + { + static char buf[9]="\x00\x00\x00\x00\x00\x00\x00\x00"; + os.write (buf, PAD (len) - len); + } +} + +template void write_mat5_integer_data (std::ostream& os, + const int8NDArray &m, int size); +template void write_mat5_integer_data (std::ostream& os, + const int16NDArray &m, int size); +template void write_mat5_integer_data (std::ostream& os, + const int32NDArray &m, int size); +template void write_mat5_integer_data (std::ostream& os, + const int64NDArray &m, int size); +template void write_mat5_integer_data (std::ostream& os, + const uint8NDArray &m, int size); +template void write_mat5_integer_data (std::ostream& os, + const uint16NDArray &m, int size); +template void write_mat5_integer_data (std::ostream& os, + const uint32NDArray &m, int size); +template void write_mat5_integer_data (std::ostream& os, + const uint64NDArray &m, int size); + // Write out cell element values in the cell array to OS, preceded by // the appropriate tag. @@ -742,6 +1013,7 @@ FOUR_BYTE_INT flags=0; FOUR_BYTE_INT junk=0; std::streampos fixup, contin; + std::string cname = tc.class_name (); // element type and length fixup = os.tellp (); @@ -758,6 +1030,22 @@ if (tc.is_string ()) flags |= mxCHAR_CLASS; + else if (cname == "int8") + flags |= mxINT8_CLASS; + else if (cname == "int16") + flags |= mxINT16_CLASS; + else if (cname == "int32") + flags |= mxINT32_CLASS; + else if (cname == "int64") + flags |= mxINT64_CLASS; + else if (cname == "uint8") + flags |= mxUINT8_CLASS; + else if (cname == "uint16") + flags |= mxUINT16_CLASS; + else if (cname == "uint32") + flags |= mxUINT32_CLASS; + else if (cname == "uint64") + flags |= mxUINT64_CLASS; else if (tc.is_real_scalar ()) flags |= mxDOUBLE_CLASS; else if (tc.is_real_matrix () || tc.is_range ()) @@ -840,6 +1128,54 @@ if (paddedlength > len) os.write ((char *)buf, paddedlength - len); } + else if (cname == "int8") + { + int8NDArray m = tc.int8_array_value (); + + write_mat5_integer_data (os, m, -1); + } + else if (cname == "int16") + { + int16NDArray m = tc.int16_array_value (); + + write_mat5_integer_data (os, m, -2); + } + else if (cname == "int32") + { + int32NDArray m = tc.int32_array_value (); + + write_mat5_integer_data (os, m, -4); + } + else if (cname == "int64") + { + int64NDArray m = tc.int64_array_value (); + + write_mat5_integer_data (os, m, -8); + } + else if (cname == "uint8") + { + uint8NDArray m = tc.uint8_array_value (); + + write_mat5_integer_data (os, m, 1); + } + else if (cname == "uint16") + { + uint16NDArray m = tc.uint16_array_value (); + + write_mat5_integer_data (os, m, 2); + } + else if (cname == "uint32") + { + uint32NDArray m = tc.uint32_array_value (); + + write_mat5_integer_data (os, m, 4); + } + else if (cname == "uint64") + { + uint64NDArray m = tc.uint64_array_value (); + + write_mat5_integer_data (os, m, 8); + } else if (tc.is_real_scalar () || tc.is_real_matrix () || tc.is_range ()) { NDArray m = tc.array_value ();