bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
HDF5D4Enum.cc
Go to the documentation of this file.
1// This file is part of hdf5_handler a HDF5 file handler for the OPeNDAP
2// data server.
3// Copyright (c) The HDF Group, Inc. and OPeNDAP, Inc.
4//
5// This is free software; you can redistribute it and/or modify it under the
6// terms of the GNU Lesser General Public License as published by the Free
7// Software Foundation; either version 2.1 of the License, or (at your
8// option) any later version.
9//
10// This software is distributed in the hope that it will be useful, but
11// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13// License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public
16// License along with this library; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18//
19// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
20// You can contact The HDF Group, Inc. at 410 E University Ave,
21// Suite 200, Champaign, IL 61820
22
27
28
29#include "BESDebug.h"
30#include <string>
31#include <ctype.h>
32#include <memory>
33
34#include <libdap/InternalErr.h>
35
36#include "HDF5D4Enum.h"
37
38using namespace std;
39using namespace libdap;
40
41HDF5D4Enum::HDF5D4Enum(const string & n, const string &vpath,const string &d, libdap::Type type) : D4Enum(n, d, type),var_path(vpath)
42{
43}
44
46{
47 auto HDF5D4Enum_unique = make_unique<HDF5D4Enum>(*this);
48 return HDF5D4Enum_unique.release();
49}
50
52{
53 if (read_p())
54 return true;
55
56 if (false == is_dap4())
57 throw InternalErr(__FILE__,__LINE__, "HDF5 ENUM only maps to DAP4 ENUM.");
58
59 hid_t file_id = H5Fopen(dataset().c_str(),H5F_ACC_RDONLY,H5P_DEFAULT);
60 if(file_id < 0) {
61 throw InternalErr(__FILE__,__LINE__, "Fail to obtain the HDF5 file ID .");
62 }
63
64 hid_t dset_id = -1;
65 dset_id = H5Dopen2(file_id,var_path.c_str(),H5P_DEFAULT);
66
67 if(dset_id < 0) {
68 H5Fclose(file_id);
69 throw InternalErr(__FILE__,__LINE__, "Fail to obtain the dataset .");
70 }
71
72 hid_t dtypeid = H5Dget_type(dset_id);
73 if(dtypeid < 0) {
74 H5Dclose(dset_id);
75 H5Fclose(file_id);
76 throw InternalErr(__FILE__,__LINE__, "Fail to obtain the datatype .");
77 }
78
79 if (H5T_ENUM != H5Tget_class(dtypeid)) {
80 H5Dclose(dset_id);
81 H5Fclose(file_id);
82 throw InternalErr(__FILE__,__LINE__, "Fail to obtain the datatype .");
83 }
84
85 hid_t base_type = H5Tget_super(dtypeid);
86
87 hid_t memtype = H5Tget_native_type(base_type, H5T_DIR_ASCEND);
88 if (memtype < 0){
89 close_objids(-1,base_type,dtypeid,dset_id,file_id);
90 throw InternalErr(__FILE__, __LINE__, "Cannot obtain the native datatype.");
91 }
92
93 if (H5Tget_class(base_type) != H5T_INTEGER) {
94 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
95 throw InternalErr(__FILE__, __LINE__, "We currently only support the case when the enum's base type is an integer.");
96 }
97
98 size_t dsize = H5Tget_size(base_type);
99 if (dsize == 0){
100 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
101 throw InternalErr(__FILE__, __LINE__,
102 "size of enum base data type is invalid");
103 }
104
105 H5T_sign_t sign = H5Tget_sign(base_type);
106 if (sign < 0){
107 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
108 throw InternalErr(__FILE__, __LINE__,
109 "sign of enum base data type is invalid");
110 }
111
112 switch (dsize) {
113
114 case 1:
115 if (sign == H5T_SGN_NONE) {
116 uint8_t val = 0;
117 if (H5Dread(dset_id,H5T_NATIVE_UCHAR,H5S_ALL,H5S_ALL,H5P_DEFAULT,&val)<0) {
118 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
119 throw InternalErr(__FILE__, __LINE__,
120 "Cannot read the enum data for the unsigned char base type. ");
121 }
122 set_value(val);
123 }
124 else {
125 int8_t val = 0;
126 if (H5Dread(dset_id,H5T_NATIVE_SCHAR,H5S_ALL,H5S_ALL,H5P_DEFAULT,&val)<0) {
127 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
128 throw InternalErr(__FILE__, __LINE__,
129 "Cannot read the enum data for the signed char base type. ");
130 }
131 set_value(val);
132 }
133 break;
134 case 2:
135
136 if (sign == H5T_SGN_NONE) {
137 uint16_t val = 0;
138 if (H5Dread(dset_id,H5T_NATIVE_USHORT,H5S_ALL,H5S_ALL,H5P_DEFAULT,&val)<0) {
139 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
140 throw InternalErr(__FILE__, __LINE__,
141 "Cannot read the enum data for the 16-bit signed integer base type. ");
142 }
143 set_value(val);
144 }
145 else {
146 int16_t val = 0;
147 if (H5Dread(dset_id,H5T_NATIVE_SHORT,H5S_ALL,H5S_ALL,H5P_DEFAULT,&val)<0) {
148 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
149 throw InternalErr(__FILE__, __LINE__,
150 "Cannot read the enum data for the 16-bit signed integer base type. ");
151 }
152 set_value(val);
153 }
154
155 break;
156
157 case 4:
158 if (sign == H5T_SGN_NONE) {
159 uint32_t val = 0;
160 if (H5Dread(dset_id,H5T_NATIVE_UINT,H5S_ALL,H5S_ALL,H5P_DEFAULT,&val)<0) {
161 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
162 throw InternalErr(__FILE__, __LINE__,
163 "Cannot read the enum data for the 32-bit signed integer base type. ");
164 }
165 set_value(val);
166
167 }
168 else {
169 int32_t val = 0;
170 if (H5Dread(dset_id,H5T_NATIVE_INT,H5S_ALL,H5S_ALL,H5P_DEFAULT,&val)<0) {
171 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
172 throw InternalErr(__FILE__, __LINE__,
173 "Cannot read the enum data for the 32-bit signed integer base type. ");
174 }
175 set_value(val);
176
177 }
178 break;
179
180 case 8:
181 if (sign == H5T_SGN_NONE) {
182 uint64_t val = 0;
183 if (H5Dread(dset_id,H5T_NATIVE_ULLONG,H5S_ALL,H5S_ALL,H5P_DEFAULT,&val)<0) {
184 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
185 throw InternalErr(__FILE__, __LINE__,
186 "Cannot read the enum data for the 64-bit unsigned integer base type. ");
187 }
188 set_value(val);
189
190 }
191 else {
192 int64_t val = 0;
193 if (H5Dread(dset_id,H5T_NATIVE_LLONG,H5S_ALL,H5S_ALL,H5P_DEFAULT,&val)<0) {
194 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
195 throw InternalErr(__FILE__, __LINE__,
196 "Cannot read the enum data for the 64-bit signed integer base type. ");
197 }
198 set_value(val);
199 }
200 break;
201
202 default:
203 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
204 throw InternalErr(__FILE__, __LINE__,"The enum base type size is not within the currently supported values.");
205 }
206
207 close_objids(memtype,base_type,dtypeid,dset_id,file_id);
208
209 return true;
210}
211
212void HDF5D4Enum::close_objids(hid_t mem_type, hid_t base_type, hid_t dtype, hid_t dset_id, hid_t file_id) const {
213
214 if (mem_type >0)
215 H5Tclose(mem_type);
216 if (base_type >0)
217 H5Tclose(base_type);
218 if (dtype >0)
219 H5Tclose(dtype);
220 if (dset_id >0)
221 H5Dclose(dset_id);
222 if (file_id >0)
223 H5Fclose(file_id);
224
225}
A class to map HDF5 Enum type.
libdap::BaseType * ptr_duplicate() override
Definition HDF5D4Enum.cc:45
HDF5D4Enum(const std::string &n, const std::string &vpath, const std::string &dataset, libdap::Type type)
Constructor.
Definition HDF5D4Enum.cc:41
bool read() override
Reads HDF5 16-bit integer data into local buffer.
Definition HDF5D4Enum.cc:51