comparison libinterp/corefcn/ls-hdf5.cc @ 20299:bfe66db8addb

don't include hdf5.h or use HDF5 typedefs in public header files (bug #43180) * oct-hdf5-types.h: Rename from oct-hdf5-id.h. * oct-hdf5-types.cc: Rename from oct-hdf5-id.cc. * libinterp/corefcn/module.mk: Update. * oct-hdf5-types.h (octave_hdf5_err): New typedef. * oct-hdf5-types.h, oct-hdf5-types.cc (check_hdf5_types): Rename from check_hdf5_id_type. Also check size of herr_t. * load-save.cc: Include oct-hdf5.h. * ls-hdf5.cc: Include oct-hdf5.h instead of oct-hdf5-id.h. Define hdf5_fstreambase functions that require HDF5 types here instead of in ls-hdf5.h. * ls-hdf5.h, ls-hdf5.cc: Use octave types in public interfaces. * ls-hdf5.h, ov-base.h: Include oct-hdf5-types.h instead of oct-hdf5.h. * oct-hdf5.h: Include oct-hdf5-types.h. Define H5T_NATIVE_IDX here. * ls-hdf5.h: Not here.
author John W. Eaton <jwe@octave.org>
date Mon, 15 Jun 2015 17:42:44 -0400
parents 09ed6f7538dd
children df4165dfc676
comparison
equal deleted inserted replaced
20298:5c088348fddb 20299:bfe66db8addb
53 #include "Cell.h" 53 #include "Cell.h"
54 #include "defun.h" 54 #include "defun.h"
55 #include "error.h" 55 #include "error.h"
56 #include "gripes.h" 56 #include "gripes.h"
57 #include "load-save.h" 57 #include "load-save.h"
58 #include "oct-hdf5-id.h" 58 #include "oct-hdf5.h"
59 #include "oct-obj.h" 59 #include "oct-obj.h"
60 #include "oct-map.h" 60 #include "oct-map.h"
61 #include "ov-cell.h" 61 #include "ov-cell.h"
62 #include "pager.h" 62 #include "pager.h"
63 #include "pt-exp.h" 63 #include "pt-exp.h"
70 #include "ov-lazy-idx.h" 70 #include "ov-lazy-idx.h"
71 71
72 #include "ls-utils.h" 72 #include "ls-utils.h"
73 #include "ls-hdf5.h" 73 #include "ls-hdf5.h"
74 74
75 hdf5_fstreambase::hdf5_fstreambase (const char *name, int mode, int /* prot */)
76 : file_id (-1), current_item (-1)
77 {
78 if (mode & std::ios::in)
79 file_id = H5Fopen (name, H5F_ACC_RDONLY, H5P_DEFAULT);
80 else if (mode & std::ios::out)
81 {
82 if (mode & std::ios::app && H5Fis_hdf5 (name) > 0)
83 file_id = H5Fopen (name, H5F_ACC_RDWR, H5P_DEFAULT);
84 else
85 file_id = H5Fcreate (name, H5F_ACC_TRUNC, H5P_DEFAULT,
86 H5P_DEFAULT);
87 }
88 if (file_id < 0)
89 std::ios::setstate (std::ios::badbit);
90
91 current_item = 0;
92 }
93
94 void
95 hdf5_fstreambase::close (void)
96 {
97 if (file_id >= 0)
98 {
99 if (H5Fclose (file_id) < 0)
100 std::ios::setstate (std::ios::badbit);
101 file_id = -1;
102 }
103 }
104
105 void
106 hdf5_fstreambase::open (const char *name, int mode, int)
107 {
108 clear ();
109
110 if (mode & std::ios::in)
111 file_id = H5Fopen (name, H5F_ACC_RDONLY, H5P_DEFAULT);
112 else if (mode & std::ios::out)
113 {
114 if (mode & std::ios::app && H5Fis_hdf5 (name) > 0)
115 file_id = H5Fopen (name, H5F_ACC_RDWR, H5P_DEFAULT);
116 else
117 file_id = H5Fcreate (name, H5F_ACC_TRUNC, H5P_DEFAULT,
118 H5P_DEFAULT);
119 }
120 if (file_id < 0)
121 std::ios::setstate (std::ios::badbit);
122
123 current_item = 0;
124 }
125
75 static std::string 126 static std::string
76 make_valid_identifier (const std::string& nm) 127 make_valid_identifier (const std::string& nm)
77 { 128 {
78 std::string retval; 129 std::string retval;
79 130
102 // are compatible for reading/writing. This function only 153 // are compatible for reading/writing. This function only
103 // works for non-nested types composed of simple elements (ints, floats...), 154 // works for non-nested types composed of simple elements (ints, floats...),
104 // which is all we need it for 155 // which is all we need it for
105 156
106 bool 157 bool
107 hdf5_types_compatible (hid_t t1, hid_t t2) 158 hdf5_types_compatible (octave_hdf5_id t1, octave_hdf5_id t2)
108 { 159 {
109 int n; 160 int n;
110 if ((n = H5Tget_nmembers (t1)) != H5Tget_nmembers (t2)) 161 if ((n = H5Tget_nmembers (t1)) != H5Tget_nmembers (t2))
111 return false; 162 return false;
112 163
127 178
128 // Return true if loc_id has the attribute named attr_name, and false 179 // Return true if loc_id has the attribute named attr_name, and false
129 // otherwise. 180 // otherwise.
130 181
131 bool 182 bool
132 hdf5_check_attr (hid_t loc_id, const char *attr_name) 183 hdf5_check_attr (octave_hdf5_id loc_id, const char *attr_name)
133 { 184 {
134 bool retval = false; 185 bool retval = false;
135 186
136 // we have to pull some shenanigans here to make sure 187 // we have to pull some shenanigans here to make sure
137 // HDF5 doesn't print out all sorts of error messages if we 188 // HDF5 doesn't print out all sorts of error messages if we
168 #endif 219 #endif
169 return retval; 220 return retval;
170 } 221 }
171 222
172 bool 223 bool
173 hdf5_get_scalar_attr (hid_t loc_id, hid_t type_id, 224 hdf5_get_scalar_attr (octave_hdf5_id loc_id, octave_hdf5_id type_id,
174 const char *attr_name, void *buf) 225 const char *attr_name, void *buf)
175 { 226 {
176 bool retval = false; 227 bool retval = false;
177 228
178 // we have to pull some shenanigans here to make sure 229 // we have to pull some shenanigans here to make sure
222 // we will store Octave complex types (pairs of floating-point numbers). 273 // we will store Octave complex types (pairs of floating-point numbers).
223 // NUM_TYPE is the HDF5 numeric type to use for storage (e.g. 274 // NUM_TYPE is the HDF5 numeric type to use for storage (e.g.
224 // H5T_NATIVE_DOUBLE to save as 'double'). Note that any necessary 275 // H5T_NATIVE_DOUBLE to save as 'double'). Note that any necessary
225 // conversions are handled automatically by HDF5. 276 // conversions are handled automatically by HDF5.
226 277
227 hid_t 278 octave_hdf5_id
228 hdf5_make_complex_type (hid_t num_type) 279 hdf5_make_complex_type (octave_hdf5_id num_type)
229 { 280 {
230 hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 2); 281 hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 2);
231 282
232 H5Tinsert (type_id, "real", 0 * sizeof (double), num_type); 283 H5Tinsert (type_id, "real", 0 * sizeof (double), num_type);
233 H5Tinsert (type_id, "imag", 1 * sizeof (double), num_type); 284 H5Tinsert (type_id, "imag", 1 * sizeof (double), num_type);
243 // 294 //
244 // It returns 1 on success (in which case H5Giterate stops and returns), 295 // It returns 1 on success (in which case H5Giterate stops and returns),
245 // -1 on error, and 0 to tell H5Giterate to continue on to the next item 296 // -1 on error, and 0 to tell H5Giterate to continue on to the next item
246 // (e.g. if NAME was a data type we don't recognize). 297 // (e.g. if NAME was a data type we don't recognize).
247 298
248 herr_t 299 octave_hdf5_err
249 hdf5_read_next_data (hid_t group_id, const char *name, void *dv) 300 hdf5_read_next_data (octave_hdf5_id group_id, const char *name, void *dv)
250 { 301 {
251 hdf5_callback_data *d = static_cast<hdf5_callback_data *> (dv); 302 hdf5_callback_data *d = static_cast<hdf5_callback_data *> (dv);
252 hid_t type_id = -1; 303 hid_t type_id = -1;
253 hid_t type_class_id = -1; 304 hid_t type_class_id = -1;
254 hid_t data_id = -1; 305 hid_t data_id = -1;
586 std::string 637 std::string
587 read_hdf5_data (std::istream& is, const std::string& /* filename */, 638 read_hdf5_data (std::istream& is, const std::string& /* filename */,
588 bool& global, octave_value& tc, std::string& doc, 639 bool& global, octave_value& tc, std::string& doc,
589 const string_vector& argv, int argv_idx, int argc) 640 const string_vector& argv, int argv_idx, int argc)
590 { 641 {
591 check_hdf5_id_type (); 642 check_hdf5_types ();
592 643
593 std::string retval; 644 std::string retval;
594 645
595 doc.resize (0); 646 doc.resize (0);
596 647
661 return retval; 712 return retval;
662 } 713 }
663 714
664 // Add an attribute named attr_name to loc_id (a simple scalar 715 // Add an attribute named attr_name to loc_id (a simple scalar
665 // attribute with value 1). Return value is >= 0 on success. 716 // attribute with value 1). Return value is >= 0 on success.
666 herr_t 717 octave_hdf5_err
667 hdf5_add_attr (hid_t loc_id, const char *attr_name) 718 hdf5_add_attr (octave_hdf5_id loc_id, const char *attr_name)
668 { 719 {
669 herr_t retval = 0; 720 herr_t retval = 0;
670 721
671 hid_t as_id = H5Screate (H5S_SCALAR); 722 hid_t as_id = H5Screate (H5S_SCALAR);
672 723
696 retval = as_id; 747 retval = as_id;
697 748
698 return retval; 749 return retval;
699 } 750 }
700 751
701 herr_t 752 octave_hdf5_err
702 hdf5_add_scalar_attr (hid_t loc_id, hid_t type_id, 753 hdf5_add_scalar_attr (octave_hdf5_id loc_id, octave_hdf5_id type_id,
703 const char *attr_name, void *buf) 754 const char *attr_name, void *buf)
704 { 755 {
705 herr_t retval = 0; 756 herr_t retval = 0;
706 757
707 hid_t as_id = H5Screate (H5S_SCALAR); 758 hid_t as_id = H5Screate (H5S_SCALAR);
735 // Save an empty matrix, if needed. Returns 786 // Save an empty matrix, if needed. Returns
736 // > 0 Saved empty matrix 787 // > 0 Saved empty matrix
737 // = 0 Not an empty matrix; did nothing 788 // = 0 Not an empty matrix; did nothing
738 // < 0 Error condition 789 // < 0 Error condition
739 int 790 int
740 save_hdf5_empty (hid_t loc_id, const char *name, const dim_vector d) 791 save_hdf5_empty (octave_hdf5_id loc_id, const char *name, const dim_vector d)
741 { 792 {
742 hsize_t sz = d.length (); 793 hsize_t sz = d.length ();
743 OCTAVE_LOCAL_BUFFER (octave_idx_type, dims, sz); 794 OCTAVE_LOCAL_BUFFER (octave_idx_type, dims, sz);
744 bool empty = false; 795 bool empty = false;
745 hid_t space_hid = -1; 796 hid_t space_hid = -1;
785 // Load an empty matrix, if needed. Returns 836 // Load an empty matrix, if needed. Returns
786 // > 0 loaded empty matrix, dimensions returned 837 // > 0 loaded empty matrix, dimensions returned
787 // = 0 Not an empty matrix; did nothing 838 // = 0 Not an empty matrix; did nothing
788 // < 0 Error condition 839 // < 0 Error condition
789 int 840 int
790 load_hdf5_empty (hid_t loc_id, const char *name, dim_vector &d) 841 load_hdf5_empty (octave_hdf5_id loc_id, const char *name, dim_vector &d)
791 { 842 {
792 if (! hdf5_check_attr (loc_id, "OCTAVE_EMPTY_MATRIX")) 843 if (! hdf5_check_attr (loc_id, "OCTAVE_EMPTY_MATRIX"))
793 return 0; 844 return 0;
794 845
795 hsize_t hdims, maxdims; 846 hsize_t hdims, maxdims;
824 875
825 #if HAVE_HDF5_INT2FLOAT_CONVERSIONS 876 #if HAVE_HDF5_INT2FLOAT_CONVERSIONS
826 877
827 // return the HDF5 type id corresponding to the Octave save_type 878 // return the HDF5 type id corresponding to the Octave save_type
828 879
829 hid_t 880 octave_hdf5_id
830 save_type_to_hdf5 (save_type st) 881 save_type_to_hdf5 (save_type st)
831 { 882 {
832 switch (st) 883 switch (st)
833 { 884 {
834 case LS_U_CHAR: 885 case LS_U_CHAR:
863 // be either a file or a group within a file. Return true if 914 // be either a file or a group within a file. Return true if
864 // successful. This function calls itself recursively for lists 915 // successful. This function calls itself recursively for lists
865 // (stored as HDF5 groups). 916 // (stored as HDF5 groups).
866 917
867 bool 918 bool
868 add_hdf5_data (hid_t loc_id, const octave_value& tc, 919 add_hdf5_data (octave_hdf5_id loc_id, const octave_value& tc,
869 const std::string& name, const std::string& doc, 920 const std::string& name, const std::string& doc,
870 bool mark_as_global, bool save_as_floats) 921 bool mark_as_global, bool save_as_floats)
871 { 922 {
872 hsize_t dims[3]; 923 hsize_t dims[3];
873 hid_t type_id, space_id, data_id, data_type_id; 924 hid_t type_id, space_id, data_id, data_type_id;
953 bool 1004 bool
954 save_hdf5_data (std::ostream& os, const octave_value& tc, 1005 save_hdf5_data (std::ostream& os, const octave_value& tc,
955 const std::string& name, const std::string& doc, 1006 const std::string& name, const std::string& doc,
956 bool mark_as_global, bool save_as_floats) 1007 bool mark_as_global, bool save_as_floats)
957 { 1008 {
958 check_hdf5_id_type (); 1009 check_hdf5_types ();
959 1010
960 hdf5_ofstream& hs = dynamic_cast<hdf5_ofstream&> (os); 1011 hdf5_ofstream& hs = dynamic_cast<hdf5_ofstream&> (os);
961 1012
962 return add_hdf5_data (hs.file_id, tc, name, doc, 1013 return add_hdf5_data (hs.file_id, tc, name, doc,
963 mark_as_global, save_as_floats); 1014 mark_as_global, save_as_floats);