OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
util_ff.cc
Go to the documentation of this file.
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of ff_handler a FreeForm API handler for the OPeNDAP
5 // DAP2 data server.
6 
7 // Copyright (c) 2005 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 //
10 // This is free software; you can redistribute it and/or modify it under the
11 // terms of the GNU Lesser General Public License as published by the Free
12 // Software Foundation; either version 2.1 of the License, or (at your
13 // option) any later version.
14 //
15 // This software is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 // License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 // (c) COPYRIGHT URI/MIT 1997-99
27 // Please read the full copyright statement in the file COPYRIGHT.
28 //
29 // Authors: reza (Reza Nekovei)
30 
31 // Utility functions for the FreeForm data server.
32 //
33 // jhrg 3/29/96
34 
35 #include "config_ff.h"
36 
37 static char rcsid[] not_used =
38  { "$Id$" };
39 
40 #ifndef WIN32
41 #include <unistd.h> // for access
42 #else
43 #define F_OK 0
44 #endif
45 
46 #include <iostream>
47 #include <sstream>
48 #include <fstream>
49 #include <string>
50 #include <vector>
51 #include <cstdlib>
52 
53 #include <BESDebug.h>
54 
55 #include <BaseType.h>
56 #include <Byte.h>
57 #include <Int16.h>
58 #include <Int32.h>
59 #include <UInt16.h>
60 #include <UInt32.h>
61 #include <Float32.h>
62 #include <Float64.h>
63 #include <InternalErr.h>
64 #include <dods-limits.h>
65 #include <util.h>
66 #include <debug.h>
67 
68 #include "FFRequestHandler.h"
69 #include "util_ff.h"
70 
71 using namespace std;
72 
86 static string &remove_paths(string &src)
87 {
88  size_t p1 = src.find_first_of('/');
89  if (p1 == string::npos)
90  return src;
91  size_t p2 = src.find_last_of('/');
92  // The string has one '/', not a big deal
93  if (p2 == p1)
94  return src;
95 
96  src.erase(p1, p2-p1+1);
97  return src;
98 }
99 
100 // These two functions are defined in FFND/error.c. They were originally
101 // static functions. I used them to read error strings since FreeForm
102 // did not have a good way to get the error text. jhrg 9/11/12
103 extern "C" FF_ERROR_PTR pull_error(void);
104 extern "C" BOOLEAN is_a_warning(FF_ERROR_PTR error);
105 
119 static string freeform_error_message()
120 {
121  FF_ERROR_PTR error = pull_error();
122  if (!error)
123  throw BESInternalError("Called the FreeForm error message code, but there was no error.", __FILE__, __LINE__);
124 
125  ostringstream oss;
126  do {
127  if (is_a_warning(error))
128  oss << "Warning: ";
129  else
130  oss << "Error: ";
131 
132  // if either of these contain a pathname, remove it
133  string problem = error->problem;
134  string message = error->message;
135  oss << remove_paths(problem) << ": " << remove_paths(message) << endl;
136 
137  ff_destroy_error (error);
138  error = pull_error();
139  } while (error);
140 
141  return oss.str();
142 }
143 
156 long read_ff(const char *dataset, const char *if_file, const char *o_format, char *o_buffer, unsigned long bsize)
157 {
158  FF_BUFSIZE_PTR newform_log = NULL;
159  FF_STD_ARGS_PTR std_args = NULL;
160 
161  try {
162  std_args = ff_create_std_args();
163  if (!std_args)
164  throw BESInternalError("FreeForm could not allocate a 'stdargs' object.", __FILE__, __LINE__);
165 
166  // set the std_arg structure values - cast away const for dataset, if_file,
167  // and o_format.
168  std_args->error_prompt = FALSE;
169  std_args->user.is_stdin_redirected = 0;
170  std_args->input_file = (char*) (dataset);
171  std_args->input_format_file = (char*) (if_file);
172  std_args->output_file = NULL;
173  std_args->output_format_buffer = (char*) (o_format);
174  std_args->log_file = (char *) "/dev/null";
175 #if 0
176  // This just doesn't seem to work within the BES framework. jhrg 9/11/12
177  std_args->log_file = (char *)"/tmp/ffdods.log";
178 #endif
179 
180  // memory freed automatically on exit
181  vector<char> l_bufsz(sizeof(FF_BUFSIZE));
182  //bufsz = (FF_BUFSIZE *)&l_bufsz[0];
183  FF_BUFSIZE_PTR bufsz = reinterpret_cast<FF_BUFSIZE_PTR>(&l_bufsz[0]);
184 
185  bufsz->usage = 1;
186  bufsz->buffer = o_buffer;
187  bufsz->total_bytes = (FF_BSS_t) bsize;
188  bufsz->bytes_used = (FF_BSS_t) 0;
189 
190  std_args->output_bufsize = bufsz;
191 
192  newform_log = ff_create_bufsize(SCRATCH_QUANTA);
193  if (!newform_log)
194  throw BESInternalError("FreeForm could not allocate a 'newform_log' object.", __FILE__, __LINE__);
195 
196  // passing 0 for the FILE* param is a wash since a non-null
197  // value for newform_log selects that as the 'logging' sink.
198  // jhrg 9/11/12
199  int status = newform(std_args, newform_log, 0 /*stderr*/);
200 
201  BESDEBUG("ff", "FreeForm: newform returns " << status << endl);
202 
203  if (err_count()) {
204  string message = freeform_error_message();
205  BESDEBUG("ff", "FreeForm: error message " << message << endl);
206  throw BESError(message, BES_SYNTAX_USER_ERROR, __FILE__, __LINE__);
207  }
208 
209  ff_destroy_bufsize(newform_log);
210  ff_destroy_std_args(std_args);
211 
212  return bufsz->bytes_used;
213  }
214  catch (...) {
215  if (newform_log)
216  ff_destroy_bufsize(newform_log);
217  if (std_args)
218  ff_destroy_std_args(std_args);
219 
220  throw;
221  }
222 
223  return 0;
224 }
225 
232 void free_ff_char_vector(char **v, int len)
233 {
234  for (int i = 0; i < len; ++i)
235  if (v && v[i])
236  free (v[i]);
237  if (v && len > 0)
238  free (v);
239 }
240 
241 // Given the name of a DODS data type, return the name of the corresponding
242 // FreeForm data type.
243 //
244 // Returns: a const char * if the DODS type maps into a FreeForm type,
245 // otherwise NULL.
246 
247 const string ff_types(Type dods_type)
248 {
249  switch (dods_type) {
250  case dods_byte_c:
251  return "uint8";
252  case dods_int16_c:
253  return "int16";
254  case dods_uint16_c:
255  return "uint16";
256  case dods_int32_c:
257  return "int32";
258  case dods_uint32_c:
259  return "uint32";
260  case dods_float32_c:
261  return "float32";
262  case dods_float64_c:
263  return "float64";
264  case dods_str_c:
265  return "text";
266  case dods_url_c:
267  return "text";
268  default:
269  throw Error("ff_types: DODS type " + D2type_name(dods_type) + " does not map to a FreeForm type.");
270  }
271 }
272 
273 // Given the name of a DODS data type, return the precision of the
274 // corresponding FreeForm data type.
275 //
276 // Returns: a positive integer if the DODS type maps into a FreeForm type,
277 // otherwise -1.
278 
279 int ff_prec(Type dods_type)
280 {
281  switch (dods_type) {
282  case dods_byte_c:
283  case dods_int16_c:
284  case dods_uint16_c:
285  case dods_int32_c:
286  case dods_uint32_c:
287  return 0;
288  case dods_float32_c:
289  return DODS_FLT_DIG;
290  case dods_float64_c:
291  return DODS_DBL_DIG;
292  case dods_str_c:
293  case dods_url_c:
294  return 0;
295  default:
296  throw Error("ff_prec: DODS type " + D2type_name(dods_type) + " does not map to a FreeForm type.");
297  }
298 }
299 
305 const string
306 make_output_format(const string & name, Type type, const int width)
307 {
308  ostringstream str;
309 
310  str << "binary_output_data \"DODS binary output data\"" << endl;
311  str << name << " 1 " << width << " " << ff_types(type)
312  << " " << ff_prec(type) << endl;
313 
314  return str.str();
315 }
316 
317 // format for multi-dimension array
318 const string
319 makeND_output_format(const string & name, Type type, const int width,
320  int ndim, const long *start, const long *edge, const
321  long *stride, string * dname)
322 {
323  ostringstream str;
324  str << "binary_output_data \"DODS binary output data\"" << endl;
325  str << name << " 1 " << width << " ARRAY";
326 
327  for (int i = 0; i < ndim; i++)
328  str << "[" << "\"" << dname[i] << "\" " << start[i] + 1 << " to "
329  << start[i] + (edge[i] - 1) * stride[i] +
330  1 << " by " << stride[i] << " ]";
331 
332  str << " of " << ff_types(type) << " " << ff_prec(type) << endl;
333 
334  DBG(cerr << "ND output format: " << str.str() << endl);
335 
336  return str.str();
337 }
338 
344 const string & format_delimiter(const string & new_delimiter)
345 {
346  static string delimiter = ".";
347 
348  if (new_delimiter != "")
349  delimiter = new_delimiter;
350 
351  return delimiter;
352 }
353 
360 const string & format_extension(const string & new_extension)
361 {
362  static string extension = ".fmt";
363 
364  if (new_extension != "")
365  extension = new_extension;
366 
367  return extension;
368 }
369 
372 static bool
373 cmp_array_conduit(FF_ARRAY_CONDUIT_PTR src_conduit,
374  FF_ARRAY_CONDUIT_PTR trg_conduit)
375 {
376  if (src_conduit->input && trg_conduit->input)
377  return (bool) ff_format_comp(src_conduit->input->fd->format,
378  trg_conduit->input->fd->format);
379  else if (src_conduit->output && trg_conduit->output)
380  return (bool) ff_format_comp(src_conduit->output->fd->format,
381  trg_conduit->output->fd->format);
382  else
383  return false;
384 }
385 
386 static int merge_redundant_conduits(FF_ARRAY_CONDUIT_LIST conduit_list)
387 {
388  int error = 0;
389  error = list_replace_items((pgenobj_cmp_t) cmp_array_conduit,
390  conduit_list);
391  return (error);
392 }
393 
402 int SetDodsDB(FF_STD_ARGS_PTR std_args, DATA_BIN_HANDLE dbin_h, char *Msgt)
403 {
404  FORMAT_DATA_LIST format_data_list = NULL;
405  int error = 0;
406 
407  assert(dbin_h);
408 
409  if (!dbin_h) {
410  snprintf(Msgt, Msgt_size, "Error: NULL DATA_BIN_HANDLE in %s", ROUTINE_NAME);
411  return (ERR_API);
412  }
413 
414  if (!*dbin_h) {
415  *dbin_h = db_make(std_args->input_file);
416 
417  if (!*dbin_h) {
418  snprintf(Msgt, Msgt_size, "Error in Standard Data Bin");
419  return (ERR_MEM_LACK);
420  }
421  }
422 
423  /* Now set the formats and the auxiliary files */
424 
425  if (db_set(*dbin_h, DBSET_READ_EQV, std_args->input_file)) {
426  snprintf(Msgt, Msgt_size, "Error making name table for %s",
427  std_args->input_file);
428  return (DBSET_READ_EQV);
429  }
430 
431  if (db_set(*dbin_h,
433  std_args->input_file,
434  std_args->output_file,
435  std_args->input_format_file,
436  std_args->input_format_buffer,
437  std_args->input_format_title, &format_data_list)) {
438  if (format_data_list)
439  dll_free_holdings(format_data_list);
440 
441  snprintf(Msgt, Msgt_size, "Error setting an input format for %s",
442  std_args->input_file);
443  return (DBSET_INPUT_FORMATS);
444  }
445 
446  error =
447  db_set(*dbin_h, DBSET_CREATE_CONDUITS, std_args, format_data_list);
448  dll_free_holdings(format_data_list);
449  if (error) {
450  snprintf(Msgt, Msgt_size, "Error creating array information for %s",
451  std_args->input_file);
452  return (DBSET_CREATE_CONDUITS);
453  }
454 
456  std_args->input_file)) {
457  snprintf(Msgt, Msgt_size, "Error determining input header file names for %s",
458  std_args->input_file);
459  return (DBSET_HEADER_FILE_NAMES);
460  }
461 
462  if (db_set(*dbin_h, DBSET_HEADERS)) {
463  snprintf(Msgt, Msgt_size, "getting header file for %s", std_args->input_file);
464  return (DBSET_HEADERS);
465  }
466 
467 
468  if (db_set(*dbin_h, DBSET_INIT_CONDUITS, FFF_DATA,
469  std_args->records_to_read)) {
470  snprintf(Msgt, Msgt_size, "Error creating array information for %s",
471  std_args->input_file);
472  return (DBSET_INIT_CONDUITS);
473  }
474 
475  error = merge_redundant_conduits((*dbin_h)->array_conduit_list);
476  if (error)
477  snprintf(Msgt, Msgt_size, "Error merging redundent conduits");
478 
479  return (error);
480 }
481 
487 long Records(const string &filename)
488 {
489  int error = 0;
490  DATA_BIN_PTR dbin = NULL;
491  FF_STD_ARGS_PTR SetUps = NULL;
492  PROCESS_INFO_LIST pinfo_list = NULL;
493  PROCESS_INFO_PTR pinfo = NULL;
494  static char Msgt[255];
495 
496  SetUps = ff_create_std_args();
497  if (!SetUps) {
498  return -1;
499  }
500 
502  SetUps->user.is_stdin_redirected = 0;
503  SetUps->input_file = const_cast<char*>(filename.c_str());
504 
505  SetUps->output_file = NULL;
506 
507  error = SetDodsDB(SetUps, &dbin, Msgt);
508  if (error && error < ERR_WARNING_ONLY) {
509  db_destroy(dbin);
510  return -1;
511  }
512 
513  ff_destroy_std_args(SetUps);
514 
515  error = db_ask(dbin, DBASK_PROCESS_INFO, FFF_INPUT | FFF_DATA, &pinfo_list);
516  if (error)
517  return (-1);
518 
519  pinfo_list = dll_first(pinfo_list);
520 
521  pinfo = ((PROCESS_INFO_PTR) (pinfo_list)->data.u.pi);
522 
523  long num_records = PINFO_SUPER_ARRAY_ELS(pinfo);
524 
525  ff_destroy_process_info_list(pinfo_list);
526  db_destroy(dbin);
527 
528  return num_records;
529 }
530 
531 
532 bool file_exist(const char *filename)
533 {
534  return access(filename, F_OK) == 0;
535 }
536 
549 const string
550 find_ancillary_rss_formats(const string & dataset, const string & /* delimiter */,
551  const string & /* extension */)
552 {
553  string FormatFile;
554  string FormatPath = FFRequestHandler::get_RSS_format_files();
555  string BaseName;
556  string FileName;
557 
558  // Separate the filename from the pathname, for both plain files
559  // and cached decompressed files (ones with '#' in their names).
560  size_t delim = dataset.rfind("#");
561  if (delim != string::npos)
562  FileName = dataset.substr(delim + 1, dataset.length() - delim + 1);
563  else {
564  delim = dataset.rfind("/");
565  if (delim != string::npos)
566  FileName = dataset.substr(delim + 1, dataset.length() - delim + 1);
567  else
568  FileName = dataset;
569  }
570 
571  // The file/dataset name has to have an underscore...
572  delim = FileName.find("_");
573  if ( delim != string::npos ) {
574  BaseName = FileName.substr(0,delim+1);
575  }
576  else {
577  throw Error("Could not find input format for: " + dataset);
578  }
579 
580  // Now determine if this is files holds averaged or daily data.
581  string DatePart = FileName.substr(delim+1, FileName.length()-delim+1);
582 
583  if (FormatPath[FormatPath.length()-1] != '/')
584  FormatPath.append("/");
585 
586  if ( (DatePart.find("_") != string::npos) || (DatePart.length() < 10) )
587  FormatFile = FormatPath + BaseName + "averaged.fmt";
588  else
589  FormatFile = FormatPath + BaseName + "daily.fmt";
590 
591  return string(FormatFile);
592 }
593 
606 const string
607 find_ancillary_rss_das(const string & dataset, const string & /* delimiter */,
608  const string & /* extension */)
609 {
610  string FormatFile;
611  string FormatPath = FFRequestHandler::get_RSS_format_files();
612  string BaseName;
613  string FileName;
614 
615  size_t delim = dataset.rfind("#");
616  if (delim != string::npos)
617  FileName = dataset.substr(delim + 1, dataset.length() - delim + 1);
618  else {
619  delim = dataset.rfind("/");
620  if (delim != string::npos)
621  FileName = dataset.substr(delim + 1, dataset.length() - delim + 1);
622  else
623  FileName = dataset;
624  }
625 
626  delim = FileName.find("_");
627  if ( delim != string::npos ) {
628  BaseName = FileName.substr(0,delim+1);
629  }
630  else {
631  string msg = "Could not find input format for: ";
632  msg += dataset;
633  throw InternalErr(msg);
634  }
635 
636  string DatePart = FileName.substr(delim+1, FileName.length()-delim+1);
637 
638  if (FormatPath[FormatPath.length()-1] != '/')
639  FormatPath.append("/");
640 
641  if ( (DatePart.find("_") != string::npos) || (DatePart.length() < 10) )
642  FormatFile = FormatPath + BaseName + "averaged.das";
643  else
644  FormatFile = FormatPath + BaseName + "daily.das";
645 
646  return string(FormatFile);
647 }
648 
649 // These functions are used by the Date/Time Factory classes but they might
650 // be generally useful in writing server-side functions. 1/21/2002 jhrg
651 
652 bool is_integer_type(BaseType * btp)
653 {
654  switch (btp->type()) {
655  case dods_null_c:
656  return false;
657 
658  case dods_byte_c:
659  case dods_int16_c:
660  case dods_uint16_c:
661  case dods_int32_c:
662  case dods_uint32_c:
663  return true;
664 
665  case dods_float32_c:
666  case dods_float64_c:
667  case dods_str_c:
668  case dods_url_c:
669  case dods_array_c:
670  case dods_structure_c:
671  case dods_sequence_c:
672  case dods_grid_c:
673  default:
674  return false;
675  }
676 }
677 
678 bool is_float_type(BaseType * btp)
679 {
680  switch (btp->type()) {
681  case dods_null_c:
682  case dods_byte_c:
683  case dods_int16_c:
684  case dods_uint16_c:
685  case dods_int32_c:
686  case dods_uint32_c:
687  return false;
688 
689  case dods_float32_c:
690  case dods_float64_c:
691  return true;
692 
693  case dods_str_c:
694  case dods_url_c:
695  case dods_array_c:
696  case dods_structure_c:
697  case dods_sequence_c:
698  case dods_grid_c:
699  default:
700  return false;
701  }
702 }
703 
708 dods_uint32 get_integer_value(BaseType * var) throw(InternalErr)
709 {
710  if (!var)
711  return 0;
712 
713  switch (var->type()) {
714  case dods_byte_c:
715  return static_cast<Byte*>(var)->value();
716 
717  case dods_int16_c:
718  return static_cast<Int16*>(var)->value();
719 
720  case dods_int32_c:
721  return static_cast<Int32*>(var)->value();
722 
723  case dods_uint16_c:
724  return static_cast<UInt16*>(var)->value();
725 
726  case dods_uint32_c:
727  return static_cast<UInt32*>(var)->value();
728 
729  default:
730  throw InternalErr(__FILE__, __LINE__,
731  "Tried to get an integer value for a non-integer datatype!");
732  }
733 }
734 
735 dods_float64 get_float_value(BaseType * var) throw(InternalErr)
736 {
737  if (!var)
738  return 0.0;
739 
740  switch (var->type()) {
741  case dods_int16_c:
742  case dods_uint16_c:
743  case dods_int32_c:
744  case dods_uint32_c:
745  return get_integer_value(var);
746 
747  case dods_float32_c:
748  return static_cast<Float32*>(var)->value();
749 
750  case dods_float64_c:
751  return static_cast<Float64*>(var)->value();
752 
753  default:
754  throw InternalErr(__FILE__, __LINE__,
755  "Tried to get an float value for a non-numeric datatype!");
756  }
757 }
758 
#define BES_SYNTAX_USER_ERROR
Definition: BESError.h:44
#define ERR_MEM_LACK
Definition: err.h:36
void free(void *)
BOOLEAN error_prompt
Definition: freeform.h:889
void ff_destroy_process_info_list(PROCESS_INFO_LIST)
void ff_destroy_error(FF_ERROR_PTR error)
#define ERR_API
Definition: err.h:121
char * input_format_file
Definition: freeform.h:874
bool is_integer_type(BaseType *btp)
Definition: util_ff.cc:652
char HUGE * buffer
Definition: freeform.h:850
char * input_format_title
Definition: freeform.h:875
exception thrown if inernal error encountered
FF_BSS_t bytes_used
Definition: freeform.h:852
const string find_ancillary_rss_formats(const string &dataset, const string &, const string &)
Find the RSS (Remote Sensing Systems) format file using their naming convention.
Definition: util_ff.cc:550
#define not_used
Definition: config.h:315
FF_ARRAY_DIPOLE_PTR input
Definition: freeform.h:1184
char * message
Definition: freeform.h:951
#define DBSET_READ_EQV
Definition: freeform.h:1328
long Records(const string &filename)
Figure out how many records there are in the dataset.
Definition: util_ff.cc:487
#define FFF_INPUT
Definition: freeform.h:660
bool file_exist(const char *filename)
Definition: util_ff.cc:532
bool is_float_type(BaseType *btp)
Definition: util_ff.cc:678
void ff_destroy_bufsize(FF_BUFSIZE_PTR bufsize)
STL namespace.
int SetDodsDB(FF_STD_ARGS_PTR std_args, DATA_BIN_HANDLE dbin_h, char *Msgt)
Given a set of standard arguments (input filenames), allocate a DATA-BIN_HANDLE and return an error c...
Definition: util_ff.cc:402
char * output_format_buffer
Definition: freeform.h:882
unsigned short usage
Definition: freeform.h:851
#define DBSET_HEADER_FILE_NAMES
Definition: freeform.h:1330
FF_ARRAY_DIPOLE_PTR output
Definition: freeform.h:1185
#define assert(exp)
Definition: freeform.h:735
DLL_NODE_PTR dll_first(DLL_NODE_PTR node)
struct struct_ff_std_args::struct_std_args_user user
dods_float64 get_float_value(BaseType *var)
Definition: util_ff.cc:735
const string & format_extension(const string &new_extension)
Set or get the format file extension.
Definition: util_ff.cc:360
int db_set(DATA_BIN_PTR, int,...)
const string make_output_format(const string &name, Type type, const int width)
Make a FreeForm output format specification.
Definition: util_ff.cc:306
#define DBASK_PROCESS_INFO
Definition: freeform.h:1343
const string makeND_output_format(const string &name, Type type, const int width, int ndim, const long *start, const long *edge, const long *stride, string *dname)
Definition: util_ff.cc:319
BOOLEAN(* pgenobj_cmp_t)(void *, void *)
Definition: freeform.h:1492
BOOLEAN is_a_warning(FF_ERROR_PTR error)
FF_BUFSIZE_PTR ff_create_bufsize(long total_bytes)
FF_ERROR_PTR pull_error(void)
dods_uint32 get_integer_value(BaseType *var)
Get the value of the BaseType Variable.
Definition: util_ff.cc:708
char * problem
Definition: freeform.h:952
Abstract exception class for the BES with basic string message.
Definition: BESError.h:51
char * input_format_buffer
Definition: freeform.h:876
FORMAT_DATA_PTR fd
Definition: freeform.h:1145
FF_BSS_t total_bytes
Definition: freeform.h:853
#define PINFO_SUPER_ARRAY_ELS(pi)
Definition: freeform.h:1399
const int Msgt_size
Definition: util_ff.h:44
#define ROUTINE_NAME
Definition: memtrack.h:65
#define NULL
Definition: wcsUtil.h:65
#define FFF_DATA
Definition: freeform.h:656
#define DBSET_HEADERS
Definition: freeform.h:1327
char * output_file
Definition: freeform.h:877
unsigned FF_BSS_t
Definition: freeform.h:838
void ff_destroy_std_args(FF_STD_ARGS_PTR)
BOOLEAN ff_format_comp(FORMAT_PTR, FORMAT_PTR)
short BOOLEAN
Definition: os_utils.h:115
#define ERR_WARNING_ONLY
Definition: err.h:130
void db_destroy(DATA_BIN_PTR)
DATA_BIN_PTR db_make(char *title)
int newform(FF_STD_ARGS_PTR std_args, FF_BUFSIZE_PTR log, FILE *to_user)
FF_BUFSIZE_PTR output_bufsize
Definition: freeform.h:879
FF_STD_ARGS_PTR ff_create_std_args(void)
const string ff_types(Type dods_type)
Definition: util_ff.cc:247
int dll_free_holdings(DLL_NODE_PTR head)
int db_ask(DATA_BIN_PTR, int,...)
#define FALSE
Definition: gse_parser.h:33
int err_count(void)
void free_ff_char_vector(char **v, int len)
Free a char ** vector that db_ask() allocates.
Definition: util_ff.cc:232
#define DBSET_INIT_CONDUITS
Definition: freeform.h:1336
int ff_prec(Type dods_type)
Definition: util_ff.cc:279
static string get_RSS_format_files()
#define SCRATCH_QUANTA
Definition: freeform.h:829
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
#define DBSET_CREATE_CONDUITS
Definition: freeform.h:1334
int list_replace_items(pgenobj_cmp_t lmi_cmp, DLL_NODE_PTR list)
struct struct_ff_process_info * PROCESS_INFO_PTR
Definition: freeform.h:1192
#define DBSET_INPUT_FORMATS
Definition: freeform.h:1325
const string & format_delimiter(const string &new_delimiter)
Set or get the format file delimiter.
Definition: util_ff.cc:344
const string find_ancillary_rss_das(const string &dataset, const string &, const string &)
Find the RSS (Remote Sensing Systems) format file using their naming convention.
Definition: util_ff.cc:607
long read_ff(const char *dataset, const char *if_file, const char *o_format, char *o_buffer, unsigned long bsize)
Read from a file/database using the FreeForm API.
Definition: util_ff.cc:156