OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
FFArray.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/18/97
35 
36 #include "config_ff.h"
37 
38 static char rcsid[] not_used = { "$Id$" };
39 
40 #include <cstring>
41 #include <iostream>
42 #include <string>
43 
44 #include <BESDebug.h>
45 
46 #include <dods-datatypes.h>
47 #include <D4Attributes.h>
48 #include <D4Group.h>
49 #include <Error.h>
50 #include <InternalErr.h>
51 
52 #include "FFArray.h"
53 #include "util_ff.h"
54 #include "util.h"
55 
56 BaseType *
58 {
59  return new FFArray(*this);
60 }
61 
62 FFArray::FFArray(const string &n, const string &d, BaseType *v, const string &iff) :
63  Array(n, d, v), d_input_format_file(iff)
64 {
65 }
66 
68 {
69 }
70 
71 // parse constraint expr. and make coordinate point location for an array.
72 // return number of elements to read.
73 
74 long FFArray::Arr_constraint(long *cor, long *step, long *edg, string *dim_nms, bool *has_stride)
75 {
76  long start, stride, stop;
77 
78  int id = 0;
79  long nels = 1;
80  *has_stride = false;
81 
82  Array::Dim_iter i = dim_begin();
83  while (i != dim_end()) {
84  start = (long) dimension_start(i, true);
85  stride = (long) dimension_stride(i, true);
86  stop = (long) dimension_stop(i, true);
87  string dimname = dimension_name(i);
88 
89  // Check for empty constraint
90  if (start + stop + stride == 0)
91  return -1;
92 
93  dim_nms[id] = dimname;
94  // (void) strcpy(dim_nms[id], dimname.c_str());
95 
96  cor[id] = start;
97  step[id] = stride;
98  edg[id] = ((stop - start) / stride) + 1; // count of elements
99 
100  nels *= edg[id]; // total number of values for variable
101 
102  if (stride != 1)
103  *has_stride = true;
104 
105  ++id;
106  ++i;
107  }
108  return nels;
109 }
110 
111 #if 0
112 // parse constraint expr. and make coordinate point location.
113 // return number of elements to read.
114 
115 long FFArray::Seq_constraint(long *cor, long *step, long *edg, bool *has_stride)
116 {
117  int start, stride, stop;
118  int id = 0;
119  long nels = 1;
120  *has_stride = false;
121 
122  Array::Dim_iter i = dim_begin();
123  while (i != dim_end()) {
124  start = (long) dimension_start(i, true);
125  stride = (long) dimension_stride(i, true);
126  stop = (long) dimension_stop(i, true);
127 
128  // Check for empty constraint
129  if (start + stop + stride == 0)
130  return -1;
131 
132  cor[id] = start;
133  step[id] = stride;
134  edg[id] = ((stop - start) / stride) + 1; // count of elements
135  nels *= edg[id]; // total number of values for variable
136  if (stride != 1)
137  *has_stride = true;
138 
139  ++id;
140  ++i;
141  }
142  return nels;
143 }
144 #endif
145 
146 #if 0
147 static int hyper_get(void *dest, void *src, unsigned szof, const int dim_num, int index, const int dimsz[],
148  const long start[], const long edge[])
149 {
150  long jump = 1;
151 
152  // The THEN part of this IF handles the cases where we are hyper-slabbing
153  // any dimension *other* than the rightmost dimension. E.G. Suppose
154  // a[10][10][10] is in SRC, for INDEX == 0 and 1 we do the code in the
155  // THEN clause and for INDEX == 2 the ELSE clause is executed.
156 
157  // NOTE: I have added casts for src and dest from void * to char * since
158  // ANSI C++ won't allow pointer arithmetic on void * variables. 4/17/98
159  // jhrg
160 
161  if (dim_num != (index + 1)) {
162  // number of lines, pages, etc to skip
163  for (int i = dim_num - 1; i > index; i--)
164  jump *= dimsz[i];
165 
166  for (int edge_tmp = 0; edge_tmp < edge[index]; edge_tmp++) {
167  void *srctmp = ((char *) src + (start[index] + edge_tmp) * jump * szof);
168  dest = (char *) dest + hyper_get(dest, srctmp, szof, dim_num, index + 1, dimsz, start, edge);
169  }
170  return (0);
171  }
172  else {
173  // number of bytes to jump
174  void *srctmp = (char *) src + start[index] * szof;
175  memcpy(dest, srctmp, (size_t) edge[index] * szof);
176  return (edge[index] * szof);
177  }
178 }
179 #endif
180 
181 #if 0
182 template<class T>
183 static void seq2vects(T * t, FFArray & array)
184 {
185  bool has_stride;
186  int ndim = array.dimensions();
187  long *start = new long[ndim];
188  long *stride = new long[ndim];
189  long *edge = new long[ndim];
190 
191  long count = array.Seq_constraint(start, stride, edge, &has_stride);
192 
193  if (count != -1) { // non-null hyperslab
194  T *t_hs = new T[count];
195  int *dimsz = new int[array.dimensions()];
196 
197  int i = 0;
198  Array::Dim_iter p = array.dim_begin();
199  while (p != array.dim_end()) {
200  dimsz[i] = array.dimension_size(p);
201  ++i;
202  ++p;
203  }
204 
205  hyper_get(t_hs, t, array.var()->width(), ndim, 0, dimsz, start, edge);
206 
207  array.set_read_p(true); // reading is done
208  array.val2buf((void *) t_hs); // put values in the buffer
209 
210  delete[] t_hs;
211  delete[] dimsz;
212  }
213  else {
214  array.set_read_p(true);
215  array.val2buf((void *) t);
216  }
217 
218  delete[] start;
219  delete[] stride;
220  delete[] edge;
221 }
222 #endif
223 
224 // Read cardinal types and ctor types separately. Cardinal types are
225 // stored in arrays of the C++ data type while ctor types are stored
226 // in arrays of the DODS classes used to store those types.
227 //
228 // NB: Currently this code only reads arrays of Byte, Int32 and
229 // Float64. Str and Url as well as all the ctor types are not
230 // supported.
231 //
232 // Throws an Error object if an error was detected.
233 // Returns true if more data still needs to be read, otherwise returns false.
234 
236 {
237  if (read_p()) // Nothing to do
238  return true;
239 
240  bool has_stride;
241  int ndims = dimensions();
242  vector<string> dname(ndims);
243  vector<long> start(ndims);
244  vector<long> stride(ndims);
245  vector<long> edge(ndims);
246  long count = Arr_constraint(&start[0], &stride[0], &edge[0], &dname[0], &has_stride);
247 
248  if (!count) {
249  throw Error(unknown_error, "Constraint returned an empty dataset.");
250  }
251 
252  string output_format = makeND_output_format(name(), var()->type(), var()->width(),
253  ndims, &start[0], &edge[0], &stride[0], &dname[0]);
254 
255  // For each cardinal-type variable, do the following:
256  // Use ff to read the data
257  // Store the (possibly constrained) data
258  // NB: extract_array throws an Error object to signal problems.
259 
260  switch (var()->type()) {
261  case dods_byte_c:
262  extract_array<dods_byte>(dataset(), d_input_format_file, output_format);
263  break;
264 
265  case dods_int16_c:
266  extract_array<dods_int16>(dataset(), d_input_format_file, output_format);
267  break;
268 
269  case dods_uint16_c:
270  extract_array<dods_uint16>(dataset(), d_input_format_file, output_format);
271  break;
272 
273  case dods_int32_c:
274  extract_array<dods_int32>(dataset(), d_input_format_file, output_format);
275  break;
276 
277  case dods_uint32_c:
278  extract_array<dods_uint32>(dataset(), d_input_format_file, output_format);
279  break;
280 
281  case dods_float32_c:
282  extract_array<dods_float32>(dataset(), d_input_format_file, output_format);
283  break;
284 
285  case dods_float64_c:
286  extract_array<dods_float64>(dataset(), d_input_format_file, output_format);
287  break;
288 
289  default:
290  throw InternalErr(__FILE__, __LINE__,
291  (string) "FFArray::read: Unsupported array type " + var()->type_name() + ".");
292  }
293 
294  return true;
295 }
296 
297 // This template reads arrays of simple types into the Array object's _buf
298 // member. It returns true if successful, false otherwise.
299 
300 template<class T>
301 bool FFArray::extract_array(const string &ds, const string &if_fmt, const string &o_fmt)
302 {
303  vector<T> d(length());
304  long bytes = read_ff(ds.c_str(), if_fmt.c_str(), o_fmt.c_str(), (char *) &d[0], width());
305 
306  BESDEBUG("ff", "FFArray::extract_array: Read " << bytes << " bytes." << endl);
307 
308  if (bytes == -1) {
309  throw Error(unknown_error, "Could not read values from the dataset.");
310  }
311  else {
312  set_read_p(true);
313  set_value(d, d.size());
314  }
315 
316  return true;
317 }
#define not_used
Definition: config.h:315
virtual BaseType * ptr_duplicate()
Definition: FFArray.cc:57
string dimension_name
Definition: he5dds.tab.cc:190
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
virtual bool read()
Definition: FFArray.cc:235
FFArray(const string &n, const string &d, BaseType *v, const string &iff)
Definition: FFArray.cc:62
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
virtual ~FFArray()
Definition: FFArray.cc:67
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