bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
HDFStructure.cc
1
2// This file is part of the hdf4 data handler for the OPeNDAP data server.
3
4// Copyright (c) 2005 OPeNDAP, Inc.
5// Author: James Gallagher <jgallagher@opendap.org>
6//
7// This is free software; you can redistribute it and/or modify it under the
8// terms of the GNU Lesser General Public License as published by the Free
9// Software Foundation; either version 2.1 of the License, or (at your
10// option) any later version.
11//
12// This software is distributed in the hope that it will be useful, but
13// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15// License for more details.
16//
17// You should have received a copy of the GNU Lesser General Public License
18// along with this software; if not, write to the Free Software Foundation,
19// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20//
21// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
22
23// Copyright 1996, by the California Institute of Technology.
24// ALL RIGHTS RESERVED. United States Government Sponsorship
25// acknowledged. Any commercial use must be negotiated with the
26// Office of Technology Transfer at the California Institute of
27// Technology. This software may be subject to U.S. export control
28// laws and regulations. By accepting this software, the user
29// agrees to comply with all applicable U.S. export laws and
30// regulations. User has the responsibility to obtain export
31// licenses, or other export authority as may be required before
32// exporting such information to foreign countries or providing
33// access to foreign persons.
34
35// Author: Todd Karakashian, NASA/Jet Propulsion Laboratory
36// Todd.K.Karakashian@jpl.nasa.gov
37//
39
40#include "config_hdf.h"
41//#define DODS_DEBUG
42
43#include <vector>
44
45// Include this on linux to suppress an annoying warning about multiple
46// definitions of MIN and MAX.
47#ifdef HAVE_SYS_PARAM_H
48#include <sys/param.h>
49#endif
50#include <mfhdf.h>
51#include <hdfclass.h>
52#include <hcstream.h>
53
54#include <libdap/Error.h>
55#include <libdap/escaping.h>
56#include <libdap/Sequence.h>
57#include <libdap/Array.h>
58#include <libdap/util.h>
59#include <libdap/debug.h>
60#include <BESDebug.h>
61
62#include "HDFStructure.h"
63
64using namespace libdap;
65using namespace std;
66
67HDFStructure::HDFStructure(const string &n, const string &d) :
68 Structure(n, d) {
69}
70
71HDFStructure::~HDFStructure() = default;
72
73BaseType *HDFStructure::ptr_duplicate() {
74 return new HDFStructure(*this);
75}
76void LoadStructureFromVgroup(HDFStructure * str, const hdf_vgroup & vgroup,
77 const string & hdf_file);
78
79void HDFStructure::set_read_p(bool state) {
80 // override Structure::set_read_p() to not set children as read yet
81 BaseType::set_read_p(state);
82}
83
84bool HDFStructure::read_from_value(vector<uint8_t> &values, size_t &values_offset) {
85
86#if 0
87 Constructor::Vars_iter vi = this->var_begin();
88 Constructor::Vars_iter ve = this->var_end();
89
90 for (; vi != ve; vi++) {
91#endif
92
93 for (auto &bt:this->variables()) {
94 Type t_bt = bt->type();
95 if (libdap::is_simple_type(t_bt) && t_bt != dods_str_c && t_bt != dods_url_c && t_bt!= dods_enum_c && t_bt!=dods_opaque_c) {
96
97#if 0
98 if(t_bt == dods_int32_c) {
99 //Int32 *val_int = static_cast<Int32 *>(bt);
100 //val_int->set_value(*((dods_int32*)(values.data()+values_offset)));
101 BESDEBUG("dmrpp", "int value is: " << *((dods_int32*)(values.data()+values_offset)) << "'" << endl);
102 }
103 else if (t_bt == dods_float32_c) {
104 //Float32 *val_float = static_cast<Float32 *>(bt);
105 //val_float->set_value(*((dods_float32*)(values.data()+values_offset)));
106 BESDEBUG("dmrpp", "float value is: " << *((dods_float32*)(values.data()+values_offset)) << "'" << endl);
107 }
108 else
109 bt->val2buf(values.data() + values_offset);
110#endif
111
112 bt->val2buf(values.data() + values_offset);
113 bt->set_read_p(true);
114 values_offset += bt->width_ll();
115
116 }
117 else if (t_bt == dods_array_c) {
118
119 auto t_a = dynamic_cast<Array *>(bt);
120 Type t_array_var = t_a->var()->type();
121 if (libdap::is_simple_type(t_array_var) && t_array_var != dods_str_c && t_array_var != dods_url_c && t_array_var!= dods_enum_c && t_array_var!=dods_opaque_c) {
122 t_a->val2buf(values.data()+values_offset);
123 t_a->set_read_p(true);
124 // update values_offset.
125 values_offset +=t_a->width_ll();
126 }
127 else
128 throw InternalErr(__FILE__, __LINE__, "The base type of this structure is not integer or float. Currently it is not supported.");
129 }
130 else
131 throw InternalErr(__FILE__, __LINE__, "The base type of this structure is not integer or float. Currently it is not supported.");
132 }
133
134 return true;
135}
136bool HDFStructure::read() {
137 int err = 0;
138 int status = read_tagref(-1, -1, err);
139 if (err)
140 throw Error(unknown_error, "Could not read from dataset.");
141 return status;
142}
143
144// TODO: Combine the try/catch block and the following if/then/else and
145// eliminate the boolean 'foundvgroup' Consider moving the
146// LoadStructureFromVgroup() from hc2dap.cc here since this is the only
147// place it's used.
148bool HDFStructure::read_tagref(int32 /*tag //unused SBL 2/7/20*/, int32 ref, int &err) {
149 if (read_p())
150 return true;
151
152 // get the HDF dataset name, Vgroup name
153 string hdf_file = dataset();
154 string hdf_name = this->name();
155
156 BESDEBUG("h4", " hdf_name = " << hdf_name << endl);
157
158 hdf_vgroup vgroup;
159
160 // Wrap this with a try/catch block but don't do anything with it. The
161 // error condition is checked later in this function. pcw 02/19/2008
162 try {
163 hdfistream_vgroup vgin(hdf_file.c_str());
164 if (ref != -1)
165 vgin.seek_ref(ref);
166 else
167 vgin.seek(hdf_name.c_str());
168 vgin >> vgroup;
169 vgin.close();
170
171 set_read_p(true);
172
173 LoadStructureFromVgroup(this, vgroup, hdf_file);
174 return true;
175 }
176 catch (...) {
177 set_read_p(false);
178 err = 1;
179 return false;
180 }
181}
182
204
205 BESDEBUG("h4", "Entering HDFStructure::transfer_attributes for variable " << name() << endl);
206
207 if (at) {
208 Vars_iter var = var_begin();
209 while (var != var_end()) {
210 try {
211 BESDEBUG("h4", "Processing the attributes for: " << (*var)->name() << " a " << (*var)->type_name() << endl);
212 (*var)->transfer_attributes(at);
213 var++;
214 } catch (Error &e) {
215 BESDEBUG("h4", "Got this exception: " << e.get_error_message() << endl);
216 var++;
217 throw e;
218 }
219 }
220
221 AttrTable *mine = at->get_attr_table(name());
222
223 if (mine) {
224 mine->set_is_global_attribute(false);
225 AttrTable::Attr_iter at_p = mine->attr_begin();
226 while (at_p != mine->attr_end()) {
227 if (mine->get_attr_type(at_p) == Attr_container)
228 get_attr_table().append_container(new AttrTable(*mine->get_attr_table(at_p)), mine->get_name(at_p));
229 else
230 get_attr_table().append_attr(mine->get_name(at_p), mine->get_type(at_p), mine->get_attr_vector(at_p));
231 at_p++;
232 }
233 }
234 }
235}
void transfer_attributes(libdap::AttrTable *at_container) override
Type
Type of JSON value.
Definition rapidjson.h:664