bes  Updated for version 3.19.1
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 "CachedSequence.h"
52 
53 using namespace std;
54 using namespace libdap;
55 
56 // namespace bes {
57 
58 void CachedSequence::load_prototypes_with_values(BaseTypeRow &btr, bool safe)
59 {
60  // For each of the prototype variables in the Sequence, load it
61  // with a values from the BaseType* vector. The order should match.
62  // Test the type, but assume if that matches, the value is correct
63  // for the variable.
64  Vars_iter i = d_vars.begin(), e = d_vars.end();
65  for (BaseTypeRow::iterator vi = btr.begin(), ve = btr.end(); vi != ve; ++vi) {
66 
67  if (safe && (i == e || ((*i)->type() != (*vi)->type())))
68  throw InternalErr(__FILE__, __LINE__, "Expected number and types to match when loading values.");
69 
70  // Ugly... but faster than the generic code that allocates storage for each scalar?
71  switch ((*i)->type()) {
72  case dods_byte_c:
73  static_cast<Byte*>(*i++)->set_value(static_cast<Byte*>(*vi)->value());
74  break;
75  case dods_int16_c:
76  static_cast<Int16*>(*i++)->set_value(static_cast<Int16*>((*vi))->value());
77  break;
78  case dods_int32_c:
79  static_cast<Int32*>(*i++)->set_value(static_cast<Int32*>((*vi))->value());
80  break;
81  case dods_uint16_c:
82  static_cast<UInt16*>(*i++)->set_value(static_cast<UInt16*>((*vi))->value());
83  break;
84  case dods_uint32_c:
85  static_cast<UInt32*>(*i++)->set_value(static_cast<UInt32*>((*vi))->value());
86  break;
87  case dods_float32_c:
88  static_cast<Float32*>(*i++)->set_value(static_cast<Float32*>((*vi))->value());
89  break;
90  case dods_float64_c:
91  static_cast<Float64*>(*i++)->set_value(static_cast<Float64*>((*vi))->value());
92  break;
93  case dods_str_c:
94  static_cast<Str*>(*i++)->set_value(static_cast<Str*>((*vi))->value());
95  break;
96  case dods_url_c:
97  static_cast<Url*>(*i++)->set_value(static_cast<Url*>((*vi))->value());
98  break;
99 
100  case dods_sequence_c:
101  if (vi + 1 != ve)
102  throw InternalErr(__FILE__, __LINE__, "Expected nested sequence to be the last variable.");
103  break;
104 
105  default:
106  throw InternalErr(__FILE__, __LINE__, "Expected a scalar (or nested sequence) when loading values.");
107  }
108  }
109 }
110 
111 // Public member functions
112 
141 bool CachedSequence::read_row(int row, DDS &dds, ConstraintEvaluator &eval, bool ce_eval)
142 {
143  DBGN(cerr << __PRETTY_FUNCTION__ << " name: " << name() << ", row number " << row << ", current row " << get_row_number() << endl);
144 
145  // get_row_number() returns the current row number for the sequence. This
146  // means the number of the current row that satisfies the selection constraint.
147  // Thus, if 20 rows have been res (d_value_index == 19 then) but only 5
148  // satisfy the selection, get_row_number() will return 4 (the number of
149  // the current row). We alwasy have to be asking for a row greater then
150  // the current row - it is not possible to back-up when reading a Sequences's
151  // values.
152  assert(row > get_row_number());
153 
154  while (row > get_row_number()) {
155  // Read the next row of values. d_value_index is reset when the code
156  // first runs serialize() or intern_data(). This enables the code here
157  // to mimic the 'read the next set of values' behavior of the parent
158  // class.
159  BaseTypeRow *btr_ptr = row_value(d_value_index++);
160 
161  // This corresponds to the 'return false on EOF' behavior of Sequence:read_row.
162  // When the Sequence::read() method returns 'true' at EOF (the last value has
163  // been read). This works because the row_value() method above returns 0 (NULL)
164  // when the code tries to read past the end of the vector or BaseTypeRow*s.
165  if (!btr_ptr) return false;
166 
167  // Load the values into the variables
168 #ifdef NDEBUG
169  load_prototypes_with_values(*btr_ptr, false);
170 #else
171  load_prototypes_with_values(*btr_ptr, true);
172 #endif
173  if (!ce_eval) {
174  increment_row_number(1);
175  return true;
176  }
177  else if (ce_eval && eval.eval_selection(dds, dataset())) {
178  increment_row_number(1);
179  return true;
180  }
181  }
182 
183  return false;
184 }
185 
198 bool CachedSequence::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval)
199 {
200  // Reset the index to the parent's value field's index
201  d_value_index = 0;
202 
203  return Sequence::serialize(eval, dds, m, ce_eval);
204 }
205 
215 void CachedSequence::intern_data(ConstraintEvaluator &eval, DDS &dds)
216 {
217  d_value_index = 0;
218 
219  Sequence::intern_data(eval, dds);
220 }
221 
230 void
231 CachedSequence::dump(ostream &strm) const
232 {
233  strm << DapIndent::LMarg << "CachedSequence::dump - (" << (void *)this << ")" << endl ;
234  DapIndent::Indent() ;
235  Sequence::dump(strm) ;
236  DapIndent::UnIndent() ;
237 }
238 
239 // } // namespace bes
240 
virtual bool read_row(int row, libdap::DDS &dds, libdap::ConstraintEvaluator &eval, bool ce_eval)
Read row number row of the Sequence.
STL namespace.
virtual void intern_data(libdap::ConstraintEvaluator &eval, libdap::DDS &dds)
Specialization that resets CachedSequence&#39;s &#39;value index&#39; state variable.
virtual void dump(ostream &strm) const
dumps information about this object
virtual bool serialize(libdap::ConstraintEvaluator &eval, libdap::DDS &dds, libdap::Marshaller &m, bool ce_eval=true)
Specialization that resets CachedSequence&#39;s &#39;value index&#39; state variable.