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