OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
vgroup.cc
Go to the documentation of this file.
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 1998, 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 // U.S. Government Sponsorship under NASA Contract
36 // NAS7-1260 is acknowledged.
37 //
38 // Author: Todd.K.Karakashian@jpl.nasa.gov
39 // Jake.Hamby@jpl.nasa.gov
40 //
41 // $RCSfile: vgroup.cc,v $ - classes for HDF VGROUP
42 //
44 
45 #include "config_hdf.h"
46 
47 #include <mfhdf.h>
48 
49 #ifdef __POWERPC__
50 #undef isascii
51 #endif
52 
53 #include <string>
54 #include <vector>
55 #include <set>
56 #include <algorithm>
57 
58 using std::vector;
59 using std::set;
60 using std::less;
61 
62 #include <hcstream.h>
63 #include <hdfclass.h>
64 
65 #include <BESDebug.h>
66 
67 static bool IsInternalVgroup(int32 fid, int32 ref);
68 
69 //
70 // hdfistream_vgroup -- protected member functions
71 //
72 
73 // initialize hdfistream_vgroup
75 {
77  _meta = false;
78  _vgroup_refs.clear();
79  _recs.set = false;
80  return;
81 }
82 
84 {
85 
86  // build list ref numbers of all Vgroup's in the file
87  int32 ref = -1;
88  while ((ref = Vgetid(_file_id, ref)) != -1) {
89  if (!IsInternalVgroup(_file_id, ref))
90  _vgroup_refs.push_back(ref);
91  }
92 
93  return;
94 }
95 
97 {
98  _index++;
99  if (!eos())
101  return;
102 }
103 
104 void hdfistream_vgroup::_seek(const char *name)
105 {
106  int32 ref = Vfind(_file_id, name);
107  if (ref < 0)
109  else
110  _seek(ref);
111 
112  return;
113 }
114 
116 {
117  if (_vgroup_id != 0)
118  Vdetach(_vgroup_id);
119  vector < int32 >::iterator r =
120  find(_vgroup_refs.begin(), _vgroup_refs.end(), ref);
121  if (r == _vgroup_refs.end())
123  _index = r - _vgroup_refs.begin();
124  if ((_vgroup_id = Vattach(_file_id, ref, "r")) < 0) {
125  _vgroup_id = 0;
127  }
128  _attr_index = 0;
129  _nattrs = Vnattrs(_vgroup_id);
130  return;
131 }
132 
134 {
135  char mName[hdfclass::MAXSTR];
136  int member_id;
137 
138  if ((member_id = Vattach(_file_id, ref, "r")) >= 0) {
139  if (Vgetname(member_id, mName) < 0) {
140  Vdetach(member_id);
142  }
143  Vdetach(member_id);
144  return mName;
145  }
146 
147  return "";
148 }
149 
150 
151 //
152 // hdfistream_vgroup -- public member functions
153 //
154 
156  (filename)
157 {
158  _init();
159  if (_filename.length() != 0) // if ctor specified a null filename
160  open(_filename.c_str());
161  return;
162 }
163 
164 void hdfistream_vgroup::open(const string & filename)
165 {
166  open(filename.c_str());
167  return;
168 }
169 
170 void hdfistream_vgroup::open(const char *filename)
171 {
172  if (_file_id != 0)
173  close();
174  if ((_file_id = Hopen(filename, DFACC_RDONLY, 0)) < 0)
176  if (Vstart(_file_id) < 0)
178 
179  BESDEBUG("h4", "vgroup file opened: id=" << _file_id << endl);
180 
181  _filename = filename;
182  _get_fileinfo();
183  rewind();
184  return;
185 }
186 
188 {
189  BESDEBUG("h4", "vgroup file closed: id=" << _file_id << ", this: " << this << endl);
190 
191  int status;
192 
193  if (_vgroup_id != 0) {
194  status = Vdetach(_vgroup_id);
195  BESDEBUG("h4", "vgroup Vdetach status: " << status << ", this: " << this << endl);
196  }
197 
198  if (_file_id != 0) {
199  status = Vend(_file_id);
200  BESDEBUG("h4", "vgroup vend status: " << status << ", this: " << this << endl);
201 
202  status = Hclose(_file_id);
203  BESDEBUG("h4", "vgroup HClose status: " << status << ", this: " << this << endl);
204  BESDEBUG("h4", "Error: " << HEstring((hdf_err_code_t)HEvalue(1)) << endl);
205  }
207  _vgroup_refs = vector < int32 > (); // clear refs
208  _recs.set = false;
209  return;
210 }
211 
212 void hdfistream_vgroup::seek(int index)
213 {
214  if (index < 0 || index >= (int) _vgroup_refs.size())
216  _seek(_vgroup_refs[index]);
217  _index = index;
218  return;
219 }
220 
222 {
223  _seek(ref); // _seek() sets _index
224  return;
225 }
226 
227 void hdfistream_vgroup::seek(const string & name)
228 {
229  seek(name.c_str());
230 }
231 
232 void hdfistream_vgroup::seek(const char *name)
233 {
234  _seek(name);
235  return;
236 }
237 
239 {
240  string mName = _memberName(ref);
241  return mName;
242 }
243 
244 
245 // read all Vgroup's in the stream
247  &hvv)
248 {
249  for (hdf_vgroup hv; !eos();) {
250  *this >> hv;
251  hvv.push_back(hv);
252  }
253  return *this;
254 }
255 
256 // read a Vgroup from the stream
258 {
259 
260  // delete any previous data in hv
261  hv.tags.clear();
262  hv.refs.clear();
263  hv.vnames.clear();
264  hv.vclass = hv.name = string();
265 
266  if (_vgroup_id == 0)
267  THROW(hcerr_invstream); // no vgroup open!
268  if (eos())
269  return *this;
270 
271  // assign Vgroup ref
272  hv.ref = _vgroup_refs[_index];
273  // retrieve Vgroup attributes
274  *this >> hv.attrs;
275  // retrieve Vgroup name, class, number of entries
276  char name[hdfclass::MAXSTR];
277  char vclass[hdfclass::MAXSTR];
278  int32 nentries;
279  if (Vinquire(_vgroup_id, &nentries, name) < 0)
281  hv.name = string(name);
282  if (Vgetclass(_vgroup_id, vclass) < 0)
284  hv.vclass = string(vclass);
285 
286  // retrieve entry tags and refs
287  int32 npairs = Vntagrefs(_vgroup_id);
289 
290  for (int i = 0; i < npairs; ++i) {
291  int32 tag, ref;
292  string vname;
293  if (Vgettagref(_vgroup_id, i, &tag, &ref) < 0)
295  switch (tag) {
296  case DFTAG_VH:
297  if (!vdin.isInternalVdata(ref)) {
298  hv.tags.push_back(tag);
299  hv.refs.push_back(ref);
300  hv.vnames.push_back(memberName(ref));
301  }
302  break;
303  default:
304  hv.tags.push_back(tag);
305  hv.refs.push_back(ref);
306  hv.vnames.push_back(memberName(ref));
307  }
308  }
309  vdin.close();
310  _seek_next();
311  return *this;
312 }
313 
314 //
315 // hdf_vgroup related member functions
316 //
317 
318 bool hdf_vgroup::_ok(void) const
319 {
320 
321  // make sure there are tags stored in this vgroup
322  if (tags.size() == 0)
323  return false;
324 
325  // make sure there are refs stored in this vgroup
326  if (refs.size() == 0)
327  return false;
328 
329  return true; // passed all the tests
330 }
331 
332 bool IsInternalVgroup(int32 fid, int32 ref)
333 {
334  // block vgroups used internally
335  set < string, less < string > >reserved_names;
336  reserved_names.insert("RIATTR0.0N");
337  reserved_names.insert("RIG0.0");
338 
339  set < string, less < string > >reserved_classes;
340  reserved_classes.insert("Attr0.0");
341  reserved_classes.insert("RIATTR0.0C");
342  reserved_classes.insert("DimVal0.0");
343  reserved_classes.insert("DimVal0.1");
344  reserved_classes.insert("CDF0.0");
345  reserved_classes.insert("Var0.0");
346  reserved_classes.insert("Dim0.0");
347  reserved_classes.insert("UDim0.0");
348  reserved_classes.insert("Data0.0");
349  reserved_classes.insert("RI0.0");
350 
351  // get name, class of vgroup
352  int vid;
353  if ((vid = Vattach(fid, ref, "r")) < 0) {
355  }
356 
357  char name[hdfclass::MAXSTR];
358  char vclass[hdfclass::MAXSTR];
359  if (Vgetname(vid, name) < 0) {
360  Vdetach(vid);
362  }
363  if (reserved_names.find(string(name)) != reserved_names.end()) {
364  Vdetach(vid);
365  return true;
366  }
367 
368  if (Vgetclass(vid, vclass) < 0) {
369  Vdetach(vid);
371  }
372 
373  Vdetach(vid);
374 
375  if (reserved_classes.find(string(vclass)) != reserved_classes.end())
376  return true;
377 
378  return false;
379 }
380 
381 // check to see if stream is positioned past the last attribute in the
382 // currently open Vgroup
384 {
385  if (_filename.length() == 0) // no file open
387  if (eos() && !bos()) // if eos(), then always eo_attr()
388  return true;
389  else {
390  return (_attr_index >= _nattrs); // or positioned after last Vgroup attr?
391  }
392 }
393 
394 // Read all attributes in the stream
396 {
397 // hav = vector<hdf_attr>0; // reset vector
398  for (hdf_attr att; !eo_attr();) {
399  *this >> att;
400  hav.push_back(att);
401  }
402  return *this;
403 }
404 
405 // read an attribute from the stream
407 {
408  // delete any previous data in ha
409  ha.name = string();
410  ha.values = hdf_genvec();
411 
412  if (_filename.length() == 0) // no file open
414  if (eo_attr()) // if positioned past last attr, do nothing
415  return *this;
416 
417  char name[hdfclass::MAXSTR];
418  int32 number_type, count, size;
419  if (Vattrinfo
420  (_vgroup_id, _attr_index, name, &number_type, &count, &size) < 0)
422 
423  // allocate a temporary C array to hold data from VSgetattr()
424  char *data;
425  data = new char[count * DFKNTsize(number_type)];
426  if (data == 0)
428 
429  // read attribute values and store them in an hdf_genvec
430  if (Vgetattr(_vgroup_id, _attr_index, data) < 0) {
431  delete[]data; // problem: clean up and throw an exception
433  }
434  // try { // try to allocate an hdf_genvec
435  if (count > 0) {
436  ha.values = hdf_genvec(number_type, data, count);
437  // }
438  // catch(...) { // problem allocating hdf_genvec: clean up and rethrow
439  // delete []data;
440  // throw;
441  // }
442  }
443  delete[]data; // deallocate temporary C array
444 
445  // increment attribute index to next attribute
446  ++_attr_index;
447  ha.name = name; // assign attribute name
448  return *this;
449 }
450 
bool _ok(void) const
Definition: vgroup.cc:318
void _init(void)
Definition: vgroup.cc:74
virtual void seek(int index=0)
Definition: vgroup.cc:212
void _get_fileinfo(void)
Definition: vgroup.cc:83
virtual void close(void)
Definition: vgroup.cc:187
string vclass
Definition: hdfclass.h:224
virtual int index(void) const
Definition: hcstream.h:71
virtual bool eo_attr(void) const
Definition: vgroup.cc:383
virtual void close(void)
Definition: vdata.cc:165
void _seek_next(void)
Definition: vgroup.cc:96
virtual bool eos(void) const
Definition: hcstream.h:347
virtual void rewind(void)
Definition: hcstream.h:339
virtual bool bos(void) const
Definition: hcstream.h:343
int32 _file_id
Definition: hcstream.h:80
vector< int32 > _vgroup_refs
Definition: hcstream.h:382
string name
Definition: hdfclass.h:151
virtual bool isInternalVdata(int ref) const
Definition: vdata.cc:353
vector< int32 > tags
Definition: hdfclass.h:225
vector< int32 > refs
Definition: hdfclass.h:226
#define THROW(x)
Definition: dhdferr.h:51
vector< string > vnames
Definition: hdfclass.h:227
string _filename
Definition: hcstream.h:79
virtual void open(const char *filename)
Definition: vgroup.cc:170
hdf_genvec values
Definition: hdfclass.h:152
string _memberName(int32 ref)
Definition: vgroup.cc:133
string name
Definition: hdfclass.h:223
int32 ref
Definition: hdfclass.h:222
void _seek(const char *name)
Definition: vgroup.cc:104
struct hdfistream_vgroup::@4 _recs
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
hdfistream_vgroup(const string filename="")
Definition: vgroup.cc:155
virtual void seek_ref(int ref)
Definition: vgroup.cc:221
string memberName(int32 ref)
Definition: vgroup.cc:238
hdfistream_vgroup & operator>>(hdf_vgroup &hs)
Definition: vgroup.cc:257
vector< hdf_attr > attrs
Definition: hdfclass.h:228