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>
72#include "FFRequestHandler.h"
90static string &remove_paths(
string &src)
92 size_t p1 = src.find_first_of(
'/');
93 if (p1 == string::npos)
95 size_t p2 = src.find_last_of(
'/');
100 src.erase(p1, p2-p1+1);
123static string freeform_error_message()
127 throw BESInternalError(
"Called the FreeForm error message code, but there was no error.", __FILE__, __LINE__);
131 if (is_a_warning(error))
137 string problem = error->problem;
138 string message = error->message;
139 oss << remove_paths(problem) <<
": " << remove_paths(message) << endl;
141 ff_destroy_error (error);
142 error = pull_error();
160long read_ff(
const char *dataset,
const char *if_file,
const char *o_format,
char *o_buffer,
unsigned long bsize)
166 std_args = ff_create_std_args();
168 throw BESInternalError(
"FreeForm could not allocate a 'stdargs' object.", __FILE__, __LINE__);
172 std_args->error_prompt = FALSE;
173 std_args->user.is_stdin_redirected = 0;
174 std_args->input_file = (
char*) (dataset);
175 std_args->input_format_file = (
char*) (if_file);
176 std_args->output_file = NULL;
177 std_args->output_format_buffer = (
char*) (o_format);
178 std_args->log_file = (
char *)
"/dev/null";
181 std_args->log_file = (
char *)
"/tmp/ffdods.log";
190 bufsz->buffer = o_buffer;
191 bufsz->total_bytes = (FF_BSS_t) bsize;
192 bufsz->bytes_used = (FF_BSS_t) 0;
194 std_args->output_bufsize = bufsz;
196 newform_log = ff_create_bufsize(SCRATCH_QUANTA);
198 throw BESInternalError(
"FreeForm could not allocate a 'newform_log' object.", __FILE__, __LINE__);
203 int status = newform(std_args, newform_log, 0 );
205 BESDEBUG(
"ff",
"FreeForm: newform returns " << status << endl);
208 string message = freeform_error_message();
209 BESDEBUG(
"ff",
"FreeForm: error message " << message << endl);
210 throw BESError(message, BES_SYNTAX_USER_ERROR, __FILE__, __LINE__);
213 ff_destroy_bufsize(newform_log);
214 ff_destroy_std_args(std_args);
216 return bufsz->bytes_used;
220 ff_destroy_bufsize(newform_log);
222 ff_destroy_std_args(std_args);
236void free_ff_char_vector(
char **v,
int len)
238 for (
int i = 0; i < len; ++i)
251const string ff_types(
Type dods_type)
273 throw Error(
"ff_types: DODS type " + D2type_name(dods_type) +
" does not map to a FreeForm type.");
283int ff_prec(
Type dods_type)
300 throw Error(
"ff_prec: DODS type " + D2type_name(dods_type) +
" does not map to a FreeForm type.");
310make_output_format(
const string & name,
Type type,
const int width)
314 str <<
"binary_output_data \"DODS binary output data\"" << endl;
315 str << name <<
" 1 " << width <<
" " << ff_types(type)
316 <<
" " << ff_prec(type) << endl;
323makeND_output_format(
const string & name,
Type type,
const int width,
324 int ndim,
const long *start,
const long *edge,
const
325 long *stride,
string * dname)
328 str <<
"binary_output_data \"DODS binary output data\"" << endl;
329 str << name <<
" 1 " << width <<
" ARRAY";
331 for (
int i = 0; i < ndim; i++)
332 str <<
"[" <<
"\"" << dname[i] <<
"\" " << start[i] + 1 <<
" to "
333 << start[i] + (edge[i] - 1) * stride[i] +
334 1 <<
" by " << stride[i] <<
" ]";
336 str <<
" of " << ff_types(type) <<
" " << ff_prec(type) << endl;
338 DBG(cerr <<
"ND output format: " << str.str() << endl);
348const string & format_delimiter(
const string & new_delimiter)
350 static string delimiter =
".";
352 if (new_delimiter !=
"")
353 delimiter = new_delimiter;
364const string & format_extension(
const string & new_extension)
366 static string extension =
".fmt";
368 if (new_extension !=
"")
369 extension = new_extension;
380 if (src_conduit->input && trg_conduit->input)
381 return (
bool) ff_format_comp(src_conduit->input->fd->format,
382 trg_conduit->input->fd->format);
383 else if (src_conduit->output && trg_conduit->output)
384 return (
bool) ff_format_comp(src_conduit->output->fd->format,
385 trg_conduit->output->fd->format);
393 error = list_replace_items((pgenobj_cmp_t) cmp_array_conduit,
414 snprintf(Msgt, Msgt_size,
"Error: NULL DATA_BIN_HANDLE in %s", ROUTINE_NAME);
419 *dbin_h = db_make(std_args->input_file);
422 snprintf(Msgt, Msgt_size,
"Error in Standard Data Bin");
423 return (ERR_MEM_LACK);
429 if (db_set(*dbin_h, DBSET_READ_EQV, std_args->input_file)) {
430 snprintf(Msgt, Msgt_size,
"Error making name table for %s",
431 std_args->input_file);
432 return (DBSET_READ_EQV);
437 std_args->input_file,
438 std_args->output_file,
439 std_args->input_format_file,
440 std_args->input_format_buffer,
441 std_args->input_format_title, &format_data_list)) {
442 if (format_data_list)
443 dll_free_holdings(format_data_list);
445 snprintf(Msgt, Msgt_size,
"Error setting an input format for %s",
446 std_args->input_file);
447 return (DBSET_INPUT_FORMATS);
451 db_set(*dbin_h, DBSET_CREATE_CONDUITS, std_args, format_data_list);
452 dll_free_holdings(format_data_list);
454 snprintf(Msgt, Msgt_size,
"Error creating array information for %s",
455 std_args->input_file);
456 return (DBSET_CREATE_CONDUITS);
459 if (db_set(*dbin_h, DBSET_HEADER_FILE_NAMES, FFF_INPUT,
460 std_args->input_file)) {
461 snprintf(Msgt, Msgt_size,
"Error determining input header file names for %s",
462 std_args->input_file);
463 return (DBSET_HEADER_FILE_NAMES);
466 if (db_set(*dbin_h, DBSET_HEADERS)) {
467 snprintf(Msgt, Msgt_size,
"getting header file for %s", std_args->input_file);
468 return (DBSET_HEADERS);
472 if (db_set(*dbin_h, DBSET_INIT_CONDUITS, FFF_DATA,
473 std_args->records_to_read)) {
474 snprintf(Msgt, Msgt_size,
"Error creating array information for %s",
475 std_args->input_file);
476 return (DBSET_INIT_CONDUITS);
479 error = merge_redundant_conduits((*dbin_h)->array_conduit_list);
481 snprintf(Msgt, Msgt_size,
"Error merging redundent conduits");
491long Records(
const string &filename)
498 static char Msgt[255];
500 SetUps = ff_create_std_args();
506 SetUps->user.is_stdin_redirected = 0;
507 SetUps->input_file =
const_cast<char*
>(filename.c_str());
509 SetUps->output_file = NULL;
511 error = SetDodsDB(SetUps, &dbin, Msgt);
512 if (error && error < ERR_WARNING_ONLY) {
513 ff_destroy_std_args(SetUps);
518 ff_destroy_std_args(SetUps);
520 error = db_ask(dbin, DBASK_PROCESS_INFO, FFF_INPUT | FFF_DATA, &pinfo_list);
524 pinfo_list = dll_first(pinfo_list);
528 long num_records = PINFO_SUPER_ARRAY_ELS(pinfo);
530 ff_destroy_process_info_list(pinfo_list);
537bool file_exist(
const char *filename)
539 return access(filename, F_OK) == 0;
555find_ancillary_rss_formats(
const string & dataset,
const string & ,
559 string FormatPath = FFRequestHandler::get_RSS_format_files();
565 size_t delim = dataset.rfind(
"#");
566 if (delim != string::npos)
567 FileName = dataset.substr(delim + 1, dataset.length() - delim + 1);
569 delim = dataset.rfind(
"/");
570 if (delim != string::npos)
571 FileName = dataset.substr(delim + 1, dataset.length() - delim + 1);
577 delim = FileName.find(
"_");
578 if ( delim != string::npos ) {
579 BaseName = FileName.substr(0,delim+1);
582 throw Error(
"Could not find input format for: " + dataset);
586 string DatePart = FileName.substr(delim+1, FileName.length()-delim+1);
588 if (FormatPath[FormatPath.length()-1] !=
'/')
589 FormatPath.append(
"/");
591 if ( (DatePart.find(
"_") != string::npos) || (DatePart.length() < 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.length() - delim + 1);
624 delim = dataset.rfind(
"/");
625 if (delim != string::npos)
626 FileName = dataset.substr(delim + 1, dataset.length() - 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.length()-delim+1);
643 if (FormatPath[FormatPath.length()-1] !=
'/')
644 FormatPath.append(
"/");
646 if ( (DatePart.find(
"_") != string::npos) || (DatePart.length() < 10) )
647 FormatFile = FormatPath + BaseName +
"averaged.das";
649 FormatFile = FormatPath + BaseName +
"daily.das";
651 return string(FormatFile);
657bool is_integer_type(BaseType * btp)
659 switch (btp->type()) {
675 case dods_structure_c:
676 case dods_sequence_c:
683bool is_float_type(BaseType * btp)
685 switch (btp->type()) {
701 case dods_structure_c:
702 case dods_sequence_c:
713dods_uint32 get_integer_value(BaseType * var)
throw(InternalErr)
718 switch (var->type()) {
720 return static_cast<Byte*
>(var)->value();
723 return static_cast<Int16*
>(var)->value();
726 return static_cast<Int32*
>(var)->value();
729 return static_cast<UInt16*
>(var)->value();
732 return static_cast<UInt32*
>(var)->value();
735 throw InternalErr(__FILE__, __LINE__,
736 "Tried to get an integer value for a non-integer datatype!");
740dods_float64 get_float_value(BaseType * var)
throw(InternalErr)
745 switch (var->type()) {
750 return get_integer_value(var);
753 return static_cast<Float32*
>(var)->value();
756 return static_cast<Float64*
>(var)->value();
759 throw InternalErr(__FILE__, __LINE__,
760 "Tried to get an float value for a non-numeric datatype!");
764string get_Regex_format_file(
const string & filename)
766 string::size_type found = filename.find_last_of(
"/\\");
767 string base_name = filename.substr(found+1);
769 std::map<string,string> mapFF = FFRequestHandler::get_fmt_regex_map();
770 for (
auto rgx = mapFF.begin(); rgx != mapFF.end(); ++ rgx) {
771 BESDEBUG(
"ff",
"get_Regex_format_file() - filename: '" << filename <<
"'" <<
772 " regex: '" << (*rgx).first <<
"'" <<
773 " format: '" << (*rgx).second <<
"'" << endl);
774 BESRegex regex(((*rgx).first).c_str());
775 if ( (
unsigned long) regex.match(base_name.c_str(), base_name.length()) == base_name.length() ){
776 retVal = string((*rgx).second);
780 BESDEBUG(
"ff",
"get_Regex_format_file() - returning format filename: '"<< retVal <<
"'" << endl);
Abstract exception class for the BES with basic string message.
exception thrown if internal error encountered
Regular expression matching.