*** ./ov-re-mat.cc.orig 2004-02-16 20:57:23.000000000 +0100 --- ./ov-re-mat.cc 2004-03-01 22:48:58.000000000 +0100 *************** *** 53,58 **** --- 53,59 ---- #include "byte-swap.h" #include "ls-oct-ascii.h" #include "ls-utils.h" + #include "ls-hdf5.h" #if ! defined (UCHAR_MAX) #define UCHAR_MAX 255 *************** *** 508,524 **** octave_matrix::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats) { dim_vector d = dims (); ! hsize_t hdims[d.length () > 2 ? d.length () : 3]; hid_t space_hid = -1, data_hid = -1; - int rank = ( (d (0) == 1) && (d.length () == 2) ? 1 : d.length ()); bool retval = true; NDArray m = array_value (); // Octave uses column-major, while HDF5 uses row-major ordering ! for (int i = 0, j = d.length() - 1; i < d.length (); i++, j--) ! hdims[i] = d (j); - space_hid = H5Screate_simple (rank, hdims, (hsize_t*) 0); if (space_hid < 0) return false; hid_t save_type_hid = H5T_NATIVE_DOUBLE; --- 509,531 ---- octave_matrix::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats) { dim_vector d = dims (); ! int empty = save_hdf5_empty (loc_id, name, d); ! if (empty != 0) ! return (empty > 0); ! ! int rank = d.length (); hid_t space_hid = -1, data_hid = -1; bool retval = true; NDArray m = array_value (); + OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank); + // Octave uses column-major, while HDF5 uses row-major ordering ! for (int i = 0; i < rank; i++) ! hdims[i] = d (rank-i-1); ! ! space_hid = H5Screate_simple (rank, hdims, (hsize_t *)0); if (space_hid < 0) return false; hid_t save_type_hid = H5T_NATIVE_DOUBLE; *************** *** 566,571 **** --- 573,585 ---- octave_matrix::load_hdf5 (hid_t loc_id, const char *name, bool /* have_h5giterate_bug */) { + dim_vector dv; + int empty = load_hdf5_empty (loc_id, name, dv); + if (empty > 0) + matrix.resize(dv); + if (empty != 0) + return (empty > 0); + bool retval = false; hid_t data_hid = H5Dopen (loc_id, name); hid_t space_id = H5Dget_space (data_hid); *************** *** 584,591 **** H5Sget_simple_extent_dims (space_id, hdims, maxdims); - dim_vector dv; - // Octave uses column-major, while HDF5 uses row-major ordering if (rank == 1) { --- 598,603 ---- *** ./ChangeLog.orig 2004-02-20 22:16:54.000000000 +0100 --- ./ChangeLog 2004-03-01 17:59:25.000000000 +0100 *************** *** 1,3 **** --- 1,18 ---- + 2004-02-16 David Bateman + + * ls-hdf5.cc (save_hdf5_empty, load_hdf5_empty): New functions + to save/load empty matrices keeping their dimensions + * ls-hdf5.h (save_hdf5_empty, load_hdf5_empty): decl + + * ov-re-mat.cc (save_hdf5, load_hdf5): cleanup, check empty + matrix + * ov-cx-mat.cc (save_hdf5, load_hdf5): ditto + * ov-bool-mat.cc (save_hdf5, load_hdf5): ditto + + * ov-str-mat.cc (save_ascoo, load_ascii, save_binary, + load_binary, save_hdf5, load_hdf5): cleanup, check empty + matrix, and save/load Nd arrays + 2004-02-20 John W. Eaton * version.h (OCTAVE_VERSION): Now 2.1.55. *** ./ls-hdf5.h.orig 2004-01-21 05:46:59.000000000 +0100 --- ./ls-hdf5.h 2004-03-01 15:55:41.000000000 +0100 *************** *** 153,158 **** --- 153,164 ---- const std::string& name, const std::string& doc, bool mark_as_global, bool save_as_floats); + extern int + save_hdf5_empty (hid_t loc_id, const char *name, const dim_vector d); + + extern int + load_hdf5_empty (hid_t loc_id, const char *name, dim_vector &d); + extern std::string read_hdf5_data (std::istream& is, const std::string& filename, bool& global, octave_value& tc, std::string& doc); *** ./ls-hdf5.cc.orig 2004-02-16 20:57:23.000000000 +0100 --- ./ls-hdf5.cc 2004-03-01 22:29:02.000000000 +0100 *************** *** 514,519 **** --- 514,596 ---- return retval; } + // Save an empty matrix, if needed. Returns + // > 0 Saved empty matrix + // = 0 Not an empty matrix; did nothing + // < 0 Error condition + int + save_hdf5_empty (hid_t loc_id, const char *name, const dim_vector d) + { + hsize_t sz = d.length (); + int dims[sz]; + bool empty = false; + hid_t space_hid = -1, data_hid = -1; + int retval; + for (hsize_t i = 0; i < sz; i++) + { + dims[i] = d(i); + if (dims[i] < 1) + empty = true; + } + + if (!empty) + return 0; + + space_hid = H5Screate_simple (1, &sz, (hsize_t *) 0); + if (space_hid < 0) return space_hid; + + data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_INT, space_hid, + H5P_DEFAULT); + if (data_hid < 0) + { + H5Sclose (space_hid); + return data_hid; + } + + retval = H5Dwrite (data_hid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, (void*) dims) >= 0; + + H5Dclose (data_hid); + H5Sclose (space_hid); + + if (retval >= 0) + retval = hdf5_add_attr (loc_id, "OCTAVE_EMPTY_MATRIX"); + + return (retval == 0 ? 1 : retval); + } + + // Load an empty matrix, if needed. Returns + // > 0 loaded empty matrix, dimensions returned + // = 0 Not an empty matrix; did nothing + // < 0 Error condition + int + load_hdf5_empty (hid_t loc_id, const char *name, dim_vector &d) + { + if (!hdf5_check_attr(loc_id, "OCTAVE_EMPTY_MATRIX")) + return 0; + + hsize_t hdims, maxdims; + hid_t data_hid = H5Dopen (loc_id, name); + hid_t space_id = H5Dget_space (data_hid); + H5Sget_simple_extent_dims (space_id, &hdims, &maxdims); + int dims[hdims]; + int retval; + + retval = H5Dread (data_hid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, (void *) dims); + if (retval >= 0) + { + d.resize (hdims); + for (hsize_t i = 0; i < hdims; i++) + d(i) = dims[i]; + } + + H5Sclose (space_id); + H5Dclose (data_hid); + + return (retval == 0 ? hdims : retval); + } + // save_type_to_hdf5 is not currently used, since hdf5 doesn't yet support // automatic float<->integer conversions: *** ./ov-bool-mat.cc.orig 2004-02-16 20:57:23.000000000 +0100 --- ./ov-bool-mat.cc 2004-03-01 22:49:40.000000000 +0100 *************** *** 344,359 **** bool /* save_as_floats */) { dim_vector d = dims (); ! hsize_t hdims[d.length () > 2 ? d.length () : 3]; hid_t space_hid = -1, data_hid = -1; - int rank = ( (d (0) == 1) && (d.length () == 2) ? 1 : d.length ()); bool retval = true; - boolNDArray m = bool_array_value (); // Octave uses column-major, while HDF5 uses row-major ordering ! for (int i = 0, j = d.length() - 1; i < d.length (); i++, j--) ! hdims[i] = d (j); space_hid = H5Screate_simple (rank, hdims, (hsize_t*) 0); if (space_hid < 0) return false; --- 344,363 ---- bool /* save_as_floats */) { dim_vector d = dims (); ! int empty = save_hdf5_empty (loc_id, name, d); ! if (empty != 0) ! return (empty > 0); ! ! int rank = d.length (); hid_t space_hid = -1, data_hid = -1; bool retval = true; boolNDArray m = bool_array_value (); + OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank); + // Octave uses column-major, while HDF5 uses row-major ordering ! for (int i = 0; i < rank; i++) ! hdims[i] = d (rank-i-1); space_hid = H5Screate_simple (rank, hdims, (hsize_t*) 0); if (space_hid < 0) return false; *************** *** 385,390 **** --- 389,401 ---- octave_bool_matrix::load_hdf5 (hid_t loc_id, const char *name, bool /* have_h5giterate_bug */) { + dim_vector dv; + int empty = load_hdf5_empty (loc_id, name, dv); + if (empty > 0) + matrix.resize(dv); + if (empty != 0) + return (empty > 0); + bool retval = false; hid_t data_hid = H5Dopen (loc_id, name); hid_t space_id = H5Dget_space (data_hid); *************** *** 402,409 **** H5Sget_simple_extent_dims (space_id, hdims, maxdims); - dim_vector dv; - // Octave uses column-major, while HDF5 uses row-major ordering if (rank == 1) { --- 413,418 ---- *** ./ov-cx-mat.cc.orig 2004-02-16 20:57:23.000000000 +0100 --- ./ov-cx-mat.cc 2004-03-01 22:49:30.000000000 +0100 *************** *** 446,461 **** bool save_as_floats) { dim_vector d = dims (); ! hsize_t hdims[d.length () > 2 ? d.length () : 3]; ! hid_t space_hid = -1, type_hid = -1, data_hid = -1; ! int rank = ( (d (0) == 1) && (d.length () == 2) ? 1 : d.length ()); bool retval = true; ComplexNDArray m = complex_array_value (); ! // Octave uses column-major, while HDF5 uses row-major ordering ! for (int i = 0, j = d.length() - 1; i < d.length (); i++, j--) ! hdims[i] = d (j); space_hid = H5Screate_simple (rank, hdims, (hsize_t*) 0); if (space_hid < 0) return false; --- 446,466 ---- bool save_as_floats) { dim_vector d = dims (); ! int empty = save_hdf5_empty (loc_id, name, d); ! if (empty != 0) ! return (empty > 0); ! ! int rank = d.length (); ! hid_t space_hid = -1, data_hid = -1, type_hid = -1; bool retval = true; ComplexNDArray m = complex_array_value (); ! OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank); + // Octave uses column-major, while HDF5 uses row-major ordering + for (int i = 0; i < rank; i++) + hdims[i] = d (rank-i-1); + space_hid = H5Screate_simple (rank, hdims, (hsize_t*) 0); if (space_hid < 0) return false; *************** *** 523,528 **** --- 528,540 ---- octave_complex_matrix::load_hdf5 (hid_t loc_id, const char *name, bool /* have_h5giterate_bug */) { + dim_vector dv; + int empty = load_hdf5_empty (loc_id, name, dv); + if (empty > 0) + matrix.resize(dv); + if (empty != 0) + return (empty > 0); + bool retval = false; hid_t data_hid = H5Dopen (loc_id, name); hid_t type_hid = H5Dget_type (data_hid); *************** *** 553,560 **** H5Sget_simple_extent_dims (space_id, hdims, maxdims); - dim_vector dv; - // Octave uses column-major, while HDF5 uses row-major ordering if (rank == 1) { --- 565,570 ---- *** ./ov-str-mat.cc.orig 2004-03-01 17:52:13.000000000 +0100 --- ./ov-str-mat.cc 2004-03-02 00:37:51.000000000 +0100 *************** *** 240,258 **** bool& /* infnan_warned */, bool /* strip_nan_and_inf */) { ! charMatrix chm = char_matrix_value (); ! int elements = chm.rows (); ! os << "# elements: " << elements << "\n"; ! for (int i = 0; i < elements; i++) { ! unsigned len = chm.cols (); ! os << "# length: " << len << "\n"; ! std::string tstr = chm.row_as_string (i, false, true); ! const char *tmp = tstr.data (); ! if (tstr.length () > len) ! panic_impossible (); ! os.write (X_CAST (char *, tmp), len); os << "\n"; } return true; --- 240,274 ---- bool& /* infnan_warned */, bool /* strip_nan_and_inf */) { ! dim_vector d = dims (); ! if (d.length () > 2) { ! charNDArray tmp = char_array_value (); ! os << "# ndims: " << d.length () << "\n"; ! for (int i=0; i < d.length (); i++) ! os << " " << d (i); os << "\n"; + os.write (X_CAST (char *, tmp.fortran_vec ()), d.numel ()); + os << "\n"; + } + else + { + // Keep this case, rather than use generic code above for + // backward compatiability. Makes load_ascii much more complex!! + charMatrix chm = char_matrix_value (); + int elements = chm.rows (); + os << "# elements: " << elements << "\n"; + for (int i = 0; i < elements; i++) + { + unsigned len = chm.cols (); + os << "# length: " << len << "\n"; + std::string tstr = chm.row_as_string (i, false, true); + const char *tmp = tstr.data (); + if (tstr.length () > len) + panic_impossible (); + os.write (X_CAST (char *, tmp), len); + os << "\n"; + } } return true; *************** *** 261,348 **** bool octave_char_matrix_str::load_ascii (std::istream& is) { ! int elements; bool success = true; std::streampos pos = is.tellg (); ! if (extract_keyword (is, "elements", elements, true)) { ! ! if (elements >= 0) { ! // XXX FIXME XXX -- need to be able to get max length ! // before doing anything. ! charMatrix chm (elements, 0); ! int max_len = 0; ! for (int i = 0; i < elements; i++) { ! int len; ! if (extract_keyword (is, "length", len) && len >= 0) ! { ! OCTAVE_LOCAL_BUFFER (char, tmp, len+1); ! ! if (len > 0 && ! is.read (X_CAST (char *, tmp), len)) ! { ! error ("load: failed to load string constant"); ! success = false; ! break; ! } ! else ! { ! tmp [len] = '\0'; ! if (len > max_len) ! { ! max_len = len; ! chm.resize (elements, max_len, 0); ! } ! chm.insert (tmp, i, 0); ! } ! } ! else ! { ! error ("load: failed to extract string length for element %d", ! i+1); ! success = false; ! } } ! ! if (! error_state) ! matrix = chm; ! } else { ! error ("load: failed to extract number of string elements"); success = false; } } else { // re-read the same line again is.clear (); is.seekg (pos); ! int len; ! ! if (extract_keyword (is, "length", len) && len >= 0) { - // This is cruft for backward compatiability, but relatively harmless. ! OCTAVE_LOCAL_BUFFER (char, tmp, len+1); ! ! if (len > 0 && ! is.read (X_CAST (char *, tmp), len)) { ! error ("load: failed to load string constant"); } else { ! tmp [len] = '\0'; ! if (is) ! matrix = charMatrix (tmp); else ! error ("load: failed to load string constant"); } } } --- 277,406 ---- bool octave_char_matrix_str::load_ascii (std::istream& is) { ! int mdims = 0; bool success = true; std::streampos pos = is.tellg (); ! if (extract_keyword (is, "ndims", mdims, true)) { ! if (mdims >= 0) { ! dim_vector dv; ! dv.resize (mdims); ! ! for (int i = 0; i < mdims; i++) ! is >> dv(i); ! ! charNDArray tmp(dv); ! char *ftmp = tmp.fortran_vec (); ! ! // Skip the return line ! if (! is.read (ftmp, 1)) ! return false; ! if (! is.read (ftmp, dv.numel ()) || !is) { ! error ("load: failed to load string constant"); ! success = false; } ! else ! matrix = tmp; } else { ! error ("load: failed to extract matrix size"); success = false; } } else { + int elements; + // re-read the same line again is.clear (); is.seekg (pos); ! if (extract_keyword (is, "elements", elements, true)) { ! if (elements >= 0) { ! // XXX FIXME XXX -- need to be able to get max length ! // before doing anything. ! ! charMatrix chm (elements, 0); ! int max_len = 0; ! for (int i = 0; i < elements; i++) ! { ! int len; ! if (extract_keyword (is, "length", len) && len >= 0) ! { ! OCTAVE_LOCAL_BUFFER (char, tmp, len+1); ! ! if (len > 0 && ! ! is.read (X_CAST (char *, tmp), len)) ! { ! error ("load: failed to load string constant"); ! success = false; ! break; ! } ! else ! { ! tmp [len] = '\0'; ! if (len > max_len) ! { ! max_len = len; ! chm.resize (elements, max_len, 0); ! } ! chm.insert (tmp, i, 0); ! } ! } ! else ! { ! error ("load: failed to extract string length for element %d", ! i+1); ! success = false; ! } ! } ! ! if (! error_state) ! matrix = chm; ! } else { ! error ("load: failed to extract number of string elements"); ! success = false; ! } ! } ! else ! { ! // re-read the same line again ! is.clear (); ! is.seekg (pos); ! ! int len; ! ! if (extract_keyword (is, "length", len) && len >= 0) ! { ! // This is cruft for backward compatiability, ! // but relatively harmless. ! OCTAVE_LOCAL_BUFFER (char, tmp, len+1); ! ! if (len > 0 && ! is.read (X_CAST (char *, tmp), len)) ! { ! error ("load: failed to load string constant"); ! } else ! { ! tmp [len] = '\0'; ! ! if (is) ! matrix = charMatrix (tmp); ! else ! error ("load: failed to load string constant"); ! } } } } *************** *** 354,370 **** octave_char_matrix_str::save_binary (std::ostream& os, bool& /* save_as_floats */) { ! FOUR_BYTE_INT nr = rows (); ! os.write (X_CAST (char *, &nr), 4); ! charMatrix chm = char_matrix_value (); ! for (int i = 0; i < nr; i++) { ! FOUR_BYTE_INT len = chm.cols (); ! os.write (X_CAST (char *, &len), 4); ! std::string tstr = chm.row_as_string (i); ! const char *btmp = tstr.data (); ! os.write (X_CAST (char *, btmp), len); } return true; } --- 412,432 ---- octave_char_matrix_str::save_binary (std::ostream& os, bool& /* save_as_floats */) { ! dim_vector d = dims (); ! if (d.length() < 1) ! return false; ! ! // Use negative value for ndims to differentiate with old format!! ! FOUR_BYTE_INT tmp = - d.length(); ! os.write (X_CAST (char *, &tmp), 4); ! for (int i=0; i < d.length (); i++) { ! tmp = d(i); ! os.write (X_CAST (char *, &tmp), 4); } + + charNDArray m = char_array_value (); + os.write (m.fortran_vec (), d.numel ()); return true; } *************** *** 377,404 **** return false; if (swap) swap_4_bytes (X_CAST (char *, &elements)); ! charMatrix chm (elements, 0); ! int max_len = 0; ! for (int i = 0; i < elements; i++) { ! FOUR_BYTE_INT len; ! if (! is.read (X_CAST (char *, &len), 4)) ! return false; ! if (swap) ! swap_4_bytes (X_CAST (char *, &len)); ! OCTAVE_LOCAL_BUFFER (char, btmp, len+1); ! if (! is.read (X_CAST (char *, btmp), len)) return false; ! if (len > max_len) { ! max_len = len; ! chm.resize (elements, max_len, 0); } ! btmp [len] = '\0'; ! chm.insert (btmp, i, 0); } - - matrix = chm; return true; } --- 439,493 ---- return false; if (swap) swap_4_bytes (X_CAST (char *, &elements)); ! ! if (elements < 0) { ! FOUR_BYTE_INT mdims = - elements; ! FOUR_BYTE_INT di; ! dim_vector dv; ! dv.resize (mdims); ! ! for (int i = 0; i < mdims; i++) ! { ! if (! is.read (X_CAST (char *, &di), 4)) ! return false; ! if (swap) ! swap_4_bytes (X_CAST (char *, &di)); ! dv(i) = di; ! } ! ! charNDArray m(dv); ! char *tmp = m.fortran_vec (); ! is.read (tmp, dv.numel ()); ! ! if (error_state || ! is) return false; ! matrix = m; ! } ! else ! { ! charMatrix chm (elements, 0); ! int max_len = 0; ! for (int i = 0; i < elements; i++) { ! FOUR_BYTE_INT len; ! if (! is.read (X_CAST (char *, &len), 4)) ! return false; ! if (swap) ! swap_4_bytes (X_CAST (char *, &len)); ! OCTAVE_LOCAL_BUFFER (char, btmp, len+1); ! if (! is.read (X_CAST (char *, btmp), len)) ! return false; ! if (len > max_len) ! { ! max_len = len; ! chm.resize (elements, max_len, 0); ! } ! btmp [len] = '\0'; ! chm.insert (btmp, i, 0); } ! matrix = chm; } return true; } *************** *** 407,453 **** octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name, bool /* save_as_floats */) { ! hsize_t dimens[3]; ! hid_t space_hid = -1, type_hid = -1, data_hid = -1; bool retval = true; ! int nr = rows (); ! charMatrix chm = char_matrix_value (); ! int nc = chm.cols (); ! ! // create datatype for (null-terminated) string to write from: ! type_hid = H5Tcopy (H5T_C_S1); H5Tset_size (type_hid, nc + 1); ! if (type_hid < 0) return false; ! dimens[0] = nr; ! space_hid = H5Screate_simple (nr > 0 ? 1 : 0, dimens, (hsize_t*) 0); if (space_hid < 0) ! { ! H5Tclose (type_hid); ! return false; ! } ! data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT); if (data_hid < 0) { H5Sclose (space_hid); - H5Tclose (type_hid); return false; } ! OCTAVE_LOCAL_BUFFER (char, s, nr * (nc + 1)); ! for (int i = 0; i < nr; ++i) ! { ! std::string tstr = chm.row_as_string (i); ! strcpy (s + i * (nc+1), tstr.c_str ()); ! } ! retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT, ! (void*) s) >= 0; H5Dclose (data_hid); - H5Tclose (type_hid); H5Sclose (space_hid); return retval; } --- 496,538 ---- octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name, bool /* save_as_floats */) { ! dim_vector d = dims (); ! int empty = save_hdf5_empty (loc_id, name, d); ! if (empty != 0) ! return (empty > 0); ! ! int rank = d.length (); ! hid_t space_hid = -1, data_hid = -1; bool retval = true; + charNDArray m = char_array_value (); ! OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank); ! // Octave uses column-major, while HDF5 uses row-major ordering ! for (int i = 0; i < rank; i++) ! hdims[i] = d (rank-i-1); ! ! space_hid = H5Screate_simple (rank, hdims, (hsize_t *)0); if (space_hid < 0) ! return false; ! data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_CHAR, space_hid, ! H5P_DEFAULT); if (data_hid < 0) { H5Sclose (space_hid); return false; } ! OCTAVE_LOCAL_BUFFER (char, s, d.numel ()); ! for (int i = 0; i < d.numel(); ++i) ! s[i] = m(i); ! retval = H5Dwrite (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, ! H5P_DEFAULT, (void*) s) >= 0; H5Dclose (data_hid); H5Sclose (space_hid); return retval; } *************** *** 456,561 **** octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name, bool /* have_h5giterate_bug */) { hid_t data_hid = H5Dopen (loc_id, name); hid_t space_hid = H5Dget_space (data_hid); hsize_t rank = H5Sget_simple_extent_ndims (space_hid); hid_t type_hid = H5Dget_type (data_hid); ! if (rank == 0) { ! // a single string: ! int slen = H5Tget_size (type_hid); ! if (slen < 0) { H5Tclose (type_hid); H5Sclose (space_hid); H5Dclose (data_hid); return false; } else { ! OCTAVE_LOCAL_BUFFER (char, s, slen); ! // create datatype for (null-terminated) string ! // to read into: ! hid_t st_id = H5Tcopy (H5T_C_S1); ! H5Tset_size (st_id, slen); ! if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, ! H5P_DEFAULT, (void *) s) < 0) { - H5Tclose (st_id); H5Tclose (type_hid); H5Sclose (space_hid); H5Dclose (data_hid); return false; } ! matrix = charMatrix (s); ! H5Tclose (st_id); ! H5Tclose (type_hid); ! H5Sclose (space_hid); ! H5Dclose (data_hid); ! return true; ! } ! } ! else if (rank == 1) ! { ! // string vector ! hsize_t elements, maxdim; ! H5Sget_simple_extent_dims (space_hid, &elements, &maxdim); ! int slen = H5Tget_size (type_hid); ! if (slen < 0) ! { ! H5Tclose (type_hid); ! H5Sclose (space_hid); ! H5Dclose (data_hid); ! return false; } ! else { ! // hdf5 string arrays store strings of all the ! // same physical length (I think), which is ! // slightly wasteful, but oh well. ! ! OCTAVE_LOCAL_BUFFER (char, s, elements * slen); ! ! // create datatype for (null-terminated) string ! // to read into: ! hid_t st_id = H5Tcopy (H5T_C_S1); ! H5Tset_size (st_id, slen); ! ! if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, ! H5P_DEFAULT, (void *) s) < 0) { - H5Tclose (st_id); H5Tclose (type_hid); H5Sclose (space_hid); H5Dclose (data_hid); return false; } ! ! charMatrix chm (elements, slen - 1); ! for (hsize_t i = 0; i < elements; ++i) { ! chm.insert (s + i*slen, i, 0); ! } ! matrix = chm; ! H5Tclose (st_id); H5Tclose (type_hid); H5Sclose (space_hid); H5Dclose (data_hid); ! return true; } } - else - { - H5Tclose (type_hid); - H5Sclose (space_hid); - H5Dclose (data_hid); - return false; - } } #endif --- 541,703 ---- octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name, bool /* have_h5giterate_bug */) { + dim_vector dv; + int empty = load_hdf5_empty (loc_id, name, dv); + if (empty > 0) + matrix.resize(dv); + if (empty != 0) + return (empty > 0); + hid_t data_hid = H5Dopen (loc_id, name); hid_t space_hid = H5Dget_space (data_hid); hsize_t rank = H5Sget_simple_extent_ndims (space_hid); hid_t type_hid = H5Dget_type (data_hid); + hid_t type_class_hid = H5Tget_class (type_hid); ! if (type_class_hid == H5T_INTEGER) { ! bool retval = false; ! if (rank < 1) { H5Tclose (type_hid); H5Sclose (space_hid); H5Dclose (data_hid); return false; } + + OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank); + OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank); + + H5Sget_simple_extent_dims (space_hid, hdims, maxdims); + + // Octave uses column-major, while HDF5 uses row-major ordering + if (rank == 1) + { + dv.resize (2); + dv(0) = 1; + dv(1) = hdims[0]; + } else { ! dv.resize (rank); ! for (int i = 0, j = rank - 1; i < (int)rank; i++, j--) ! dv(j) = hdims[i]; ! } ! ! charNDArray m (dv); ! char *str = m.fortran_vec (); ! if (H5Dread (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, ! H5P_DEFAULT, (void *) str) >= 0) ! { ! retval = true; ! matrix = m; ! } ! ! H5Tclose (type_hid); ! H5Sclose (space_hid); ! H5Dclose (data_hid); ! return true; ! } ! else ! { ! // This is cruft for backward compatiability and easy data ! // importation ! if (rank == 0) ! { ! // a single string: ! int slen = H5Tget_size (type_hid); ! if (slen < 0) { H5Tclose (type_hid); H5Sclose (space_hid); H5Dclose (data_hid); return false; } + else + { + OCTAVE_LOCAL_BUFFER (char, s, slen); + // create datatype for (null-terminated) string + // to read into: + hid_t st_id = H5Tcopy (H5T_C_S1); + H5Tset_size (st_id, slen); + if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, + H5P_DEFAULT, (void *) s) < 0) + { + H5Tclose (st_id); + H5Tclose (type_hid); + H5Sclose (space_hid); + H5Dclose (data_hid); + return false; + } ! matrix = charMatrix (s); ! H5Tclose (st_id); ! H5Tclose (type_hid); ! H5Sclose (space_hid); ! H5Dclose (data_hid); ! return true; ! } } ! else if (rank == 1) { ! // string vector ! hsize_t elements, maxdim; ! H5Sget_simple_extent_dims (space_hid, &elements, &maxdim); ! int slen = H5Tget_size (type_hid); ! if (slen < 0) { H5Tclose (type_hid); H5Sclose (space_hid); H5Dclose (data_hid); return false; } ! else { ! // hdf5 string arrays store strings of all the ! // same physical length (I think), which is ! // slightly wasteful, but oh well. ! ! OCTAVE_LOCAL_BUFFER (char, s, elements * slen); ! // create datatype for (null-terminated) string ! // to read into: ! hid_t st_id = H5Tcopy (H5T_C_S1); ! H5Tset_size (st_id, slen); ! if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, ! H5P_DEFAULT, (void *) s) < 0) ! { ! H5Tclose (st_id); ! H5Tclose (type_hid); ! H5Sclose (space_hid); ! H5Dclose (data_hid); ! return false; ! } ! ! charMatrix chm (elements, slen - 1); ! for (hsize_t i = 0; i < elements; ++i) ! { ! chm.insert (s + i*slen, i, 0); ! } ! ! matrix = chm; ! ! H5Tclose (st_id); ! H5Tclose (type_hid); ! H5Sclose (space_hid); ! H5Dclose (data_hid); ! return true; ! } ! } ! else ! { H5Tclose (type_hid); H5Sclose (space_hid); H5Dclose (data_hid); ! return false; } } } #endif