44#include "config_hdf.h"
58#include <libdap/InternalErr.h>
59#include <libdap/util.h>
60#include <libdap/debug.h>
72static void LoadField(int32 vid,
int index, int32 begin, int32 end,
74static bool IsInternalVdata(int32 fid, int32 ref);
81void hdfistream_vdata::_init(
void) {
82 _vdata_id = _index = _attr_index = _nattrs = 0;
89void hdfistream_vdata::_get_fileinfo(
void) {
92 while ((ref = VSgetid(_file_id, ref)) != -1) {
93 if (!IsInternalVdata(_file_id, ref))
94 _vdata_refs.push_back(ref);
99void hdfistream_vdata::_seek_next(
void) {
102 _seek(_vdata_refs[_index]);
106void hdfistream_vdata::_seek(
const char *name) {
107 int32 ref = VSfind(_file_id, name);
109 THROW(hcerr_vdatafind);
116void hdfistream_vdata::_seek(int32 ref) {
119 auto r = find(_vdata_refs.begin(), _vdata_refs.end(),ref);
120 if (r == _vdata_refs.end())
121 THROW(hcerr_vdatafind);
122 _index = r - _vdata_refs.begin();
123 if ((_vdata_id = VSattach(_file_id, ref,
"r")) < 0) {
125 THROW(hcerr_vdataopen);
128 _nattrs = VSfnattrs(_vdata_id, _HDF_VDATA);
136hdfistream_vdata::hdfistream_vdata(
const string& filename) :
139 if (_filename.size() != 0)
140 open(_filename.c_str());
144void hdfistream_vdata::open(
const string & filename) {
145 open(filename.c_str());
149void hdfistream_vdata::open(
const char *filename) {
152 if ((_file_id = Hopen(filename, DFACC_RDONLY, 0)) < 0)
153 THROW(hcerr_openfile);
154 if (Vstart(_file_id) < 0)
155 THROW(hcerr_openfile);
157 BESDEBUG(
"h4",
"vdata file opened: id=" << _file_id << endl);
159 _filename = filename;
165void hdfistream_vdata::close(
void) {
167 "vdata file closed: id=" << _file_id <<
", this: " <<
this << endl);
172 int status = Vend(_file_id);
174 "vdata Vend status: " << status <<
", this: " <<
this << endl);
176 status = Hclose(_file_id);
178 "vdata HClose status: " << status <<
", this: " <<
this << endl);
180 _vdata_id = _file_id = _index = _attr_index = _nattrs = 0;
186void hdfistream_vdata::seek(
int index) {
187 if (index < 0 || index >= (
int) _vdata_refs.size())
189 _seek(_vdata_refs[index]);
194void hdfistream_vdata::seek_ref(
int ref) {
199void hdfistream_vdata::seek(
const string & name) {
203void hdfistream_vdata::seek(
const char *name) {
208bool hdfistream_vdata::setrecs(int32 begin, int32 end) {
209 if (_vdata_id != 0) {
211 VSQueryinterlace(_vdata_id, &il);
212 if (il != FULL_INTERLACE)
216 VSQuerycount(_vdata_id, &cnt);
217 if (begin < 0 || end >= cnt)
231bool hdfistream_vdata::eo_attr(
void)
const {
232 if (_filename.size() == 0)
233 THROW(hcerr_invstream);
237 return (_attr_index >= _nattrs);
244 for (hdf_attr att; !eo_attr();) {
253 for (hdf_vdata hv; !eos();) {
264 ha.values = hdf_genvec();
266 if (_filename.size() == 0)
267 THROW(hcerr_invstream);
271 char name[hdfclass::MAXSTR];
276 if (VSattrinfo(_vdata_id, _HDF_VDATA, _attr_index, name, &number_type,
278 THROW(hcerr_vdatainfo);
281 auto data =
new char[count * DFKNTsize(number_type)];
283 THROW(hcerr_nomemory);
286 if (VSgetattr(_vdata_id, _HDF_VDATA, _attr_index, data) < 0) {
288 THROW(hcerr_vdatainfo);
291 ha.values = hdf_genvec(number_type, data, count);
306 hv.vclass = hv.name = string();
309 THROW(hcerr_invstream);
314 hv.ref = _vdata_refs[_index];
318 char name[hdfclass::MAXSTR];
319 char vclass[hdfclass::MAXSTR];
321 if (VSinquire(_vdata_id, &nrecs,
nullptr,
nullptr,
nullptr, name)
323 THROW(hcerr_vdatainfo);
324 hv.name = string(name);
325 if (VSgetclass(_vdata_id, vclass) < 0)
326 THROW(hcerr_vdatainfo);
327 hv.vclass = string(vclass);
330 int nfields = VFnfields(_vdata_id);
332 THROW(hcerr_vdatainfo);
335 hv.fields = vector<hdf_field> ();
336 for (
int i = 0; i < nfields; ++i) {
337 hv.fields.push_back(hdf_field());
339 LoadField(_vdata_id, i, 0, 0, hv.fields[i]);
341 LoadField(_vdata_id, i, _recs.begin, _recs.end, hv.fields[i]);
343 LoadField(_vdata_id, i, 0, nrecs - 1, hv.fields[i]);
353bool hdfistream_vdata::isInternalVdata(
int ref)
const {
354 set<string, less<string> > reserved_names;
355 reserved_names.insert(
"RIATTR0.0N");
357 set<string, less<string> > reserved_classes;
358 reserved_classes.insert(
"Attr0.0");
359 reserved_classes.insert(
"RIATTR0.0C");
360 reserved_classes.insert(
"DimVal0.0");
361 reserved_classes.insert(
"DimVal0.1");
362 reserved_classes.insert(
"_HDF_CHK_TBL_0");
366 if ((vid = VSattach(_file_id, ref,
"r")) < 0) {
367 THROW(hcerr_vdataopen);
369 char name[hdfclass::MAXSTR];
370 char vclass[hdfclass::MAXSTR];
371 if (VSgetname(vid, name) < 0) {
373 THROW(hcerr_vdatainfo);
375 if (reserved_names.find(
string(name)) != reserved_names.end()) {
380 if (VSgetclass(vid, vclass) < 0) {
382 THROW(hcerr_vdatainfo);
387 if (reserved_classes.find(
string(vclass)) != reserved_classes.end())
394static void LoadField(int32 vid,
int index, int32 begin, int32 end,
396 DBG(cerr <<
"LoadField - vid: " << vid << endl);
399 if (VSseek(vid, begin) < 0)
401 int32 nrecs = end - begin + 1;
404 DBG(cerr <<
"vid: " << vid <<
", index: " << index << endl);
405 const char *fieldname = VFfieldname(vid, index);
406 if (fieldname ==
nullptr)
408 f.name = string(fieldname);
411 int32 fieldorder = VFfieldorder(vid, index);
416 int32 fieldsize = VFfieldisize(vid, index);
421 int32 fieldtype = VFfieldtype(vid, index);
429 data.resize(fieldsize * nrecs);
430 DBG(cerr <<
"LoadField: vid=" << vid <<
", fieldname=" << fieldname << endl);
439 if (VSsetfields(vid, fieldname) < 0) {
443 if (VSread(vid, (uchar8 *)data.data(), nrecs, FULL_INTERLACE) < 0) {
444 throw InternalErr(__FILE__, __LINE__,
"VSread error with the field: " + f.name +
" (" + long_to_string(vid) +
").");
447 if ((VSsetfields(vid, fieldname) < 0) || (VSread(vid, (uchar8 *) data,
448 nrecs, FULL_INTERLACE) < 0)) {
454 int stride = fieldorder;
455 for (
int i = 0; i < fieldorder; ++i) {
459 gv =
hdf_genvec(fieldtype, data.data(), i, (nrecs * fieldorder) - 1, stride);
460 f.vals.push_back(gv);
469bool hdf_field::_ok(
void)
const {
472 if (vals.empty() ==
true)
477 if (vals.size() > 1) {
478 int32 nt = vals[0].number_type();
481 for (
int i = 1; i < (int) vals.size(); ++i)
482 if (vals[i].number_type() != nt || vals[i].number_type() == 0)
489bool hdf_vdata::_ok(
void)
const {
492 if (fields.empty() ==
true)
496 for (
const auto & field:fields)
503static bool IsInternalVdata(int32 fid, int32 ref) {
504 set<string, less<string> > reserved_names;
505 reserved_names.insert(
"RIATTR0.0N");
507 set<string, less<string> > reserved_classes;
508 reserved_classes.insert(
"Attr0.0");
509 reserved_classes.insert(
"RIATTR0.0C");
510 reserved_classes.insert(
"DimVal0.0");
511 reserved_classes.insert(
"DimVal0.1");
512 reserved_classes.insert(
"_HDF_CHK_TBL_0");
516 if ((vid = VSattach(fid, ref,
"r")) < 0) {
519 char name[hdfclass::MAXSTR];
520 char vclass[hdfclass::MAXSTR];
521 if (VSgetname(vid, name) < 0) {
525 if (reserved_names.find(
string(name)) != reserved_names.end()) {
530 if (VSgetclass(vid, vclass) < 0) {
537 if (reserved_classes.find(
string(vclass)) != reserved_classes.end())