Mercurial > hg > octave-lyh
view src/octave-value/ov-str-mat.cc @ 15057:46b19589b593
maint: Partition src/ directory with more code in subdirs.
Create new octave-value dir for ov* code.
Create new parse-tre dir for pt* code.
Move OPERATORS and TEMPLATE-INST directories to lowercase names
* octave-value/module.mk: Hook code in octave-value dir into build system.
* octave-value/ov-base-diag.cc,
octave-value/ov-base-diag.h, octave-value/ov-base-int.cc,
octave-value/ov-base-int.h, octave-value/ov-base-mat.cc,
octave-value/ov-base-mat.h, octave-value/ov-base-scalar.cc,
octave-value/ov-base-scalar.h, octave-value/ov-base-sparse.cc,
octave-value/ov-base-sparse.h, octave-value/ov-base.cc, octave-value/ov-base.h,
octave-value/ov-bool-mat.cc, octave-value/ov-bool-mat.h,
octave-value/ov-bool-sparse.cc, octave-value/ov-bool-sparse.h,
octave-value/ov-bool.cc, octave-value/ov-bool.h, octave-value/ov-builtin.cc,
octave-value/ov-builtin.h, octave-value/ov-cell.cc, octave-value/ov-cell.h,
octave-value/ov-ch-mat.cc, octave-value/ov-ch-mat.h, octave-value/ov-class.cc,
octave-value/ov-class.h, octave-value/ov-colon.cc, octave-value/ov-colon.h,
octave-value/ov-complex.cc, octave-value/ov-complex.h,
octave-value/ov-cs-list.cc, octave-value/ov-cs-list.h,
octave-value/ov-cx-diag.cc, octave-value/ov-cx-diag.h,
octave-value/ov-cx-mat.cc, octave-value/ov-cx-mat.h,
octave-value/ov-cx-sparse.cc, octave-value/ov-cx-sparse.h,
octave-value/ov-dld-fcn.cc, octave-value/ov-dld-fcn.h,
octave-value/ov-fcn-handle.cc, octave-value/ov-fcn-handle.h,
octave-value/ov-fcn-inline.cc, octave-value/ov-fcn-inline.h,
octave-value/ov-fcn.cc, octave-value/ov-fcn.h, octave-value/ov-float.cc,
octave-value/ov-float.h, octave-value/ov-flt-complex.cc,
octave-value/ov-flt-complex.h, octave-value/ov-flt-cx-diag.cc,
octave-value/ov-flt-cx-diag.h, octave-value/ov-flt-cx-mat.cc,
octave-value/ov-flt-cx-mat.h, octave-value/ov-flt-re-diag.cc,
octave-value/ov-flt-re-diag.h, octave-value/ov-flt-re-mat.cc,
octave-value/ov-flt-re-mat.h, octave-value/ov-int-traits.h,
octave-value/ov-int16.cc, octave-value/ov-int16.h, octave-value/ov-int32.cc,
octave-value/ov-int32.h, octave-value/ov-int64.cc, octave-value/ov-int64.h,
octave-value/ov-int8.cc, octave-value/ov-int8.h, octave-value/ov-intx.h,
octave-value/ov-lazy-idx.cc, octave-value/ov-lazy-idx.h,
octave-value/ov-mex-fcn.cc, octave-value/ov-mex-fcn.h,
octave-value/ov-null-mat.cc, octave-value/ov-null-mat.h,
octave-value/ov-oncleanup.cc, octave-value/ov-oncleanup.h,
octave-value/ov-perm.cc, octave-value/ov-perm.h, octave-value/ov-range.cc,
octave-value/ov-range.h, octave-value/ov-re-diag.cc, octave-value/ov-re-diag.h,
octave-value/ov-re-mat.cc, octave-value/ov-re-mat.h,
octave-value/ov-re-sparse.cc, octave-value/ov-re-sparse.h,
octave-value/ov-scalar.cc, octave-value/ov-scalar.h,
octave-value/ov-str-mat.cc, octave-value/ov-str-mat.h,
octave-value/ov-struct.cc, octave-value/ov-struct.h,
octave-value/ov-type-conv.h, octave-value/ov-typeinfo.cc,
octave-value/ov-typeinfo.h, octave-value/ov-uint16.cc,
octave-value/ov-uint16.h, octave-value/ov-uint32.cc, octave-value/ov-uint32.h,
octave-value/ov-uint64.cc, octave-value/ov-uint64.h, octave-value/ov-uint8.cc,
octave-value/ov-uint8.h, octave-value/ov-usr-fcn.cc, octave-value/ov-usr-fcn.h,
octave-value/ov.cc, octave-value/ov.h: Moved from src/ dir to octave-value dir.
* operators/module.mk, operators/op-b-b.cc, operators/op-b-bm.cc,
operators/op-b-sbm.cc, operators/op-bm-b.cc, operators/op-bm-bm.cc,
operators/op-bm-sbm.cc, operators/op-cdm-cdm.cc, operators/op-cdm-cm.cc,
operators/op-cdm-cs.cc, operators/op-cdm-dm.cc, operators/op-cdm-m.cc,
operators/op-cdm-s.cc, operators/op-cell.cc, operators/op-chm.cc,
operators/op-class.cc, operators/op-cm-cdm.cc, operators/op-cm-cm.cc,
operators/op-cm-cs.cc, operators/op-cm-dm.cc, operators/op-cm-m.cc,
operators/op-cm-pm.cc, operators/op-cm-s.cc, operators/op-cm-scm.cc,
operators/op-cm-sm.cc, operators/op-cs-cm.cc, operators/op-cs-cs.cc,
operators/op-cs-m.cc, operators/op-cs-s.cc, operators/op-cs-scm.cc,
operators/op-cs-sm.cc, operators/op-dm-cdm.cc, operators/op-dm-cm.cc,
operators/op-dm-cs.cc, operators/op-dm-dm.cc, operators/op-dm-m.cc,
operators/op-dm-s.cc, operators/op-dm-scm.cc, operators/op-dm-sm.cc,
operators/op-dm-template.cc, operators/op-dms-template.cc,
operators/op-double-conv.cc, operators/op-fcdm-fcdm.cc,
operators/op-fcdm-fcm.cc, operators/op-fcdm-fcs.cc, operators/op-fcdm-fdm.cc,
operators/op-fcdm-fm.cc, operators/op-fcdm-fs.cc, operators/op-fcm-fcdm.cc,
operators/op-fcm-fcm.cc, operators/op-fcm-fcs.cc, operators/op-fcm-fdm.cc,
operators/op-fcm-fm.cc, operators/op-fcm-fs.cc, operators/op-fcm-pm.cc,
operators/op-fcn.cc, operators/op-fcs-fcm.cc, operators/op-fcs-fcs.cc,
operators/op-fcs-fm.cc, operators/op-fcs-fs.cc, operators/op-fdm-fcdm.cc,
operators/op-fdm-fcm.cc, operators/op-fdm-fcs.cc, operators/op-fdm-fdm.cc,
operators/op-fdm-fm.cc, operators/op-fdm-fs.cc, operators/op-float-conv.cc,
operators/op-fm-fcdm.cc, operators/op-fm-fcm.cc, operators/op-fm-fcs.cc,
operators/op-fm-fdm.cc, operators/op-fm-fm.cc, operators/op-fm-fs.cc,
operators/op-fm-pm.cc, operators/op-fs-fcm.cc, operators/op-fs-fcs.cc,
operators/op-fs-fm.cc, operators/op-fs-fs.cc, operators/op-i16-i16.cc,
operators/op-i32-i32.cc, operators/op-i64-i64.cc, operators/op-i8-i8.cc,
operators/op-int-concat.cc, operators/op-int-conv.cc, operators/op-int.h,
operators/op-m-cdm.cc, operators/op-m-cm.cc, operators/op-m-cs.cc,
operators/op-m-dm.cc, operators/op-m-m.cc, operators/op-m-pm.cc,
operators/op-m-s.cc, operators/op-m-scm.cc, operators/op-m-sm.cc,
operators/op-pm-cm.cc, operators/op-pm-fcm.cc, operators/op-pm-fm.cc,
operators/op-pm-m.cc, operators/op-pm-pm.cc, operators/op-pm-scm.cc,
operators/op-pm-sm.cc, operators/op-pm-template.cc, operators/op-range.cc,
operators/op-s-cm.cc, operators/op-s-cs.cc, operators/op-s-m.cc,
operators/op-s-s.cc, operators/op-s-scm.cc, operators/op-s-sm.cc,
operators/op-sbm-b.cc, operators/op-sbm-bm.cc, operators/op-sbm-sbm.cc,
operators/op-scm-cm.cc, operators/op-scm-cs.cc, operators/op-scm-m.cc,
operators/op-scm-s.cc, operators/op-scm-scm.cc, operators/op-scm-sm.cc,
operators/op-sm-cm.cc, operators/op-sm-cs.cc, operators/op-sm-m.cc,
operators/op-sm-s.cc, operators/op-sm-scm.cc, operators/op-sm-sm.cc,
operators/op-str-m.cc, operators/op-str-s.cc, operators/op-str-str.cc,
operators/op-struct.cc, operators/op-ui16-ui16.cc, operators/op-ui32-ui32.cc,
operators/op-ui64-ui64.cc, operators/op-ui8-ui8.cc: Moved from OPERATORS/
dir to operators/ directory.
* mkops: Correctly print comment in generated file ops.cc that it is made by
mkops. Change sed expression for OPERATORS/ to operators/.
* parse-tree/module.mk: Hook code in parse-tree dir into build system.
* parse-tree/pt-all.h, parse-tree/pt-arg-list.cc, parse-tree/pt-arg-list.h,
parse-tree/pt-assign.cc, parse-tree/pt-assign.h, parse-tree/pt-binop.cc,
parse-tree/pt-binop.h, parse-tree/pt-bp.cc, parse-tree/pt-bp.h,
parse-tree/pt-cbinop.cc, parse-tree/pt-cbinop.h, parse-tree/pt-cell.cc,
parse-tree/pt-cell.h, parse-tree/pt-check.cc, parse-tree/pt-check.h,
parse-tree/pt-cmd.cc, parse-tree/pt-cmd.h, parse-tree/pt-colon.cc,
parse-tree/pt-colon.h, parse-tree/pt-const.cc, parse-tree/pt-const.h,
parse-tree/pt-decl.cc, parse-tree/pt-decl.h, parse-tree/pt-eval.cc,
parse-tree/pt-eval.h, parse-tree/pt-except.cc, parse-tree/pt-except.h,
parse-tree/pt-exp.cc, parse-tree/pt-exp.h, parse-tree/pt-fcn-handle.cc,
parse-tree/pt-fcn-handle.h, parse-tree/pt-id.cc, parse-tree/pt-id.h,
parse-tree/pt-idx.cc, parse-tree/pt-idx.h, parse-tree/pt-jump.cc,
parse-tree/pt-jump.h, parse-tree/pt-loop.cc, parse-tree/pt-loop.h,
parse-tree/pt-mat.cc, parse-tree/pt-mat.h, parse-tree/pt-misc.cc,
parse-tree/pt-misc.h, parse-tree/pt-pr-code.cc, parse-tree/pt-pr-code.h,
parse-tree/pt-select.cc, parse-tree/pt-select.h, parse-tree/pt-stmt.cc,
parse-tree/pt-stmt.h, parse-tree/pt-unop.cc, parse-tree/pt-unop.h,
parse-tree/pt-walk.h, parse-tree/pt.cc, parse-tree/pt.h:
Moved from src/ dir to parse-tree dir.
* template-inst/Array-jit.cc, template-inst/Array-os.cc,
template-inst/Array-sym.cc, template-inst/Array-tc.cc, template-inst/module.mk:
Moved from TEMPLATE-INST dir to template-inst/ directory.
* src/Makefile.am: Add new directories to build system.
* corefcn/module.mk: Use COREFCN_SRC with all capitals to indicate it is not an
Automake special target.
author | Rik <rik@octave.org> |
---|---|
date | Mon, 30 Jul 2012 15:29:19 -0700 |
parents | src/ov-str-mat.cc@f7afecdd87ef |
children |
line wrap: on
line source
/* Copyright (C) 1996-2012 John W. Eaton Copyright (C) 2009-2010 VZLU Prague This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <cctype> #include <iostream> #include <vector> #include "data-conv.h" #include "lo-ieee.h" #include "mach-info.h" #include "mx-base.h" #include "oct-locbuf.h" #include "byte-swap.h" #include "defun.h" #include "gripes.h" #include "ls-ascii-helper.h" #include "ls-hdf5.h" #include "ls-oct-ascii.h" #include "ls-utils.h" #include "oct-obj.h" #include "oct-stream.h" #include "ops.h" #include "ov-scalar.h" #include "ov-re-mat.h" #include "ov-str-mat.h" #include "pr-output.h" #include "pt-mat.h" #include "utils.h" DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_str); DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_sq_str); DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_str, "string", "char"); DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_sq_str, "sq_string", "char"); static octave_base_value * default_numeric_conversion_function (const octave_base_value& a) { octave_base_value *retval = 0; CAST_CONV_ARG (const octave_char_matrix_str&); NDArray nda = v.array_value (true); if (! error_state) { if (nda.numel () == 1) retval = new octave_scalar (nda(0)); else retval = new octave_matrix (nda); } return retval; } octave_base_value::type_conv_info octave_char_matrix_str::numeric_conversion_function (void) const { return octave_base_value::type_conv_info (default_numeric_conversion_function, octave_matrix::static_type_id ()); } octave_value octave_char_matrix_str::do_index_op_internal (const octave_value_list& idx, bool resize_ok, char type) { octave_value retval; octave_idx_type len = idx.length (); switch (len) { case 0: retval = octave_value (matrix, type); break; case 1: { idx_vector i = idx (0).index_vector (); if (! error_state) retval = octave_value (charNDArray (matrix.index (i, resize_ok)), type); } break; case 2: { idx_vector i = idx (0).index_vector (); idx_vector j = idx (1).index_vector (); if (! error_state) retval = octave_value (charNDArray (matrix.index (i, j, resize_ok)), type); } break; default: { Array<idx_vector> idx_vec (dim_vector (len, 1)); for (octave_idx_type i = 0; i < len; i++) idx_vec(i) = idx(i).index_vector (); if (! error_state) retval = octave_value (charNDArray (matrix.index (idx_vec, resize_ok)), type); } break; } return retval; } octave_value octave_char_matrix_str::resize (const dim_vector& dv, bool fill) const { charNDArray retval (matrix); if (fill) retval.resize (dv, 0); else retval.resize (dv); return octave_value (retval, is_sq_string () ? '\'' : '"'); } #define CHAR_MATRIX_CONV(T, INIT, TNAME, FCN) \ T retval INIT; \ \ if (! force_string_conv) \ gripe_invalid_conversion ("string", TNAME); \ else \ { \ warning_with_id ("Octave:str-to-num", \ "implicit conversion from %s to %s", \ "string", TNAME); \ \ retval = octave_char_matrix::FCN (); \ } \ \ return retval double octave_char_matrix_str::double_value (bool force_string_conv) const { CHAR_MATRIX_CONV (double, = 0, "real scalar", double_value); } Complex octave_char_matrix_str::complex_value (bool force_string_conv) const { CHAR_MATRIX_CONV (Complex, = 0, "complex scalar", complex_value); } Matrix octave_char_matrix_str::matrix_value (bool force_string_conv) const { CHAR_MATRIX_CONV (Matrix, , "real matrix", matrix_value); } ComplexMatrix octave_char_matrix_str::complex_matrix_value (bool force_string_conv) const { CHAR_MATRIX_CONV (ComplexMatrix, , "complex matrix", complex_matrix_value); } NDArray octave_char_matrix_str::array_value (bool force_string_conv) const { CHAR_MATRIX_CONV (NDArray, , "real N-d array", array_value); } ComplexNDArray octave_char_matrix_str::complex_array_value (bool force_string_conv) const { CHAR_MATRIX_CONV (ComplexNDArray, , "complex N-d array", complex_array_value); } string_vector octave_char_matrix_str::all_strings (bool) const { string_vector retval; if (matrix.ndims () == 2) { charMatrix chm = matrix.matrix_value (); octave_idx_type n = chm.rows (); retval.resize (n); for (octave_idx_type i = 0; i < n; i++) retval[i] = chm.row_as_string (i); } else error ("invalid conversion of charNDArray to string_vector"); return retval; } std::string octave_char_matrix_str::string_value (bool) const { std::string retval; if (matrix.ndims () == 2) { charMatrix chm = matrix.matrix_value (); retval = chm.row_as_string (0); // FIXME??? } else error ("invalid conversion of charNDArray to string"); return retval; } Array<std::string> octave_char_matrix_str::cellstr_value (void) const { Array<std::string> retval; if (matrix.ndims () == 2) { const charMatrix chm = matrix.matrix_value (); octave_idx_type nr = chm.rows (); retval.clear (nr, 1); for (octave_idx_type i = 0; i < nr; i++) retval.xelem (i) = chm.row_as_string (i); } else error ("cellstr: cannot convert multidimensional arrays"); return retval; } void octave_char_matrix_str::print_raw (std::ostream& os, bool pr_as_read_syntax) const { octave_print_internal (os, matrix, pr_as_read_syntax, current_print_indent_level (), true); } bool octave_char_matrix_str::save_ascii (std::ostream& os) { 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 (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 (); octave_idx_type elements = chm.rows (); os << "# elements: " << elements << "\n"; for (octave_idx_type i = 0; i < elements; i++) { unsigned len = chm.cols (); os << "# length: " << len << "\n"; std::string tstr = chm.row_as_string (i); const char *tmp = tstr.data (); if (tstr.length () > len) panic_impossible (); os.write (tmp, len); os << "\n"; } } return true; } bool octave_char_matrix_str::load_ascii (std::istream& is) { bool success = true; string_vector keywords(3); keywords[0] = "ndims"; keywords[1] = "elements"; keywords[2] = "length"; std::string kw; int val = 0; if (extract_keyword (is, keywords, kw, val, true)) { if (kw == "ndims") { int mdims = val; if (mdims >= 0) { dim_vector dv; dv.resize (mdims); for (int i = 0; i < mdims; i++) is >> dv(i); if (is) { charNDArray tmp(dv); if (tmp.is_empty ()) matrix = tmp; else { char *ftmp = tmp.fortran_vec (); skip_preceeding_newline (is); if (! is.read (ftmp, dv.numel ()) || !is) { error ("load: failed to load string constant"); success = false; } else matrix = tmp; } } else { error ("load: failed to read dimensions"); success = false; } } else { error ("load: failed to extract matrix size"); success = false; } } else if (kw == "elements") { int elements = val; if (elements >= 0) { // FIXME -- 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) { // Use this instead of a C-style character // buffer so that we can properly handle // embedded NUL characters. charMatrix tmp (1, len); char *ptmp = tmp.fortran_vec (); if (len > 0 && ! is.read (ptmp, len)) { error ("load: failed to load string constant"); success = false; break; } else { 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 if (kw == "length") { int len = val; if (len >= 0) { // This is cruft for backward compatiability, // but relatively harmless. // Use this instead of a C-style character buffer so // that we can properly handle embedded NUL characters. charMatrix tmp (1, len); char *ptmp = tmp.fortran_vec (); if (len > 0 && ! is.read (ptmp, len)) { error ("load: failed to load string constant"); } else { if (is) matrix = tmp; else error ("load: failed to load string constant"); } } } else panic_impossible (); } else { error ("load: failed to extract number of rows and columns"); success = false; } return success; } bool 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!! int32_t tmp = - d.length (); os.write (reinterpret_cast<char *> (&tmp), 4); for (int i=0; i < d.length (); i++) { tmp = d(i); os.write (reinterpret_cast<char *> (&tmp), 4); } charNDArray m = char_array_value (); os.write (m.fortran_vec (), d.numel ()); return true; } bool octave_char_matrix_str::load_binary (std::istream& is, bool swap, oct_mach_info::float_format /* fmt */) { int32_t elements; if (! is.read (reinterpret_cast<char *> (&elements), 4)) return false; if (swap) swap_bytes<4> (&elements); if (elements < 0) { int32_t mdims = - elements; int32_t di; dim_vector dv; dv.resize (mdims); for (int i = 0; i < mdims; i++) { if (! is.read (reinterpret_cast<char *> (&di), 4)) return false; if (swap) swap_bytes<4> (&di); dv(i) = di; } // Convert an array with a single dimension to be a row vector. // Octave should never write files like this, other software // might. if (mdims == 1) { mdims = 2; dv.resize (mdims); dv(1) = dv(0); dv(0) = 1; } 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++) { int32_t len; if (! is.read (reinterpret_cast<char *> (&len), 4)) return false; if (swap) swap_bytes<4> (&len); charMatrix btmp (1, len); char *pbtmp = btmp.fortran_vec (); if (! is.read (pbtmp, len)) return false; if (len > max_len) { max_len = len; chm.resize (elements, max_len, 0); } chm.insert (btmp, i, 0); } matrix = chm; } return true; } #if defined (HAVE_HDF5) bool octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name, bool /* save_as_floats */) { dim_vector dv = dims (); int empty = save_hdf5_empty (loc_id, name, dv); if (empty) return (empty > 0); int rank = dv.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] = dv (rank-i-1); space_hid = H5Screate_simple (rank, hdims, 0); if (space_hid < 0) return false; #if HAVE_HDF5_18 data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_CHAR, space_hid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); #else data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_CHAR, space_hid, H5P_DEFAULT); #endif if (data_hid < 0) { H5Sclose (space_hid); return false; } OCTAVE_LOCAL_BUFFER (char, s, dv.numel ()); for (int i = 0; i < dv.numel (); ++i) s[i] = m(i); retval = H5Dwrite (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, s) >= 0; H5Dclose (data_hid); H5Sclose (space_hid); return retval; } bool octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name) { bool retval = false; dim_vector dv; int empty = load_hdf5_empty (loc_id, name, dv); if (empty > 0) matrix.resize (dv); if (empty) return (empty > 0); #if HAVE_HDF5_18 hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT); #else hid_t data_hid = H5Dopen (loc_id, name); #endif 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) { 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 (hsize_t i = 0, j = rank - 1; i < 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, 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, 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, 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; } } return retval; } #endif