bes  Updated for version 3.20.6
HDFSPArray_RealField.cc
1 // This file is part of the hdf4 data handler for the OPeNDAP data server.
3 // It retrieves the real SDS field values for special HDF4 data products.
4 // Authors: MuQun Yang <myang6@hdfgroup.org> Eunsoo Seo
5 // Copyright (c) 2010-2012 The HDF Group
7 #include "HDFSPArray_RealField.h"
8 #include <iostream>
9 #include <sstream>
10 #include <cassert>
11 #include <debug.h>
12 #include "hdf.h"
13 #include "mfhdf.h"
14 #include "InternalErr.h"
15 #include <BESDebug.h>
16 #include "BESInternalError.h"
17 #include "HDFCFUtil.h"
18 #include "HDF4RequestHandler.h"
19 
20 //#include "BESH4MCache.h"
21 #include "dodsutil.h"
22 
23 using namespace std;
24 using namespace libdap;
25 #define SIGNED_BYTE_TO_INT32 1
26 
27 
28 bool
30 {
31 
32  BESDEBUG("h4","Coming to HDFSPArray_RealField read "<<endl);
33  if(length() == 0)
34  return true;
35 
36  // Declare offset, count and step
37  vector<int>offset;
38  offset.resize(rank);
39  vector<int>count;
40  count.resize(rank);
41  vector<int>step;
42  step.resize(rank);
43 
44  // Obtain offset,step and count from the client expression constraint
45  int nelms = format_constraint (&offset[0], &step[0], &count[0]);
46 
47  // Cache
48  // Check if a BES key H4.EnableDataCacheFile is true, if yes, we will check
49  // if we can read the data from this file.
50 #if 0
51  string check_data_cache_key = "H4.EnableDataCacheFile";
52  bool enable_check_data_cache_key = false;
53  enable_check_data_cache_key = HDFCFUtil::check_beskeys(check_data_cache_key);
54 #endif
55 
56  bool data_from_cache = false;
57  bool data_to_cache = false;
58 
59  short dtype_size = HDFCFUtil::obtain_type_size(dtype);
60  if(-1 == dtype_size) {
61  string err_mesg = "Wrong data type size for the variable ";
62  err_mesg += name();
63  throw InternalErr(__FILE__,__LINE__,err_mesg);
64  }
65 
66  string cache_fpath;
67  //if(true == enable_check_data_cache_key) {
68  if(true == HDF4RequestHandler::get_enable_data_cachefile()) {
69 
71 
72  // Here we have a sanity check for the cached parameters:Cached directory,file prefix and cached directory size.
73  // Supposedly Hyrax BES cache feature should check this and the code exists. However, the
74  // current hyrax 1.9.7 doesn't provide this feature. KY 2014-10-24
75 #if 0
76  string bescachedir= llcache->getCacheDirFromConfig();
77  string bescacheprefix = llcache->getCachePrefixFromConfig();
78  unsigned int cachesize = llcache->getCacheSizeFromConfig();
79 #endif
80 
81  // Make it simple, the data cache parameters also shares with the HDF-EOS2 grid lat/lon cache
82  string bescachedir = HDF4RequestHandler::get_cache_latlon_path();
83  string bescacheprefix = HDF4RequestHandler::get_cache_latlon_prefix();
84  long cachesize = HDF4RequestHandler::get_cache_latlon_size();
85 
86  if(("" == bescachedir)||(""==bescacheprefix)||(cachesize <=0))
87  throw InternalErr (__FILE__, __LINE__, "Either the cached dir is empty or the prefix is NULL or the cache size is not set.");
88  else {
89  struct stat sb;
90  if(stat(bescachedir.c_str(),&sb) !=0) {
91  string err_mesg="The cached directory " + bescachedir;
92  err_mesg = err_mesg + " doesn't exist. ";
93  throw InternalErr(__FILE__,__LINE__,err_mesg);
94  }
95  else {
96  if(true == S_ISDIR(sb.st_mode)) {
97  if(access(bescachedir.c_str(),R_OK|W_OK|X_OK) == -1) {
98  string err_mesg="The cached directory " + bescachedir;
99  err_mesg = err_mesg + " can NOT be read,written or executable.";
100  throw InternalErr(__FILE__,__LINE__,err_mesg);
101  }
102  }
103  else {
104  string err_mesg="The cached directory " + bescachedir;
105  err_mesg = err_mesg + " is not a directory.";
106  throw InternalErr(__FILE__,__LINE__,err_mesg);
107  }
108  }
109  }
110 
111  //string cache_fname=HDFCFUtil::obtain_cache_fname(llcache->getCachePrefixFromConfig(),filename,name());
112  string cache_fname=HDFCFUtil::obtain_cache_fname(bescacheprefix,filename,name());
113  cache_fpath = bescachedir + "/"+ cache_fname;
114 
115  int total_elems = 1;
116  for (unsigned int i = 0; i <dimsizes.size();i++)
117  total_elems = total_elems*dimsizes[i];
118  dtype_size = HDFCFUtil::obtain_type_size(dtype);
119  if(-1 == dtype_size) {
120  string err_mesg = "Wrong data type size for the variable ";
121  err_mesg += name();
122  throw InternalErr(__FILE__,__LINE__,err_mesg);
123  }
124  int expected_file_size = dtype_size *total_elems;
125  int fd = 0;
126  if( true == llcache->get_data_from_cache(cache_fpath, expected_file_size,fd)) {
127 
128  vector<int32>offset32;
129  offset32.resize(offset.size());
130  for (int i = 0; i< rank;i++)
131  offset32[i] = offset[i];
132  int offset_1st = INDEX_nD_TO_1D(dimsizes,offset32);
133  vector<int32>end;
134  end.resize(rank);
135  for (int i = 0; i < rank; i++)
136  end[i] = offset[i] +(count[i]-1)*step[i];
137  int offset_last = INDEX_nD_TO_1D(dimsizes,end);
138 //cerr<<"offset_1d is "<<offset_1st <<endl;
139 //cerr<<"offset_last is "<<offset_last <<endl;
140  size_t total_read = dtype_size*(offset_last-offset_1st+1);
141 
142  off_t fpos = lseek(fd,dtype_size*offset_1st,SEEK_SET);
143  if (-1 == fpos) {
144  llcache->unlock_and_close(cache_fpath);
145  llcache->purge_file(cache_fpath);
146  }
147 
149  else
150  data_from_cache = obtain_cached_data(llcache,cache_fpath,fd, step,count,total_read,dtype_size);
151 
152  }
153 
154  if(true == data_from_cache)
155  return true;
156  else
157  data_to_cache = true;
158 
159  }
160 
161 #if 0
162  string check_pass_fileid_key_str="H4.EnablePassFileID";
163  bool check_pass_fileid_key = false;
164  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
165 #endif
166  bool check_pass_fileid_key = HDF4RequestHandler::get_pass_fileid();
167 
168  // Just declare offset,count and step in the int32 type.
169  vector<int32>offset32;
170  offset32.resize(rank);
171  vector<int32>count32;
172  count32.resize(rank);
173  vector<int32>step32;
174  step32.resize(rank);
175 
176  // Just obtain the offset,count and step in the datatype of int32.
177  for (int i = 0; i < rank; i++) {
178  offset32[i] = (int32) offset[i];
179  count32[i] = (int32) count[i];
180  step32[i] = (int32) step[i];
181  }
182 
183  int32 sdid = -1;
184 
185  // Obtain SD ID.
186  if(false == check_pass_fileid_key) {
187  sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
188  if (sdid < 0) {
189  ostringstream eherr;
190  eherr << "File " << filename.c_str () << " cannot be open.";
191  throw InternalErr (__FILE__, __LINE__, eherr.str ());
192  }
193  }
194  else {
195  // This code will make sure that the file ID is not passed when H4.EnableMetaDataCacheFile key is set.
196  // We will wait to see if Hyrax core supports the cache and then make improvement. KY 2015-04-30
197 #if 0
198  string check_enable_mcache_key="H4.EnableMetaDataCacheFile";
199  bool turn_on_enable_mcache_key= false;
200  turn_on_enable_mcache_key = HDFCFUtil::check_beskeys(check_enable_mcache_key);
201 #endif
202 
203  //if(true == turn_on_enable_mcache_key) {
204  if(true == HDF4RequestHandler::get_enable_metadata_cachefile()) {
205 
206  sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
207  if (sdid < 0) {
208  ostringstream eherr;
209  eherr << "File " << filename.c_str () << " cannot be open.";
210  throw InternalErr (__FILE__, __LINE__, eherr.str ());
211  }
212  // Reset the pass file ID key to be false for resource clean-up.
213  check_pass_fileid_key = false;
214 
215  }
216  else
217  sdid = sdfd;
218  }
219 
220  // Initialize SDS ID.
221  int32 sdsid = 0;
222 
223  // Obtain the SDS index based on the input sds reference number.
224  int32 sdsindex = SDreftoindex (sdid, (int32) fieldref);
225  if (sdsindex == -1) {
226  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
227  ostringstream eherr;
228  eherr << "SDS index " << sdsindex << " is not right.";
229  throw InternalErr (__FILE__, __LINE__, eherr.str ());
230  }
231 
232  // Obtain this SDS ID.
233  sdsid = SDselect (sdid, sdsindex);
234  if (sdsid < 0) {
235  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
236  ostringstream eherr;
237  eherr << "SDselect failed.";
238  throw InternalErr (__FILE__, __LINE__, eherr.str ());
239  }
240 
241  // Initialize the temp. returned value.
242  int32 r = 0;
243 
244  // Loop through all the possible SDS datatype and then read the data.
245  switch (dtype) {
246 
247  case DFNT_INT8:
248  {
249  vector<char>buf;
250  buf.resize(nelms);
251  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &buf[0]);
252  if (r != 0) {
253  SDendaccess (sdsid);
254  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
255  ostringstream eherr;
256  eherr << "SDreaddata failed.";
257  throw InternalErr (__FILE__, __LINE__, eherr.str ());
258  }
259 
260 #ifndef SIGNED_BYTE_TO_INT32
261  val2buf(&buf[0]);
262  set_read_p(true);
263 #else
264  vector<int32>newval;
265  newval.resize(nelms);
266  for (int counter = 0; counter < nelms; counter++)
267  newval[counter] = (int32) (buf[counter]);
268 
269  set_value ((dods_int32 *) &newval[0], nelms);
270 #endif
271  if(true == data_to_cache) {
272  try {
273  write_data_to_cache(sdsid,cache_fpath,dtype_size,buf,nelms);
274  }
275  catch(...) {
276  SDendaccess (sdsid);
277  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
278  ostringstream eherr;
279  eherr << "write data to cache failed.";
280  throw InternalErr (__FILE__, __LINE__, eherr.str ());
281 
282  }
283  }
284  }
285  break;
286 
287  // Will keep the following comments until we formally decide not to support these old products.
288  // --------------------------------------------------------
289  // HANDLE this later if necessary. KY 2010-8-17
290  //if(sptype == TRMML2_V6)
291  // Find scale_factor, add_offset attributes
292  // create a new val to float32, remember to change int16 at HDFSP.cc to float32
293  // if(sptype == OBPGL3) 16-bit unsigned integer
294  // Find slope and intercept,
295  // CZCS: also find base. data = base**((slope*l3m_data)+intercept)
296  // Others : slope*data+intercept
297  // OBPGL2: 16-bit signed integer, (8-bit signed integer or 32-bit signed integer)
298  // If slope = 1 and intercept = 0 no need to do conversion
299  // ---------------------------------------------------------
300 
301  case DFNT_UINT8:
302  case DFNT_UCHAR8:
303  case DFNT_INT16:
304  case DFNT_UINT16:
305  case DFNT_INT32:
306  case DFNT_UINT32:
307  case DFNT_FLOAT32:
308  case DFNT_FLOAT64:
309  {
310  vector<char>buf;
311  buf.resize(nelms*dtype_size);
312 
313  r = SDreaddata (sdsid, &offset32[0], &step32[0], &count32[0], &buf[0]);
314  if (r != 0) {
315  SDendaccess (sdsid);
316  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
317  ostringstream eherr;
318  eherr << "SDreaddata failed";
319  throw InternalErr (__FILE__, __LINE__, eherr.str ());
320  }
321 
322  val2buf(&buf[0]);
323  set_read_p(true);
324 
325  // write data to cache if cache is set.
326  if(true == data_to_cache) {
327  try {
328  write_data_to_cache(sdsid,cache_fpath,dtype_size,buf,nelms);
329  }
330  catch(...) {
331  SDendaccess (sdsid);
332  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
333  ostringstream eherr;
334  eherr << "write data to cache failed.";
335  throw InternalErr (__FILE__, __LINE__, eherr.str ());
336 
337  }
338  }
339  }
340  break;
341  default:
342  SDendaccess (sdsid);
343  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
344  throw InternalErr (__FILE__, __LINE__, "unsupported data type.");
345  }
346 
347  // Close the SDS interface
348  r = SDendaccess (sdsid);
349  if (r != 0) {
350  ostringstream eherr;
351  eherr << "SDendaccess failed.";
352  throw InternalErr (__FILE__, __LINE__, eherr.str ());
353  }
354  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
355 
356 #if 0
357  // Close the SD interface
358  r = SDend (sdid);
359  if (r != 0) {
360  ostringstream eherr;
361  eherr << "SDend failed.";
362  throw InternalErr (__FILE__, __LINE__, eherr.str ());
363  }
364 #endif
365 
366  return true;
367 }
368 
369 bool HDFSPArray_RealField::obtain_cached_data(BESH4Cache *llcache,const string & cache_fpath, int fd,vector<int> &cd_step, vector<int>&cd_count,size_t total_read,short dtype_size) {
370 
371  ssize_t ret_read_val = -1;
372  vector<char>buf;
373  //char* buf;
374  //buf = malloc(total_read);
375  buf.resize(total_read);
376  ret_read_val = HDFCFUtil::read_buffer_from_file(fd,(void*)&buf[0],total_read);
377  llcache->unlock_and_close(cache_fpath);
378  if((-1 == ret_read_val) || (ret_read_val != (ssize_t)total_read)) {
379  llcache->purge_file(cache_fpath);
380  return false;
381  }
382  else {
383  unsigned int nele_to_read = 1;
384  for(int i = 0; i<rank;i++)
385  nele_to_read *=cd_count[i];
386 
387  if(nele_to_read == (total_read/dtype_size)) {
388 //cerr<<"use the buffer" <<endl;
389  val2buf(&buf[0]);
390  set_read_p(true);
391  }
392  else { // Need to re-assemble the buffer according to different datatype
393 
394  vector<int>cd_start(rank,0);
395  vector<int32>cd_pos(rank,0);
396  int nelms_to_send = 1;
397  for(int i = 0; i <rank; i++)
398  nelms_to_send = nelms_to_send*cd_count[i];
399  switch (dtype) {
400 
401  case DFNT_INT8:
402  {
403 
404 #ifndef SIGNED_BYTE_TO_INT32
405  vector<int8>total_val;
406  total_val.resize(total_read/dtype_size);
407  memcpy(&total_val[0],(void*)&buf[0],total_read);
408 
409  vector<int8>final_val;
410  subset<int8>(
411  &total_val[0],
412  rank,
413  dimsizes,
414  cd_start,
415  cd_step,
416  cd_count,
417  &final_val,
418  cd_pos,
419  0
420  );
421 
422  set_value((dods_byte*)&final_val[0],nelms_to_send);
423 
424 #else
425  vector<int32>total_val2;
426  total_val2.resize(total_read/dtype_size);
427  memcpy(&total_val2[0],(void*)&buf[0],total_read);
428 
429  vector<int32>final_val2;
430  subset<int32>(
431  &total_val2[0],
432  rank,
433  dimsizes,
434  cd_start,
435  cd_step,
436  cd_count,
437  &final_val2,
438  cd_pos,
439  0
440  );
441 
442  set_value((dods_int32*)&final_val2[0],nelms_to_send);
443 
444 #endif
445  }
446 
447  break;
448  case DFNT_UINT8:
449  case DFNT_UCHAR8:
450  {
451  vector<uint8>total_val;
452  total_val.resize(total_read/dtype_size);
453  memcpy(&total_val[0],(void*)&buf[0],total_read);
454 
455  vector<uint8>final_val;
456  subset<uint8>(
457  &total_val[0],
458  rank,
459  dimsizes,
460  cd_start,
461  cd_step,
462  cd_count,
463  &final_val,
464  cd_pos,
465  0
466  );
467 
468 
469  set_value ((dods_byte *) &final_val[0], nelms_to_send);
470  }
471  break;
472 
473  case DFNT_INT16:
474  {
475  vector<int16>total_val;
476  total_val.resize(total_read/dtype_size);
477  memcpy(&total_val[0],(void*)&buf[0],total_read);
478 
479  vector<int16>final_val;
480  subset<int16>(
481  &total_val[0],
482  rank,
483  dimsizes,
484  cd_start,
485  cd_step,
486  cd_count,
487  &final_val,
488  cd_pos,
489  0
490  );
491 
492 
493  set_value ((dods_int16 *) &final_val[0], nelms_to_send);
494  }
495  break;
496 
497  case DFNT_UINT16:
498  {
499  vector<uint16>total_val;
500  total_val.resize(total_read/dtype_size);
501  memcpy(&total_val[0],(void*)&buf[0],total_read);
502 
503  vector<uint16>final_val;
504  subset<uint16>(
505  &total_val[0],
506  rank,
507  dimsizes,
508  cd_start,
509  cd_step,
510  cd_count,
511  &final_val,
512  cd_pos,
513  0
514  );
515 
516 
517  set_value ((dods_uint16 *) &final_val[0], nelms_to_send);
518  }
519  break;
520 
521  case DFNT_INT32:
522  {
523  vector<int32>total_val;
524  total_val.resize(total_read/dtype_size);
525  memcpy(&total_val[0],(void*)&buf[0],total_read);
526 
527  vector<int32>final_val;
528  subset<int32>(
529  &total_val[0],
530  rank,
531  dimsizes,
532  cd_start,
533  cd_step,
534  cd_count,
535  &final_val,
536  cd_pos,
537  0
538  );
539 
540 
541  set_value ((dods_int32 *) &final_val[0], nelms_to_send);
542  }
543  break;
544 
545  case DFNT_UINT32:
546  {
547  vector<uint32>total_val;
548  total_val.resize(total_read/dtype_size);
549  memcpy(&total_val[0],(void*)&buf[0],total_read);
550 
551  vector<uint32>final_val;
552  subset<uint32>(
553  &total_val[0],
554  rank,
555  dimsizes,
556  cd_start,
557  cd_step,
558  cd_count,
559  &final_val,
560  cd_pos,
561  0
562  );
563 
564 
565  set_value ((dods_uint32 *) &final_val[0], nelms_to_send);
566  }
567  break;
568 
569  case DFNT_FLOAT32:
570  {
571  vector<float32>total_val;
572  total_val.resize(total_read/dtype_size);
573  memcpy(&total_val[0],(void*)&buf[0],total_read);
574 
575  vector<float32>final_val;
576  subset<float32>(
577  &total_val[0],
578  rank,
579  dimsizes,
580  cd_start,
581  cd_step,
582  cd_count,
583  &final_val,
584  cd_pos,
585  0
586  );
587 
588 
589  set_value ((dods_float32 *) &final_val[0], nelms_to_send);
590  }
591  break;
592  case DFNT_FLOAT64:
593  {
594  vector<float64>total_val;
595  total_val.resize(total_read/dtype_size);
596  memcpy(&total_val[0],(void*)&buf[0],total_read);
597 
598  vector<float64>final_val;
599  subset<float64>(
600  &total_val[0],
601  rank,
602  dimsizes,
603  cd_start,
604  cd_step,
605  cd_count,
606  &final_val,
607  cd_pos,
608  0
609  );
610 
611  set_value ((dods_float64 *) &final_val[0], nelms_to_send);
612  }
613  break;
614  default:
615  throw InternalErr (__FILE__, __LINE__, "unsupported data type.");
616 
617  }// end switch(dtype)
618  }// end else (stride is not 1)
619  return true;
620  }// end else(full_read = true)
621 }
622 
623 void
624 HDFSPArray_RealField::write_data_to_cache(int32 sdsid, const string& cache_fpath,short dtype_size,const vector<char> &buf, int nelms) {
625 
627  vector<int32>woffset32(rank,0);
628  vector<int32>wstep32(rank,1);
629  vector<int32>wcount32;
630  wcount32.resize(rank);
631  int total_nelem = 1;
632  for(int i = 0; i <rank; i++){
633  wcount32[i] = (int32)dimsizes[i];
634  total_nelem = total_nelem*dimsizes[i];
635  }
636  vector<char>val;
637  if(DFNT_INT8 == dtype) {
638 
639 #ifndef SIGNED_BYTE_TO_INT32
640  if(total_nelem == nelms)
641  llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)&buf[0]);
642  else {
643  val.resize(dtype_size*total_nelem);
644  if(SDreaddata (sdsid, &woffset32[0], &wstep32[0], &wcount32[0], &val[0])<0)
645  throw InternalErr (__FILE__, __LINE__, "Cannot read the whole SDS for cache.");
646  llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)&val[0]);
647  }
648 
649 #else
650  vector<int>newval;
651  newval.resize(total_nelem);
652  if(total_nelem == nelms) {
653  for (int i = 0; i < total_nelem;i++)
654  newval[i] = (int)buf[i];
655  llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)&newval[0]);
656  }
657  else {
658  vector<char>val2;
659  val2.resize(total_nelem);
660  if(SDreaddata (sdsid, &woffset32[0], &wstep32[0], &wcount32[0], &val2[0])<0)
661  throw InternalErr (__FILE__, __LINE__, "Cannot read the whole SDS for cache.");
662  for (int i = 0; i < total_nelem;i++)
663  newval[i] = (int)val2[i];
664  llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)&newval[0]);
665  }
666 #endif
667  }
668  else {
669  if(total_nelem == nelms) {
670  llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)&buf[0]);
671  }
672  else {
673  val.resize(dtype_size*total_nelem);
674  if(SDreaddata (sdsid, &woffset32[0], &wstep32[0], &wcount32[0], &val[0])<0)
675  throw InternalErr (__FILE__, __LINE__, "Cannot read the whole SDS for cache.");
676 
677  llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)&val[0]);
678  }
679  }
680 }
681 // Standard way to pass the coordinates of the subsetted region from the client to the handlers
682 // Returns the number of elements
683 int
684 HDFSPArray_RealField::format_constraint (int *offset, int *step, int *count)
685 {
686  long nels = 1;
687  int id = 0;
688 
689  Dim_iter p = dim_begin ();
690  while (p != dim_end ()) {
691 
692  int start = dimension_start (p, true);
693  int stride = dimension_stride (p, true);
694  int stop = dimension_stop (p, true);
695 
696  // Check for illegal constraint
697  if (start > stop) {
698  ostringstream oss;
699  oss << "Array/Grid hyperslab start point "<< start <<
700  " is greater than stop point " << stop <<".";
701  throw Error(malformed_expr, oss.str());
702  }
703 
704  offset[id] = start;
705  step[id] = stride;
706  count[id] = ((stop - start) / stride) + 1; // count of elements
707  nels *= count[id]; // total number of values for variable
708 
709  BESDEBUG ("h4",
710  "=format_constraint():"
711  << "id=" << id << " offset=" << offset[id]
712  << " step=" << step[id]
713  << " count=" << count[id]
714  << endl);
715 
716  id++;
717  p++;
718  }// while (p != dim_end ())
719 
720  return nels;
721 }
722 
723 
725 //
726 // \param input Input variable
727 // \param dim dimension info of the input
728 // \param start start indexes of each dim
729 // \param stride stride of each dim
730 // \param edge count of each dim
731 // \param poutput output variable
732 // \parrm index dimension index
733 // \return 0 if successful. -1 otherwise.
734 //
735 template<typename T> int
736 HDFSPArray_RealField::subset(
737  const T input[],
738  int sf_rank,
739  vector<int32> & dim,
740  vector<int> & start,
741  vector<int> & stride,
742  vector<int> & edge,
743  std::vector<T> *poutput,
744  vector<int32>& pos,
745  int index)
746 {
747  for(int k=0; k<edge[index]; k++)
748  {
749  pos[index] = start[index] + k*stride[index];
750  if(index+1<sf_rank)
751  subset(input, sf_rank, dim, start, stride, edge, poutput,pos,index+1);
752  if(index==sf_rank-1)
753  {
754  poutput->push_back(input[INDEX_nD_TO_1D( dim, pos)]);
755  }
756  } // end of for
757  return 0;
758 } // end of template<typename T> static int subset
HDFSPArray_RealField::read
virtual bool read()
Definition: HDFSPArray_RealField.cc:29
BESH4Cache::get_instance
static BESH4Cache * get_instance()
Definition: BESH4MCache.cc:100
BESFileLockingCache::purge_file
virtual void purge_file(const std::string &file)
Purge a single file from the cache.
Definition: BESFileLockingCache.cc:1085
HDFCFUtil::obtain_type_size
static short obtain_type_size(int32)
Obtain datatype size.
Definition: HDFCFUtil.cc:447
libdap
Definition: BESDapFunctionResponseCache.h:35
BESFileLockingCache::unlock_and_close
virtual void unlock_and_close(const std::string &target)
Definition: BESFileLockingCache.cc:713
Error
HDFCFUtil::close_fileid
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)
Definition: HDFCFUtil.cc:3685
BESH4Cache
Definition: BESH4MCache.h:16