37#include <unordered_map>
43#include <libdap/DMR.h>
44#include <libdap/D4BaseTypeFactory.h>
45#include <ObjMemCache.h>
48#include <libdap/mime_util.h>
54#include <BESDASResponse.h>
55#include <libdap/Ancillary.h>
57#include <BESDapNames.h>
58#include <BESResponseNames.h>
59#include <BESVersionInfo.h>
60#include <BESServiceRegistry.h>
62#include <BESDapError.h>
63#include <BESInternalFatalError.h>
64#include <BESSyntaxUserError.h>
65#include <TheBESKeys.h>
67#include <BESStopWatch.h>
77#define prolog std::string("HDF5RequestHandler::").append(__func__).append("() - ")
80void get_attr_contents(AttrTable* temp_table);
84void write_das_to_file(DAS*das_ptr,FILE* das_file);
87void write_das_table_to_file(AttrTable*temp_table,FILE* das_file);
90void write_container_name_to_file(
const string&,FILE* das_file);
93void write_das_attr_info(AttrTable* dtp,
const string&,
const string&,FILE * das_file);
96char* copy_str(
char *temp_ptr,
const string & str);
100char* obtain_str(
char*temp_ptr,
string & str);
103char* get_attr_info_from_dc(
char*temp_pointer,DAS *das,AttrTable *at);
107static unsigned int get_uint_key(
const string &key,
unsigned int def_val);
108static unsigned long get_ulong_key(
const string &key,
unsigned long def_val);
111static float get_float_key(
const string &key,
float def_val);
114static string get_beskeys(
const string&);
117bool obtain_beskeys_info(
const string &,
bool &);
120extern void read_cfdas(DAS &das,
const string & filename,hid_t fileid);
121extern void read_cfdds(DDS &dds,
const string & filename,hid_t fileid);
122extern void read_cfdmr(DMR *dmr,
const string & filename,hid_t fileid);
125unsigned int HDF5RequestHandler::_mdcache_entries = 500;
126unsigned int HDF5RequestHandler::_lrdcache_entries = 0;
127unsigned int HDF5RequestHandler::_srdcache_entries = 0;
128float HDF5RequestHandler::_cache_purge_level = 0.2F;
131ObjMemCache *HDF5RequestHandler::das_cache =
nullptr;
132ObjMemCache *HDF5RequestHandler::dds_cache =
nullptr;
133ObjMemCache *HDF5RequestHandler::datadds_cache =
nullptr;
134ObjMemCache *HDF5RequestHandler::dmr_cache =
nullptr;
136ObjMemCache *HDF5RequestHandler::lrdata_mem_cache =
nullptr;
137ObjMemCache *HDF5RequestHandler::srdata_mem_cache =
nullptr;
145bool HDF5RequestHandler::_usecf =
true;
146bool HDF5RequestHandler::_pass_fileid =
false;
147bool HDF5RequestHandler::_disable_structmeta =
true;
148bool HDF5RequestHandler::_disable_ecsmeta =
false;
149bool HDF5RequestHandler::_keep_var_leading_underscore =
false;
150bool HDF5RequestHandler::_check_name_clashing =
false;
151bool HDF5RequestHandler::_add_path_attrs =
true;
152bool HDF5RequestHandler::_drop_long_string =
true;
153bool HDF5RequestHandler::_fillvalue_check =
true;
154bool HDF5RequestHandler::_check_ignore_obj =
false;
155bool HDF5RequestHandler::_flatten_coor_attr =
true;
156bool HDF5RequestHandler::_default_handle_dimension =
true;
157bool HDF5RequestHandler::_eos5_rm_convention_attr_path =
true;
158bool HDF5RequestHandler::_dmr_long_int =
true;
159bool HDF5RequestHandler::_no_zero_size_fullnameattr =
false;
160bool HDF5RequestHandler::_enable_coord_attr_add_path =
true;
162bool HDF5RequestHandler::_usecfdmr =
true;
163bool HDF5RequestHandler::_add_dap4_coverage =
true;
165bool HDF5RequestHandler::_common_cache_dirs =
false;
167bool HDF5RequestHandler::_use_disk_cache =
false;
168bool HDF5RequestHandler::_use_disk_dds_cache =
false;
169string HDF5RequestHandler::_disk_cache_dir;
170string HDF5RequestHandler::_disk_cachefile_prefix;
171unsigned long long HDF5RequestHandler::_disk_cache_size = 0;
173bool HDF5RequestHandler::_disk_cache_comp_data =
false;
174bool HDF5RequestHandler::_disk_cache_float_only_comp_data =
false;
175float HDF5RequestHandler::_disk_cache_comp_threshold = 1.0;
176unsigned long HDF5RequestHandler::_disk_cache_var_size = 0;
178bool HDF5RequestHandler::_use_disk_meta_cache =
false;
179string HDF5RequestHandler::_disk_meta_cache_path;
181bool HDF5RequestHandler::_use_latlon_disk_cache =
false;
182long HDF5RequestHandler::_latlon_disk_cache_size = 0;
183string HDF5RequestHandler::_latlon_disk_cache_dir;
184string HDF5RequestHandler::_latlon_disk_cachefile_prefix;
186bool HDF5RequestHandler::_escape_utf8_attr =
true;
188DMR* HDF5RequestHandler::dmr_int64 =
nullptr;
190string HDF5RequestHandler::_stp_east_filename;
191string HDF5RequestHandler::_stp_north_filename;
192vector<string> HDF5RequestHandler::lrd_cache_dir_list;
193vector<string> HDF5RequestHandler::lrd_non_cache_dir_list;
194vector<string> HDF5RequestHandler::lrd_var_cache_file_list;
197HDF5RequestHandler::HDF5RequestHandler(
const string & name)
200 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN" << endl);
202 add_handler(DAS_RESPONSE, HDF5RequestHandler::hdf5_build_das);
203 add_handler(DDS_RESPONSE, HDF5RequestHandler::hdf5_build_dds);
204 add_handler(DATA_RESPONSE, HDF5RequestHandler::hdf5_build_data);
205 add_handler(DMR_RESPONSE, HDF5RequestHandler::hdf5_build_dmr);
206 add_handler(DAP4DATA_RESPONSE, HDF5RequestHandler::hdf5_build_dmr);
208 add_handler(HELP_RESPONSE, HDF5RequestHandler::hdf5_build_help);
209 add_handler(VERS_RESPONSE, HDF5RequestHandler::hdf5_build_version);
213#if !(DYNAMIC_CONFIG_ENABLED)
217 BESDEBUG(HDF5_NAME, prolog <<
"END" << endl);
220HDF5RequestHandler::~HDF5RequestHandler()
225 delete datadds_cache;
227 delete lrdata_mem_cache;
228 delete srdata_mem_cache;
235void HDF5RequestHandler::load_config()
237 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN" << endl);
238 BES_STOPWATCH_START(HDF5_NAME, prolog +
"ClockTheBESKeys");
241 HDF5RequestHandler::_mdcache_entries = get_uint_key(
"H5.MetaDataMemCacheEntries", 0);
242 HDF5RequestHandler::_lrdcache_entries = get_uint_key(
"H5.LargeDataMemCacheEntries", 0);
243 HDF5RequestHandler::_srdcache_entries = get_uint_key(
"H5.SmallDataMemCacheEntries", 0);
244 HDF5RequestHandler::_cache_purge_level = get_float_key(
"H5.CachePurgeLevel", 0.2F);
246 if (get_mdcache_entries()) {
247 das_cache =
new ObjMemCache(get_mdcache_entries(), get_cache_purge_level());
248 dds_cache =
new ObjMemCache(get_mdcache_entries(), get_cache_purge_level());
249 datadds_cache =
new ObjMemCache(get_mdcache_entries(), get_cache_purge_level());
250 dmr_cache =
new ObjMemCache(get_mdcache_entries(), get_cache_purge_level());
262 bool has_key =
false;
263 bool key_value = obtain_beskeys_info(
"H5.EnableCF",has_key);
266 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableCF: " << (_usecf?
"true":
"false") << endl);
269 key_value = obtain_beskeys_info(
"H5.DefaultHandleDimension",has_key);
271 _default_handle_dimension = key_value;
272 BESDEBUG(HDF5_NAME, prolog <<
"H5.DefaultHandleDimension: " << (_default_handle_dimension?
"true":
"false") << endl);
275 key_value = obtain_beskeys_info(
"H5.EnablePassFileID",has_key);
277 _pass_fileid = key_value;
278 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnablePassFileID: " << (_pass_fileid?
"true":
"false") << endl);
280 key_value = obtain_beskeys_info(
"H5.DisableStructMetaAttr",has_key);
282 _disable_structmeta = key_value;
283 BESDEBUG(HDF5_NAME, prolog <<
"H5.DisableStructMetaAttr: " << (_disable_structmeta?
"true":
"false") << endl);
285 key_value = obtain_beskeys_info(
"H5.DisableECSMetaAttr",has_key);
287 _disable_ecsmeta = key_value;
288 BESDEBUG(HDF5_NAME, prolog <<
"H5.DisableECSMetaAttr: " << (_disable_ecsmeta?
"true":
"false") << endl);
290 key_value = obtain_beskeys_info(
"H5.KeepVarLeadingUnderscore",has_key);
292 _keep_var_leading_underscore = key_value;
293 BESDEBUG(HDF5_NAME, prolog <<
"H5.KeepVarLeadingUnderscore: " << (_keep_var_leading_underscore?
"true":
"false") << endl);
295 key_value = obtain_beskeys_info(
"H5.EnableCheckNameClashing",has_key);
297 _check_name_clashing = key_value;
298 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableCheckNameClashing: " << (_check_name_clashing?
"true":
"false") << endl);
300 key_value = obtain_beskeys_info(
"H5.EnableAddPathAttrs",has_key);
302 _add_path_attrs = key_value;
303 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableAddPathAttrs: " << (_add_path_attrs?
"true":
"false") << endl);
305 key_value = obtain_beskeys_info(
"H5.EnableDropLongString",has_key);
307 _drop_long_string = key_value;
308 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableDropLongString: " << (_drop_long_string?
"true":
"false") << endl);
310 key_value = obtain_beskeys_info(
"H5.EnableFillValueCheck",has_key);
312 _fillvalue_check = key_value;
313 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableFillValueCheck: " << (_fillvalue_check?
"true":
"false") << endl);
316 key_value = obtain_beskeys_info(
"H5.CheckIgnoreObj",has_key);
318 _check_ignore_obj = key_value;
319 BESDEBUG(HDF5_NAME, prolog <<
"H5.CheckIgnoreObj: " << (_check_ignore_obj?
"true":
"false") << endl);
321 key_value = obtain_beskeys_info(
"H5.ForceFlattenNDCoorAttr",has_key);
323 _flatten_coor_attr = key_value;
324 BESDEBUG(HDF5_NAME, prolog <<
"H5.ForceFlattenNDCoorAttr: " << (_flatten_coor_attr?
"true":
"false") << endl);
326 key_value = obtain_beskeys_info(
"H5.RmConventionAttrPath",has_key);
328 _eos5_rm_convention_attr_path = key_value;
329 BESDEBUG(HDF5_NAME, prolog <<
"H5.RmConventionAttrPath: " << (_eos5_rm_convention_attr_path?
"true":
"false") << endl);
331 key_value = obtain_beskeys_info(
"H5.EnableDMR64bitInt",has_key);
333 _dmr_long_int = key_value;
334 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableDMR64bitInt: " << (_dmr_long_int?
"true":
"false") << endl);
336 key_value = obtain_beskeys_info(
"H5.NoZeroSizeFullnameAttr",has_key);
338 _no_zero_size_fullnameattr = key_value;
339 BESDEBUG(HDF5_NAME, prolog <<
"H5.NoZeroSizeFullnameAttr: " << (_no_zero_size_fullnameattr?
"true":
"false") << endl);
341 key_value = obtain_beskeys_info(
"H5.EnableCoorattrAddPath",has_key);
343 _enable_coord_attr_add_path = key_value;
344 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableCoorattrAddPath: " << (_enable_coord_attr_add_path?
"true":
"false") << endl);
349 key_value = obtain_beskeys_info(
"H5.EnableCFDMR",has_key);
351 _usecfdmr = key_value;
352 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableCFDMR: " << (_usecfdmr?
"true":
"false") << endl);
354 key_value = obtain_beskeys_info(
"H5.EnableDAP4Coverage",has_key);
356 _add_dap4_coverage = key_value;
357 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableDAP4Coverage: " << (_add_dap4_coverage?
"true":
"false") << endl);
361 load_config_disk_cache();
364 key_value = obtain_beskeys_info(
"H5.EscapeUTF8Attr", has_key);
366 _escape_utf8_attr = key_value;
370 load_config_cf_cache();
372 _stp_east_filename = get_beskeys(
"H5.STPEastFileName");
373 _stp_north_filename = get_beskeys(
"H5.STPNorthFileName");
374 BESDEBUG(HDF5_NAME, prolog <<
"END" << endl);
377void HDF5RequestHandler::load_config_disk_cache() {
379 bool has_key =
false;
380 bool key_value = obtain_beskeys_info(
"H5.EnableDiskDataCache",has_key);
382 _use_disk_cache = key_value;
383 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableDiskDataCache: " << (_use_disk_cache?
"true":
"false") << endl);
385 _disk_cache_dir = get_beskeys(
"H5.DiskCacheDataPath");
386 _disk_cachefile_prefix = get_beskeys(
"H5.DiskCacheFilePrefix");
387 _disk_cache_size = get_ulong_key(
"H5.DiskCacheSize",0);
389 key_value = obtain_beskeys_info(
"H5.DiskCacheComp",has_key);
391 _disk_cache_comp_data = key_value;
392 BESDEBUG(HDF5_NAME, prolog <<
"H5.DiskCacheComp: " << (_disk_cache_comp_data?
"true":
"false") << endl);
394 key_value = obtain_beskeys_info(
"H5.DiskCacheFloatOnlyComp",has_key);
396 _disk_cache_float_only_comp_data = key_value;
397 BESDEBUG(HDF5_NAME, prolog <<
"H5.DiskCacheFloatOnlyComp: " << (_disk_cache_float_only_comp_data?
"true":
"false") << endl);
398 _disk_cache_comp_threshold = get_float_key(
"H5.DiskCacheCompThreshold",1.0);
399 _disk_cache_var_size = 1024*get_uint_key(
"H5.DiskCacheCompVarSize",0);
401 key_value = obtain_beskeys_info(
"H5.EnableDiskMetaDataCache",has_key);
403 _use_disk_meta_cache = key_value;
404 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableDiskMetaDataCache: " << (_use_disk_meta_cache?
"true":
"false") << endl);
406 key_value = obtain_beskeys_info(
"H5.EnableDiskDDSCache",has_key);
408 _use_disk_dds_cache = key_value;
409 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableDiskDDSCache: " << (_use_disk_dds_cache?
"true":
"false") << endl);
410 _disk_meta_cache_path = get_beskeys(
"H5.DiskMetaDataCachePath");
412 key_value = obtain_beskeys_info(
"H5.EnableEOSGeoCacheFile",has_key);
414 _use_latlon_disk_cache = key_value;
415 BESDEBUG(HDF5_NAME, prolog <<
"H5.EnableEOSGeoCacheFile: " << (_use_latlon_disk_cache?
"true":
"false") << endl);
416 _latlon_disk_cache_size = get_uint_key(
"H5.Cache.latlon.size",0);
417 _latlon_disk_cache_dir = get_beskeys(
"H5.Cache.latlon.path");
418 _latlon_disk_cachefile_prefix= get_beskeys(
"H5.Cache.latlon.prefix");
420 if (_disk_cache_comp_data ==
true && _use_disk_cache ==
true) {
421 if (_disk_cache_comp_threshold < 1.0) {
423 ss<< _disk_cache_comp_threshold;
424 string _comp_threshold_str(ss.str());
425 string invalid_comp_threshold =
"The Compression Threshold is the total size of the variable array";
426 invalid_comp_threshold+=
" divided by the storage size of compressed array. It should always be >1";
427 invalid_comp_threshold+=
" The current threshold set at h5.conf is ";
428 invalid_comp_threshold+=_comp_threshold_str;
429 invalid_comp_threshold+=
" . Go back to h5.conf and change the H5.DiskCacheCompThreshold to a >1.0 number.";
430 throw BESInternalError(invalid_comp_threshold,__FILE__,__LINE__);
435void HDF5RequestHandler::load_config_cf_cache() {
437 bool has_key =
false;
438 if (get_lrdcache_entries()) {
440 lrdata_mem_cache =
new ObjMemCache(get_lrdcache_entries(), get_cache_purge_level());
441 bool has_LFMC_config =
false;
442 bool key_value = obtain_beskeys_info(
"H5.LargeDataMemCacheConfig",has_key);
444 has_LFMC_config = key_value;
445 BESDEBUG(HDF5_NAME, prolog <<
"H5.LargeDataMemCacheConfig: " << (has_LFMC_config?
"true":
"false") << endl);
446 if (
true == has_LFMC_config)
447 _common_cache_dirs =obtain_lrd_common_cache_dirs();
449 if (get_srdcache_entries()) {
451 BESDEBUG(HDF5_NAME, prolog <<
"Generate memory cache for smaller coordinate variables" << endl);
452 srdata_mem_cache =
new ObjMemCache(get_srdcache_entries(),get_cache_purge_level());
462 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN" << endl);
463#if DYNAMIC_CONFIG_ENABLED
468 hid_t cf_fileid = -1;
477 auto bdas =
dynamic_cast < BESDASResponse *
>(response) ;
479 throw BESInternalError(
"cast error", __FILE__, __LINE__ ) ;
483 DAS *das = bdas->get_das();
486 DAS *cached_das_ptr =
nullptr;
487 bool use_das_cache =
false;
489 cached_das_ptr =
dynamic_cast<DAS*
>(das_cache->get(filename));
491 use_das_cache =
true;
493 if (
true == use_das_cache) {
496 BESDEBUG(HDF5_NAME, prolog <<
"DAS Cached hit for : " << filename << endl);
497 *das = *cached_das_ptr;
500 hdf5_build_das_internal_no_mem_cache(filename, das, cf_fileid);
501 bdas->clear_container() ;
503 catch(
const BESSyntaxUserError & e) {
506 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESSyntaxUserError! Message: " << e.
get_message() << endl);
510 catch(
const BESError & e) {
513 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESError! Message: " << e.
get_message() << endl);
516 catch(
const InternalErr & e) {
519 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
522 catch(
const Error & e) {
525 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
531 string s =
"unknown exception caught building HDF5 DAS";
532 throw BESInternalFatalError(s, __FILE__, __LINE__);
535 BESDEBUG(HDF5_NAME, prolog <<
"END" << endl);
539void HDF5RequestHandler::hdf5_build_das_internal_no_mem_cache(
const string& filename, DAS *das, hid_t &cf_fileid)
541 bool das_from_dc =
false;
542 string das_cache_fname;
545 if (_use_disk_meta_cache ==
true) {
547 string base_filename = HDF5CFUtil::obtain_string_after_lastslash(filename);
548 das_cache_fname = _disk_meta_cache_path+
"/" +base_filename+
"_das";
550 if (access(das_cache_fname.c_str(),F_OK) !=-1)
556 if (
true == das_from_dc) {
557 read_das_from_disk_cache(das_cache_fname,das);
562 BESDEBUG(HDF5_NAME, prolog <<
"HDF5 DAS reading DAS from the disk cache. For memory cache, DAS added to the cache for : " << filename << endl);
563 das_cache->add(
new DAS(*das), filename);
568 H5Eset_auto2(H5E_DEFAULT,
nullptr,
nullptr);
569 if (
true == _usecf) {
571 cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
573 string invalid_file_msg=
"Could not open this HDF5 file ";
574 invalid_file_msg +=filename;
575 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
576 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
577 invalid_file_msg +=
" distributor.";
578 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
581 if (HDF5RequestHandler::get_dmr_64bit_int()!=
nullptr)
582 HDF5RequestHandler::set_dmr_64bit_int(
nullptr);
583 read_cfdas( *das,filename,cf_fileid);
587 hid_t fileid = get_fileid(filename.c_str());
589 string invalid_file_msg=
"Could not open this HDF5 file ";
590 invalid_file_msg +=filename;
591 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
592 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
593 invalid_file_msg +=
" distributor.";
594 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
599 close_fileid(fileid);
602 Ancillary::read_ancillary_das( *das, filename ) ;
606AttrTable* top_table = das->get_top_level_attributes();
607get_attr_contents(top_table);
610AttrTable::Attr_iter start_aiter=das->var_begin();
611AttrTable::Attr_iter it = start_aiter;
612AttrTable::Attr_iter end_aiter = das->var_end();
613while(it != end_aiter) {
614AttrTable* temp_table = das->get_table(it);
616cerr<<
"var_begin"<<endl;
617temp_table->print(cerr);
625 BESDEBUG(HDF5_NAME, prolog <<
"DAS added to the cache for : " << filename << endl);
626 das_cache->add(
new DAS(*das), filename);
631 if (das_cache_fname.empty() ==
false) {
632 BESDEBUG(HDF5_NAME, prolog <<
"HDF5 Build DAS: Write DAS to disk cache " << das_cache_fname << endl);
633 write_das_to_disk_cache(das_cache_fname,das);
641 const string &container_name,
const string& filename,
642 const string &dds_cache_fname,
const string &das_cache_fname,
643 bool dds_from_dc,
bool das_from_dc,
bool build_data)
646 if (
true == build_data)
647 dds = data_bdds->get_dds();
653 hid_t cf_fileid = -1;
658 const DDS* cached_dds_ptr =
nullptr;
659 bool use_dds_cache =
false;
661 cached_dds_ptr =
dynamic_cast<DDS*
>(dds_cache->get(filename));
663 use_dds_cache =
true;
664 if (
true == use_dds_cache) {
667 BESDEBUG(HDF5_NAME, prolog <<
"DDS Metadata Cached hit for : " << filename << endl);
668 *dds = *cached_dds_ptr;
670 else if (
true ==dds_from_dc) {
671 read_dds_from_disk_cache(bdds,data_bdds,build_data,container_name,filename,dds_cache_fname,
672 das_cache_fname,-1,das_from_dc);
675 read_dds_from_file(dds, filename, cf_fileid, fileid, dds_cache_fname, dds_from_dc);
678 add_das_to_dds_wrapper(dds,filename,cf_fileid,fileid,container_name,das_cache_fname,das_from_dc);
683 BESDEBUG(HDF5_NAME, prolog <<
"DDS added to the cache for : " << filename << endl);
684 dds_cache->add(
new DDS(*dds), filename);
693 catch(
const InternalErr & e) {
694 close_h5_files(cf_fileid, fileid);
695 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
698 catch(
const Error & e) {
699 close_h5_files(cf_fileid, fileid);
700 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
703 catch(
const BESSyntaxUserError & e) {
704 close_h5_files(cf_fileid, fileid);
705 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESSyntaxUserError! Message: " << e.
get_message() << endl);
709 close_h5_files(cf_fileid, fileid);
710 string s =
"unknown exception caught building HDF5 DDS";
711 throw BESInternalFatalError(s, __FILE__, __LINE__);
715void HDF5RequestHandler::read_dds_from_file(DDS *dds,
const string &filename, hid_t &cf_fileid, hid_t &fileid,
716 const string &dds_cache_fname,
bool dds_from_dc)
718 BESDEBUG(HDF5_NAME, prolog <<
"Build DDS from the HDF5 file. " << filename << endl);
719 H5Eset_auto2(H5E_DEFAULT,
nullptr,
nullptr);
720 dds->filename(filename);
723 if (
true == _usecf) {
725 cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
727 string invalid_file_msg=
"Could not open this HDF5 file ";
728 invalid_file_msg +=filename;
729 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
730 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
731 invalid_file_msg +=
" distributor.";
732 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
737 if(HDF5RequestHandler::get_dmr_64bit_int() !=
nullptr)
738 HDF5RequestHandler::set_dmr_64bit_int(
nullptr);
739 read_cfdds(*dds,filename,cf_fileid);
743 fileid = get_fileid(filename.c_str());
745 string invalid_file_msg=
"Could not open this HDF5 file ";
746 invalid_file_msg +=filename;
747 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
748 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
749 invalid_file_msg +=
" distributor.";
750 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
753 depth_first(fileid, (
char*)
"/", *dds, filename.c_str());
757 if (!dds->check_semantics()) {
759 throw InternalErr(__FILE__, __LINE__,
760 "DDS check_semantics() failed. This can happen when duplicate variable names are defined. ");
763 Ancillary::read_ancillary_dds( *dds, filename ) ;
766 if(dds_cache_fname.empty() ==
false && dds_from_dc ==
false)
767 write_dds_to_disk_cache(dds_cache_fname,dds);
771void HDF5RequestHandler::add_das_to_dds_wrapper(DDS *dds,
const string &filename, hid_t cf_fileid, hid_t fileid,
772 const string &container_name,
const string &das_cache_fname,
780 add_das_to_dds(dds,container_name,filename,das_cache_fname,h5_fd,das_from_dc);
783void HDF5RequestHandler::get_dds_without_attributes_datadds(
BESDataDDSResponse*data_bdds,
const string& filename)
785 DDS *dds = data_bdds->get_dds();
789 hid_t cf_fileid = -1;
794 const DDS* cached_dds_ptr =
nullptr;
795 bool use_datadds_cache =
false;
798 cached_dds_ptr =
dynamic_cast<DDS*
>(datadds_cache->get(filename));
801 use_datadds_cache =
true;
802 if (
true == use_datadds_cache) {
805 BESDEBUG(HDF5_NAME, prolog <<
"DataDDS Metadata Cached hit for : " << filename << endl);
806 *dds = *cached_dds_ptr;
809 read_datadds_from_file(dds, filename, cf_fileid, fileid);
811 BESDEBUG(HDF5_NAME, prolog <<
"Data ACCESS build_data(): set the including attribute flag to false: "<<filename << endl);
812 data_bdds->set_ia_flag(
false);
815 catch(
const BESSyntaxUserError & e) {
817 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESSyntaxUserError! Message: " << e.
get_message() << endl);
818 close_h5_files(cf_fileid, fileid);
822 catch(
const InternalErr & e) {
824 close_h5_files(cf_fileid, fileid);
825 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
828 catch(
const Error & e) {
830 close_h5_files(cf_fileid, fileid);
831 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
836 close_h5_files(cf_fileid, fileid);
837 string s =
"unknown exception caught building HDF5 DDS";
838 throw BESInternalFatalError(s, __FILE__, __LINE__);
842void HDF5RequestHandler::read_datadds_from_file(DDS *dds,
const string &filename, hid_t &cf_fileid, hid_t &fileid)
844 BESDEBUG(HDF5_NAME, prolog <<
"Build DDS from the HDF5 file. " << filename << endl);
845 H5Eset_auto2(H5E_DEFAULT,
nullptr,
nullptr);
846 dds->filename(filename);
849 if (
true == _usecf) {
851 cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
853 string invalid_file_msg=
"Could not open this HDF5 file ";
854 invalid_file_msg +=filename;
855 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
856 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
857 invalid_file_msg +=
" distributor.";
858 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
862 if (HDF5RequestHandler::get_dmr_64bit_int() !=
nullptr)
863 HDF5RequestHandler::set_dmr_64bit_int(
nullptr);
864 read_cfdds(*dds,filename,cf_fileid);
867 fileid = get_fileid(filename.c_str());
869 string invalid_file_msg=
"Could not open this HDF5 file ";
870 invalid_file_msg +=filename;
871 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
872 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
873 invalid_file_msg +=
" distributor.";
874 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
877 depth_first(fileid, (
char*)
"/", *dds, filename.c_str());
880 if (!dds->check_semantics()) {
882 throw InternalErr(__FILE__, __LINE__,
883 "DDS check_semantics() failed. This can happen when duplicate variable names are defined. ");
885 Ancillary::read_ancillary_dds( *dds, filename ) ;
890 BESDEBUG(HDF5_NAME, prolog <<
"DataDDS added to the cache for : " << filename << endl);
891 datadds_cache->add(
new DDS(*dds), filename);
894 close_h5_files(cf_fileid, fileid);
901 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN" << endl);
902#if DYNAMIC_CONFIG_ENABLED
911 auto bdds =
dynamic_cast < BESDDSResponse *
>(response);
913 throw BESInternalError(
"cast error", __FILE__, __LINE__ ) ;
918 bool dds_from_dc =
false;
919 bool das_from_dc =
false;
920 bool build_data =
false;
921 string dds_cache_fname;
922 string das_cache_fname;
924 if (_use_disk_meta_cache) {
926 string base_filename = HDF5CFUtil::obtain_string_after_lastslash(filename);
929 if (_use_disk_dds_cache) {
930 dds_cache_fname = _disk_meta_cache_path+
"/" +base_filename+
"_dds";
931 if (access(dds_cache_fname.c_str(),F_OK) !=-1)
935 das_cache_fname = _disk_meta_cache_path+
"/" +base_filename+
"_das";
937 if (access(das_cache_fname.c_str(),F_OK) !=-1)
941 get_dds_with_attributes(bdds,
nullptr,container_name,filename, dds_cache_fname,das_cache_fname,
942 dds_from_dc,das_from_dc,build_data);
949 catch(
const BESSyntaxUserError & e) {
950 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESSyntaxUserError! Message: " << e.
get_message() << endl);
953 catch(
const BESError & e) {
954 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESError! Message: " << e.
get_message() << endl);
957 catch(
const InternalErr & e) {
958 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
961 catch(
const Error & e) {
962 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
966 string s =
"unknown exception caught building HDF5 DDS";
967 throw BESInternalFatalError(s, __FILE__, __LINE__);
970 BESDEBUG(HDF5_NAME, prolog <<
"END" << endl);
976 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN" << endl);
977#if DYNAMIC_CONFIG_ENABLED
981 if (_usecf && _pass_fileid)
982 return hdf5_build_data_with_IDs(dhi);
988 auto bdds =
dynamic_cast < BESDataDDSResponse *
>(response);
990 throw BESInternalError(
"cast error", __FILE__, __LINE__ ) ;
998 bool dds_from_dc =
false;
999 bool build_data =
true;
1004 bool das_from_dc =
false;
1005 string dds_cache_fname;
1006 string das_cache_fname;
1010 if(_use_disk_meta_cache ==
true) {
1012 string base_filename = HDF5CFUtil::obtain_string_after_lastslash(filename);
1013 das_cache_fname = _disk_meta_cache_path+
"/" +base_filename+
"_das";
1015 if(access(das_cache_fname.c_str(),F_OK) !=-1)
1021 get_dds_without_attributes_datadds(bdds, filename);
1027 catch(
const BESSyntaxUserError & e) {
1028 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESSyntaxUserError! Message: " << e.
get_message() << endl);
1031 catch(
const BESError & e) {
1032 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESError! Message: " << e.
get_message() << endl);
1035 catch(
const InternalErr & e) {
1036 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
1037 __FILE__, __LINE__);
1039 catch(
const Error & e) {
1040 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
1041 __FILE__, __LINE__);
1044 string s =
"unknown exception caught building HDF5 DDS";
1045 throw BESInternalFatalError(s, __FILE__, __LINE__);
1048 BESDEBUG(HDF5_NAME, prolog <<
"END" << endl);
1055 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN" << endl);
1056#if DYNAMIC_CONFIG_ENABLED
1060 BESDEBUG(HDF5_NAME,prolog <<
"Building DataDDS by passing file IDs. "<<endl);
1061 hid_t cf_fileid = -1;
1065 H5Eset_auto2(H5E_DEFAULT,
nullptr,
nullptr);
1066 cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
1068 string invalid_file_msg=
"Could not open this HDF5 file ";
1069 invalid_file_msg +=filename;
1070 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
1071 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
1072 invalid_file_msg +=
" distributor.";
1073 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1077 auto bdds =
dynamic_cast < BESDataDDSResponse *
>(response);
1079 throw BESInternalError(
"cast error", __FILE__, __LINE__ ) ;
1085 auto hdds_unique = make_unique<HDF5DDS>(bdds->
get_dds());
1088 auto hdds = hdds_unique.release();
1090 hdds->setHDF5Dataset(cf_fileid);
1092 read_cfdds( *hdds,filename,cf_fileid);
1094 if (!hdds->check_semantics()) {
1096 throw InternalErr(__FILE__, __LINE__,
1097 "DDS check_semantics() failed. This can happen when duplicate variable names are defined.");
1100 Ancillary::read_ancillary_dds( *hdds, filename ) ;
1102 auto das_unique = make_unique<DAS>();
1103 auto das = das_unique.release();
1104 BESDASResponse bdas( das ) ;
1106 read_cfdas( *das,filename,cf_fileid);
1107 Ancillary::read_ancillary_das( *das, filename ) ;
1109 hdds->transfer_attributes(das);
1115 catch(
const BESSyntaxUserError & e) {
1116 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESSyntaxUserError! Message: " << e.
get_message() << endl);
1119 H5Fclose(cf_fileid);
1122 catch(
const BESError & e) {
1124 H5Fclose(cf_fileid);
1125 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESError! Message: " << e.
get_message() << endl);
1128 catch(
const InternalErr & e) {
1130 H5Fclose(cf_fileid);
1131 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
1132 __FILE__, __LINE__);
1134 catch(
const Error & e) {
1136 H5Fclose(cf_fileid);
1137 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
1138 __FILE__, __LINE__);
1142 H5Fclose(cf_fileid);
1143 string s =
"unknown exception caught building HDF5 DataDDS";
1144 throw BESInternalFatalError(s, __FILE__, __LINE__);
1147 BESDEBUG(HDF5_NAME, prolog <<
"END" << endl);
1153 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN" << endl);
1154#if DYNAMIC_CONFIG_ENABLED
1161 BESDMRResponse &bes_dmr_response =
dynamic_cast<BESDMRResponse &
>(*response);
1165 DMR *dmr = bes_dmr_response.get_dmr();
1169 hid_t cf_fileid = -1;
1173 const DMR* cached_dmr_ptr =
nullptr;
1175 BESDEBUG(HDF5_NAME, prolog <<
"Checking DMR cache for : " << filename << endl);
1176 cached_dmr_ptr =
dynamic_cast<DMR*
>(dmr_cache->get(filename));
1179 if (cached_dmr_ptr) {
1181 BESDEBUG(HDF5_NAME, prolog <<
"DMR cache hit for : " << filename << endl);
1182 *dmr = *cached_dmr_ptr;
1186 if (
true == hdf5_build_dmr_from_file(dhi,bes_dmr_response,dmr, filename, cf_fileid, fileid))
1190 catch(
const BESError & e) {
1191 close_h5_files(cf_fileid, fileid);
1192 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESError! Message: " << e.
get_message() << endl);
1195 catch(
const InternalErr & e) {
1197 close_h5_files(cf_fileid, fileid);
1198 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
1199 __FILE__, __LINE__);
1201 catch(
const Error & e) {
1203 close_h5_files(cf_fileid, fileid);
1204 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
1205 __FILE__, __LINE__);
1209 close_h5_files(cf_fileid, fileid);
1210 string s =
"unknown exception caught building HDF5 DMR";
1211 throw BESInternalFatalError(s, __FILE__, __LINE__);
1221 dmr->set_factory(
nullptr);
1223 BESDEBUG(HDF5_NAME, prolog <<
"END" << endl);
1228 DMR *dmr,
const string &filename,
1229 hid_t &cf_fileid, hid_t &fileid)
1231 H5Eset_auto2(H5E_DEFAULT,
nullptr,
nullptr);
1232 D4BaseTypeFactory MyD4TypeFactory;
1233 dmr->set_factory(&MyD4TypeFactory);
1234 if(_escape_utf8_attr ==
false)
1235 dmr->set_utf8_xml_encoding();
1239 if(
true == _usecfdmr) {
1241 cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
1242 if (cf_fileid < 0) {
1243 string invalid_file_msg=
"Could not open this HDF5 file ";
1244 invalid_file_msg +=filename;
1245 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
1246 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
1247 invalid_file_msg +=
" distributor.";
1248 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1250 read_cfdmr(dmr,filename,cf_fileid);
1251 H5Fclose(cf_fileid);
1254 dmr->set_factory(
nullptr);
1256 BESDEBUG(HDF5_NAME, prolog <<
"END" << endl);
1261 if(
true == _pass_fileid)
1262 return hdf5_build_dmr_with_IDs(dhi);
1264 cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
1266 string invalid_file_msg=
"Could not open this HDF5 file ";
1267 invalid_file_msg +=filename;
1268 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
1269 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
1270 invalid_file_msg +=
" distributor.";
1271 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1274 BaseTypeFactory factory;
1275 DDS dds(&factory, name_path(filename),
"3.2");
1276 dds.filename(filename);
1282 HDF5RequestHandler::set_dmr_64bit_int(dmr);
1283 read_cfdds( dds,filename,cf_fileid);
1284 if (!dds.check_semantics()) {
1286 throw InternalErr(__FILE__, __LINE__,
1287 "DDS check_semantics() failed. This can happen when duplicate variable names are defined.");
1290 read_cfdas(das,filename,cf_fileid);
1291 Ancillary::read_ancillary_das( das, filename ) ;
1293 dds.transfer_attributes(&das);
1297 H5Fclose(cf_fileid);
1299 dmr->build_using_dds(dds);
1306 fileid = get_fileid(filename.c_str());
1308 string invalid_file_msg=
"Could not open this HDF5 file ";
1309 invalid_file_msg +=filename;
1310 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
1311 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
1312 invalid_file_msg +=
" distributor.";
1313 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1317 bool is_eos5 = check_eos5(fileid);
1320 bool use_dimscale =
false;
1321 if (
true == _default_handle_dimension)
1322 use_dimscale = check_dimscale(fileid);
1326 eos5_dim_info_t eos5_dim_info;
1327 if (is_eos5 && !use_dimscale)
1328 obtain_eos5_dims(fileid,eos5_dim_info);
1330 dmr->set_name(name_path(filename));
1331 dmr->set_filename(name_path(filename));
1336 D4Group* root_grp = dmr->root();
1337 BESDEBUG(
"h5",
"use_dimscale is "<< use_dimscale <<endl);
1345 vector<link_info_t> hdf5_hls;
1346 vector<string> handled_coord_names;
1348 breadth_first(fileid, fileid,(
const char*)
"/",root_grp,filename.c_str(),use_dimscale,is_eos5,hdf5_hls,
1349 eos5_dim_info,handled_coord_names);
1351 if (is_eos5 ==
false)
1356 BESDEBUG(
"h5",
"build_dmr - before obtain dimensions"<< endl);
1357 D4Dimensions *root_dims = root_grp->dims();
1358for(D4Dimensions::D4DimensionsIter di = root_dims->dim_begin(), de = root_dims->dim_end(); di != de; ++di) {
1359BESDEBUG(
"fonc",
"transform_dap4() - check dimensions"<< endl);
1360BESDEBUG(
"fonc",
"transform_dap4() - dim name is: "<<(*di)->name()<<endl);
1361BESDEBUG(
"fonc",
"transform_dap4() - dim size is: "<<(*di)->size()<<endl);
1362BESDEBUG(
"fonc",
"transform_dap4() - fully_qualfied_dim name is: "<<(*di)->fully_qualified_name()<<endl);
1366 BESDEBUG(
"h5",
"build_dmr - after obtain dimensions"<< endl);
1369 close_fileid(fileid);
1376 BESDEBUG(HDF5_NAME, prolog <<
"DMR added to the cache for : " << filename << endl);
1377 dmr_cache->add(
new DMR(*dmr), filename);
1384 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN" << endl);
1385#if DYNAMIC_CONFIG_ENABLED
1390 hid_t cf_fileid = -1;
1392 H5Eset_auto2(H5E_DEFAULT,
nullptr,
nullptr);
1393 cf_fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
1395 string invalid_file_msg=
"Could not open this HDF5 file ";
1396 invalid_file_msg +=filename;
1397 invalid_file_msg +=
". It is very possible that this file is not an HDF5 file ";
1398 invalid_file_msg +=
" but with the .h5/.HDF5 suffix. Please check with the data";
1399 invalid_file_msg +=
" distributor.";
1400 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1403 BaseTypeFactory factory;
1404 DDS dds(&factory, name_path(filename),
"3.2");
1405 dds.filename(filename);
1411 read_cfdds( dds,filename,cf_fileid);
1413 if (!dds.check_semantics()) {
1415 throw InternalErr(__FILE__, __LINE__,
1416 "DDS check_semantics() failed. This can happen when duplicate variable names are defined.");
1419 Ancillary::read_ancillary_dds( dds, filename ) ;
1421 read_cfdas(das,filename,cf_fileid);
1423 Ancillary::read_ancillary_das( das, filename ) ;
1425 dds.transfer_attributes(&das);
1430 catch(
const BESError & e) {
1432 H5Fclose(cf_fileid);
1433 BESDEBUG(HDF5_NAME, prolog <<
"Caught BESError! Message: " << e.
get_message() << endl);
1436 catch(
const InternalErr & e) {
1439 H5Fclose(cf_fileid);
1441 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
1442 __FILE__, __LINE__);
1444 catch(
const Error & e) {
1447 H5Fclose(cf_fileid);
1449 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
1450 __FILE__, __LINE__);
1455 H5Fclose(cf_fileid);
1457 string s =
"unknown exception caught building HDF5 DataDDS";
1458 throw BESInternalFatalError(s, __FILE__, __LINE__);
1464 BESDMRResponse &bes_dmr =
dynamic_cast<BESDMRResponse &
>(*response);
1471 DMR *dmr = bes_dmr.get_dmr();
1472 D4BaseTypeFactory MyD4TypeFactory;
1473 dmr->set_factory(&MyD4TypeFactory);
1474 dmr->build_using_dds(dds);
1476 auto hdf5_dmr_unique = make_unique<HDF5DMR>(dmr);
1477 auto hdf5_dmr = hdf5_dmr_unique.release();
1478 hdf5_dmr->setHDF5Dataset(cf_fileid);
1480 bes_dmr.set_dmr(hdf5_dmr);
1489 hdf5_dmr->set_factory(
nullptr);
1491 BESDEBUG(HDF5_NAME, prolog <<
"END" << endl);
1498 auto info =
dynamic_cast<BESInfo *
>(response);
1500 throw BESInternalError(
"cast error", __FILE__, __LINE__ ) ;
1502 string add_info=
"Just for Test";
1504 map<string, string, std::less<>> attrs ;
1505 attrs[
"name"] = MODULE_NAME ;
1506 attrs[
"version"] = MODULE_VERSION ;
1507 list<string> services ;
1508 BESServiceRegistry::TheRegistry()->
services_handled( HDF5_NAME, services );
1509 if ( services.empty()==
false ) {
1511 attrs[
"handles"] = handles ;
1513 info->begin_tag(
"module", &attrs ) ;
1514 info->end_tag(
"module" ) ;
1515 info->add_data(add_info);
1523 auto info =
dynamic_cast < BESVersionInfo *
>(response);
1525 throw BESInternalError(
"cast error", __FILE__, __LINE__ ) ;
1527 info->add_module( MODULE_NAME, MODULE_VERSION ) ;
1533bool HDF5RequestHandler::obtain_lrd_common_cache_dirs()
1535 string lrd_config_fpath;
1536 string lrd_config_fname;
1539 lrd_config_fpath = get_beskeys(
"H5.DataCachePath");
1542 lrd_config_fname = get_beskeys(
"H5.LargeDataMemCacheFileName");
1545 if (lrd_config_fpath.empty() || lrd_config_fname.empty())
1552 string mcache_config_fname = lrd_config_fpath+
"/"+lrd_config_fname;
1555 ifstream mcache_config_file(mcache_config_fname.c_str());
1558 if (mcache_config_file.is_open()==
false) {
1559 BESDEBUG(HDF5_NAME, prolog <<
"The large data memory cache configure file "<<mcache_config_fname );
1560 BESDEBUG(HDF5_NAME, prolog <<
" cannot be opened."<<endl);
1565 while(getline(mcache_config_file,temp_line)) {
1568 if (temp_line.size() >1 && temp_line.at(1)==
' ') {
1570 string subline = temp_line.substr(2);
1571 vector<string> temp_name_list;
1574 if(temp_line.at(0)==
'1') {
1575 HDF5CFUtil::Split_helper(temp_name_list,subline,sep);
1576 lrd_cache_dir_list.insert(lrd_cache_dir_list.end(),temp_name_list.begin(),temp_name_list.end());
1579 else if(temp_line.at(0)==
'0'){
1580 HDF5CFUtil::Split_helper(temp_name_list,subline,sep);
1581 lrd_non_cache_dir_list.insert(lrd_non_cache_dir_list.end(),temp_name_list.begin(),temp_name_list.end());
1584 else if(temp_line.at(0)==
'2')
1585 obtain_lrd_common_cache_dirs_data_vars(temp_name_list, subline, sep);
1590 mcache_config_file.close();
1591 if(lrd_cache_dir_list.empty() && lrd_non_cache_dir_list.empty() && lrd_var_cache_file_list.empty())
1597void HDF5RequestHandler::obtain_lrd_common_cache_dirs_data_vars(vector<string> &temp_name_list,
const string &subline,
1602 vector<unsigned int>dq_pos;
1603 vector<unsigned int>sq_pos;
1604 for (
unsigned int i = 0; i<subline.size();i++) {
1605 if (subline[i]==
'"') {
1606 dq_pos.push_back(i);
1608 else if(subline[i]==
'\'')
1609 sq_pos.push_back(i);
1611 if (dq_pos.empty() && sq_pos.empty())
1612 HDF5CFUtil::Split_helper(temp_name_list,subline,sep);
1613 else if((dq_pos.empty()==
false) && (dq_pos.size()%2==0) && sq_pos.empty()==
true) {
1614 unsigned int dq_index= 0;
1615 while(dq_index < dq_pos.size()){
1616 if(dq_pos[dq_index+1]>(dq_pos[dq_index]+1)) {
1617 temp_name_list.push_back
1618 (subline.substr(dq_pos[dq_index]+1,dq_pos[dq_index+1]-dq_pos[dq_index]-1));
1620 dq_index = dq_index + 2;
1623 else if((sq_pos.empty()==
false) &&(sq_pos.size()%2==0) && dq_pos.empty()==
true) {
1624 unsigned int sq_index= 0;
1625 while(sq_index < sq_pos.size()){
1626 if (sq_pos[sq_index+1]>(sq_pos[sq_index]+1)) {
1627 temp_name_list.push_back
1628 (subline.substr(sq_pos[sq_index]+1,sq_pos[sq_index+1]-sq_pos[sq_index]-1));
1630 sq_index = sq_index+2;
1634 lrd_var_cache_file_list.insert(lrd_var_cache_file_list.end(),temp_name_list.begin(),temp_name_list.end());
1637bool HDF5RequestHandler::read_das_from_disk_cache(
const string & cache_filename,DAS *das_ptr) {
1639 BESDEBUG(HDF5_NAME, prolog <<
"Coming to read_das_from_disk_cache() " << cache_filename << endl);
1640 bool ret_value =
true;
1641 FILE *md_file =
nullptr;
1642 md_file = fopen(cache_filename.c_str(),
"rb");
1644 if(
nullptr == md_file) {
1645 string bes_error =
"An error occurred trying to open a metadata cache file " + cache_filename;
1646 throw BESInternalError( bes_error, __FILE__, __LINE__);
1650 int fd_md = fileno(md_file);
1652 l_md = lock(F_RDLCK);
1655 if (fcntl(fd_md,F_SETLKW,l_md) == -1) {
1658 oss <<
"cache process: " << l_md->l_pid <<
" triggered a locking error: " << get_errno();
1659 throw BESInternalError( oss.str(), __FILE__, __LINE__);
1665 if (stat(cache_filename.c_str(),&sb) != 0) {
1666 string bes_error =
"An error occurred trying to stat a metadata cache file size " + cache_filename;
1667 throw BESInternalError( bes_error, __FILE__, __LINE__);
1671 auto bytes_expected_read=(size_t)sb.st_size;
1672 BESDEBUG(HDF5_NAME, prolog <<
"DAS Disk cache file size is " << bytes_expected_read << endl);
1675 buf.resize(bytes_expected_read);
1676 size_t bytes_to_read =fread((
void*)buf.data(),1,bytes_expected_read,md_file);
1677 if (bytes_to_read != bytes_expected_read)
1678 throw InternalErr(__FILE__,__LINE__,
"Fail to read the data from the das cache file.");
1680 char* temp_pointer =buf.data();
1682 AttrTable*at =
nullptr;
1684 temp_pointer = get_attr_info_from_dc(temp_pointer,das_ptr,at);
1687 if (fcntl(fd_md,F_SETLK,lock(F_UNLCK)) == -1) {
1689 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1693 throw InternalErr(__FILE__,__LINE__,
"Fail to parse a das cache file.");
1697 if(fcntl(fd_md,F_SETLK,lock(F_UNLCK)) == -1) {
1699 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1708bool HDF5RequestHandler::write_dds_to_disk_cache(
const string& dds_cache_fname,DDS *dds_ptr) {
1710 BESDEBUG(HDF5_NAME, prolog <<
"Write DDS to disk cache " << dds_cache_fname << endl);
1711 FILE *dds_file = fopen(dds_cache_fname.c_str(),
"w");
1713 if(
nullptr == dds_file) {
1714 string bes_error =
"An error occurred trying to open a metadata cache file " + dds_cache_fname;
1715 throw BESInternalError( bes_error, __FILE__, __LINE__);
1719 int fd_md = fileno(dds_file);
1721 l_md = lock(F_WRLCK);
1724 if (fcntl(fd_md,F_SETLKW,l_md) == -1) {
1727 oss <<
"cache process: " << l_md->l_pid <<
" triggered a locking error: " << get_errno();
1728 throw BESInternalError( oss.str(), __FILE__, __LINE__);
1732 dds_ptr->print(dds_file);
1735 if (fcntl(fd_md,F_SETLK,lock(F_UNLCK)) == -1) {
1737 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1741 throw InternalErr(__FILE__,__LINE__,
"Fail to parse a dds cache file.");
1744 if (fcntl(fd_md,F_SETLK,lock(F_UNLCK)) == -1) {
1746 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1756bool HDF5RequestHandler::write_das_to_disk_cache(
const string & das_cache_fname, DAS *das_ptr) {
1758 BESDEBUG(HDF5_NAME, prolog <<
"Write DAS to disk cache " << das_cache_fname << endl);
1759 FILE *das_file = fopen(das_cache_fname.c_str(),
"wb");
1760 if(
nullptr == das_file) {
1761 string bes_error =
"An error occurred trying to open a metadata cache file " + das_cache_fname;
1762 throw BESInternalError( bes_error, __FILE__, __LINE__);
1765 int fd_md = fileno(das_file);
1767 l_md = lock(F_WRLCK);
1770 if(fcntl(fd_md,F_SETLKW,l_md) == -1) {
1773 oss <<
"cache process: " << l_md->l_pid <<
" triggered a locking error: " << get_errno();
1774 throw BESInternalError( oss.str(), __FILE__, __LINE__);
1778 write_das_to_file(das_ptr,das_file);
1781 if(fcntl(fd_md,F_SETLK,lock(F_UNLCK)) == -1) {
1783 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1787 throw InternalErr(__FILE__,__LINE__,
"Fail to parse a dds cache file.");
1790 if(fcntl(fd_md,F_SETLK,lock(F_UNLCK)) == -1) {
1792 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1804void write_das_to_file(DAS*das_ptr,FILE* das_file) {
1807 uint8_t category_flag = 2;
1808 AttrTable* top_table = das_ptr->get_top_level_attributes();
1809 write_das_table_to_file(top_table,das_file);
1812 fwrite((
const void*)&category_flag,1,1,das_file);
1817void write_das_table_to_file(AttrTable*temp_table,FILE* das_file) {
1819 if(temp_table !=
nullptr) {
1822 uint8_t category_flag = 2;
1825 AttrTable::Attr_iter top_startit = temp_table->attr_begin();
1826 AttrTable::Attr_iter top_endit = temp_table->attr_end();
1827 AttrTable::Attr_iter top_it = top_startit;
1828 while(top_it !=top_endit) {
1829 AttrType atype = temp_table->get_attr_type(top_it);
1830 if (atype == Attr_unknown)
1831 throw InternalErr(__FILE__,__LINE__,
"Unsupported DAS Attribute type");
1832 else if (atype!=Attr_container) {
1833 BESDEBUG(HDF5_NAME, prolog <<
"DAS to the disk cache, attr name is: "
1834 << temp_table->get_name(top_it) << endl);
1835 BESDEBUG(HDF5_NAME, prolog <<
"DAS to the disk cache, attr type is: "
1836 << temp_table->get_type(top_it) << endl);
1847 write_das_attr_info(temp_table,temp_table->get_name(top_it),
1848 temp_table->get_type(top_it),das_file);
1851 BESDEBUG(HDF5_NAME, prolog <<
"DAS to the disk cache, attr container name is: "
1852 << (*top_it)->name << endl);
1854 AttrTable* sub_table = temp_table->get_attr_table(top_it);
1855 write_container_name_to_file(sub_table->get_name(),das_file);
1856 write_das_table_to_file(sub_table,das_file);
1859 fwrite((
const void*)&category_flag,1,1,das_file);
1869void write_container_name_to_file(
const string& cont_name,FILE *das_file) {
1872 uint8_t category_flag = 1;
1874 size_t bytes_to_write = cont_name.size()+
sizeof(
size_t)+1;
1875 buf.resize(bytes_to_write);
1876 char*temp_pointer =buf.data();
1877 memcpy((
void*)temp_pointer,(
void*)&category_flag,1);
1879 temp_pointer=copy_str(temp_pointer,cont_name);
1881 size_t bytes_to_be_written = fwrite((
const void*)buf.data(),1,bytes_to_write,das_file);
1882 if (bytes_to_be_written != bytes_to_write)
1883 throw InternalErr(__FILE__, __LINE__,
"Failed to write a DAS container name to a cache");
1889void write_das_attr_info(AttrTable* dtp,
const string& attr_name,
const string & attr_type,FILE * das_file) {
1892 uint8_t category_flag = 0;
1894 unsigned int num_attr_elems = dtp->get_attr_num(attr_name);
1895 vector<string> attr_values;
1896 size_t total_attr_values_size = 0;
1897 for (
unsigned int i = 0; i <num_attr_elems;i++){
1898 attr_values.push_back((*(dtp->get_attr_vector(attr_name)))[i]);
1899 total_attr_values_size += attr_values[i].size();
1903 size_t bytes_to_write_attr = 1 + attr_name.size() + attr_type.size() + 2*
sizeof(
size_t);
1909 bytes_to_write_attr +=
sizeof(
unsigned int) + num_attr_elems*
sizeof(
size_t)+total_attr_values_size;
1911 vector<char>attr_buf;
1912 attr_buf.resize(bytes_to_write_attr);
1913 char* temp_attrp =attr_buf.data();
1916 memcpy((
void*)temp_attrp,(
void*)&category_flag,1);
1920 temp_attrp=copy_str(temp_attrp,attr_name);
1921 temp_attrp=copy_str(temp_attrp,attr_type);
1924 memcpy((
void*)temp_attrp,(
void*)&num_attr_elems,
sizeof(
unsigned int));
1925 temp_attrp+=
sizeof(
unsigned int);
1928 for (
unsigned int i = 0; i <num_attr_elems;i++)
1929 temp_attrp=copy_str(temp_attrp,(*(dtp->get_attr_vector(attr_name)))[i]);
1931 size_t bytes_to_be_written = fwrite((
const void*)attr_buf.data(),1,bytes_to_write_attr,das_file);
1932 if (bytes_to_be_written != bytes_to_write_attr)
1933 throw InternalErr(__FILE__, __LINE__,
"Failed to write a DAS attribute to a cache");
1939 bool build_data,
const string & container_name,
const string & h5_fname,
1940 const string & dds_cache_fname,
const string &das_cache_fname, hid_t h5_fd,
1944 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN dds_cache_fname: " << dds_cache_fname << endl);
1947 if(
true == build_data)
1948 dds = data_bdds->get_dds();
1954 DDS tdds(&tf,name_path(h5_fname),
"3.2");
1955 tdds.filename(h5_fname);
1957 FILE *dds_file = fopen(dds_cache_fname.c_str(),
"r");
1958 tdds.parse(dds_file);
1960 auto cache_dds_unique = make_unique<DDS>(tdds);
1963 auto cache_dds = cache_dds_unique.release();
1964 Ancillary::read_ancillary_dds( *cache_dds, h5_fname ) ;
1966 add_das_to_dds(cache_dds,container_name,h5_fname,das_cache_fname,h5_fd,das_from_dc);
1967 if(
true == build_data)
1968 data_bdds->
set_dds(cache_dds);
1971 if(dds_file !=
nullptr)
1976 BESDEBUG(HDF5_NAME, prolog <<
"For memory cache, DDS added to the cache for : " << h5_fname << endl);
1977 dds_cache->add(
new DDS(*cache_dds), h5_fname);
1983void HDF5RequestHandler::add_das_to_dds(DDS *dds,
const string &,
const string &filename,
1984 const string &das_cache_fname, hid_t h5_fd,
bool das_from_dc) {
1986 BESDEBUG(HDF5_NAME, prolog <<
"BEGIN" << endl);
1989 DAS *das = nullptr ;
1990 bool use_das_cache =
false;
1992 das =
dynamic_cast<DAS*
>(das_cache->get(filename));
1994 use_das_cache =
true;
1996 if (
true == use_das_cache) {
1997 BESDEBUG(HDF5_NAME, prolog <<
"DAS Cached hit for : " << filename << endl);
1998 dds->transfer_attributes(das);
2003 auto das_unique = make_unique<DAS>();
2004 das = das_unique.get();
2011 if (!container_name.empty())
2012 das->container_name(container_name);
2014 if (das_from_dc ==
true)
2015 read_das_from_disk_cache(das_cache_fname,das);
2017 read_das_from_file(das, filename, das_cache_fname, h5_fd, das_from_dc);
2019 dds->transfer_attributes(das);
2023 BESDEBUG(HDF5_NAME, prolog <<
"For memory cache, DAS added to the cache for : " << filename << endl);
2024 das_cache->add(
new DAS(*das), filename);
2031void HDF5RequestHandler::read_das_from_file(DAS *das,
const string &filename,
const string &das_cache_fname,
2032 hid_t h5_fd,
bool das_from_dc)
2035 bool h5_file_open =
true;
2037 h5_file_open =
false;
2038 if (
true == _usecf) {
2040 if (h5_file_open ==
false)
2041 h5_fd = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
2043 read_cfdas( *das,filename,h5_fd);
2044 if (h5_file_open ==
false)
2048 if(h5_file_open ==
false)
2049 h5_fd = get_fileid(filename.c_str());
2052 if(h5_file_open ==
false)
2053 close_fileid(h5_fd);
2056 Ancillary::read_ancillary_das( *das, filename ) ;
2058 if (das_cache_fname.empty() ==
false && das_from_dc ==
false)
2059 write_das_to_disk_cache(das_cache_fname,das);
2062bool obtain_beskeys_info(
const string& key,
bool & has_key) {
2064 bool ret_value =
false;
2068 const string dosettrue =
"true";
2069 const string dosetyes =
"yes";
2071 ret_value = (dosettrue == doset || dosetyes == doset);
2078static unsigned int get_uint_key(
const string &key,
unsigned int def_val)
2084 if (
true == found) {
2093static unsigned long get_ulong_key(
const string &key,
unsigned long def_val)
2099 if (
true == found) {
2101 return stoul(doset);
2107static float get_float_key(
const string &key,
float def_val)
2119static string get_beskeys(
const string &key) {
2129char* copy_str(
char*temp_ptr,
const string & str) {
2131 size_t str_size=str.size();
2132 memcpy((
void*)temp_ptr,(
void*)&str_size,
sizeof(
size_t));
2133 temp_ptr+=
sizeof(
size_t);
2134 vector<char>temp_vc2(str.begin(),str.end());
2135 memcpy((
void*)temp_ptr,(
void*)temp_vc2.data(),str.size());
2136 temp_ptr+=str.size();
2145char* obtain_str(
char*temp_ptr,
string & str) {
2147 size_t oname_size = *((
size_t *)temp_ptr);
2148 temp_ptr = temp_ptr +
sizeof(
size_t);
2150 for(
unsigned int i =0; i<oname_size; i++){
2151 oname.push_back(*temp_ptr);
2162char* get_attr_info_from_dc(
char*temp_pointer,DAS *das,AttrTable *at_par) {
2167 flag = *((uint8_t*)(temp_pointer));
2168 BESDEBUG(HDF5_NAME, prolog <<
"Build DAS from the disk cache file flag: "
2169 <<
" flag = 0, attribute; flag = 1, container; flag =2; end of container;"
2170 <<
" flag = 3; the initial value to get the attribute retrieval process started."
2171 <<
" The flag value is "
2172 << (
int)flag <<endl);
2176 string container_name;
2177 temp_pointer = obtain_str(temp_pointer,container_name);
2178 BESDEBUG(HDF5_NAME, prolog <<
"DAS from the disk cache, container name is " << container_name << endl);
2181 AttrTable*temp_at_par = at_par;
2182 if(at_par ==
nullptr) {
2183 auto new_attr_table_unique = make_unique<libdap::AttrTable>();
2184 auto new_attr_table = new_attr_table_unique.release();
2185 at_par = das->add_table(container_name, new_attr_table);
2188 at_par = at_par->append_container(container_name);
2190 temp_pointer = get_attr_info_from_dc(temp_pointer,das,at_par);
2192 at_par = temp_at_par;
2195 else if(flag == 0) {
2197 if(at_par ==
nullptr)
2198 throw BESInternalError(
"The AttrTable must exist for DAS attributes", __FILE__, __LINE__ ) ;
2202 temp_pointer = obtain_str(temp_pointer,attr_name);
2203 BESDEBUG(HDF5_NAME, prolog <<
"DAS from the disk cache, attr name is: " << attr_name << endl);
2207 temp_pointer = obtain_str(temp_pointer,attr_type);
2208 BESDEBUG(HDF5_NAME, prolog <<
"DAS from the disk cache, attr type is: " << attr_type << endl);
2211 unsigned int num_values = *((
unsigned int*)(temp_pointer));
2212 BESDEBUG(HDF5_NAME, prolog <<
"DAS from the disk cache, number of attribute values is: " << num_values << endl);
2213 temp_pointer+=
sizeof(
unsigned int);
2215 vector <string> attr_values;
2217 for(
unsigned int i = 0; i<num_values; i++) {
2219 temp_pointer = obtain_str(temp_pointer,attr_value);
2220 attr_values.push_back(attr_value);
2221 BESDEBUG(HDF5_NAME, prolog <<
"DAS from the disk cache, attribute value is: " << attr_value << endl);
2224 at_par->append_attr(attr_name,attr_type,&attr_values);
2228 return temp_pointer;
2232void get_attr_contents(AttrTable*temp_table) {
2233 if(temp_table !=
nullptr) {
2234 AttrTable::Attr_iter top_startit = temp_table->attr_begin();
2235 AttrTable::Attr_iter top_endit = temp_table->attr_end();
2236 AttrTable::Attr_iter top_it = top_startit;
2237 while(top_it !=top_endit) {
2238 AttrType atype = temp_table->get_attr_type(top_it);
2239 if(atype == Attr_unknown)
2240 cerr<<
"unsupported DAS attributes" <<endl;
2241 else if(atype!=Attr_container) {
2243 cerr<<
"Attribute name is "<<temp_table->get_name(top_it)<<endl;
2244 cerr<<
"Attribute type is "<<temp_table->get_type(top_it)<<endl;
2245 unsigned int num_attrs = temp_table->get_attr_num(temp_table->get_name(top_it));
2246 cerr<<
"Attribute values are "<<endl;
2247 for (
unsigned int i = 0; i <num_attrs;i++)
2248 cerr<<(*(temp_table->get_attr_vector(temp_table->get_name(top_it))))[i]<<
" ";
2252 cerr<<
"Coming to the attribute container. "<<endl;
2253 cerr<<
"container name is "<<(*top_it)->name <<endl;
2254 AttrTable* sub_table = temp_table->get_attr_table(top_it);
2255 cerr<<
"container table name is "<<sub_table->get_name() <<endl;
2256 get_attr_contents(sub_table);
2268 auto bdds =
dynamic_cast<BESDataDDSResponse *
>(response);
2270 throw BESInternalError(
"cast error", __FILE__, __LINE__);
2275 bool das_from_mcache =
false;
2277 das =
dynamic_cast<DAS*
>(das_cache->get(filename));
2279 BESDEBUG(HDF5_NAME, prolog <<
"DAS Cached hit for : " << filename << endl);
2280 dds->transfer_attributes(das);
2281 das_from_mcache =
true;
2285 if(
false == das_from_mcache) {
2286 auto das_unique = make_unique<DAS>();
2287 das = das_unique.release();
2290 if (!container_name.empty()) das->container_name(container_name);
2293 if (
true == _usecf) {
2295 h5_fd = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
2297 read_cfdas( *das,filename,h5_fd);
2302 h5_fd = get_fileid(filename.c_str());
2305 close_fileid(h5_fd);
2308 Ancillary::read_ancillary_das(*das, filename);
2310 dds->transfer_attributes(das);
2315 BESDEBUG(HDF5_NAME, prolog <<
"DAS added to the cache for : " << filename << endl);
2316 das_cache->add(das, filename);
2322 BESDEBUG(HDF5_NAME, prolog <<
"Data ACCESS in add_attributes(): set the including attribute flag to true: "<<filename << endl);
2323 bdds->set_ia_flag(
true);
2327void HDF5RequestHandler::close_h5_files(hid_t cf_fileid, hid_t fileid) {
2329 if (cf_fileid != -1)
2330 H5Fclose(cf_fileid);
This class describes the different categories of HDF5 products for the CF option.
include the entry functions to execute the handlers
std::string get_symbolic_name() const
retrieve the symbolic name for this container
virtual std::string access()=0
returns the true name of this container
Holds a DDS object within the BES.
virtual void set_container(const std::string &cn)
set the container in the DAP response object
void set_dds(libdap::DDS *ddsIn)
virtual void clear_container()
clear the container in the DAP response object
Represents an OPeNDAP DMR DAP4 data object within the BES.
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
bool get_explicit_containers() const
Should containers be explicitly represented in the DD* responses?
std::string get_request_xml_base() const
Return the xml:base URL for this request.
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
void set_dds(libdap::DDS *ddsIn)
Structure storing information used by the BES to handle the request.
BESContainer * container
pointer to current container in this interface
std::string get_message() const
get the error message for this exception
exception thrown if internal error encountered
Represents a specific data type request handler.
virtual BESResponseObject * get_response_object()
return the current response object
virtual void services_handled(const std::string &handler, std::list< std::string > &services)
returns the list of servies provided by the handler in question
static std::string lowercase(const std::string &s)
static std::string implode(const std::list< std::string > &values, char delim)
An in-memory cache for DapObj (DAS, DDS, ...) objects.
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()
Access to the singleton.
Helper functions for generating DAS attributes and a function to check BES Key.
void depth_first(hid_t pid, const char *gname, DAS &das)
void find_gloattr(hid_t file, DAS &das)
bool breadth_first(hid_t file_id, hid_t pid, const char *gname, D4Group *par_grp, const char *fname, bool use_dimscale, bool is_eos5, vector< link_info_t > &hdf5_hls, eos5_dim_info_t &eos5_dim_info, vector< string > &handled_cv_names)
void add_dap4_coverage_default(D4Group *d4_root, const vector< string > &handled_all_cv_names)
Add DAP4 coverage.
The main header of the HDF5 OPeNDAP handler.