OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDF5Str.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 
4 // Author: Hyo-Kyung Lee <hyoklee@hdfgroup.org> and Muqun Yang
5 // <myang6@hdfgroup.org>
6 
7 // Copyright (c) 2009-2013 The HDF Group, Inc. and OPeNDAP, Inc.
8 //
9 // This is free software; you can redistribute it and/or modify it under the
10 // terms of the GNU Lesser General Public License as published by the Free
11 // Software Foundation; either version 2.1 of the License, or (at your
12 // option) any later version.
13 //
14 // This software is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 // License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 // You can contact The HDF Group, Inc. at 1901 South First Street,
25 // Suite C-2, Champaign, IL 61820
26 
40 
41 
42 #include "config_hdf5.h"
43 
44 
45 #include <string>
46 #include <ctype.h>
47 
48 #include "InternalErr.h"
49 
50 #include "h5dds.h"
51 #include "HDF5Str.h"
52 #include "HDF5Structure.h"
53 // #define DODS_DEBUG
54 #include "debug.h"
55 
57 typedef struct s2_str_t {
59  char a[max_str_len];
60 } s2_str_t;
61 
62 
63 HDF5Str::HDF5Str(const string & n, const string &d)
64  : Str(n,d),dset_id(-1),ty_id(-1), array_flag(0)
65 {
66 }
67 
69 {
70  return new HDF5Str(*this);
71 }
72 
74 {
75  size_t size = H5Tget_size(ty_id);
76  DBG(cerr << ">read() size=" << size << endl);
77  if (read_p())
78  return true;
79 
80 #if 0
81  if (array_flag == 1) {
82  DBG(cerr << "=read(): array is dected." << endl);
83  return true;
84  }
85 #endif
86 
87  if (size == 0) {
88  throw InternalErr(__FILE__, __LINE__, "cannot return the size of datatype");
89  }
90  if (get_dap_type(ty_id) == "String") {
91  vector<char>chr;
92  chr.resize(size+1);
93  get_data(dset_id, (void *) &chr[0]);
94  set_read_p(true);
95  string str(chr.begin(),chr.end());
96  set_value(str);
97 
98  // Release the handles.
99  if (H5Tclose(ty_id) < 0) {
100  throw InternalErr(__FILE__, __LINE__, "Unable to close the datatype.");
101  }
102  if (H5Dclose(dset_id) < 0) {
103  throw InternalErr(__FILE__, __LINE__, "Unable to close the dset.");
104  }
105 
106  }
107 
108  if (get_dap_type(ty_id) == "Structure") {
109  BaseType *q = get_parent();
110 
111  int i = H5Tget_nmembers(ty_id);
112  int j = 0;
113  int k = 0;
114 
115  hid_t s2_str_tid = H5Tcreate(H5T_COMPOUND, sizeof(s2_str_t));
116  hid_t stemp_tid;
117 
118  vector<s2_str_t> buf(i);
119  string myname = name();
120  string parent_name;
121 
122  if (i < 0) {
123  throw InternalErr(__FILE__, __LINE__, "H5Tget_nmembers() failed.");
124  }
125  if (s2_str_tid < 0) {
126  throw InternalErr(__FILE__, __LINE__, "cannot create a new datatype");
127  }
128 
129  DBG(cerr << "=read() ty_id=" << ty_id << " name=" << myname <<
130  " size=" << i << endl);
131  while (q != NULL) {
132  if (q->is_constructor_type()) { // Grid, structure or sequence
133  if (k == 0) {
134  hid_t type = H5Tcopy(H5T_C_S1);
135  if (type < 0) {
136  throw InternalErr(__FILE__, __LINE__, "cannot copy");
137  }
138  if (H5Tset_size(type, (size_t) size) < 0) {
139  throw InternalErr(__FILE__, __LINE__, "Unable to set size of datatype.");
140  }
141  if (H5Tset_strpad(type, H5T_STR_NULLTERM) < 0) {
142  throw InternalErr(__FILE__, __LINE__, "H5Tset_strpad() failed.");
143  }
144  if (H5Tinsert(s2_str_tid, myname.c_str(), 0, type) < 0) {
145  throw InternalErr(__FILE__, __LINE__, "Unable to add to datatype.");
146  }
147  }
148  else {
149  stemp_tid = H5Tcreate(H5T_COMPOUND, sizeof(s2_str_t));
150  if (stemp_tid < 0) {
151  throw InternalErr(__FILE__, __LINE__, "cannot create a new datatype");
152  }
153  if (H5Tinsert(stemp_tid, parent_name.c_str(), 0, s2_str_tid) < 0) {
154  throw InternalErr(__FILE__, __LINE__, "Unable to add datatype.");
155  }
156  s2_str_tid = stemp_tid;
157  }
158  // Remember the last parent name.
159  parent_name = q->name();
160  HDF5Structure &p = static_cast<HDF5Structure &> (*q);
161  // Remember the index of array from the last parent.
162  j = p.get_array_index();
163  q = q->get_parent();
164  }
165  else {
166  q = NULL;
167  }
168  k++;
169  }
170 
171  if (H5Dread(dset_id, s2_str_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &buf[0]) < 0) {
172  // buf is deleted in the catch ... block below so
173  // shouldn't be deleted here. pwest Mar 18, 2009
174  //delete[] buf;
175  throw InternalErr(__FILE__, __LINE__, "hdf5_dods server failed when getting int32 data for structure");
176  // string("hdf5_dods server failed when getting int32 data for structure\n")
177  // + Msgi);
178  }
179  set_read_p(true);
180  string str = buf[j].a;
181  val2buf(&str);
182  }
183 
184  return true;
185 }
186 
187 void HDF5Str::set_did(hid_t dset)
188 {
189  dset_id = dset;
190 }
191 
192 void HDF5Str::set_tid(hid_t type)
193 {
194  ty_id = type;
195 }
196 
198 {
199  return dset_id;
200 }
201 
203 {
204  return ty_id;
205 }
HDF5Str(const string &n, const string &d)
Constructor.
Definition: HDF5Str.cc:63
This class converts HDF5 compound type into DAP structure for the default option. ...
string get_dap_type(hid_t type)
returns the string representation of HDF5 type.
Definition: h5get.cc:237
int get_array_index()
returns the array index of this Structure if it's a part of array of structures.
Data structure and retrieval processing header for the default option.
void get_data(hid_t dset, void *buf)
will get all data of a dset dataset and put it into buf.
Definition: h5get.cc:521
void set_tid(hid_t type)
remembers HDF5 datatype id.
Definition: HDF5Str.cc:192
#define NULL
Definition: wcsUtil.h:65
virtual bool read()
Reads HDF5 string data into local buffer.
Definition: HDF5Str.cc:73
This class that translates HDF5 string into DAP string for the default option.
void set_did(hid_t dset)
remembers HDF5 dataset id.
Definition: HDF5Str.cc:187
hid_t get_did()
returns HDF5 dataset id.
Definition: HDF5Str.cc:197
hid_t get_tid()
returns HDF5 datatype id.
Definition: HDF5Str.cc:202
virtual BaseType * ptr_duplicate()
Clone this instance.
Definition: HDF5Str.cc:68
struct s2_str_t s2_str_t
A temporary structure for retrieving data from HDF5 compound data type.