1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 #include <string>
15
16 #include "H5private.h" // for HDmemset
17 #include "H5Include.h"
18 #include "H5Exception.h"
19 #include "H5IdComponent.h"
20 #include "H5PropList.h"
21 #include "H5OcreatProp.h"
22 #include "H5DcreatProp.h"
23 #include "H5DxferProp.h"
24 #include "H5DataSpace.h"
25 #include "H5LcreatProp.h"
26 #include "H5LaccProp.h"
27 #include "H5DaccProp.h"
28 #include "H5Location.h"
29 #include "H5Object.h"
30 #include "H5AbstractDs.h"
31 #include "H5DataType.h"
32 #include "H5DataSet.h"
33 #include "H5AtomType.h"
34 #include "H5IntType.h"
35 #include "H5EnumType.h"
36
37 namespace H5 {
38
39 //--------------------------------------------------------------------------
40 // Function: EnumType default constructor
41 ///\brief Default constructor: Creates a stub datatype
42 // Programmer Binh-Minh Ribler - 2000
43 //--------------------------------------------------------------------------
EnumType()44 EnumType::EnumType() : DataType() {}
45
46 //--------------------------------------------------------------------------
47 // Function: EnumType overloaded constructor
48 ///\brief Creates an EnumType object using the id of an existing datatype.
49 ///\param existing_id - IN: Id of an existing datatype
50 ///\exception H5::DataTypeIException
51 // Programmer Binh-Minh Ribler - 2000
52 //--------------------------------------------------------------------------
EnumType(const hid_t existing_id)53 EnumType::EnumType(const hid_t existing_id) : DataType( existing_id ) {}
54
55 //--------------------------------------------------------------------------
56 // Function: EnumType copy constructor
57 ///\brief Copy constructor: same HDF5 object as \a original
58 // Programmer Binh-Minh Ribler - 2000
59 //--------------------------------------------------------------------------
EnumType(const EnumType & original)60 EnumType::EnumType(const EnumType& original) : DataType( original ) {}
61
62 //--------------------------------------------------------------------------
63 // Function: EnumType overloaded constructor
64 ///\brief Creates an empty enumeration datatype given a size, in bytes.
65 ///\param size - IN: Number of bytes in the datatype to create
66 ///\exception H5::DataTypeIException
67 // Description
68 // The DataType constructor calls the C API H5Tcreate to create
69 // the enum datatype.
70 // Programmer Binh-Minh Ribler - 2000
71 //--------------------------------------------------------------------------
EnumType(size_t size)72 EnumType::EnumType(size_t size) : DataType( H5T_ENUM, size ) {}
73
74 //--------------------------------------------------------------------------
75 // Function: EnumType overloaded constructor
76 ///\brief Gets the enum datatype of the specified dataset.
77 ///\param dataset - IN: Dataset that this enum datatype associates with
78 ///\exception H5::DataTypeIException
79 // Programmer Binh-Minh Ribler - 2000
80 //--------------------------------------------------------------------------
EnumType(const DataSet & dataset)81 EnumType::EnumType(const DataSet& dataset) : DataType()
82 {
83 // Calls C function H5Dget_type to get the id of the datatype
84 id = H5Dget_type(dataset.getId());
85
86 // If the datatype id is not valid, throw an exception
87 if (id < 0)
88 {
89 throw DataSetIException("EnumType constructor", "H5Dget_type failed");
90 }
91 }
92
93 //--------------------------------------------------------------------------
94 // Function: EnumType overloaded constructor
95 ///\brief Creates a new enum datatype based on an integer datatype.
96 ///\param data_type - IN: Base datatype
97 ///\exception H5::DataTypeIException
98 // Programmer Binh-Minh Ribler - 2000
99 //--------------------------------------------------------------------------
EnumType(const IntType & data_type)100 EnumType::EnumType(const IntType& data_type) : DataType()
101 {
102 // Calls C function H5Tenum_create to get the id of the datatype
103 id = H5Tenum_create(data_type.getId());
104
105 // If the datatype id is not valid, throw an exception
106 if (id < 0)
107 {
108 throw DataSetIException("EnumType constructor", "H5Tenum_create failed");
109 }
110 }
111
112 //--------------------------------------------------------------------------
113 // Function: EnumType overloaded constructor
114 ///\brief Creates an EnumType instance by opening an HDF5 enum datatype
115 /// given its name, provided as a C character string.
116 ///\param dtype_name - IN: Enum datatype name
117 ///\param loc - IN: Location of the type
118 ///\exception H5::DataTypeIException
119 // Programmer Binh-Minh Ribler - Dec 2016
120 // Description
121 // In 1.10.1, this constructor was introduced and may replace the
122 // existing function CommonFG::openEnumType(const char*) to
123 // improve usability.
124 // -BMR, Dec 2016
125 //--------------------------------------------------------------------------
EnumType(const H5Location & loc,const char * dtype_name)126 EnumType::EnumType(const H5Location& loc, const char *dtype_name) : DataType()
127 {
128 id = p_opentype(loc, dtype_name);
129 }
130
131 //--------------------------------------------------------------------------
132 // Function: EnumType overloaded constructor
133 ///\brief Creates an EnumType instance by opening an HDF5 enum datatype
134 /// given its name, provided as an \c H5std_string.
135 ///\param loc - IN: Location of the type
136 ///\param dtype_name - IN: Enum datatype name
137 ///\exception H5::DataTypeIException
138 // Programmer Binh-Minh Ribler - Dec 2016
139 // Description
140 // In 1.10.1, this constructor was introduced and may replace the
141 // existing function CommonFG::openEnumType(const H5std_string&)
142 // to improve usability.
143 // -BMR, Dec 2016
144 //--------------------------------------------------------------------------
EnumType(const H5Location & loc,const H5std_string & dtype_name)145 EnumType::EnumType(const H5Location& loc, const H5std_string& dtype_name) : DataType()
146 {
147 id = p_opentype(loc, dtype_name.c_str());
148 }
149
150 //--------------------------------------------------------------------------
151 // Function: EnumType::decode
152 ///\brief Returns an EnumType object via DataType* by decoding the
153 /// binary object description of this type.
154 ///
155 ///\exception H5::DataTypeIException
156 // Programmer Binh-Minh Ribler - Aug 2017
157 //--------------------------------------------------------------------------
decode() const158 DataType* EnumType::decode() const
159 {
160 hid_t encoded_enumtype_id = H5I_INVALID_HID;
161 try {
162 encoded_enumtype_id = p_decode();
163 }
164 catch (DataTypeIException &err) {
165 throw;
166 }
167 EnumType *encoded_enumtype = new EnumType;
168 encoded_enumtype->p_setId(encoded_enumtype_id);
169 return(encoded_enumtype);
170 }
171
172 //--------------------------------------------------------------------------
173 // Function: EnumType::insert
174 ///\brief Inserts a new member to this enumeration datatype.
175 ///\param name - IN: Name of the new member
176 ///\param value - IN: Pointer to the value of the new member
177 ///\exception H5::DataTypeIException
178 // Programmer Binh-Minh Ribler - 2000
179 //--------------------------------------------------------------------------
insert(const char * name,void * value) const180 void EnumType::insert(const char* name, void *value) const
181 {
182 // Calls C routine H5Tenum_insert to insert the new enum datatype member.
183 herr_t ret_value = H5Tenum_insert(id, name, value);
184 if (ret_value < 0)
185 {
186 throw DataTypeIException("EnumType::insert", "H5Tenum_insert failed");
187 }
188 }
189
190 //--------------------------------------------------------------------------
191 // Function: EnumType::insert
192 ///\brief This is an overloaded member function, provided for convenience.
193 /// It differs from the above function only in the type of
194 /// argument \a name.
195 // Programmer Binh-Minh Ribler - 2000
196 //--------------------------------------------------------------------------
insert(const H5std_string & name,void * value) const197 void EnumType::insert(const H5std_string& name, void *value) const
198 {
199 insert(name.c_str(), value);
200 }
201
202 //--------------------------------------------------------------------------
203 // Function: EnumType::nameOf
204 ///\brief Returns the symbol name corresponding to a specified member
205 /// of this enumeration datatype.
206 ///\param value - IN: Pointer to the value of the enum datatype
207 ///\param size - IN: Size for the name
208 ///\exception H5::DataTypeIException
209 // Programmer Binh-Minh Ribler - 2000
210 //--------------------------------------------------------------------------
nameOf(void * value,size_t size) const211 H5std_string EnumType::nameOf(void *value, size_t size) const
212 {
213 char* name_C = new char[size+1]; // temporary C-string for C API
214 HDmemset(name_C, 0, size+1); // clear buffer
215
216 // Calls C routine H5Tenum_nameof to get the name of the specified enum type
217 herr_t ret_value = H5Tenum_nameof(id, value, name_C, size);
218
219 // If H5Tenum_nameof returns a negative value, raise an exception,
220 if (ret_value < 0)
221 {
222 delete []name_C;
223 throw DataTypeIException("EnumType::nameOf", "H5Tenum_nameof failed");
224 }
225 // otherwise, create the string to hold the datatype name and return it
226 H5std_string name(name_C);
227 delete []name_C;
228 return(name);
229 }
230
231 //--------------------------------------------------------------------------
232 // Function: EnumType::valueOf
233 ///\brief Retrieves the value corresponding to a member of this
234 /// enumeration datatype, given the member's name.
235 ///\param name - IN: Name of the queried member
236 ///\param value - OUT: Pointer to the retrieved value
237 ///\exception H5::DataTypeIException
238 // Programmer Binh-Minh Ribler - 2000
239 //--------------------------------------------------------------------------
valueOf(const char * name,void * value) const240 void EnumType::valueOf(const char* name, void *value) const
241 {
242 // Calls C routine H5Tenum_valueof to get the enum datatype value
243 herr_t ret_value = H5Tenum_valueof(id, name, value);
244 if (ret_value < 0)
245 {
246 throw DataTypeIException("EnumType::valueOf", "H5Tenum_valueof failed");
247 }
248 }
249
250 //--------------------------------------------------------------------------
251 // Function: EnumType::valueOf
252 ///\brief This is an overloaded member function, provided for convenience.
253 /// It differs from the above function only in the type of
254 /// argument \a name.
255 // Programmer Binh-Minh Ribler - 2000
256 //--------------------------------------------------------------------------
valueOf(const H5std_string & name,void * value) const257 void EnumType::valueOf(const H5std_string& name, void *value) const
258 {
259 valueOf(name.c_str(), value);
260 }
261
262 //--------------------------------------------------------------------------
263 // Function: EnumType::getMemberIndex
264 ///\brief Returns the index of a member in this enumeration datatype.
265 ///\param name - IN: Name of the queried member
266 ///\return Index of the member if it exists. Index will have the value
267 /// between 0 and \c N-1, where \c N is the value returned by the
268 /// member function \c EnumType::getNmembers.
269 ///\exception H5::DataTypeIException
270 // Programmer Binh-Minh Ribler - May 16, 2002
271 //--------------------------------------------------------------------------
getMemberIndex(const char * name) const272 int EnumType::getMemberIndex(const char *name) const
273 {
274 int member_index = H5Tget_member_index(id, name);
275 if (member_index < 0)
276 {
277 throw DataTypeIException("EnumType::getMemberIndex",
278 "H5Tget_member_index returns negative value");
279 }
280 return(member_index);
281 }
282
283 //--------------------------------------------------------------------------
284 // Function: EnumType::getMemberIndex
285 ///\brief This is an overloaded member function, provided for convenience.
286 /// It differs from the above function only in the type of
287 /// argument \a name.
288 // Programmer Binh-Minh Ribler - May 16, 2002
289 //--------------------------------------------------------------------------
getMemberIndex(const H5std_string & name) const290 int EnumType::getMemberIndex(const H5std_string& name) const
291 {
292 return(EnumType::getMemberIndex(name.c_str()));
293 }
294
295 //--------------------------------------------------------------------------
296 // Function: EnumType::getNmembers
297 ///\brief Returns the number of members in this enumeration datatype.
298 ///\return Number of members
299 ///\exception H5::DataTypeIException
300 // Programmer Binh-Minh Ribler - May, 2004
301 //--------------------------------------------------------------------------
getNmembers() const302 int EnumType::getNmembers() const
303 {
304 int num_members = H5Tget_nmembers(id);
305 if (num_members < 0)
306 {
307 throw DataTypeIException("EnumType::getNmembers",
308 "H5Tget_nmembers returns negative number of members");
309 }
310 return(num_members);
311 }
312
313 //--------------------------------------------------------------------------
314 // Function: EnumType::getMemberValue
315 ///\brief Retrieves the value of a member in this enumeration datatype,
316 /// given the member's index.
317 ///\param memb_no - IN: Index of the queried member
318 ///\param value - OUT: Pointer to the retrieved value
319 ///\exception H5::DataTypeIException
320 // Programmer Binh-Minh Ribler - 2000
321 //--------------------------------------------------------------------------
getMemberValue(unsigned memb_no,void * value) const322 void EnumType::getMemberValue(unsigned memb_no, void *value) const
323 {
324 // Call C routine H5Tget_member_value to get the datatype member's value
325 hid_t ret_value = H5Tget_member_value(id, memb_no, value);
326 if (ret_value < 0)
327 {
328 throw DataTypeIException("EnumType::getMemberValue", "H5Tget_member_value failed");
329 }
330 }
331
332 //--------------------------------------------------------------------------
333 // Function: EnumType destructor
334 ///\brief Properly terminates access to this enum datatype.
335 // Programmer Binh-Minh Ribler - 2000
336 //--------------------------------------------------------------------------
~EnumType()337 EnumType::~EnumType() {}
338
339 } // end namespace
340