37static char rcsid[] not_used =
56#include <libdap/BaseType.h>
57#include <libdap/Byte.h>
58#include <libdap/Int16.h>
59#include <libdap/Int32.h>
60#include <libdap/UInt16.h>
61#include <libdap/UInt32.h>
62#include <libdap/Float32.h>
63#include <libdap/Float64.h>
64#include <libdap/InternalErr.h>
65#include <libdap/dods-limits.h>
66#include <libdap/util.h>
67#include <libdap/debug.h>
73#include "FFRequestHandler.h"
91static string &remove_paths(
string &src)
93 size_t p1 = src.find_first_of(
'/');
94 if (p1 == string::npos)
96 size_t p2 = src.find_last_of(
'/');
101 src.erase(p1, p2-p1+1);
108extern "C" FF_ERROR_PTR pull_error(
void);
109extern "C" BOOLEAN is_a_warning(FF_ERROR_PTR error);
124static string freeform_error_message()
126 FF_ERROR_PTR error = pull_error();
128 throw BESInternalError(
"Called the FreeForm error message code, but there was no error.", __FILE__, __LINE__);
132 if (is_a_warning(error))
138 string problem = error->problem;
139 string message = error->message;
140 oss << remove_paths(problem) <<
": " << remove_paths(message) << endl;
142 ff_destroy_error (error);
143 error = pull_error();
161long read_ff(
const char *dataset,
const char *if_file,
const char *o_format,
char *o_buffer,
unsigned long bsize)
163 FF_BUFSIZE_PTR newform_log = NULL;
164 FF_STD_ARGS_PTR std_args = NULL;
167 std_args = ff_create_std_args();
169 throw BESInternalError(
"FreeForm could not allocate a 'stdargs' object.", __FILE__, __LINE__);
173 std_args->error_prompt = FALSE;
174 std_args->user.is_stdin_redirected = 0;
175 std_args->input_file = (
char*) (dataset);
176 std_args->input_format_file = (
char*) (if_file);
177 std_args->output_file = NULL;
178 std_args->output_format_buffer = (
char*) (o_format);
179 std_args->log_file = (
char *)
"/dev/null";
182 std_args->log_file = (
char *)
"/tmp/ffdods.log";
186 vector<char> l_bufsz(
sizeof(FF_BUFSIZE));
188 FF_BUFSIZE_PTR bufsz =
reinterpret_cast<FF_BUFSIZE_PTR
>(l_bufsz.data());
191 bufsz->buffer = o_buffer;
192 bufsz->total_bytes = (FF_BSS_t) bsize;
193 bufsz->bytes_used = (FF_BSS_t) 0;
195 std_args->output_bufsize = bufsz;
197 newform_log = ff_create_bufsize(SCRATCH_QUANTA);
199 throw BESInternalError(
"FreeForm could not allocate a 'newform_log' object.", __FILE__, __LINE__);
204 int status = newform(std_args, newform_log, 0 );
206 BESDEBUG(
"ff",
"FreeForm: newform returns " << status << endl);
209 string message = freeform_error_message();
210 BESDEBUG(
"ff",
"FreeForm: error message " << message << endl);
211 throw BESError(message, BES_SYNTAX_USER_ERROR, __FILE__, __LINE__);
214 ff_destroy_bufsize(newform_log);
215 ff_destroy_std_args(std_args);
217 return bufsz->bytes_used;
221 ff_destroy_bufsize(newform_log);
223 ff_destroy_std_args(std_args);
237void free_ff_char_vector(
char **v,
int len)
239 for (
int i = 0; i < len; ++i)
252const string ff_types(
Type dods_type)
274 throw Error(
"ff_types: DODS type " + D2type_name(dods_type) +
" does not map to a FreeForm type.");
284int ff_prec(
Type dods_type)
301 throw Error(
"ff_prec: DODS type " + D2type_name(dods_type) +
" does not map to a FreeForm type.");
311make_output_format(
const string & name,
Type type,
const int width)
315 str <<
"binary_output_data \"DODS binary output data\"" << endl;
316 str << name <<
" 1 " << width <<
" " << ff_types(type)
317 <<
" " << ff_prec(type) << endl;
324makeND_output_format(
const string & name,
Type type,
const int width,
325 int ndim,
const long *start,
const long *edge,
const
326 long *stride,
string * dname)
329 str <<
"binary_output_data \"DODS binary output data\"" << endl;
330 str << name <<
" 1 " << width <<
" ARRAY";
332 for (
int i = 0; i < ndim; i++)
333 str <<
"[" <<
"\"" << dname[i] <<
"\" " << start[i] + 1 <<
" to "
334 << start[i] + (edge[i] - 1) * stride[i] +
335 1 <<
" by " << stride[i] <<
" ]";
337 str <<
" of " << ff_types(type) <<
" " << ff_prec(type) << endl;
339 DBG(cerr <<
"ND output format: " << str.str() << endl);
349const string & format_delimiter(
const string & new_delimiter)
351 static string delimiter =
".";
353 if (new_delimiter !=
"")
354 delimiter = new_delimiter;
365const string & format_extension(
const string & new_extension)
367 static string extension =
".fmt";
369 if (new_extension !=
"")
370 extension = new_extension;
378cmp_array_conduit(FF_ARRAY_CONDUIT_PTR src_conduit,
379 FF_ARRAY_CONDUIT_PTR trg_conduit)
381 if (src_conduit->input && trg_conduit->input)
382 return (
bool) ff_format_comp(src_conduit->input->fd->format,
383 trg_conduit->input->fd->format);
384 else if (src_conduit->output && trg_conduit->output)
385 return (
bool) ff_format_comp(src_conduit->output->fd->format,
386 trg_conduit->output->fd->format);
391static int merge_redundant_conduits(FF_ARRAY_CONDUIT_LIST conduit_list)
394 error = list_replace_items((pgenobj_cmp_t) cmp_array_conduit,
407int SetDodsDB(FF_STD_ARGS_PTR std_args, DATA_BIN_HANDLE dbin_h,
char *Msgt)
409 FORMAT_DATA_LIST format_data_list = NULL;
415 snprintf(Msgt, Msgt_size,
"Error: NULL DATA_BIN_HANDLE in %s", ROUTINE_NAME);
420 *dbin_h = db_make(std_args->input_file);
423 snprintf(Msgt, Msgt_size,
"Error in Standard Data Bin");
424 return (ERR_MEM_LACK);
430 if (db_set(*dbin_h, DBSET_READ_EQV, std_args->input_file)) {
431 snprintf(Msgt, Msgt_size,
"Error making name table for %s",
432 std_args->input_file);
433 return (DBSET_READ_EQV);
438 std_args->input_file,
439 std_args->output_file,
440 std_args->input_format_file,
441 std_args->input_format_buffer,
442 std_args->input_format_title, &format_data_list)) {
443 if (format_data_list)
444 dll_free_holdings(format_data_list);
446 snprintf(Msgt, Msgt_size,
"Error setting an input format for %s",
447 std_args->input_file);
448 return (DBSET_INPUT_FORMATS);
452 db_set(*dbin_h, DBSET_CREATE_CONDUITS, std_args, format_data_list);
453 dll_free_holdings(format_data_list);
455 snprintf(Msgt, Msgt_size,
"Error creating array information for %s",
456 std_args->input_file);
457 return (DBSET_CREATE_CONDUITS);
460 if (db_set(*dbin_h, DBSET_HEADER_FILE_NAMES, FFF_INPUT,
461 std_args->input_file)) {
462 snprintf(Msgt, Msgt_size,
"Error determining input header file names for %s",
463 std_args->input_file);
464 return (DBSET_HEADER_FILE_NAMES);
467 if (db_set(*dbin_h, DBSET_HEADERS)) {
468 snprintf(Msgt, Msgt_size,
"getting header file for %s", std_args->input_file);
469 return (DBSET_HEADERS);
473 if (db_set(*dbin_h, DBSET_INIT_CONDUITS, FFF_DATA,
474 std_args->records_to_read)) {
475 snprintf(Msgt, Msgt_size,
"Error creating array information for %s",
476 std_args->input_file);
477 return (DBSET_INIT_CONDUITS);
480 error = merge_redundant_conduits((*dbin_h)->array_conduit_list);
482 snprintf(Msgt, Msgt_size,
"Error merging redundent conduits");
492long Records(
const string &filename)
495 DATA_BIN_PTR dbin = NULL;
496 FF_STD_ARGS_PTR SetUps = NULL;
497 PROCESS_INFO_LIST pinfo_list = NULL;
498 PROCESS_INFO_PTR pinfo = NULL;
499 static char Msgt[255];
501 SetUps = ff_create_std_args();
507 SetUps->user.is_stdin_redirected = 0;
508 SetUps->input_file =
const_cast<char*
>(filename.c_str());
510 SetUps->output_file = NULL;
512 error = SetDodsDB(SetUps, &dbin, Msgt);
513 if (error && error < ERR_WARNING_ONLY) {
514 ff_destroy_std_args(SetUps);
519 ff_destroy_std_args(SetUps);
521 error = db_ask(dbin, DBASK_PROCESS_INFO, FFF_INPUT | FFF_DATA, &pinfo_list);
525 pinfo_list = dll_first(pinfo_list);
527 pinfo = ((PROCESS_INFO_PTR) (pinfo_list)->data.u.pi);
529 long num_records = PINFO_SUPER_ARRAY_ELS(pinfo);
531 ff_destroy_process_info_list(pinfo_list);
538bool file_exist(
const char *filename)
540 return access(filename, F_OK) == 0;
556find_ancillary_rss_formats(
const string & dataset,
const string & ,
560 string FormatPath = FFRequestHandler::get_RSS_format_files();
566 size_t delim = dataset.rfind(
"#");
567 if (delim != string::npos)
568 FileName = dataset.substr(delim + 1, dataset.size() - delim + 1);
570 delim = dataset.rfind(
"/");
571 if (delim != string::npos)
572 FileName = dataset.substr(delim + 1, dataset.size() - delim + 1);
578 delim = FileName.find(
"_");
579 if ( delim != string::npos ) {
580 BaseName = FileName.substr(0,delim+1);
583 throw Error(
"Could not find input format for: " + dataset);
587 string DatePart = FileName.substr(delim+1, FileName.size()-delim+1);
591 if ( (DatePart.find(
"_") != string::npos) || (DatePart.size() < 10) )
592 FormatFile = FormatPath + BaseName +
"averaged.fmt";
594 FormatFile = FormatPath + BaseName +
"daily.fmt";
596 return string(FormatFile);
612find_ancillary_rss_das(
const string & dataset,
const string & ,
616 string FormatPath = FFRequestHandler::get_RSS_format_files();
620 size_t delim = dataset.rfind(
"#");
621 if (delim != string::npos)
622 FileName = dataset.substr(delim + 1, dataset.size() - delim + 1);
624 delim = dataset.rfind(
"/");
625 if (delim != string::npos)
626 FileName = dataset.substr(delim + 1, dataset.size() - delim + 1);
631 delim = FileName.find(
"_");
632 if ( delim != string::npos ) {
633 BaseName = FileName.substr(0,delim+1);
636 string msg =
"Could not find input format for: ";
638 throw InternalErr(msg);
641 string DatePart = FileName.substr(delim+1, FileName.size()-delim+1);
644 if ( (DatePart.find(
"_") != string::npos) || (DatePart.size() < 10) )
645 FormatFile = FormatPath + BaseName +
"averaged.das";
647 FormatFile = FormatPath + BaseName +
"daily.das";
649 return string(FormatFile);
655bool is_integer_type(BaseType * btp)
657 switch (btp->type()) {
673 case dods_structure_c:
674 case dods_sequence_c:
681bool is_float_type(BaseType * btp)
683 switch (btp->type()) {
699 case dods_structure_c:
700 case dods_sequence_c:
711dods_uint32 get_integer_value(BaseType * var)
throw(InternalErr)
716 switch (var->type()) {
718 return static_cast<Byte*
>(var)->value();
721 return static_cast<Int16*
>(var)->value();
724 return static_cast<Int32*
>(var)->value();
727 return static_cast<UInt16*
>(var)->value();
730 return static_cast<UInt32*
>(var)->value();
733 throw InternalErr(__FILE__, __LINE__,
734 "Tried to get an integer value for a non-integer datatype!");
738dods_float64 get_float_value(BaseType * var)
throw(InternalErr)
743 switch (var->type()) {
748 return get_integer_value(var);
751 return static_cast<Float32*
>(var)->value();
754 return static_cast<Float64*
>(var)->value();
757 throw InternalErr(__FILE__, __LINE__,
758 "Tried to get an float value for a non-numeric datatype!");
762string get_Regex_format_file(
const string & filename)
764 string::size_type found = filename.find_last_of(
"/\\");
765 string base_name = filename.substr(found+1);
767 std::map<string,string> mapFF = FFRequestHandler::get_fmt_regex_map();
768 for (
auto rgx = mapFF.begin(); rgx != mapFF.end(); ++ rgx) {
769 BESDEBUG(
"ff",
"get_Regex_format_file() - filename: '" << filename <<
"'" <<
770 " regex: '" << (*rgx).first <<
"'" <<
771 " format: '" << (*rgx).second <<
"'" << endl);
772 BESRegex regex(((*rgx).first).c_str());
773 if ( (
unsigned long) regex.match(base_name.c_str(), base_name.size()) == base_name.size() ){
774 retVal = string((*rgx).second);
778 BESDEBUG(
"ff",
"get_Regex_format_file() - returning format filename: '"<< retVal <<
"'" << endl);
Base exception class for the BES with basic string message.
exception thrown if internal error encountered
Regular expression matching.
static void trim_if_trailing_slash(std::string &value)
If the string ends in a slash, remove it This function works for empty strings (doing nothing)....