26#if defined (HAVE_CONFIG_H)
30#if defined (HAVE_HDF5)
77#if defined (HAVE_HDF5)
82 if (
id > std::numeric_limits<hid_t>::max ())
83 error (
"%s: internal error: ID too large for hid_t", who);
85 return static_cast<hid_t
> (id);
90OCTAVE_NORETURN
static void
91error_unexpected (
const char *name)
93 error (
"unexpected call to %s when HAVE_HDF5 is not defined - please report this bug", name);
99 : file_id (-1), current_item (-1)
101#if defined (HAVE_HDF5)
114#if defined (HAVE_HDF5)
119 std::ios::setstate (std::ios::badbit);
125 error_unexpected (
"hdf5_fstreambase::close");
133#if defined (HAVE_HDF5)
143 error_unexpected (
"hdf5_fstreambase::open");
151#if defined (HAVE_HDF5)
154# if defined (HAVE_HDF5_UTF8)
155 const char *fname = name;
157 std::string fname_str (name);
158 std::string ascii_fname_str = octave::sys::get_ASCII_filename (fname_str);
159 const char *fname = ascii_fname_str.c_str ();
162 if (mode & std::ios::in)
164 else if (mode & std::ios::out)
166 if (mode & std::ios::app && H5Fis_hdf5 (fname) > 0)
169# if defined (HAVE_HDF5_UTF8)
175 std::string abs_ascii_fname
176 = octave::sys::canonicalize_file_name (ascii_fname_str);
177 if (! abs_ascii_fname.empty ())
180 file_id = H5Fcreate (fname, H5F_ACC_TRUNC,
183 std::ios::setstate (std::ios::badbit);
189 std::string::const_iterator first_non_ASCII
190 = std::find_if (fname_str.begin (), fname_str.end (),
191 [](
char c) { return (c < 0 || c >= 128); });
192 if (first_non_ASCII == fname_str.end ())
198 std::ios::setstate (std::ios::badbit);
204 std::string tmp_name = octave::sys::tempnam (
"",
"oct-");
205 octave_hdf5_id hdf5_fid = H5Fcreate (tmp_name.c_str (), H5F_ACC_TRUNC,
211 std::ios::setstate (std::ios::badbit);
220 int res = octave::sys::rename (tmp_name, name, msg);
223 std::ios::setstate (std::ios::badbit);
229 ascii_fname_str = octave::sys::get_ASCII_filename (fname_str);
230 ascii_fname = ascii_fname_str.c_str ();
236 std::ios::setstate (std::ios::badbit);
242 error_unexpected (
"hdf5_fstreambase::open_create");
248make_valid_identifier (
const std::string& nm)
252 std::size_t nm_len = nm.length ();
256 if (! isalpha (nm[0]))
259 for (std::size_t i = 0; i < nm_len; i++)
262 retval += (isalnum (c) || c ==
'_') ? c :
'_';
277#if defined (HAVE_HDF5)
280 if ((n = H5Tget_nmembers (t1)) != H5Tget_nmembers (t2))
283 for (
int i = 0; i < n; ++i)
285 hid_t mt1 = H5Tget_member_type (t1, i);
286 hid_t mt2 = H5Tget_member_type (t2, i);
288 if (H5Tget_class (mt1) != H5Tget_class (mt2))
308#if defined (HAVE_HDF5)
322#if defined (HAVE_HDF5_18)
326 H5Eget_auto (&err_fcn, &err_fcn_data);
327 H5Eset_auto (
nullptr,
nullptr);
330 hid_t attr_id = H5Aopen_name (loc_id, attr_name);
340#if defined (HAVE_HDF5_18)
343 H5Eset_auto (err_fcn, err_fcn_data);
354 const char *attr_name,
void *buf)
356#if defined (HAVE_HDF5)
370#if defined (HAVE_HDF5_18)
374 H5Eget_auto (&err_fcn, &err_fcn_data);
375 H5Eset_auto (
nullptr,
nullptr);
378 hid_t attr_id = H5Aopen_name (loc_id, attr_name);
382 hid_t space_id = H5Aget_space (attr_id);
384 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
387 retval = H5Aread (attr_id, type_id, buf) >= 0;
392#if defined (HAVE_HDF5_18)
395 H5Eset_auto (err_fcn, err_fcn_data);
413#if defined (HAVE_HDF5)
415 hid_t type_id = H5Tcreate (H5T_COMPOUND,
sizeof (
double) * 2);
417 H5Tinsert (type_id,
"real", 0 *
sizeof (
double), num_type);
418 H5Tinsert (type_id,
"imag", 1 *
sizeof (
double), num_type);
427#if defined (HAVE_HDF5)
436hdf5_make_range_type (hid_t num_type)
438 hid_t type_id = H5Tcreate (H5T_COMPOUND,
sizeof (
double) * 3);
440 H5Tinsert (type_id,
"base", 0 *
sizeof (
double), num_type);
441 H5Tinsert (type_id,
"limit", 1 *
sizeof (
double), num_type);
442 H5Tinsert (type_id,
"increment", 2 *
sizeof (
double), num_type);
448load_inline_fcn (hid_t loc_id,
const char *name,
octave_value& retval)
450#if defined (HAVE_HDF5)
452 hid_t group_hid, data_hid, space_hid, type_hid, type_class_hid, st_id;
456#if defined (HAVE_HDF5_18)
459 group_hid = H5Gopen (loc_id, name);
461 if (group_hid < 0)
return -1;
463#if defined (HAVE_HDF5_18)
466 data_hid = H5Dopen (group_hid,
"args");
468 space_hid = H5Dget_space (data_hid);
469 rank = H5Sget_simple_extent_ndims (space_hid);
474 H5Sclose (space_hid);
475 H5Gclose (group_hid);
482 H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
492 H5Sclose (space_hid);
493 H5Gclose (group_hid);
498 H5Sclose (space_hid);
500 for (std::size_t i = 0; i < hdims[1]; i++)
501 args(i+1) = std::string (s1 + i*hdims[0]);
503#if defined (HAVE_HDF5_18)
506 data_hid = H5Dopen (group_hid,
"nm");
511 H5Gclose (group_hid);
515 type_hid = H5Dget_type (data_hid);
516 type_class_hid = H5Tget_class (type_hid);
518 if (type_class_hid != H5T_STRING)
522 H5Gclose (group_hid);
526 space_hid = H5Dget_space (data_hid);
527 rank = H5Sget_simple_extent_ndims (space_hid);
531 H5Sclose (space_hid);
534 H5Gclose (group_hid);
538 slen = H5Tget_size (type_hid);
541 H5Sclose (space_hid);
544 H5Gclose (group_hid);
551 st_id = H5Tcopy (H5T_C_S1);
552 H5Tset_size (st_id, slen);
557 H5Sclose (space_hid);
559 H5Gclose (group_hid);
567#if defined (HAVE_HDF5_18)
570 data_hid = H5Dopen (group_hid,
"iftext");
575 H5Gclose (group_hid);
579 type_hid = H5Dget_type (data_hid);
580 type_class_hid = H5Tget_class (type_hid);
582 if (type_class_hid != H5T_STRING)
586 H5Gclose (group_hid);
590 space_hid = H5Dget_space (data_hid);
591 rank = H5Sget_simple_extent_ndims (space_hid);
595 H5Sclose (space_hid);
598 H5Gclose (group_hid);
602 slen = H5Tget_size (type_hid);
605 H5Sclose (space_hid);
608 H5Gclose (group_hid);
615 st_id = H5Tcopy (H5T_C_S1);
616 H5Tset_size (st_id, slen);
621 H5Sclose (space_hid);
623 H5Gclose (group_hid);
629 args(0) = std::string (iftext_tmp);
631 octave::interpreter& interp = octave::__get_interpreter__ ();
642 octave_unused_parameter (loc_id);
643 octave_unused_parameter (name);
644 octave_unused_parameter (retval);
665hdf5_read_next_data_internal (hid_t group_id,
const char *name,
void *dv)
669 hid_t type_class_id = -1;
671 hid_t subgroup_id = -1;
676 bool ident_valid = octave::valid_identifier (name);
678 std::string vname = name;
680 octave::type_info&
type_info = octave::__get_type_info__ ();
688 vname = make_valid_identifier (vname);
691 ident_valid = octave::valid_identifier (vname);
694 H5Gget_objinfo (group_id, name, 1, &info);
696 if (info.type == H5G_GROUP && ident_valid)
698#if defined (HAVE_HDF5_18)
701 subgroup_id = H5Gopen (group_id, name);
706 retval = subgroup_id;
712#if defined (HAVE_HDF5_18)
715 data_id = H5Dopen (subgroup_id,
"type");
724 type_id = H5Dget_type (data_id);
726 type_class_id = H5Tget_class (type_id);
728 if (type_class_id != H5T_STRING)
731 space_id = H5Dget_space (data_id);
732 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
737 int slen = H5Tget_size (type_id);
744 hid_t st_id = H5Tcopy (H5T_C_S1);
745 H5Tset_size (st_id, slen);
754 if (std::string (typ, slen-1) ==
"inline function")
756 retval = load_inline_fcn (subgroup_id, name,
d->tc);
764 retval = (
d->tc.load_hdf5 (subgroup_id,
"value") ? 1 : -1);
766 catch (
const octave::execution_exception& ee)
775 H5Gclose (subgroup_id);
795 H5Gclose (subgroup_id);
799 retval = (
d->tc.load_hdf5 (group_id, name) ? 1 : -1);
801 catch (
const octave::execution_exception& ee)
808 else if (info.type == H5G_DATASET && ident_valid)
815#if defined (HAVE_HDF5_18)
818 data_id = H5Dopen (group_id, name);
827 type_id = H5Dget_type (data_id);
829 type_class_id = H5Tget_class (type_id);
831 if (type_class_id == H5T_FLOAT)
833 space_id = H5Dget_space (data_id);
835 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
844 else if (type_class_id == H5T_INTEGER)
848#if defined (HAVE_H5T_GET_NATIVE_TYPE)
852 switch (H5Tget_native_type (type_id, H5T_DIR_ASCEND))
854 case H5T_NATIVE_CHAR:
858 case H5T_NATIVE_SHORT:
863 case H5T_NATIVE_LONG:
867 case H5T_NATIVE_LLONG:
871 case H5T_NATIVE_UCHAR:
875 case H5T_NATIVE_USHORT:
879 case H5T_NATIVE_UINT:
880 case H5T_NATIVE_ULONG:
884 case H5T_NATIVE_ULLONG:
889 hid_t int_sign = H5Tget_sign (type_id);
891 if (int_sign == H5T_SGN_ERROR)
892 warning (
"load: can't read '%s' (unknown datatype)", name);
895 if (int_sign == H5T_SGN_NONE)
896 int_typ.push_back (
'u');
897 int_typ.append (
"int");
899 int slen = H5Tget_size (type_id);
901 warning (
"load: can't read '%s' (unknown datatype)", name);
907 int_typ.append (
"8 ");
911 int_typ.append (
"16 ");
915 int_typ.append (
"32 ");
919 int_typ.append (
"64 ");
923 warning (
"load: can't read '%s' (unknown datatype)",
932 warning (
"load: can't read '%s' (unknown datatype)", name);
936 space_id = H5Dget_space (data_id);
938 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
941 int_typ.append (
"scalar");
943 int_typ.append (
"matrix");
949 else if (type_class_id == H5T_STRING)
951 else if (type_class_id == H5T_COMPOUND)
954 hid_t range_type = hdf5_make_range_type (H5T_NATIVE_DOUBLE);
959 space_id = H5Dget_space (data_id);
960 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
972 d->tc = octave_value_typeinfo::lookup_type (
"range");
976 warning (
"load: can't read '%s' (unknown datatype)", name);
981 H5Tclose (range_type);
982 H5Tclose (complex_type);
986 warning (
"load: can't read '%s' (unknown datatype)", name);
996 retval = (
d->tc.load_hdf5 (group_id, name) ? 1 : -1);
998 catch (
const octave::execution_exception& ee)
1011 warning (
"load: skipping invalid identifier '%s' in hdf5 file",
1020 warning (
"load: error while reading hdf5 item '%s'", name);
1026 int comment_length = H5Gget_comment (group_id, name, 0,
nullptr);
1028 if (comment_length > 1)
1031 H5Gget_comment (group_id, name, comment_length, tdoc);
1034 else if (vname != name)
1053#if defined (HAVE_HDF5)
1055 hid_t new_id = check_hdf5_id_value (group_id,
"hdf5_read_next_data");
1057 return hdf5_read_next_data_internal (new_id, name, dv);
1066 void *operator_data)
1068#if defined (HAVE_HDF5)
1070 hid_t new_id = check_hdf5_id_value (loc_id,
"hdf5_h5g_iterate");
1072 return H5Giterate (new_id, name, idx, hdf5_read_next_data_internal,
1089#if defined (HAVE_HDF5)
1091 octave::check_hdf5_types ();
1100 herr_t H5Giterate_retval = -1;
1102 hsize_t num_obj = 0;
1103#if defined (HAVE_HDF5_18)
1106 hid_t group_id = H5Gopen (hs.
file_id,
"/");
1108 H5Gget_num_objs (group_id, &num_obj);
1109 H5Gclose (group_id);
1113 bool load_named_vars = argv_idx < argc;
1114 while (load_named_vars && hs.
current_item <
static_cast<int> (num_obj))
1116 std::vector<char> var_name;
1118 std::size_t
len = 0;
1121 var_name.resize (
len+1);
1124 for (
int i = argv_idx; i < argc; i++)
1127 if (pattern.
match (std::string (&var_name[0])))
1142 hdf5_read_next_data_internal, &
d);
1144 if (H5Giterate_retval > 0)
1157 if (!
d.name.empty ())
1172#if defined (HAVE_HDF5)
1176 hid_t as_id = H5Screate (H5S_SCALAR);
1180#if defined (HAVE_HDF5_18)
1181 hid_t a_id = H5Acreate (loc_id, attr_name, H5T_NATIVE_UCHAR,
1184 hid_t a_id = H5Acreate (loc_id, attr_name,
1189 unsigned char attr_val = 1;
1191 retval = H5Awrite (a_id, H5T_NATIVE_UCHAR, &attr_val);
1212 const char *attr_name,
void *buf)
1214#if defined (HAVE_HDF5)
1218 hid_t as_id = H5Screate (H5S_SCALAR);
1222#if defined (HAVE_HDF5_18)
1223 hid_t a_id = H5Acreate (loc_id, attr_name, type_id,
1226 hid_t a_id = H5Acreate (loc_id, attr_name,
1231 retval = H5Awrite (a_id, type_id, buf);
1257#if defined (HAVE_HDF5)
1259 hsize_t sz =
d.length ();
1262 hid_t space_hid = -1;
1263 hid_t data_hid = -1;
1265 for (hsize_t i = 0; i < sz; i++)
1275 space_hid = H5Screate_simple (1, &sz,
nullptr);
1276 if (space_hid < 0)
return space_hid;
1277#if defined (HAVE_HDF5_18)
1287 H5Sclose (space_hid);
1294 H5Dclose (data_hid);
1295 H5Sclose (space_hid);
1300 return (retval == 0 ? 1 : retval);
1314#if defined (HAVE_HDF5)
1319 hsize_t hdims, maxdims;
1320#if defined (HAVE_HDF5_18)
1323 hid_t data_hid = H5Dopen (loc_id, name);
1325 hid_t space_id = H5Dget_space (data_hid);
1326 H5Sget_simple_extent_dims (space_id, &hdims, &maxdims);
1336 for (hsize_t i = 0; i < hdims; i++)
1340 H5Sclose (space_id);
1341 H5Dclose (data_hid);
1343 return (retval == 0 ? hdims : retval);
1358#if defined (HAVE_HDF5)
1359# if defined (HAVE_HDF5_INT2FLOAT_CONVERSIONS)
1364 return H5T_NATIVE_UCHAR;
1367 return H5T_NATIVE_USHORT;
1370 return H5T_NATIVE_UINT;
1373 return H5T_NATIVE_CHAR;
1376 return H5T_NATIVE_SHORT;
1379 return H5T_NATIVE_INT;
1382 return H5T_NATIVE_FLOAT;
1386 return H5T_NATIVE_DOUBLE;
1391 octave_unused_parameter (st);
1399 octave_unused_parameter (st);
1413 const std::string& name,
const std::string& doc,
1414 bool mark_global,
bool save_as_floats)
1416#if defined (HAVE_HDF5)
1422 "Saving classdef objects is not supported. "
1423 "Attempting to save '%s' as struct.",
1431 hid_t type_id, space_id, data_id, data_type_id;
1432 type_id = space_id = data_id = data_type_id = -1;
1434 bool retval =
false;
1444#if defined (HAVE_HDF5_18)
1448 data_id = H5Gcreate (loc_id, name.c_str (), 0);
1454 type_id = H5Tcopy (H5T_C_S1);
1455 H5Tset_size (type_id, t.length () + 1);
1460 space_id = H5Screate_simple (0, dims,
nullptr);
1463#if defined (HAVE_HDF5_18)
1464 data_type_id = H5Dcreate (data_id,
"type", type_id, space_id,
1468 data_type_id = H5Dcreate (data_id,
"type", type_id, space_id,
1471 if (data_type_id < 0
1477 retval = val.
save_hdf5 (data_id,
"value", save_as_floats);
1480 if (retval && doc.length () > 0
1481 && H5Gset_comment (loc_id, name.c_str (), doc.c_str ()) < 0)
1485 if (retval && mark_global)
1494 if (data_type_id >= 0)
1495 H5Dclose (data_type_id);
1501 H5Sclose (space_id);
1507 error (
"save: error while writing '%s' to hdf5 file", name.c_str ());
1521 const std::string& name,
const std::string& doc,
1522 bool mark_global,
bool save_as_floats)
1524#if defined (HAVE_HDF5)
1526 octave::check_hdf5_types ();
1531 mark_global, save_as_floats);
Vector representing the dimensions (size) of an Array.
void open(const char *name, int mode, int)
void open_create(const char *name, int mode)
octave_map map_value() const
static int static_type_id()
octave_idx_type length() const
bool is_classdef_object() const
bool is_diag_matrix() const
octave_classdef * classdef_object_value(bool silent=false) const
bool is_perm_matrix() const
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
octave_value full_value() const
std::string type_name() const
bool match(const std::string &sym)
octave_value lookup_type(const std::string &nm)
const octave_hdf5_id octave_H5P_DEFAULT
const octave_hdf5_id octave_H5E_DEFAULT
const octave_hdf5_id octave_H5S_ALL
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
bool save_hdf5_data(std::ostream &os, const octave_value &tc, const std::string &name, const std::string &doc, bool mark_global, bool save_as_floats)
int save_hdf5_empty(octave_hdf5_id loc_id, const char *name, const dim_vector &d)
std::string read_hdf5_data(std::istream &is, const std::string &, bool &global, octave_value &tc, std::string &doc, const string_vector &argv, int argv_idx, int argc)
octave_hdf5_err hdf5_add_attr(octave_hdf5_id loc_id, const char *attr_name)
bool hdf5_get_scalar_attr(octave_hdf5_id loc_id, octave_hdf5_id type_id, const char *attr_name, void *buf)
int load_hdf5_empty(octave_hdf5_id loc_id, const char *name, dim_vector &d)
octave_hdf5_id save_type_to_hdf5(save_type st)
octave_hdf5_id hdf5_make_complex_type(octave_hdf5_id num_type)
octave_hdf5_err hdf5_read_next_data(octave_hdf5_id group_id, const char *name, void *dv)
bool add_hdf5_data(octave_hdf5_id loc_id, const octave_value &tc_in, const std::string &name, const std::string &doc, bool mark_global, bool save_as_floats)
octave_hdf5_err hdf5_h5g_iterate(octave_hdf5_id loc_id, const char *name, int *idx, void *operator_data)
bool hdf5_types_compatible(octave_hdf5_id t1, octave_hdf5_id t2)
octave_hdf5_err hdf5_add_scalar_attr(octave_hdf5_id loc_id, octave_hdf5_id type_id, const char *attr_name, void *buf)
bool hdf5_check_attr(octave_hdf5_id loc_id, const char *attr_name)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d