37#include <libdap/DMR.h>
38#include <libdap/D4BaseTypeFactory.h>
39#include <BESDMRResponse.h>
40#include <libdap/mime_util.h>
41#include <libdap/InternalErr.h>
42#include <libdap/Ancillary.h>
43#include <libdap/debug.h>
45#include "HDF4RequestHandler.h"
46#include <BESResponseNames.h>
47#include <BESDapNames.h>
48#include <BESDASResponse.h>
49#include <BESDDSResponse.h>
50#include <BESDataDDSResponse.h>
52#include <BESResponseHandler.h>
53#include <BESVersionInfo.h>
54#include <BESServiceRegistry.h>
56#include <TheBESKeys.h>
57#include <libdap/InternalErr.h>
58#include <BESInternalError.h>
59#include <BESDapError.h>
60#include <BESStopWatch.h>
62#include "BESDataNames.h"
63#include <libdap/Ancillary.h>
64#include "config_hdf.h"
71#include "HDFSPArray_RealField.h"
78const string HDF4_NAME=
"h4";
79#define prolog std::string("HDF4RequestHandler::").append(__func__).append("() - ")
81bool check_beskeys(
const string &);
82bool get_beskeys(
const string &,
string &);
83bool is_beskey_exist(
const string &key);
85extern void read_das(DAS & das,
const string & filename);
86extern void read_dds(DDS & dds,
const string & filename);
87extern void read_dmr(DMR * dmr,
const string & filename);
89extern bool read_dds_hdfsp(DDS & dds,
const string & filename,int32 sdfd, int32 fileid,
HDFSP::File*h4file);
91extern bool read_das_hdfsp(DAS & das,
const string & filename,int32 sdfd, int32 fileid,
HDFSP::File**h4fileptr);
93extern void read_das_sds(DAS & das,
const string & filename,int32 sdfd,
bool ecs_metadata,
HDFSP::File**h4fileptr);
94extern void read_dds_sds(DDS &dds,
const string & filename,int32 sdfd,
HDFSP::File*h4file,
bool dds_set_cache);
98void read_das_use_eos2lib(DAS & das,
const string & filename,int32 sdfd,int32 fileid, int32 gridfd, int32 swathfd,
bool ecs_metadata,
HDFSP::File**h4file,HDFEOS2::File**eosfile);
99void read_dds_use_eos2lib(DDS & dds,
const string & filename,int32 sdfd,int32 fileid, int32 gridfd, int32 swathfd,
HDFSP::File*h4file,HDFEOS2::File*eosfile);
100void close_fileid(
const int sdfd,
const int fileid,
const int gridfd,
const int swathfd,
HDFSP::File*h4file,HDFEOS2::File*eosfile);
104void close_hdf4_fileid(
const int sdfd,
const int fileid,
HDFSP::File*h4file);
105bool rw_das_cache_file(
const string & filename, DAS *das_ptr,
bool rw_flag);
106bool r_dds_cache_file(
const string & cache_filename, DDS *dds_ptr,
const string & hdf4_filename);
108bool HDF4RequestHandler::_direct_dmr =
false;
111bool HDF4RequestHandler::_usecf =
false;
114bool HDF4RequestHandler::_pass_fileid =
false;
115bool HDF4RequestHandler::_disable_structmeta =
false;
116bool HDF4RequestHandler::_enable_special_eos =
false;
117bool HDF4RequestHandler::_disable_scaleoffset_comp =
false;
118bool HDF4RequestHandler::_disable_ecsmetadata_min =
false;
119bool HDF4RequestHandler::_disable_ecsmetadata_all =
false;
123bool HDF4RequestHandler::_enable_eosgeo_cachefile =
false;
124bool HDF4RequestHandler::_enable_data_cachefile =
false;
125bool HDF4RequestHandler::_enable_metadata_cachefile=
false;
128bool HDF4RequestHandler::_enable_hybrid_vdata =
false;
129bool HDF4RequestHandler::_enable_ceres_vdata =
false;
130bool HDF4RequestHandler::_enable_vdata_attr =
false;
131bool HDF4RequestHandler::_enable_vdata_desc_attr =
false;
132bool HDF4RequestHandler::_disable_vdata_nameclashing_check =
false;
133bool HDF4RequestHandler::_enable_vgroup_attr =
false;
136bool HDF4RequestHandler::_enable_check_modis_geo_file =
false;
137bool HDF4RequestHandler::_enable_swath_grid_attr =
false;
138bool HDF4RequestHandler::_enable_ceres_merra_short_name =
false;
139bool HDF4RequestHandler::_enable_check_scale_offset_type =
false;
140bool HDF4RequestHandler::_disable_swath_dim_map =
false;
143bool HDF4RequestHandler::_cache_latlon_path_exist =
false;
144string HDF4RequestHandler::_cache_latlon_path =
"";
145bool HDF4RequestHandler::_cache_latlon_prefix_exist =
false;
146string HDF4RequestHandler::_cache_latlon_prefix =
"";
147bool HDF4RequestHandler::_cache_latlon_size_exist =
false;
148long HDF4RequestHandler::_cache_latlon_size =0;
149bool HDF4RequestHandler::_cache_metadata_path_exist =
false;
150string HDF4RequestHandler::_cache_metadata_path =
"";
152HDF4RequestHandler::HDF4RequestHandler(
const string & name) :
163 if (
true == is_beskey_exist(
"H4.EnableDirectDMR"))
164 _direct_dmr=check_beskeys(
"H4.EnableDirectDMR");
165 _usecf = check_beskeys(
"H4.EnableCF");
169 _pass_fileid = check_beskeys(
"H4.EnablePassFileID");
170 _disable_structmeta = check_beskeys(
"H4.DisableStructMetaAttr");
171 _enable_special_eos = check_beskeys(
"H4.EnableSpecialEOS");
172 _disable_scaleoffset_comp = check_beskeys(
"H4.DisableScaleOffsetComp");
173 _disable_ecsmetadata_min = check_beskeys(
"H4.DisableECSMetaDataMin");
174 _disable_ecsmetadata_all = check_beskeys(
"H4.DisableECSMetaDataAll");
177 _enable_eosgeo_cachefile = check_beskeys(
"H4.EnableEOSGeoCacheFile");
178 _enable_data_cachefile = check_beskeys(
"H4.EnableDataCacheFile");
179 _enable_metadata_cachefile = check_beskeys(
"H4.EnableMetaDataCacheFile");
182 _enable_hybrid_vdata = check_beskeys(
"H4.EnableHybridVdata");
183 _enable_ceres_vdata = check_beskeys(
"H4.EnableCERESVdata");
184 _enable_vdata_attr = check_beskeys(
"H4.EnableVdata_to_Attr");
185 _enable_vdata_desc_attr = check_beskeys(
"H4.EnableVdataDescAttr");
186 _disable_vdata_nameclashing_check = check_beskeys(
"H4.DisableVdataNameclashingCheck");
187 _enable_vgroup_attr = check_beskeys(
"H4.EnableVgroupAttr");
190 _enable_check_modis_geo_file = check_beskeys(
"H4.EnableCheckMODISGeoFile");
191 _enable_swath_grid_attr = check_beskeys(
"H4.EnableSwathGridAttr");
192 _enable_ceres_merra_short_name = check_beskeys(
"H4.EnableCERESMERRAShortName");
193 _enable_check_scale_offset_type = check_beskeys(
"H4.EnableCheckScaleOffsetType");
195 _disable_swath_dim_map = check_beskeys(
"H4.DisableSwathDimMap");
198 _cache_latlon_path_exist =get_beskeys(
"HDF4.Cache.latlon.path",_cache_latlon_path);
199 _cache_latlon_prefix_exist =get_beskeys(
"HDF4.Cache.latlon.prefix",_cache_latlon_prefix);
200 string temp_cache_latlon_size;
201 _cache_latlon_size_exist =get_beskeys(
"HDF4.Cache.latlon.size",temp_cache_latlon_size);
202 if (_cache_latlon_size_exist ==
true) {
203 istringstream iss(temp_cache_latlon_size);
204 iss >> _cache_latlon_size;
207 _cache_metadata_path_exist =get_beskeys(
"H4.Cache.metadata.path",_cache_metadata_path);
214 BES_STOPWATCH_START_DHI(HDF4_NAME, prolog +
"Timer", &dhi);
216 if (
true == _usecf) {
233 if ((base_file_name.size() >12) && (base_file_name.compare(0,4,
"AIRS") == 0)
234 && ((base_file_name.find(
".L3.")!=string::npos) || (base_file_name.find(
".L2.")!=string::npos))
235 && (base_file_name.find(
".v6.")!=string::npos)) {
236 return hdf4_build_das_cf_sds(dhi);
241 auto bdas =
dynamic_cast<BESDASResponse *
> (response);
243 throw BESInternalError(
"cast error", __FILE__, __LINE__);
247 DAS *das = bdas->get_das();
253 if (
true == _usecf) {
258 HDFSP::File *h4file =
nullptr;
262 sdfd = SDstart (accessed.c_str(), DFACC_READ);
264 string invalid_file_msg=
"HDF4 SDstart error for the file ";
265 invalid_file_msg +=accessed;
266 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
267 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
271 fileid = Hopen(accessed.c_str(), DFACC_READ,0);
274 string invalid_file_msg=
"HDF4 Hopen error for the file ";
275 invalid_file_msg +=accessed;
276 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
277 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
280#ifdef USE_HDFEOS2_LIB
285 HDFEOS2::File *eosfile =
nullptr;
289 gridfd = GDopen(
const_cast < char *
>(accessed.c_str()), DFACC_READ);
293 string invalid_file_msg=
"HDF-EOS GDopen error for the file ";
294 invalid_file_msg +=accessed;
295 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
296 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
300 swathfd = SWopen(
const_cast < char *
>(accessed.c_str()), DFACC_READ);
305 string invalid_file_msg=
"HDF-EOS SWopen error for the file ";
306 invalid_file_msg +=accessed;
307 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
308 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
312 bool ecs_metadata = !_disable_ecsmetadata_all;
313 read_das_use_eos2lib(*das, accessed,sdfd,fileid,gridfd,swathfd,ecs_metadata,&h4file,&eosfile);
316 close_fileid(sdfd,fileid,gridfd,swathfd,h4file,eosfile);
319 if (eosfile !=
nullptr)
326 read_das_hdfsp(*das,accessed,sdfd,fileid,&h4file);
329 close_hdf4_fileid(sdfd,fileid,h4file);
334 close_hdf4_fileid(sdfd,fileid,h4file);
337 read_das(*das,accessed);
339 Ancillary::read_ancillary_das(*das, accessed);
340 bdas->clear_container();
343 catch (BESError & e) {
347 catch (InternalErr & e) {
348 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
352 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
356 string s =
"unknown exception caught building HDF4 DAS";
357 throw BESDapError(s,
true, unknown_error, __FILE__, __LINE__);
365 BES_STOPWATCH_START_DHI(HDF4_NAME, prolog +
"Timer", &dhi);
367 if (
true == _usecf) {
384 if ((base_file_name.size() >12) && (base_file_name.compare(0,4,
"AIRS") == 0)
385 && ((base_file_name.find(
".L3.")!=string::npos) || (base_file_name.find(
".L2.")!=string::npos))
386 && (base_file_name.find(
".v6.")!=string::npos)) {
387 return hdf4_build_dds_cf_sds(dhi);
393struct timeval start_time,end_time;
394gettimeofday(&start_time,
nullptr);
398 auto bdds =
dynamic_cast<BESDDSResponse *
> (response);
400 throw BESInternalError(
"cast error", __FILE__, __LINE__);
405 DDS *dds = bdds->get_dds();
407 dds->filename(accessed);
410 BESDASResponse bdas(das);
413 if (
true == _usecf) {
417 HDFSP::File *h4file =
nullptr;
421 sdfd = SDstart (accessed.c_str(), DFACC_READ);
423 string invalid_file_msg=
"HDF4 SDstart error for the file ";
424 invalid_file_msg +=accessed;
425 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
426 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
430 fileid = Hopen(accessed.c_str(), DFACC_READ,0);
433 string invalid_file_msg=
"HDF4 Hopen error for the file ";
434 invalid_file_msg +=accessed;
435 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
436 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
439#ifdef USE_HDFEOS2_LIB
444 HDFEOS2::File *eosfile =
nullptr;
448 gridfd = GDopen(
const_cast < char *
>(accessed.c_str()), DFACC_READ);
452 string invalid_file_msg=
"HDF-EOS GDopen error for the file ";
453 invalid_file_msg +=accessed;
454 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
455 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
459 swathfd = SWopen(
const_cast < char *
>(accessed.c_str()), DFACC_READ);
464 string invalid_file_msg=
"HDF-EOS SWopen error for the file ";
465 invalid_file_msg +=accessed;
466 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
467 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
471 bool ecs_metadata = !_disable_ecsmetadata_all;
472 read_das_use_eos2lib(*das, accessed,sdfd,fileid,gridfd,swathfd,ecs_metadata,&h4file,&eosfile);
473 Ancillary::read_ancillary_das(*das, accessed);
476 read_dds_use_eos2lib(*dds, accessed,sdfd,fileid,gridfd,swathfd,h4file,eosfile);
479 close_fileid(sdfd,fileid,gridfd,swathfd,h4file,eosfile);
483 if(eosfile !=
nullptr)
491 read_das_hdfsp(*das, accessed,sdfd,fileid,&h4file);
492 Ancillary::read_ancillary_das(*das, accessed);
495 read_dds_hdfsp(*dds, accessed,sdfd,fileid,h4file);
498 close_hdf4_fileid(sdfd,fileid,h4file);
503 close_hdf4_fileid(sdfd,fileid,h4file);
506 read_das(*das, accessed);
507 Ancillary::read_ancillary_das(*das, accessed);
508 read_dds(*dds, accessed);
513gettimeofday(&end_time,
nullptr);
514int total_time_spent = (end_time.tv_sec - start_time.tv_sec)*1000000 +end_time.tv_usec-start_time.tv_usec;
515cerr<<
"total time spent for DDS buld is "<<total_time_spent<<
"micro seconds "<<endl;
518 Ancillary::read_ancillary_dds(*dds, accessed);
520 dds->transfer_attributes(das);
522 bdds->set_constraint(dhi);
524 bdds->clear_container();
526 catch (BESError & e) {
530 catch (InternalErr & e) {
531 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
535 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
539 string s =
"unknown exception caught building HDF4 DDS";
540 throw BESDapError(s,
true, unknown_error, __FILE__, __LINE__);
548 BES_STOPWATCH_START_DHI(HDF4_NAME, prolog +
"Timer", &dhi);
557 if (
true == _usecf) {
573 if ((base_file_name.size() >12) && (base_file_name.compare(0,4,
"AIRS") == 0)
574 && ((base_file_name.find(
".L3.")!=string::npos) || (base_file_name.find(
".L2.")!=string::npos))
575 && (base_file_name.find(
".v6.")!=string::npos)) {
577 BESDEBUG(
"h4",
"Coming to read the data of AIRS level 3 or level 2 products." << endl);
579 if (
true == _pass_fileid)
580 return hdf4_build_data_cf_sds_with_IDs(dhi);
582 return hdf4_build_data_cf_sds(dhi);
586 if (
true == _pass_fileid)
587 return hdf4_build_data_with_IDs(dhi);
592 auto bdds =
dynamic_cast<BESDataDDSResponse *
> (response);
595 throw BESInternalError(
"cast error", __FILE__, __LINE__);
600 DDS *dds = bdds->get_dds();
603 dds->filename(accessed);
606 BESDASResponse bdas(das);
609 if (
true == _usecf) {
611 HDFSP::File *h4file =
nullptr;
615 sdfd = SDstart (accessed.c_str(), DFACC_READ);
617 string invalid_file_msg=
"HDF4 SDstart error for the file ";
618 invalid_file_msg +=accessed;
619 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
620 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
624 fileid = Hopen(accessed.c_str(), DFACC_READ,0);
627 string invalid_file_msg=
"HDF4 Hopen error for the file ";
628 invalid_file_msg +=accessed;
629 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
630 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
634#ifdef USE_HDFEOS2_LIB
638 HDFEOS2::File *eosfile =
nullptr;
643 gridfd = GDopen(
const_cast < char *
>(accessed.c_str()), DFACC_READ);
647 string invalid_file_msg=
"HDF-EOS GDopen error for the file ";
648 invalid_file_msg +=accessed;
649 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
650 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
654 swathfd = SWopen(
const_cast < char *
>(accessed.c_str()), DFACC_READ);
659 string invalid_file_msg=
"HDF-EOS SWopen error for the file ";
660 invalid_file_msg +=accessed;
661 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
662 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
671 bool ecs_metadata =
true;
672 if ((
true == _disable_ecsmetadata_min)
673 || (
true == _disable_ecsmetadata_all))
674 ecs_metadata =
false;
676 read_das_use_eos2lib(*das, accessed,sdfd,fileid,gridfd,swathfd,ecs_metadata,&h4file,&eosfile);
677 Ancillary::read_ancillary_das(*das, accessed);
680 read_dds_use_eos2lib(*dds, accessed,sdfd,fileid,gridfd,swathfd,h4file,eosfile);
683 close_fileid(sdfd,fileid,gridfd,swathfd,h4file,eosfile);
687 if(eosfile !=
nullptr)
694 read_das_hdfsp(*das, accessed,sdfd,fileid,&h4file);
695 Ancillary::read_ancillary_das(*das, accessed);
698 read_dds_hdfsp(*dds, accessed,sdfd,fileid,h4file);
701 close_hdf4_fileid(sdfd,fileid,h4file);
705 close_hdf4_fileid(sdfd,fileid,h4file);
708 read_das(*das, accessed);
709 Ancillary::read_ancillary_das(*das, accessed);
710 read_dds(*dds, accessed);
713 Ancillary::read_ancillary_dds(*dds, accessed);
714 dds->transfer_attributes(das);
715 bdds->set_constraint(dhi);
716 bdds->clear_container();
720 catch (BESError & e) {
724 catch (InternalErr & e) {
725 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
729 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
733 string s =
"unknown exception caught building DAP2 Data Response from an HDF4 data resource";
734 throw BESDapError(s,
true, unknown_error, __FILE__, __LINE__);
742 BES_STOPWATCH_START_DHI(HDF4_NAME, prolog +
"Timer", &dhi);
746 HDFSP::File *h4file =
nullptr;
747#ifdef USE_HDFEOS2_LIB
750 HDFEOS2::File *eosfile =
nullptr;
754 auto bdds =
dynamic_cast<BESDataDDSResponse *
> (response);
757 throw BESInternalError(
"cast error", __FILE__, __LINE__);
763 auto hdds =
new HDF4DDS(bdds->get_dds());
766 delete bdds->get_dds();
771 hdds->filename(accessed);
774 BESDASResponse bdas(das);
779 sdfd = SDstart (accessed.c_str(), DFACC_READ);
781 string invalid_file_msg=
"HDF4 SDstart error for the file ";
782 invalid_file_msg +=accessed;
783 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
784 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
788 fileid = Hopen(accessed.c_str(), DFACC_READ,0);
791 string invalid_file_msg=
"HDF4 Hopen error for the file ";
792 invalid_file_msg +=accessed;
793 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
794 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
797#ifdef USE_HDFEOS2_LIB
802 gridfd = GDopen(
const_cast < char *
>(accessed.c_str()), DFACC_READ);
806 string invalid_file_msg=
"HDF-EOS GDopen error for the file ";
807 invalid_file_msg +=accessed;
808 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
809 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
813 swathfd = SWopen(
const_cast < char *
>(accessed.c_str()), DFACC_READ);
818 string invalid_file_msg=
"HDF-EOS SWopen error for the file ";
819 invalid_file_msg +=accessed;
820 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
821 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
824 hdds->setHDF4Dataset(sdfd,fileid,gridfd,swathfd);
829 bool ecs_metadata =
true;
830 if ((
true == _disable_ecsmetadata_min)
831 || (
true == _disable_ecsmetadata_all))
832 ecs_metadata =
false;
834 read_das_use_eos2lib(*das, accessed,sdfd,fileid,gridfd,swathfd,ecs_metadata,&h4file,&eosfile);
836 Ancillary::read_ancillary_das(*das, accessed);
839 read_dds_use_eos2lib(*hdds, accessed,sdfd,fileid,gridfd,swathfd,h4file,eosfile);
841 if(eosfile !=
nullptr)
845 hdds->setHDF4Dataset(sdfd,fileid);
846 read_das_hdfsp(*das, accessed,sdfd,fileid,&h4file);
847 Ancillary::read_ancillary_das(*das, accessed);
850 read_dds_hdfsp(*hdds, accessed,sdfd,fileid,h4file);
852 if(h4file !=
nullptr)
855 Ancillary::read_ancillary_dds(*hdds, accessed);
857 hdds->transfer_attributes(das);
859 bdds->set_constraint(dhi);
861 bdds->clear_container();
865 catch (InternalErr & e) {
866 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
870 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
874#ifdef USE_HDFEOS2_LIB
875 close_fileid(sdfd,fileid,gridfd,swathfd,h4file,eosfile);
877 close_hdf4_fileid(sdfd,fileid,h4file);
879 string s =
"unknown exception caught building DAP2 data response from an HDF4 data resource";
880 throw BESDapError(s,
true, unknown_error, __FILE__, __LINE__);
894 HDFSP::File *h4file =
nullptr;
897 auto bdds =
dynamic_cast<BESDDSResponse *
> (response);
900 throw BESInternalError(
"cast error", __FILE__, __LINE__);
905 DDS *dds = bdds->get_dds();
908 dds->filename(accessed);
911 BESDASResponse bdas(das);
915 bool das_set_cache =
false;
916 bool dds_set_cache =
false;
917 bool dds_das_get_cache =
false;
923 if(
true == _enable_metadata_cachefile) {
925 if(
true == _cache_metadata_path_exist) {
928 das_filename = _cache_metadata_path +
"/" + base_file_name +
"_das";
929 dds_filename = _cache_metadata_path +
"/" + base_file_name +
"_dds";
933 das_set_cache = rw_das_cache_file(das_filename,das,
false);
937 dds_set_cache = r_dds_cache_file(dds_filename,dds,accessed);
942 if((
false == das_set_cache)&&(
false == dds_set_cache))
943 dds_das_get_cache =
true;
948 if(
false == dds_das_get_cache) {
951 sdfd = SDstart (accessed.c_str(), DFACC_READ);
954 string invalid_file_msg=
"HDF4 SDstart error for the file ";
955 invalid_file_msg +=accessed;
956 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
957 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
962 bool ecs_metadata = !_disable_ecsmetadata_all;
964 read_das_sds(*das, accessed,sdfd,ecs_metadata,&h4file);
966 Ancillary::read_ancillary_das(*das, accessed);
970 read_dds_sds(*dds, accessed,sdfd,h4file,dds_set_cache);
973 if (
true == das_set_cache) {
974 if (das_filename ==
"")
975 throw InternalErr(__FILE__,__LINE__,
"DAS cache file name should be set ");
976 rw_das_cache_file(das_filename,das,
true);
980 Ancillary::read_ancillary_dds(*dds, accessed);
981 dds->transfer_attributes(das);
982 bdds->set_constraint(dhi);
984 bdds->clear_container();
986 if(h4file !=
nullptr)
994 catch (BESError & e) {
998 catch (InternalErr & e) {
999 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
1000 __FILE__, __LINE__);
1003 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
1004 __FILE__, __LINE__);
1009 if(h4file !=
nullptr)
1011 string s =
"unknown exception caught building HDF4 DataDDS";
1012 throw BESDapError(s,
true, unknown_error, __FILE__, __LINE__);
1023 HDFSP::File *h4file =
nullptr;
1026 auto bdas =
dynamic_cast<BESDASResponse *
> (response);
1029 throw BESInternalError(
"cast error", __FILE__, __LINE__);
1034 auto das = bdas->get_das();
1040 bool das_set_cache =
false;
1041 bool das_get_cache =
false;
1042 string das_filename;
1043 if (
true == _enable_metadata_cachefile) {
1044 if (
true == _cache_metadata_path_exist) {
1047 das_filename = _cache_metadata_path +
"/" + base_file_name +
"_das";
1051 das_set_cache = rw_das_cache_file(das_filename,das,
false);
1054 if (
false == das_set_cache)
1055 das_get_cache =
true;
1060 if (
false == das_get_cache) {
1063 sdfd = SDstart (accessed.c_str(), DFACC_READ);
1065 string invalid_file_msg=
"HDF4 SDstart error for the file ";
1066 invalid_file_msg +=accessed;
1067 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
1068 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1073 bool ecs_metadata = !_disable_ecsmetadata_all;
1075 read_das_sds(*das, accessed,sdfd,ecs_metadata,&h4file);
1076 Ancillary::read_ancillary_das(*das, accessed);
1079 if(
true == das_set_cache)
1080 rw_das_cache_file(das_filename,das,
true);
1084 bdas->clear_container();
1086 if(h4file !=
nullptr)
1094 catch (BESError & e) {
1096 __FILE__, __LINE__);
1098 catch (InternalErr & e) {
1099 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
1100 __FILE__, __LINE__);
1103 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
1104 __FILE__, __LINE__);
1109 if(h4file !=
nullptr)
1111 string s =
"unknown exception caught building HDF4 DataDDS";
1112 throw BESDapError(s,
true, unknown_error, __FILE__, __LINE__);
1122 HDFSP::File *h4file =
nullptr;
1125 auto bdds =
dynamic_cast<BESDataDDSResponse *
> (response);
1128 throw BESInternalError(
"cast error", __FILE__, __LINE__);
1133 DDS *dds = bdds->get_dds();
1136 dds->filename(accessed);
1139 BESDASResponse bdas(das);
1144 bool das_set_cache =
false;
1145 bool dds_set_cache =
false;
1146 bool dds_das_get_cache =
false;
1147 string das_filename;
1148 string dds_filename;
1150 if (
true == _enable_metadata_cachefile) {
1152 if (
true == _cache_metadata_path_exist) {
1153 BESDEBUG(
"h4",
"H4.Cache.metadata.path key is set and metadata cache key is set." << endl);
1158 das_filename = _cache_metadata_path +
"/" + base_file_name +
"_das_dd";
1159 dds_filename = _cache_metadata_path +
"/" + base_file_name +
"_dds";
1162 das_set_cache = rw_das_cache_file(das_filename,das,
false);
1165 dds_set_cache = r_dds_cache_file(dds_filename,dds,accessed);
1168 if((
false == das_set_cache)&&(
false == dds_set_cache))
1169 dds_das_get_cache =
true;
1172 if(
false == dds_das_get_cache) {
1175 sdfd = SDstart (accessed.c_str(), DFACC_READ);
1177 string invalid_file_msg=
"HDF4 SDstart error for the file ";
1178 invalid_file_msg +=accessed;
1179 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
1180 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1186 bool ecs_metadata =
true;
1187 if ((
true == _disable_ecsmetadata_min)
1188 || (
true == _disable_ecsmetadata_all))
1189 ecs_metadata =
false;
1191 read_das_sds(*das, accessed,sdfd,ecs_metadata,&h4file);
1193 Ancillary::read_ancillary_das(*das, accessed);
1196 if(
true == das_set_cache) {
1197 rw_das_cache_file(das_filename,das,
true);
1202 read_dds_sds(*dds, accessed,sdfd,h4file,dds_set_cache);
1206 Ancillary::read_ancillary_dds(*dds, accessed);
1208 dds->transfer_attributes(das);
1210 bdds->set_constraint(dhi);
1212 bdds->clear_container();
1214 if (h4file !=
nullptr)
1221 catch (BESError & e) {
1223 __FILE__, __LINE__);
1225 catch (InternalErr & e) {
1226 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
1227 __FILE__, __LINE__);
1230 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
1231 __FILE__, __LINE__);
1236 if(h4file !=
nullptr)
1238 string s =
"unknown exception caught building HDF4 DataDDS";
1239 throw BESDapError(s,
true, unknown_error, __FILE__, __LINE__);
1253 HDFSP::File *h4file =
nullptr;
1256 auto bdds =
dynamic_cast<BESDataDDSResponse *
> (response);
1259 throw BESInternalError(
"cast error", __FILE__, __LINE__);
1264 auto hdds =
new HDF4DDS(bdds->get_dds());
1267 delete bdds->get_dds();
1269 bdds->set_dds(hdds);
1273 hdds->filename(accessed);
1276 BESDASResponse bdas(das);
1280 sdfd = SDstart (accessed.c_str(), DFACC_READ);
1282 string invalid_file_msg=
"HDF4 SDstart error for the file ";
1283 invalid_file_msg +=accessed;
1284 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
1285 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1288 hdds->setHDF4Dataset(sdfd,-1);
1293 bool ecs_metadata =
true;
1295 if((
true == HDFCFUtil::check_beskeys(
"H4.DisableECSMetaDataMin"))
1296 || (
true == HDFCFUtil::check_beskeys(
"H4.DisableECSMetaDataAll")))
1298 if((
true == _disable_ecsmetadata_min)
1299 || (
true == _disable_ecsmetadata_all))
1300 ecs_metadata =
false;
1302 read_das_sds(*das, accessed,sdfd,ecs_metadata,&h4file);
1307 Ancillary::read_ancillary_das(*das, accessed);
1310 read_dds_sds(*hdds, accessed,sdfd,h4file,
false);
1312 if(h4file !=
nullptr)
1315 Ancillary::read_ancillary_dds(*hdds, accessed);
1317 hdds->transfer_attributes(das);
1319 bdds->set_constraint(dhi);
1321 bdds->clear_container();
1325 catch (BESError & e) {
1327 __FILE__, __LINE__);
1329 catch (InternalErr & e) {
1330 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
1331 __FILE__, __LINE__);
1334 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
1335 __FILE__, __LINE__);
1340 if(h4file !=
nullptr)
1342 string s =
"unknown exception caught building HDF4 DataDDS";
1343 throw BESDapError(s,
true, unknown_error, __FILE__, __LINE__);
1354 BES_STOPWATCH_START_DHI(HDF4_NAME, prolog +
"Timer", &dhi);
1356 if (
true == _direct_dmr)
1357 return hdf4_build_direct_dmr(dhi);
1365 BaseTypeFactory factory;
1366 DDS dds(&factory, name_path(data_path),
"3.2");
1367 dds.filename(data_path);
1377 if(
true == _usecf) {
1379 if(
true == _pass_fileid)
1380 return hdf4_build_dmr_with_IDs(dhi);
1387 if (
true == _usecf) {
1389 HDFSP::File *h4file =
nullptr;
1393 sdfd = SDstart (data_path.c_str(), DFACC_READ);
1395 string invalid_file_msg=
"HDF4 SDstart error for the file ";
1396 invalid_file_msg +=data_path;
1397 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
1398 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1402 fileid = Hopen(data_path.c_str(), DFACC_READ,0);
1405 string invalid_file_msg=
"HDF4 Hopen error for the file ";
1406 invalid_file_msg +=data_path;
1407 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
1408 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1411#ifdef USE_HDFEOS2_LIB
1416 HDFEOS2::File *eosfile =
nullptr;
1420 gridfd = GDopen(
const_cast < char *
>(data_path.c_str()), DFACC_READ);
1424 string invalid_file_msg=
"HDF-EOS GDopen error for the file ";
1425 invalid_file_msg +=data_path;
1426 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
1427 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1431 swathfd = SWopen(
const_cast < char *
>(data_path.c_str()), DFACC_READ);
1432 if (-1 == swathfd) {
1436 string invalid_file_msg=
"HDF-EOS SWopen error for the file ";
1437 invalid_file_msg +=data_path;
1438 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
1439 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1449 bool ecs_metadata =
true;
1451 if((
true == HDFCFUtil::check_beskeys(
"H4.DisableECSMetaDataMin"))
1452 || (
true == HDFCFUtil::check_beskeys(
"H4.DisableECSMetaDataAll")))
1454 if((
true == _disable_ecsmetadata_min)
1455 || (
true == _disable_ecsmetadata_all))
1456 ecs_metadata =
false;
1460 read_das_use_eos2lib(das, data_path,sdfd,fileid,gridfd,swathfd,ecs_metadata,&h4file,&eosfile);
1464 Ancillary::read_ancillary_das(das, data_path);
1467 read_dds_use_eos2lib(dds, data_path,sdfd,fileid,gridfd,swathfd,h4file,eosfile);
1471 close_fileid(sdfd,fileid,gridfd,swathfd,h4file,eosfile);
1474 if(eosfile !=
nullptr)
1481 read_das_hdfsp(das, data_path,sdfd,fileid,&h4file);
1482 Ancillary::read_ancillary_das(das, data_path);
1485 read_dds_hdfsp(dds, data_path,sdfd,fileid,h4file);
1488 close_hdf4_fileid(sdfd,fileid,h4file);
1493 close_hdf4_fileid(sdfd,fileid,h4file);
1497 read_das(das, data_path);
1498 Ancillary::read_ancillary_das(das, data_path);
1499 read_dds(dds, data_path);
1503 Ancillary::read_ancillary_dds(dds, data_path);
1505 dds.transfer_attributes(&das);
1509 catch (InternalErr & e) {
1510 throw BESDapError(e.get_error_message(),
true, e.get_error_code(),
1511 __FILE__, __LINE__);
1514 throw BESDapError(e.get_error_message(),
false, e.get_error_code(),
1515 __FILE__, __LINE__);
1518 string s =
"unknown exception caught building HDF4 DataDDS";
1519 throw BESDapError(s,
true, unknown_error, __FILE__, __LINE__);
1530 BESDMRResponse &bes_dmr =
dynamic_cast<BESDMRResponse &
>(*response);
1532 DMR *dmr = bes_dmr.get_dmr();
1534 D4BaseTypeFactory MyD4TypeFactory;
1535 dmr->set_factory(&MyD4TypeFactory);
1539 dmr->build_using_dds(dds);
1552 dmr->set_factory(
nullptr);
1562 BESDMRResponse &bes_dmr_response =
dynamic_cast<BESDMRResponse &
>(*response);
1566 BESDEBUG(
"h4",
"build_direct_dmr - filename"<< filename <<endl);
1567 DMR *dmr = bes_dmr_response.get_dmr();
1568 dmr->set_name(name_path(filename));
1569 dmr->set_filename(name_path(filename));
1570 D4BaseTypeFactory MyD4TypeFactory;
1571 dmr->set_factory(&MyD4TypeFactory);
1574 BESDEBUG(
"h4",
"build_direct_dmr - begin"<< endl);
1575 read_dmr(dmr, filename);
1576 BESDEBUG(
"h4",
"build_direct_dmr - end"<< endl);
1580 dmr->set_factory(
nullptr);
1589 BES_STOPWATCH_START_DHI(HDF4_NAME, prolog +
"Timer", &dhi);
1596 BaseTypeFactory factory;
1597 DDS dds(&factory, name_path(data_path),
"3.2");
1598 dds.filename(data_path);
1605 HDFSP::File *h4file =
nullptr;
1609 sdfd = SDstart (data_path.c_str(), DFACC_READ);
1611 string invalid_file_msg=
"HDF4 SDstart error for the file ";
1612 invalid_file_msg +=data_path;
1613 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
1614 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1618 fileid = Hopen(data_path.c_str(), DFACC_READ,0);
1621 string invalid_file_msg=
"HDF4 SDstart error for the file ";
1622 invalid_file_msg +=data_path;
1623 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
1624 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1628#ifdef USE_HDFEOS2_LIB
1633 HDFEOS2::File *eosfile =
nullptr;
1636 gridfd = GDopen(
const_cast < char *
>(data_path.c_str()), DFACC_READ);
1640 string invalid_file_msg=
"HDF4 SDstart error for the file ";
1641 invalid_file_msg +=data_path;
1642 invalid_file_msg +=
". It is very possible that this file is not an HDF4 file. ";
1643 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1648 swathfd = SWopen(
const_cast < char *
>(data_path.c_str()), DFACC_READ);
1649 if (-1 == swathfd) {
1653 string invalid_file_msg=
"HDF-EOS SWopen error for the file ";
1654 invalid_file_msg +=data_path;
1655 invalid_file_msg +=
". It is very possible that this file is not an HDF-EOS2 file. ";
1656 throw BESInternalError(invalid_file_msg,__FILE__,__LINE__);
1666 bool ecs_metadata =
true;
1668 if((
true == HDFCFUtil::check_beskeys(
"H4.DisableECSMetaDataMin"))
1669 || (
true == HDFCFUtil::check_beskeys(
"H4.DisableECSMetaDataAll")))
1671 if((
true == _disable_ecsmetadata_min)
1672 || (
true == _disable_ecsmetadata_all))
1673 ecs_metadata =
false;
1677 read_das_use_eos2lib(das, data_path,sdfd,fileid,gridfd,swathfd,ecs_metadata,&h4file,&eosfile);
1681 Ancillary::read_ancillary_das(das, data_path);
1684 read_dds_use_eos2lib(dds, data_path,sdfd,fileid,gridfd,swathfd,h4file,eosfile);
1688 close_fileid(sdfd,fileid,gridfd,swathfd,h4file,eosfile);
1691 if(eosfile !=
nullptr)
1696 read_das_hdfsp(das, data_path,sdfd,fileid,&h4file);
1697 Ancillary::read_ancillary_das(das, data_path);
1700 read_dds_hdfsp(dds, data_path,sdfd,fileid,h4file);
1703 close_hdf4_fileid(sdfd,fileid,h4file);
1707 if(h4file !=
nullptr)
1710 Ancillary::read_ancillary_dds(dds, data_path);
1712 dds.transfer_attributes(&das);
1718#ifdef USE_HDFEOS2_LIB
1731 BESDMRResponse &bes_dmr =
dynamic_cast<BESDMRResponse &
>(*response);
1737 DMR *dmr = bes_dmr.get_dmr();
1738 D4BaseTypeFactory MyD4TypeFactory;
1739 dmr->set_factory(&MyD4TypeFactory);
1740 dmr->build_using_dds(dds);
1741 auto hdf4_dmr =
new HDF4DMR(dmr);
1742#ifdef USE_HDFEOS2_LIB
1743 hdf4_dmr->setHDF4Dataset(sdfd,fileid,gridfd,swathfd);
1745 hdf4_dmr->setHDF4Dataset(sdfd,fileid);
1748 bes_dmr.set_dmr(hdf4_dmr);
1757 hdf4_dmr->set_factory(
nullptr);
1765 auto info =
dynamic_cast<BESInfo *
> (response);
1767 throw BESInternalError(
"cast error", __FILE__, __LINE__);
1769 map < string, string, std::less<> > attrs;
1770 attrs[
"name"] = MODULE_NAME ;
1771 attrs[
"version"] = MODULE_VERSION ;
1772 list < string > services;
1774 if (services.empty() ==
false) {
1776 attrs[
"handles"] = handles;
1778 info->begin_tag(
"module", &attrs);
1779 info->end_tag(
"module");
1786 auto info =
dynamic_cast<BESVersionInfo *
> (response);
1788 throw BESInternalError(
"cast error", __FILE__, __LINE__);
1790 info->add_module(MODULE_NAME, MODULE_VERSION);
1795#ifdef USE_HDFEOS2_LIB
1796void close_fileid(
int sdfd,
int fileid,
int gridfd,
int swathfd,HDFSP:: File* h4file, HDFEOS2::File*eosfile) {
1797 if (h4file !=
nullptr)
1805 if (eosfile !=
nullptr)
1814void close_hdf4_fileid(
int sdfd,
int fileid,
HDFSP::File*h4file) {
1816 if (h4file !=
nullptr)
1828bool rw_das_cache_file(
const string & filename, DAS *das_ptr,
bool w_flag) {
1830 bool das_set_cache =
false;
1831 FILE *das_file =
nullptr;
1834 das_file = fopen(filename.c_str(),
"r");
1836 das_file = fopen(filename.c_str(),
"w");
1838 if(
nullptr == das_file) {
1839 if(ENOENT == errno) {
1842 if(
false == w_flag) {
1843 BESDEBUG(
"h4",
"DAS set cache key is true." << endl);
1844 das_set_cache =
true;
1848 throw BESInternalError(
"An error occurred trying to open a das cache file " + get_errno(), __FILE__, __LINE__);
1852 int fd_das = fileno(das_file);
1855 struct flock *l_das;
1857 l_das = lock(F_RDLCK);
1859 l_das = lock(F_WRLCK);
1862 if(fcntl(fd_das,F_SETLKW,l_das) == -1) {
1865 oss <<
"cache process: " << l_das->l_pid <<
" triggered a locking error: " << get_errno();
1869 if(
false == w_flag){
1871 BESDEBUG(
"h4",
"Obtaining DAS from the cache file" << endl);
1873 das_ptr->parse(das_file);
1876 if(fcntl(fd_das,F_SETLK,lock(F_UNLCK)) == -1) {
1878 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1881 throw InternalErr(__FILE__,__LINE__,
"Fail to parse the das from a das file.");
1886 BESDEBUG(
"h4",
"write DAS to a cache file" << endl);
1888 das_ptr->print(das_file);
1891 if(fcntl(fd_das,F_SETLK,lock(F_UNLCK)) == -1) {
1893 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1896 throw InternalErr(__FILE__,__LINE__,
"Fail to generate a das cache file.");
1902 if(fcntl(fd_das,F_SETLK,lock(F_UNLCK)) == -1) {
1904 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1910 return das_set_cache;
1915bool r_dds_cache_file(
const string & cache_filename, DDS *dds_ptr,
const string & hdf4_filename) {
1917 bool dds_set_cache =
false;
1918 FILE *dds_file =
nullptr;
1919 dds_file = fopen(cache_filename.c_str(),
"rb");
1921 if(
nullptr == dds_file) {
1922 if(ENOENT == errno) {
1926 dds_set_cache =
true;
1929 throw BESInternalError(
"An error occurred trying to open a dds cache file " + get_errno(), __FILE__, __LINE__);
1933 int fd_dds = fileno(dds_file);
1934 struct flock *l_dds;
1935 l_dds = lock(F_RDLCK);
1938 if(fcntl(fd_dds,F_SETLKW,l_dds) == -1) {
1941 oss <<
"cache process: " << l_dds->l_pid <<
" triggered a locking error: " << get_errno();
1946 HDFCFUtil::read_sp_sds_dds_cache(dds_file,dds_ptr,cache_filename,hdf4_filename);
1949 if(fcntl(fd_dds,F_SETLK,lock(F_UNLCK)) == -1) {
1951 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1955 throw InternalErr(__FILE__,__LINE__,
"Fail to generate a dds cache file.");
1958 if(fcntl(fd_dds,F_SETLK,lock(F_UNLCK)) == -1) {
1960 throw BESInternalError(
"An error occurred trying to unlock the file" + get_errno(), __FILE__, __LINE__);
1967 return dds_set_cache;
1971bool check_beskeys(
const string & key) {
1975 const string dosettrue =
"true";
1976 const string dosetyes =
"yes";
1979 if(
true == found ) {
1981 if( dosettrue == doset || dosetyes == doset )
1988bool is_beskey_exist(
const string &key) {
1996bool get_beskeys(
const string & key,
string &key_value) {
2007cerr<<
"OK to pass pointer of a nullptr pointer "<<endl;
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
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
Structure storing information used by the BES to handle the request.
BESContainer * container
pointer to current container in this interface
unsigned int get_bes_error_type() const
Return the return code for this error class.
const char * what() const noexcept override
Return a brief message about the exception.
exception thrown if internal error encountered
Represents a specific data type request handler.
virtual bool add_method(const std::string &name, p_request_handler_method method)
add a handler method to the request handler that knows how to fill in a specific response object
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)
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.