OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
FFSequence.cc
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of ff_handler a FreeForm API handler for the OPeNDAP
4 // DAP2 data server.
5 
6 // Copyright (c) 2005 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This is free software; you can redistribute it and/or modify it under the
10 // terms of the GNU Lesser General Public License as published by the Free
11 // Software Foundation; either version 2.1 of the License, or (at your
12 // option) any later version.
13 //
14 // This software is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 // License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 // (c) COPYRIGHT URI/MIT 1997-99
26 // Please read the full copyright statement in the file COPYRIGHT.
27 //
28 // Authors: reza (Reza Nekovei)
29 
30 // FreeFrom sub-class implementation for FFByte,...FFGrid.
31 // The files are patterned after the subcalssing examples
32 // Test<type>.c,h files.
33 //
34 // ReZa 6/16/97
35 
36 #include "config_ff.h"
37 
38 #include <sstream>
39 
40 using std::endl;
41 using std::ostringstream;
42 
43 // #define DODS_DEBUG
44 
45 #include <D4Attributes.h>
46 #include <Error.h>
47 #include <debug.h>
48 
49 #include "FFStr.h"
50 #include "FFSequence.h"
51 #include "FFD4Sequence.h"
52 #include "util_ff.h"
53 
54 extern long BufPtr;
55 extern char *BufVal;
56 extern long BufSiz;
57 
58 // protected
59 
60 BaseType *
62 {
63  return new FFSequence(*this);
64 }
65 
66 // public
67 
68 FFSequence::FFSequence(const string &n, const string &d, const string &iff) :
69  Sequence(n, d), d_input_format_file(iff)
70 {
71 }
72 
74 {
75 }
76 
77 #if 0
78 static long Records(const string &filename)
79 {
80  int error = 0;
81  DATA_BIN_PTR dbin = NULL;
82  FF_STD_ARGS_PTR SetUps = NULL;
83  PROCESS_INFO_LIST pinfo_list = NULL;
84  PROCESS_INFO_PTR pinfo = NULL;
85  static char Msgt[255];
86 
87  SetUps = ff_create_std_args();
88  if (!SetUps) {
89  return -1;
90  }
91 
93  SetUps->user.is_stdin_redirected = 0;
94  SetUps->input_file = const_cast<char*>(filename.c_str());
95 
96  SetUps->output_file = NULL;
97 
98  error = SetDodsDB(SetUps, &dbin, Msgt);
99  if (error && error < ERR_WARNING_ONLY) {
100  db_destroy(dbin);
101  return -1;
102  }
103 
104  ff_destroy_std_args(SetUps);
105 
106  error = db_ask(dbin, DBASK_PROCESS_INFO, FFF_INPUT | FFF_DATA,
107  &pinfo_list);
108  if (error)
109  return (-1);
110 
111  pinfo_list = dll_first(pinfo_list);
112 
113  pinfo = ((PROCESS_INFO_PTR) (pinfo_list)->data.u.pi);
114 
115  long num_records = PINFO_SUPER_ARRAY_ELS(pinfo);
116 
117  ff_destroy_process_info_list(pinfo_list);
118  db_destroy(dbin);
119 
120  return num_records;
121 }
122 #endif
123 
133 {
134  DBG(cerr << "Entering FFSequence::read..." << endl);
135 
136  if (read_p()) // Nothing to do
137  return true;
138 
139  if ((BufPtr >= BufSiz) && (BufSiz != 0))
140  return true; // End of sequence
141 
142  if (!BufVal) { // Make the cache (BufVal is global)
143  // Create the output Sequence format
144  ostringstream o_fmt;
145  int endbyte = 0;
146  int stbyte = 1;
147 
148  o_fmt << "binary_output_data \"DODS binary output data\"" << endl;
149  for (Vars_iter p = var_begin(); p != var_end(); ++p) {
150  if ((*p)->synthesized_p())
151  continue;
152  if ((*p)->type() == dods_str_c)
153  endbyte += static_cast<FFStr&>(**p).length();
154  else
155  endbyte += (*p)->width();
156 
157  o_fmt << (*p)->name() << " " << stbyte << " " << endbyte << " " << ff_types((*p)->type()) << " "
158  << ff_prec((*p)->type()) << endl;
159  stbyte = endbyte + 1;
160  }
161 
162  DBG(cerr << o_fmt.str());
163 
164  // num_rec could come from DDS if sequence length was known...
165  long num_rec = Records(dataset());
166  if (num_rec == -1) {
167  return true;
168  }
169 
170  BufSiz = num_rec * (stbyte - 1);
171  BufVal = new char[BufSiz];
172 
173  long bytes = read_ff(dataset().c_str(), d_input_format_file.c_str(), o_fmt.str().c_str(), BufVal, BufSiz);
174 
175  if (bytes == -1)
176  throw Error("Could not read requested data from the dataset.");
177  }
178 
179  for (Vars_iter p = var_begin(); p != var_end(); ++p) {
180  (*p)->read();
181  }
182 
183  return false;
184 }
185 
187 {
188  if (at) {
189  Vars_iter var = var_begin();
190  while (var != var_end()) {
191  (*var)->transfer_attributes(at);
192  var++;
193  }
194  }
195 }
196 
197 BaseType *FFSequence::transform_to_dap4(D4Group *root, Constructor *container)
198 {
199  // For this class, ptr_duplicate() calls the const ctor which calls
200  // Constructor's const ctor which calls Constructor::m_duplicate().
201  // Here we replicate some of that functionality, but instead call
202  // transform_to_dap4() on the contained variables.
203 
204  FFD4Sequence *dest = new FFD4Sequence(name(), dataset(), d_input_format_file);
205 
206  Constructor::transform_to_dap4(root, dest);
207 
208  dest->set_length(-1);
209  dest->set_parent(container);
210 
211  return dest;
212 
213 #if 0
214  for (Constructor::Vars_citer i = var_begin(), e = var_end(); i != e; ++i) {
215  BaseType *new_var = (*i)->transform_to_dap4(root, dest);
216  if (new_var) {
217  new_var->set_parent(dest);
218  dest->add_var_nocopy(new_var);
219  }
220  else {
221  throw InternalErr(__FILE__, __LINE__, "transform_to_dap4() returned null, but no Grid could be here.");
222  }
223  }
224 
225  // Add attributes
226  dest->attributes()->transform_to_dap4(get_attr_table());
227 
228  dest->set_is_dap4(true);
229  dest->set_parent(container);
230 
231  dest->set_length(-1);
232 
233  return dest;
234 #endif
235 }
236 
virtual BaseType * transform_to_dap4(D4Group *root, Constructor *container)
Definition: FFSequence.cc:197
void ff_destroy_process_info_list(PROCESS_INFO_LIST)
long Records(const string &filename)
Figure out how many records there are in the dataset.
Definition: util_ff.cc:487
char * BufVal
#define FFF_INPUT
Definition: freeform.h:660
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
virtual ~FFSequence()
Definition: FFSequence.cc:73
long BufPtr
DLL_NODE_PTR dll_first(DLL_NODE_PTR node)
struct struct_ff_std_args::struct_std_args_user user
#define DBASK_PROCESS_INFO
Definition: freeform.h:1343
FFSequence(const string &n, const string &d, const string &iff)
Definition: FFSequence.cc:68
virtual void transfer_attributes(AttrTable *at)
Definition: FFSequence.cc:186
long BufSiz
#define PINFO_SUPER_ARRAY_ELS(pi)
Definition: freeform.h:1399
#define NULL
Definition: wcsUtil.h:65
#define FFF_DATA
Definition: freeform.h:656
char * output_file
Definition: freeform.h:877
void ff_destroy_std_args(FF_STD_ARGS_PTR)
#define ERR_WARNING_ONLY
Definition: err.h:130
void db_destroy(DATA_BIN_PTR)
FF_STD_ARGS_PTR ff_create_std_args(void)
const string ff_types(Type dods_type)
Definition: util_ff.cc:247
int db_ask(DATA_BIN_PTR, int,...)
virtual BaseType * ptr_duplicate()
Definition: FFSequence.cc:61
int ff_prec(Type dods_type)
Definition: util_ff.cc:279
struct struct_ff_process_info * PROCESS_INFO_PTR
Definition: freeform.h:1192
virtual bool read()
Read a row from the Sequence.
Definition: FFSequence.cc:132
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