bes  Updated for version 3.20.6
CachedSequence.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2015 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public 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 #include "config.h"
26 
27 //#define DODS_DEBUG
28 
29 #include <algorithm>
30 #include <string>
31 #include <sstream>
32 #include <cassert>
33 
34 #include <BaseType.h>
35 #include <Byte.h>
36 #include <Int16.h>
37 #include <Int32.h>
38 #include <UInt16.h>
39 #include <UInt32.h>
40 #include <Float32.h>
41 #include <Float64.h>
42 #include <Str.h>
43 #include <Url.h>
44 
45 #include <DDS.h>
46 #include <ConstraintEvaluator.h>
47 #include <Marshaller.h>
48 //#include <UnMarshaller.h>
49 #include <debug.h>
50 
51 #include "BESIndent.h"
52 #include "CachedSequence.h"
53 
54 using namespace std;
55 using namespace libdap;
56 
57 // namespace bes {
58 
59 void CachedSequence::load_prototypes_with_values(BaseTypeRow &btr, bool safe)
60 {
61  // For each of the prototype variables in the Sequence, load it
62  // with a values from the BaseType* vector. The order should match.
63  // Test the type, but assume if that matches, the value is correct
64  // for the variable.
65  Vars_iter i = d_vars.begin(), e = d_vars.end();
66  for (BaseTypeRow::iterator vi = btr.begin(), ve = btr.end(); vi != ve; ++vi) {
67 
68  if (safe && (i == e || ((*i)->type() != (*vi)->type())))
69  throw InternalErr(__FILE__, __LINE__, "Expected number and types to match when loading values.");
70 
71  // Ugly... but faster than the generic code that allocates storage for each scalar?
72  switch ((*i)->type()) {
73  case dods_byte_c:
74  static_cast<Byte*>(*i++)->set_value(static_cast<Byte*>(*vi)->value());
75  break;
76  case dods_int16_c:
77  static_cast<Int16*>(*i++)->set_value(static_cast<Int16*>((*vi))->value());
78  break;
79  case dods_int32_c:
80  static_cast<Int32*>(*i++)->set_value(static_cast<Int32*>((*vi))->value());
81  break;
82  case dods_uint16_c:
83  static_cast<UInt16*>(*i++)->set_value(static_cast<UInt16*>((*vi))->value());
84  break;
85  case dods_uint32_c:
86  static_cast<UInt32*>(*i++)->set_value(static_cast<UInt32*>((*vi))->value());
87  break;
88  case dods_float32_c:
89  static_cast<Float32*>(*i++)->set_value(static_cast<Float32*>((*vi))->value());
90  break;
91  case dods_float64_c:
92  static_cast<Float64*>(*i++)->set_value(static_cast<Float64*>((*vi))->value());
93  break;
94  case dods_str_c:
95  static_cast<Str*>(*i++)->set_value(static_cast<Str*>((*vi))->value());
96  break;
97  case dods_url_c:
98  static_cast<Url*>(*i++)->set_value(static_cast<Url*>((*vi))->value());
99  break;
100 
101  case dods_sequence_c:
102  if (vi + 1 != ve)
103  throw InternalErr(__FILE__, __LINE__, "Expected nested sequence to be the last variable.");
104  break;
105 
106  default:
107  throw InternalErr(__FILE__, __LINE__, "Expected a scalar (or nested sequence) when loading values.");
108  }
109  }
110 }
111 
112 // Public member functions
113 
142 bool CachedSequence::read_row(int row, DDS &dds, ConstraintEvaluator &eval, bool ce_eval)
143 {
144  DBGN(cerr << __PRETTY_FUNCTION__ << " name: " << name() << ", row number " << row << ", current row " << get_row_number() << endl);
145 
146  // get_row_number() returns the current row number for the sequence. This
147  // means the number of the current row that satisfies the selection constraint.
148  // Thus, if 20 rows have been res (d_value_index == 19 then) but only 5
149  // satisfy the selection, get_row_number() will return 4 (the number of
150  // the current row). We alwasy have to be asking for a row greater then
151  // the current row - it is not possible to back-up when reading a Sequences's
152  // values.
153  assert(row > get_row_number());
154 
155  while (row > get_row_number()) {
156  // Read the next row of values. d_value_index is reset when the code
157  // first runs serialize() or intern_data(). This enables the code here
158  // to mimic the 'read the next set of values' behavior of the parent
159  // class.
160  BaseTypeRow *btr_ptr = row_value(d_value_index++);
161 
162  // This corresponds to the 'return false on EOF' behavior of Sequence:read_row.
163  // When the Sequence::read() method returns 'true' at EOF (the last value has
164  // been read). This works because the row_value() method above returns 0 (NULL)
165  // when the code tries to read past the end of the vector or BaseTypeRow*s.
166  if (!btr_ptr) return false;
167 
168  // Load the values into the variables
169 #ifdef NDEBUG
170  load_prototypes_with_values(*btr_ptr, false);
171 #else
172  load_prototypes_with_values(*btr_ptr, true);
173 #endif
174  if (!ce_eval) {
175  increment_row_number(1);
176  return true;
177  }
178  else if (ce_eval && eval.eval_selection(dds, dataset())) {
179  increment_row_number(1);
180  return true;
181  }
182  }
183 
184  return false;
185 }
186 
199 bool CachedSequence::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval)
200 {
201  // Reset the index to the parent's value field's index
202  d_value_index = 0;
203 
204  return Sequence::serialize(eval, dds, m, ce_eval);
205 }
206 
216 void CachedSequence::intern_data(ConstraintEvaluator &eval, DDS &dds)
217 {
218  d_value_index = 0;
219 
220  Sequence::intern_data(eval, dds);
221 }
222 
231 void
232 CachedSequence::dump(ostream &strm) const
233 {
234  strm << BESIndent::LMarg << "CachedSequence::dump - (" << (void *)this << ")" << endl ;
235  BESIndent::Indent() ;
236  Sequence::dump(strm) ;
237  BESIndent::UnIndent() ;
238 }
239 
240 // } // namespace bes
241 
CachedSequence::dump
virtual void dump(ostream &strm) const
dumps information about this object
Definition: CachedSequence.cc:232
libdap
Definition: BESDapFunctionResponseCache.h:35
CachedSequence::serialize
virtual bool serialize(libdap::ConstraintEvaluator &eval, libdap::DDS &dds, libdap::Marshaller &m, bool ce_eval=true)
Specialization that resets CachedSequence's 'value index' state variable.
Definition: CachedSequence.cc:199
CachedSequence::read_row
virtual bool read_row(int row, libdap::DDS &dds, libdap::ConstraintEvaluator &eval, bool ce_eval)
Read row number row of the Sequence.
Definition: CachedSequence.cc:142
CachedSequence::intern_data
virtual void intern_data(libdap::ConstraintEvaluator &eval, libdap::DDS &dds)
Specialization that resets CachedSequence's 'value index' state variable.
Definition: CachedSequence.cc:216