bes Updated for version 3.20.13
HDFArray.cc
1// This file is part of the hdf4 data handler for the OPeNDAP data server.
2
3// Copyright (c) 2005 OPeNDAP, Inc.
4// Author: James Gallagher <jgallagher@opendap.org>
5//
6// This is free software; you can redistribute it and/or modify it under the
7// terms of the GNU Lesser General Public License as published by the Free
8// Software Foundation; either version 2.1 of the License, or (at your
9// option) any later version.
10//
11// This software is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14// License for more details.
15//
16// You should have received a copy of the GNU Lesser General Public License
17// along with this software; if not, write to the Free Software Foundation,
18// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19//
20// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
21
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 1
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
52#include <hdfclass.h>
53#include <hcstream.h>
54
55#include <libdap/escaping.h>
56#include <libdap/Error.h>
57#include <libdap/debug.h>
58#include <BESDebug.h>
59
60#include "HDFArray.h"
61#include "dhdferr.h"
62
63using namespace libdap;
64using namespace std;
65
66HDFArray::HDFArray(const string &n, const string &d, BaseType * v) :
67 Array(n, d, v) {
68}
69
70HDFArray::~HDFArray() {
71}
72
73BaseType *HDFArray::ptr_duplicate() {
74 return new HDFArray(*this);
75}
76void LoadArrayFromSDS(HDFArray * ar, const hdf_sds & sds);
77void LoadArrayFromGR(HDFArray * ar, const hdf_gri & gr);
78
79// Read in an Array from either an SDS or a GR in an HDF file.
80bool HDFArray::read() {
81 int err = 0;
82 int status = read_tagref(-1, -1, err);
83
84 if (err)
85 throw Error(unknown_error, "Could not read from dataset.");
86
87 return status;
88}
89
90// todo: refactor: get rid of the err value-result parameter; throw from
91// within this method.
92bool HDFArray::read_tagref(int32 tag, int32 ref, int &err) {
93 if (read_p())
94 return true;
95
96 // get the HDF dataset name, SDS name
97 string hdf_file = dataset();
98 string hdf_name = this->name();
99
100 // get slab constraint
101 vector<int> start, edge, stride;
102 bool isslab = GetSlabConstraint(start, edge, stride);
103
104 bool foundsds = false;
105 hdf_sds sds;
106 if (tag == -1 || tag == DFTAG_NDG) {
107 if (SDSExists(hdf_file.c_str(), hdf_name.c_str())) {
108 hdfistream_sds sdsin(hdf_file.c_str());
109 if (ref != -1) {
110 BESDEBUG("h4", "sds seek with ref = " << ref << endl);
111 sdsin.seek_ref(ref);
112 } else {
113 BESDEBUG("h4", "sds seek with name = '" << hdf_name << "'" << endl);
114 sdsin.seek(hdf_name.c_str());
115 }
116 if (isslab)
117 sdsin.setslab(start, edge, stride, false);
118 sdsin >> sds;
119 sdsin.close();
120 foundsds = true;
121 }
122 }
123
124 bool foundgr = false;
125 hdf_gri gr;
126 if (!foundsds && (tag == -1 || tag == DFTAG_VG)) {
127 if (GRExists(hdf_file.c_str(), hdf_name.c_str())) {
128 hdfistream_gri grin(hdf_file.c_str());
129 if (ref != -1)
130 grin.seek_ref(ref);
131 else
132 grin.seek(hdf_name.c_str());
133 if (isslab)
134 grin.setslab(start, edge, stride, false);
135 grin >> gr;
136 grin.close();
137 foundgr = true;
138 }
139 }
140
141 // Todo: refactor: move this stuff up into the above if stmts.
142 if (foundsds)
143 LoadArrayFromSDS(this, sds);
144 else if (foundgr)
145 LoadArrayFromGR(this, gr);
146
147 if (foundgr || foundsds) {
148 set_read_p(true); // Moved here; see bug 136
149 err = 0; // no error
150 return true;
151 } else {
152 err = 1;
153 return false;
154 }
155}
156
157// Read the slab constraint parameters; the arrays start_array, edge_array,
158// stride_array. Returns true if there is a slab constraint, false otherwise.
159bool HDFArray::GetSlabConstraint(vector<int>&start_array,
160 vector<int>&edge_array, vector<int>&stride_array) {
161 int start = 0, stop = 0, stride = 0;
162 int edge = 0;
163
164 start_array = vector<int> (0);
165 edge_array = vector<int> (0);
166 stride_array = vector<int> (0);
167
168 for (Array::Dim_iter p = dim_begin(); p != dim_end(); ++p) {
169 start = dimension_start(p, true);
170 stride = dimension_stride(p, true);
171 stop = dimension_stop(p, true);
172 if (start == 0 && stop == 0 && stride == 0)
173 return false; // no slab constraint
174 if (start > stop)
175 THROW(dhdferr_arrcons);
176 edge = (int) ((stop - start) / stride) + 1;
177 if (start + edge > dimension_size(p))
178 THROW(dhdferr_arrcons);
179
180 start_array.push_back(start);
181 edge_array.push_back(edge);
182 stride_array.push_back(stride);
183 }
184 return true;
185}
186
208void HDFArray::transfer_attributes(AttrTable *at) {
209 BESDEBUG("h4","Transferring attributes for " << name() << endl);
210
211 BaseType::transfer_attributes(at);
212
213 BESDEBUG("h4","...Now looking for the " << name() << " _dim_n containers." << endl);
214
215 // Here we should look for the *_dim_n where '*' is name() and n is 0, 1, ...
216 string dim_name_base = name() + "_dim_";
217
218 AttrTable::Attr_iter a_p = at->attr_begin();
219 while (a_p != at->attr_end()) {
220 string::size_type i = at->get_name(a_p).find(dim_name_base);
221 // Found a matching container?
222 // To avoid matching both Month_dim_0 and DayOfMonth_dim_0, et c.,
223 // check that i == 0 and not just i != string::npos. jhrg 8/17/11
224 if (i == 0 && at->get_attr_type(a_p) == Attr_container) {
225 AttrTable *dim = at->get_attr_table(a_p);
226 try {
227 BESDEBUG("h4","Found a dimension container for " << name() << endl);
228 transfer_dimension_attribute(dim);
229 }
230 catch (Error &e) {
231 BESDEBUG("h4","Caught an error transferring dimension attribute " << dim->get_name() << " for variable " << name() << endl);
232 throw e;
233 }
234 }
235
236 a_p++;
237 }
238}
239
240void HDFArray::transfer_dimension_attribute(AttrTable *dim) {
241 // Mark the table as not global
242 dim->set_is_global_attribute(false);
243 // copy the table
244 AttrTable *at = new AttrTable(*dim);
245 // add it to this variable using just the 'dim_<digit>' part of the name
246 string name = at->get_name().substr(at->get_name().find("dim"));
247 get_attr_table().append_container(at, name);
248}
249
virtual void transfer_attributes(libdap::AttrTable *at_container)
Definition: HDFArray.cc:208