OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
sds.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 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 // U.S. Government Sponsorship under NASA Contract
36 // NAS7-1260 is acknowledged.
37 //
38 // Author: Todd.K.Karakashian@jpl.nasa.gov
39 //
40 // $RCSfile: sds.cc,v $ - input stream class for HDF SDS
41 //
43 
44 #include "config_hdf.h"
45 
46 #include <mfhdf.h>
47 
48 #ifdef __POWERPC__
49 #undef isascii
50 #endif
51 
52 #include <string>
53 #include <vector>
54 #include <algorithm>
55 #include <functional>
56 #include <cerrno>
57 
58 #include <hcstream.h>
59 #include <hdfclass.h>
60 
61 #include <BESDebug.h>
62 
63 using std::cerr;
64 using std::endl;
65 
66 // minimum function
67 inline int min(int t1, int t2)
68 {
69  return (t1 < t2 ? t1 : t2);
70 }
71 
72 // static initializations
73 const string hdfistream_sds::long_name = "long_name";
74 const string hdfistream_sds::units = "units";
75 const string hdfistream_sds::format = "format";
76 
77 //
78 // protected member functions
79 //
80 
81 // initialize an hdfistream_sds, opening file if given
83 {
85  _nfattrs = 0;
86  _index = -1; // set BOS
87  _meta = _slab.set = false;
88  _map_ce_set = false;
89  return;
90 }
91 
92 // retrieve descriptive information about file containing SDS
94 {
95  if (SDfileinfo(_file_id, &_nsds, &_nfattrs) < 0)
97  return;
98 }
99 
100 // retrieve descriptive information about currently open SDS
102 {
103  char junk0[hdfclass::MAXSTR];
104  int32 junk1[hdfclass::MAXDIMS];
105  int32 junk2;
106 
107  // all we care about is rank and number of attributes
108  if (SDgetinfo(_sds_id, junk0, &_rank, junk1, &junk2, &_nattrs) < 0)
110 
111  if (_rank > hdfclass::MAXDIMS) // too many dimensions
113  return;
114 }
115 
116 // end access to currently open SDS
118 {
119  if (_sds_id != 0) {
120  (void) SDendaccess(_sds_id);
122  _index = -1;
123  }
124  return;
125 }
126 
127 // find the next SDS array (not necessarily the next SDS) in the file
129 {
130  if (_sds_id != 0) {
131  BESDEBUG("h4", "hdfistream_sds::_seek_next_arr called with an open sds: "
132  << _sds_id << endl);
133  SDendaccess(_sds_id);
134  _sds_id = 0;
135  }
136 
137  for (_index++, _dim_index = _attr_index = 0; _index < _nsds; ++_index) {
138  if (_sds_id != 0) {
139  BESDEBUG("h4", "hdfistream_sds::_seek_next_arr inside for-loop with an open sds: "
140  << _sds_id << endl);
141  }
142  if ((_sds_id = SDselect(_file_id, _index)) < 0)
144  if (!SDiscoordvar(_sds_id))
145  break;
146  SDendaccess(_sds_id);
147  _sds_id = 0;
148  }
149 }
150 
151 // find the arr_index'th SDS array in the file (don't count non-array SDS's)
152 void hdfistream_sds::_seek_arr(int arr_index)
153 {
154  int arr_count = 0;
155  for (_rewind(); _index < _nsds && arr_count <= arr_index;
156  _seek_next_arr(), arr_count++);
157 }
158 
159 // find the SDS array with specified name
160 void hdfistream_sds::_seek_arr(const string & name)
161 {
162  if (_sds_id != 0) {
163  BESDEBUG("h4", "hdfistream_sds::_seek_arr called with an open sds: "
164  << _sds_id << endl);
165  _close_sds();
166  }
167 
168  int index;
169  const char *nm = name.c_str();
170  if ((index = SDnametoindex(_file_id, (char *) nm)) < 0)
172  if ((_sds_id = SDselect(_file_id, index)) < 0)
174  bool iscoord = SDiscoordvar(_sds_id);
175  if (iscoord) {
176  SDendaccess(_sds_id);
177  _sds_id = 0;
179  }
180  _index = index;
181  return;
182 }
183 
184 // find the SDS array with specified ref
186 {
187  if (_sds_id != 0) {
188  BESDEBUG("h4", "hdfistream_sds::_seek_arr_ref called with an open sds: "
189  << _sds_id << endl);
190  _close_sds();
191  }
192 
193  int index;
194  if ((index = SDreftoindex(_file_id, ref)) < 0)
196  if ((_sds_id = SDselect(_file_id, index)) < 0)
198  bool iscoord = SDiscoordvar(_sds_id);
199  if (iscoord) {
200  SDendaccess(_sds_id);
201  _sds_id = 0;
203  }
204  _index = index;
205  return;
206 }
207 
208 //
209 // public member functions
210 //
211 
212 
213 // constructor
214 hdfistream_sds::hdfistream_sds(const string filename):
215 hdfistream_obj(filename)
216 {
217  _init();
218  if (_filename.length() != 0) // if ctor specified a file to open
219  open(_filename.c_str());
220  return;
221 }
222 
223 // check to see if stream has been positioned past last SDS in file
224 bool hdfistream_sds::eos(void) const
225 {
226  if (_filename.length() == 0) // no file open
228  if (_nsds == 0) // eos() is always true of there are no SDS's in file
229  return true;
230  else {
231  if (bos()) // eos() is never true if at bos() and there are SDS's
232  return false;
233  else
234  return (_index >= _nsds); // are we indexed past the last SDS?
235  }
236 }
237 
238 // check to see if stream is positioned in front of the first SDS in file
239 bool hdfistream_sds::bos(void) const
240 {
241  if (_filename.length() == 0) // no file open
243  if (_nsds == 0)
244  return true; // if there are no SDS's we still want to read file attrs so both eos() and bos() are true
245  if (_index == -1)
246  return true;
247  else
248  return false;
249 }
250 
251 // check to see if stream is positioned past the last attribute in the currently
252 // open SDS
253 bool hdfistream_sds::eo_attr(void) const
254 {
255  if (_filename.length() == 0) // no file open
257  if (eos() && !bos()) // if eos(), then always eo_attr()
258  return true;
259  else {
260  if (bos()) // are we at BOS and are positioned past last file attributes?
261  return (_attr_index >= _nfattrs);
262  else
263  return (_attr_index >= _nattrs); // or positioned after last SDS attr?
264  }
265 }
266 
267 // check to see if stream is positioned past the last dimension in the currently
268 // open SDS
269 bool hdfistream_sds::eo_dim(void) const
270 {
271  if (_filename.length() == 0) // no file open
273  if (eos()) // if eos(), then always eo_dim()
274  return true;
275  else {
276  if (bos()) // if at BOS, then never eo_dim()
277  return true;
278  else
279  return (_dim_index >= _rank); // are we positioned after last dim?
280  }
281 }
282 
283 // open a new file
284 void hdfistream_sds::open(const char *filename)
285 {
286  if (filename == 0) // no filename given
288  BESDEBUG("h4", "sds opening file " << filename << endl);
289  if (_file_id != 0) // close any currently open file
290  close();
291  if ((_file_id = SDstart((char *) filename, DFACC_READ)) < 0)
292  {
294  }
295 
296  BESDEBUG("h4", "sds file opened: id=" << _file_id << endl);
297 
298  _filename = filename; // assign filename
299  _get_fileinfo(); // get file information
300  rewind(); // position at BOS to start
301  return;
302 }
303 
304 // close currently open file (if any)
306 { // close file
307  BESDEBUG("h4", "sds file closed: id=" << _file_id << ", this: " << this<< endl);
308 
309  _close_sds(); // close any currently open SDS
310  if (_file_id != 0) // if open file, then close it
311  (void) SDend(_file_id);
312  _file_id = _nsds = _nfattrs = 0; // zero file info
313  return;
314 }
315 
316 // position SDS array index to index'th SDS array (not necessarily index'th SDS)
317 void hdfistream_sds::seek(int index)
318 {
319  if (_filename.length() == 0) // no file open
321  _close_sds(); // close any currently open SDS
322  _seek_arr(index); // seek to index'th SDS array
323  if (!eos() && !bos()) // if not BOS or EOS, get SDS information
324  _get_sdsinfo();
325 }
326 
327 // position SDS array index to SDS array with name "name"
328 void hdfistream_sds::seek(const char *name)
329 {
330  if (_filename.length() == 0) // no file open
332  _close_sds(); // close any currently open SDS
333  _seek_arr(string(name)); // seek to index'th SDS array
334  if (!eos() && !bos()) // if not BOS or EOS, get SDS information
335  _get_sdsinfo();
336 }
337 
338 // position SDS array index in front of first SDS array
340 {
341  if (_filename.length() == 0) // no file open
343  _close_sds(); // close any already open SDS
344  _rewind(); // seek to BOS
345 }
346 
347 // position to next SDS array in file
349 {
350  if (_filename.length() == 0) // no file open
352  _seek_next_arr(); // seek to next SDS array
353  if (!eos()) // if not EOS, get SDS information
354  _get_sdsinfo();
355 }
356 
357 // position to SDS array by ref
359 {
360  if (_filename.length() == 0) // no file open
362  _close_sds(); // close any currently open SDS
363  _seek_arr_ref(ref); // seek to SDS array by reference
364  if (!eos() && !bos()) // if not BOS or EOS, get SDS information
365  _get_sdsinfo();
366 }
367 
368 // set slab parameters
369 void hdfistream_sds::setslab(vector < int >start, vector < int >edge,
370  vector < int >stride, bool reduce_rank)
371 {
372  // check validity of input
373  if (start.size() != edge.size() || edge.size() != stride.size()
374  || start.size() == 0)
376 
377  int i;
378  for (i = 0; i < (int) start.size() && i < hdfclass::MAXDIMS; ++i) {
379  if (start[i] < 0)
381  if (edge[i] <= 0)
383  if (stride[i] <= 0)
385  _slab.start[i] = start[i];
386  _slab.edge[i] = edge[i];
387  _slab.stride[i] = stride[i];
388  }
389  _slab.set = true;
390  _slab.reduce_rank = reduce_rank;
391 }
392 
393 // This function, when compiled with gcc 2.8 and -O2, causes a virtual
394 // memory exceeded error. 2/25/98 jhrg
395 // load currently open SDS into an hdf_sds object
397 {
398 
399  // delete any previous data in hs
400  hs.dims = vector < hdf_dim > ();
401  hs.attrs = vector < hdf_attr > ();
402  hs.data = hdf_genvec();
403  hs.name = string();
404 
405  if (_filename.length() == 0) // no file open
407  if (bos()) // if at BOS, advance to first SDS array
408  seek(0);
409  if (eos()) // if at EOS, do nothing
410  return *this;
411 
412  // get basic info about SDS
413  char name[hdfclass::MAXSTR];
414  int32 rank;
415  int32 dim_sizes[hdfclass::MAXDIMS];
416  int32 number_type;
417  int32 nattrs;
418  if (SDgetinfo(_sds_id, name, &rank, dim_sizes, &number_type, &nattrs) <
419  0)
421 
422  // assign SDS index
423  hs.ref = SDidtoref(_sds_id);
424  // load dimensions and attributes into the appropriate objects
425  *this >> hs.dims;
426  *this >> hs.attrs;
427  hs.name = name; // assign SDS name
428  char *data = 0;
429  int nelts = 1;
430  if (_meta) // if _meta is set, just load type information
431  hs.data.import(number_type);
432  else {
433  if (_slab.set) { // load a slab of SDS array data
434  for (int i = 0; i < rank; ++i)
435  nelts *= _slab.edge[i];
436 
437  // allocate a temporary C array to hold the data from SDreaddata()
438  int datasize = nelts * DFKNTsize(number_type);
439  data = new char[datasize];
440  if (data == 0)
442  BESDEBUG("h4", "SDreaddata() on line 387. _sds_id: " << _sds_id
443  << endl);
444  if (SDreaddata(_sds_id, _slab.start, _slab.stride, _slab.edge,
445  data) < 0) {
446  delete[]data; // problem: clean up and throw an exception
448  }
449  } else { // load entire SDS array
450  // prepare for SDreaddata(): make an array of zeroes and calculate
451  // number of elements of array data
452  int32 zero[hdfclass::MAXDIMS];
453  for (int i = 0; i < rank && i < hdfclass::MAXDIMS; ++i) {
454  zero[i] = 0;
455  nelts *= dim_sizes[i];
456  }
457 
458  // allocate a temporary C array to hold the data from SDreaddata()
459  int datasize = nelts * DFKNTsize(number_type);
460  data = new char[datasize];
461  if (data == 0)
463 
464  // read the data and store it in an hdf_genvec
465  if (SDreaddata(_sds_id, zero, 0, dim_sizes, data) < 0) {
466  delete[]data; // problem: clean up and throw an exception
468  }
469  }
470 
471  hs.data.import(number_type, data, nelts);
472  delete[]data; // deallocate temporary C array
473  }
474 
475  seek_next(); // position to next SDS array
476  return *this;
477 }
478 
479 // Functor to help look for a particular map's ce in the vector of array_ce
480 // objects.
481 class ce_name_match:public std::unary_function < array_ce, bool > {
482  string name;
483  public:
484  ce_name_match(const string & n):name(n) {
485  } bool operator() (const array_ce & a_ce) {
486  return name == a_ce.name;
487  }
488 };
489 
490 // load dimension currently positioned at
492 {
493 
494  // delete any previous data in hd
495  hd.name = hd.label = hd.unit = hd.format = string();
496  hd.count = 0;
497  hd.scale = hdf_genvec();
498  hd.attrs = vector < hdf_attr > ();
499 
500  if (_filename.length() == 0) // no file open
502  if (bos()) // if at BOS, advance to first SDS array
503  seek(0);
504 
505  // This code looks like an optimization to avoid reading unneeded
506  // dimensions. If we're here because we're reading the whole Grid, it
507  // needs to be run, If we're here because the client has asked only for
508  // the Grid's maps, then it's harmless since the Grid's array's
509  // constraint is the default (the whole array) and so there'll be no
510  // reduction in rank. 2/5/2002 jhrg
511  //
512  // if reduce_rank is true, hyperslab dimensions of length 1 will be
513  // eliminated from the dimension object, thus reducing the rank of the
514  // hyperslab
515  while (_slab.set && _slab.reduce_rank && !eo_dim() &&
516  _slab.edge[_dim_index] == 1)
517  ++_dim_index;
518 
519  // if positioned past last dimension, do nothing
520  if (eo_dim())
521  return *this;
522 
523  // open dimension currently positioned at and increment dim index
524  int32 dim_id;
525  if ((dim_id = SDgetdimid(_sds_id, _dim_index)) < 0)
527 
528  // get dimension information
529 
530  char name[hdfclass::MAXSTR];
531  int32 count, number_type, nattrs;
532  if (SDdiminfo(dim_id, name, &count, &number_type, &nattrs) < 0)
534  else
535  hd.name = name; // assign dim name
536 
537  // Grab the current slab, save its value, and set _slab using map_ce. To
538  // choose the correct constraint scan the vector of array_ce objects
539  // looking for the one with the same name as this dimension. Doing this
540  // assures us that the constraint that's used when data is extracted from
541  // the hdf_genvec is done according to the constraint on this map. If we
542  // used _slab as it's set on entry to this method we would be using the
543  // constraint associated with the Grid's array. If the client asked only
544  // for maps, that constraint would default to the whole array and hence
545  // we'd be returning the whole map vector and ignoring the actual
546  // constraint sent by the client. 2/5/2002 jhrg
547  slab s = _slab;
548  if (is_map_ce_set()) { // Only go here if the map_ce_vec has been
549  // set. The is_map_ce_set() predicate is
550  // false by default.
551 #if 0
552  cerr << "dim name: " << name << endl;
553  cerr << "slab set: " << _slab.set << endl;
554  cerr << "dim index: " << _dim_index << endl;
555  cerr << "slab start: " << _slab.start[_dim_index] << endl;
556  cerr << "slab edge: " << _slab.edge[_dim_index] << endl;
557 #endif
558 
559  vector < array_ce > ce = get_map_ce();
560  vector < array_ce >::iterator ce_iter =
561  find_if(ce.begin(), ce.end(), ce_name_match(string(name)));
562 #if 0
563  cerr << "ce name: " << ce_iter->name << endl;
564  cerr << "ce set: " << (ce_iter->start != 0 || ce_iter->edge != 0
565  || ce_iter->stride != 0) << endl;
566  cerr << "ce start: " << ce_iter->start << endl;
567  cerr << "ce edge: " << ce_iter->edge << endl << endl;
568 #endif
569 
570  _slab.set = ce_iter->start != 0 || ce_iter->edge != 0
571  || ce_iter->stride != 0;
572  _slab.reduce_rank = false; // hard to reduce the rank of a vector...
573  _slab.start[_dim_index] = ce_iter->start;
574  _slab.edge[_dim_index] = ce_iter->edge;
575  _slab.stride[_dim_index] = ce_iter->stride;
576  }
577  // Catch any throws and reset _slab.
578  try {
579  char label[hdfclass::MAXSTR];
580  char unit[hdfclass::MAXSTR];
581  char cformat[hdfclass::MAXSTR];
582  if (SDgetdimstrs(dim_id, label, unit, cformat, hdfclass::MAXSTR) ==
583  0) {
584  hd.label = label; // assign dim label
585  hd.unit = unit; // assign dim unit
586  hd.format = cformat; // assign dim format
587  }
588  // if we are dealing with a dimension of size unlimited, then call
589  // SDgetinfo to get the current size of the dimension
590  if (count == 0) { // unlimited dimension
591  if (_dim_index != 0)
592  THROW(hcerr_sdsinfo); // only first dim can be unlimited
593  char junk[hdfclass::MAXSTR];
594  int32 junk2, junk3, junk4;
595  int32 dim_sizes[hdfclass::MAXDIMS];
596  if (SDgetinfo(_sds_id, junk, &junk2, dim_sizes, &junk3, &junk4)
597  < 0)
599  count = dim_sizes[0];
600  }
601  // load user-defined attributes for the dimension
602  // TBD! Not supported at present
603 
604  // load dimension scale if there is one
605 
606  if (number_type != 0) { // found a dimension scale
607 
608  /*
609  * Currently, this server cannot support dimension scales
610  * that are stored as character arrays. See bugs 748 and 756.
611  */
612  if (number_type != DFNT_CHAR) {
613  // allocate a temporary C array to hold data from
614  // SDgetdimscale()
615  char *data = new char[count * DFKNTsize(number_type)];
616 
617  if (data == 0)
619 
620  // read the scale data and store it in an hdf_genvec
621  if (SDgetdimscale(dim_id, data) < 0) {
622  delete[]data; // problem: clean up and throw an exception
624  }
625 
626  if (_slab.set) {
627  void *datastart = (char *) data +
628  _slab.start[_dim_index] * DFKNTsize(number_type);
629  hd.scale = hdf_genvec(number_type, datastart, 0,
631  _slab.stride[_dim_index] - 1,
633  } else
634  hd.scale = hdf_genvec(number_type, data, count);
635 
636  delete[]data; // deallocate temporary C array
637  }
638  }
639  // assign dim size; if slabbing is set, assigned calculated size,
640  // otherwise assign size from SDdiminfo()
641  if (_slab.set)
642  hd.count = _slab.edge[_dim_index];
643  else
644  hd.count = count;
645  _dim_index++;
646  }
647  catch(...) {
648  _slab = s;
649  throw;
650  }
651 
652  _slab = s; // reset _slab
653 
654  return *this;
655 }
656 
657 // load attribute currently positioned at
659 {
660 
661  // delete any previous data in ha
662  ha.name = string();
663  ha.values = hdf_genvec();
664 
665  if (_filename.length() == 0) // no file open
667  if (eo_attr()) // if positioned past last attribute, do nothing
668  return *this;
669 
670  // prepare to read attribute information: set nattrs, id depending on whether
671  // reading file attributes or SDS attributes
672  int32 id;
673  //int nattrs;
674  if (bos()) { // if at BOS, then read file attributes
675  //nattrs = _nfattrs;
676  id = _file_id;
677  } else { // else read SDS attributes
678  //nattrs = _nattrs;
679  id = _sds_id;
680  }
681  char name[hdfclass::MAXSTR];
682  int32 number_type, count;
683  if (SDattrinfo(id, _attr_index, name, &number_type, &count) < 0)
685 
686  // allowcate a temporary C array to hold data from SDreadattr()
687  char *data;
688  data = new char[count * DFKNTsize(number_type)];
689  if (data == 0)
691 
692  // read attribute values and store them in an hdf_genvec
693  if (SDreadattr(id, _attr_index, data) < 0) {
694  delete[]data; // problem: clean up and throw an exception
696  }
697  // eliminate trailing null characters from the data string;
698  // they cause GNU's String class problems
699  // NOTE: removed because count=0 if initial char is '\0' and we're not
700  // using GNU String anymore
701 #if 0
702  if (number_type == DFNT_CHAR)
703  count = (int32) min((int) count, (int) strlen((char *) data));
704 #endif
705 
706  // try { // try to allocate an hdf_genvec
707  if (count > 0) {
708  ha.values = hdf_genvec(number_type, data, count);
709  // }
710  // catch(...) { // problem allocating hdf_genvec: clean up and rethrow
711  // delete []data;
712  // throw;
713  // }
714  }
715  delete[]data; // deallocate temporary C array
716 
717  // increment attribute index to next attribute
718  ++_attr_index;
719  ha.name = name; // assign attribute name
720  return *this;
721 }
722 
723 // This function, when compiled with gcc 2.8 and -O2, causes a virtual
724 // Memory exceeded error. 2/25/98 jhrg
725 // read in all the SDS arrays in a file
726 hdfistream_sds & hdfistream_sds::operator>>(vector < hdf_sds > &hsv)
727 {
728  // hsv = vector<hdf_sds>0; // reset vector
729  for (hdf_sds sds; !eos();) {
730  *this >> sds;
731  hsv.push_back(sds);
732  }
733  return *this;
734 }
735 
736 // read in all of the SDS attributes for currently open SDS
737 hdfistream_sds & hdfistream_sds::operator>>(vector < hdf_attr > &hav)
738 {
739  // hav = vector<hdf_attr>0; // reset vector
740  for (hdf_attr att; !eo_attr();) {
741  *this >> att;
742  hav.push_back(att);
743  }
744  return *this;
745 }
746 
747 // read in all of the SDS dimensions for currently open SDS
748 hdfistream_sds & hdfistream_sds::operator>>(vector < hdf_dim > &hdv)
749 {
750  // hdv = vector<hdf_dim>0; // reset vector
751  for (hdf_dim dim; !eo_dim();) {
752  *this >> dim;
753  hdv.push_back(dim);
754  }
755  return *this;
756 }
757 
758 // Check to see if this hdf_sds has a dim scale: if all of the dimensions have
759 // scale sizes = to their size, it does
760 bool hdf_sds::has_scale(void) const
761 {
762  bool has_scale;
763  if (!_ok(&has_scale)) {
765  return false;
766  } else
767  return has_scale;
768 }
769 
770 // Verify that the hdf_sds is in an OK state (i.e., that it is initialized
771 // correctly) if user has passed a ptr to a bool then set that to whether
772 // there is a dimension scale for at least one of the dimensions
773 //
774 // Added `if (*has_scale)...' because `has_scale' defaults to null and
775 // dereferencing it causes segmentation faults, etc.
776 
777 bool hdf_sds::_ok(bool * has_scale) const
778 {
779 
780  if (has_scale)
781  *has_scale = false;
782 
783  // Check to see that for each SDS dimension scale, that the length of the
784  // scale matches the size of the dimension.
785  for (int i = 0; i < (int) dims.size(); ++i)
786  if (dims[i].scale.size() != 0) {
787  if (has_scale)
788  *has_scale = true;
789  if (dims[i].scale.size() != dims[i].count)
790  return false;
791  }
792 
793  return true;
794 }
void _seek_arr_ref(int ref)
Definition: sds.cc:185
string name
Definition: hdfclass.h:158
vector< hdf_attr > attrs
Definition: hdfclass.h:188
bool has_scale(void) const
Definition: sds.cc:760
vector< hdf_dim > dims
Definition: hdfclass.h:186
static const string format
Definition: hcstream.h:153
virtual void seek_ref(int ref)
Definition: sds.cc:358
virtual int index(void) const
Definition: hcstream.h:71
int32 _nfattrs
Definition: hcstream.h:160
struct hdfistream_sds::slab _slab
virtual bool eos(void) const
Definition: sds.cc:224
void import(int32 nt, void *data, int nelts)
Definition: hdfclass.h:91
int32 count
Definition: hdfclass.h:173
void _rewind(void)
Definition: hcstream.h:146
void _init(void)
Definition: sds.cc:82
int32 start[hdfclass::MAXDIMS]
Definition: hcstream.h:165
string name
Definition: hdfclass.h:185
int32 stride[hdfclass::MAXDIMS]
Definition: hcstream.h:167
hdfistream_sds(const string filename="")
Definition: sds.cc:214
vector< array_ce > get_map_ce()
Definition: hcstream.h:122
virtual bool eo_dim(void) const
Definition: sds.cc:269
void _get_sdsinfo(void)
Definition: sds.cc:101
virtual void rewind(void)
Definition: sds.cc:339
int32 _file_id
Definition: hcstream.h:80
vector< hdf_attr > attrs
Definition: hdfclass.h:175
hdf_genvec data
Definition: hdfclass.h:187
string name
Definition: hdfclass.h:151
int32 _nattrs
Definition: hcstream.h:158
int32 ref
Definition: hdfclass.h:184
void _seek_arr(int index)
Definition: sds.cc:152
void _get_fileinfo(void)
Definition: sds.cc:93
virtual bool eo_attr(void) const
Definition: sds.cc:253
virtual void seek(int index=0)
Definition: sds.cc:317
virtual bool bos(void) const
Definition: sds.cc:239
hdf_genvec scale
Definition: hdfclass.h:174
#define THROW(x)
Definition: dhdferr.h:51
string unit
Definition: hdfclass.h:171
int32 _attr_index
Definition: hcstream.h:155
string _filename
Definition: hcstream.h:79
string name
Definition: hdfclass.h:169
hdf_genvec values
Definition: hdfclass.h:152
virtual void seek_next(void)
Definition: sds.cc:348
virtual void close(void)
Definition: sds.cc:305
string format
Definition: hdfclass.h:172
bool _map_ce_set
Definition: hcstream.h:181
void _close_sds(void)
Definition: sds.cc:117
static const string long_name
Definition: hcstream.h:151
int32 _dim_index
Definition: hcstream.h:156
string label
Definition: hdfclass.h:170
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
bool is_map_ce_set()
Definition: hcstream.h:125
void setslab(vector< int >start, vector< int >edge, vector< int >stride, bool reduce_rank=false)
Definition: sds.cc:369
int32 _sds_id
Definition: hcstream.h:154
void _seek_next_arr(void)
Definition: sds.cc:128
int min(int t1, int t2)
Definition: sds.cc:67
virtual void open(const char *filename=0)
Definition: sds.cc:284
static const string units
Definition: hcstream.h:152
int32 edge[hdfclass::MAXDIMS]
Definition: hcstream.h:166
bool _ok(bool *has_scale=0) const
Definition: sds.cc:777
hdfistream_sds & operator>>(hdf_attr &ha)
Definition: sds.cc:658