bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
FFSequence.cc
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
40using std::endl;
41using std::ostringstream;
42
43// #define DODS_DEBUG
44
45#include <libdap/D4Attributes.h>
46#include <libdap/Error.h>
47#include <libdap/debug.h>
48
49#include "FFStr.h"
50#include "FFSequence.h"
51#include "FFD4Sequence.h"
52#include "util_ff.h"
53
54extern long BufPtr;
55extern char *BufVal;
56extern long BufSiz;
57
58// protected
59
60BaseType *
61FFSequence::ptr_duplicate()
62{
63 return new FFSequence(*this);
64}
65
66// public
67
68FFSequence::FFSequence(const string &n, const string &d, const string &iff) :
69 Sequence(n, d), d_input_format_file(iff)
70{
71}
72
73FFSequence::~FFSequence()
74{
75}
76
77#if 0
78static 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).size();
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
186void FFSequence::transfer_attributes(AttrTable *at)
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
197void 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 Constructor::transform_to_dap4(root, dest);
206 container->add_var_nocopy(dest);
207
208#if 0
209 for (Constructor::Vars_citer i = var_begin(), e = var_end(); i != e; ++i) {
210 BaseType *new_var = (*i)->transform_to_dap4(root, dest);
211 if (new_var) {
212 new_var->set_parent(dest);
213 dest->add_var_nocopy(new_var);
214 }
215 else {
216 throw InternalErr(__FILE__, __LINE__, "transform_to_dap4() returned null, but no Grid could be here.");
217 }
218 }
219
220 // Add attributes
221 dest->attributes()->transform_to_dap4(get_attr_table());
222
223 dest->set_is_dap4(true);
224 dest->set_parent(container);
225
226 dest->set_size(-1);
227
228 return dest;
229#endif
230}
231
virtual bool read()
Definition FFStr.h:47