bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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 <libdap/BaseType.h>
35#include <libdap/Byte.h>
36#include <libdap/Int16.h>
37#include <libdap/Int32.h>
38#include <libdap/UInt16.h>
39#include <libdap/UInt32.h>
40#include <libdap/Float32.h>
41#include <libdap/Float64.h>
42#include <libdap/Str.h>
43#include <libdap/Url.h>
44
45#include <libdap/DDS.h>
46#include <libdap/ConstraintEvaluator.h>
47#include <libdap/Marshaller.h>
48//#include <libdap/UnMarshaller.h>
49#include <libdap/debug.h>
50
51#include "BESIndent.h"
52#include "CachedSequence.h"
53
54using namespace std;
55using namespace libdap;
56
57// namespace bes {
58
59void 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
141
142bool 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
199bool 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
216void CachedSequence::intern_data(ConstraintEvaluator &eval, DDS &dds)
217{
218 d_value_index = 0;
219
220 Sequence::intern_data(eval, dds);
221}
222
231void
232CachedSequence::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
virtual void intern_data(libdap::ConstraintEvaluator &eval, libdap::DDS &dds)
Specialization that resets CachedSequence's 'value index' state variable.
virtual void dump(ostream &strm) const
dumps information about this object
virtual bool read_row(int row, libdap::DDS &dds, libdap::ConstraintEvaluator &eval, bool ce_eval)
Read row number row of the Sequence.
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.