41static char rcsid[] not_used ={
"$Id$"};
48#include <libdap/D4Attributes.h>
49#include <libdap/util.h>
50#include <libdap/InternalErr.h>
53#include "NCStructure.h"
57NCStructure::ptr_duplicate()
59 return new NCStructure(*
this);
62NCStructure::NCStructure(
const string &n,
const string &d) : Structure(n, d)
66NCStructure::NCStructure(
const NCStructure &rhs) : Structure(rhs)
70NCStructure::~NCStructure()
80 dynamic_cast<Structure&
>(*this) = rhs;
88class AddAttribute:
public unary_function<BaseType *, void> {
93 void operator()(BaseType *a) {
95 AttrTable::Attr_iter aiter;
96 a->get_attr_table().find(
"translation", &at, &aiter);
97 if (a->get_attr_table().attr_end() == aiter) {
98 a->get_attr_table().append_attr(
"translation",
"String",
127 Vars_iter var = var_begin();
128 while (var != var_end()) {
129 (*var)->transfer_attributes(at);
150 Structure *dest =
new NCStructure(name(), dataset());
151 Constructor::transform_to_dap4(root, dest);
152 container->add_var_nocopy(dest);
155void NCStructure::do_structure_read(
int ncid,
int varid, nc_type datatype,
156 vector<char> &values,
bool has_values,
int values_offset)
158#if NETCDF_VERSION >= 4
159 if (is_user_defined_type(ncid, datatype)) {
160 char type_name[NC_MAX_NAME+1];
165 int errstat = nc_inq_user_type(ncid, datatype, type_name, &size, &base_type, &nfields, &class_type);
166 if (errstat != NC_NOERR)
167 throw InternalErr(__FILE__, __LINE__,
"Could not get information about a user-defined type (" + long_to_string(errstat) +
").");
169 switch (class_type) {
173 int errstat = nc_get_var(ncid, varid, values.data() );
174 if (errstat != NC_NOERR)
175 throw Error(errstat,
string(
"Could not get the value for variable '") + name() +
string(
"'"));
179 for (
size_t i = 0; i < nfields; ++i) {
180 char field_name[NC_MAX_NAME+1];
181 nc_type field_typeid;
184 nc_inq_compound_field(ncid, datatype, i, field_name, &field_offset, &field_typeid, &field_ndims, 0);
185 if (is_user_defined_type(ncid, field_typeid)) {
189 nc_inq_compound_name(ncid, field_typeid, field_name);
190 NCStructure &ncs =
dynamic_cast<NCStructure&
>(*var(field_name));
191 ncs.do_structure_read(ncid, varid, field_typeid, values, has_values, field_offset + values_offset);
193 else if (var(field_name)->is_vector_type()) {
197 NCArray &child_array =
dynamic_cast<NCArray&
>(*var(field_name));
198 vector<size_t> cor(field_ndims);
199 vector<size_t> edg(field_ndims);
200 vector<ptrdiff_t> step(field_ndims);
202 long nels = child_array.format_constraint(cor.data(), step.data(), edg.data(), &has_stride);
203 child_array.do_array_read(ncid, varid, field_typeid,
204 values, has_values, field_offset + values_offset,
205 nels, cor.data(), edg.data(), step.data(), has_stride);
207 else if (var(field_name)->is_simple_type()) {
208 var(field_name)->val2buf(values.data() + field_offset + values_offset);
211 throw InternalErr(__FILE__, __LINE__,
"Expecting a netcdf user defined type or an array or a scalar.");
214 var(field_name)->set_read_p(
true);
220 cerr <<
"in build_user_defined; found a vlen." << endl;
223 cerr <<
"in build_user_defined; found a opaque." << endl;
226 cerr <<
"in build_user_defined; found a enum." << endl;
229 throw InternalErr(__FILE__, __LINE__,
"Expected one of NC_COMPOUND, NC_VLEN, NC_OPAQUE or NC_ENUM");
233 throw InternalErr(__FILE__, __LINE__,
"Found a DAP Structure bound to a non-user-defined type in the netcdf file " + dataset());
235 throw InternalErr(__FILE__, __LINE__,
"Found a DAP Structure bound to a non-user-defined type in the netcdf file " + dataset());
239bool NCStructure::read()
245 int errstat = nc_open(dataset().c_str(), NC_NOWRITE, &ncid);
246 if (errstat != NC_NOERR)
247 throw Error(errstat,
"Could not open the dataset's file (" + dataset() +
")");
250 errstat = nc_inq_varid(ncid, name().c_str(), &varid);
251 if (errstat != NC_NOERR)
252 throw InternalErr(__FILE__, __LINE__,
"Could not get variable ID for: " + name() +
". (error: " + long_to_string(errstat) +
").");
255 errstat = nc_inq_vartype(ncid, varid, &datatype);
256 if (errstat != NC_NOERR)
257 throw Error(errstat,
"Could not read data type information about : " + name() +
". (error: " + long_to_string(errstat) +
").");
264 do_structure_read(ncid, varid, datatype, values,
false , 0 );
268 if (nc_close(ncid) != NC_NOERR)
269 throw InternalErr(__FILE__, __LINE__,
"Could not close the dataset!");
virtual void transfer_attributes(AttrTable *at)
virtual void transform_to_dap4(D4Group *root, Constructor *container)