OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
NCMLBaseArray.cc
Go to the documentation of this file.
1 // This file is part of the "NcML Module" project, a BES module designed
3 // to allow NcML files to be used to be used as a wrapper to add
4 // AIS to existing datasets of any format.
5 //
6 // Copyright (c) 2009 OPeNDAP, Inc.
7 // Author: Michael Johnson <m.johnson@opendap.org>
8 //
9 // For more information, please also see the main website: http://opendap.org/
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // Please see the files COPYING and COPYRIGHT for more information on the GLPL.
26 //
27 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
29 
30 #include <BaseType.h>
31 #include "MyBaseTypeFactory.h"
32 #include "NCMLBaseArray.h"
33 #include "NCMLDebug.h"
34 #include "Shape.h"
35 
36 namespace ncml_module
37 {
38 
52  auto_ptr< NCMLBaseArray >
53  NCMLBaseArray::createFromArray(const libdap::Array& protoC)
54  {
55  // The const in the signature means semantic const. We promise not to change protoC,
56  // but need a non-const reference to make calls to it, unfortunately.
57  libdap::Array& proto = const_cast<libdap::Array&>(protoC);
58 
59  BESDEBUG("ncml", "NCMLBaseArray::createFromArray(): Converting prototype Array name=" + proto.name() + " into an NCMLArray..." << endl);
60 
61  BaseType* pTemplate = proto.var();
62  NCML_ASSERT_MSG(pTemplate, "NCMLArray::createFromArray(): got NULL template BaseType var() for proto name=" + proto.name());
63 
64  // Factory up and test result
65  string ncmlArrayType = "Array<" + pTemplate->type_name() + ">";
66  auto_ptr<libdap::BaseType> pNewBT = MyBaseTypeFactory::makeVariable(ncmlArrayType, proto.name());
67  VALID_PTR(pNewBT.get());
68  auto_ptr< NCMLBaseArray > pNewArray = auto_ptr< NCMLBaseArray > (dynamic_cast< NCMLBaseArray*>(pNewBT.release()));
69  VALID_PTR(pNewArray.get());
70 
71  // Finally, we should be able to copy the data now.
72  pNewArray->copyDataFrom(proto);
73 
74  return pNewArray; // relinquish
75  }
76 
78  : Array("", 0)
79  ,_noConstraints(0)
80  , _currentConstraints(0)
81  {
82 
83  }
84 
85  NCMLBaseArray::NCMLBaseArray(const std::string& name)
86  : Array(name, 0)
87  , _noConstraints(0)
88  , _currentConstraints(0)
89  {
90  }
91 
93  : Array(proto)
94  , _noConstraints(0)
95  , _currentConstraints(0)
96  {
97  copyLocalRepFrom(proto);
98  }
99 
101  {
102  destroy(); // local data
103  }
104 
107  {
108  if (&rhs == this)
109  {
110  return *this;
111  }
112 
113  // Call the super assignment
114  Array::operator=(rhs);
115 
116  // Copy local private rep
117  copyLocalRepFrom(rhs);
118 
119  return *this;
120  }
121 
122  bool
124  {
125  // If we haven't computed constrained buffer yet, or they changed,
126  // we must call return false to force read() to be called again.
128  }
129 
130  void
131  NCMLBaseArray::set_read_p(bool /* state */)
132  {
133  // Just drop it on the floor we compute it
134  // Array::set_read_p(state);
135  }
136 
137  bool
139  {
140  BESDEBUG("ncml", "NCMLArray::read() called!" << endl);
141 
142  // If first call, cache the full dataset. Throw if there's an error with this.
144 
145  // If _currentConstraints is null or different than current Array dimensions,
146  // compute the constrained data buffer from the local data cache and the current Array dimensions.
148  {
149  // Enumerate and set the constrained values into Vector super..
151 
152  // Copy the constraints we used to generate these values
153  // so we know if we need to redo this in another call to read() or not.
155  }
156  return true;
157  }
158 
159  Shape
161  {
162  // make the Shape for our superclass Array
163  return Shape(*this);
164  }
165 
166  bool
168  {
169  Shape superShape = getSuperShape();
170  return superShape.isConstrained();
171  }
172 
173  bool
175  {
176  // If there's none, then they've changed by definition.
177  if (!_currentConstraints)
178  {
179  return true;
180  }
181  else // compare the current values to those currently in our Array slice
182  {
183  return ((*_currentConstraints) != getSuperShape());
184  }
185  }
186 
187  void
189  {
190  // If got some already, blow them away...
192  {
194  }
195  _currentConstraints = new Shape(*this);
196  //BESDEBUG("ncml", "NCMLBaseArray: Cached current constraints:" << (*_currentConstraints) << endl);
197  }
198 
199 
200  void
202  {
203  // We already got it...
204  if (_noConstraints)
205  {
206  return;
207  }
208 
209  // Copy from the super Array's current dimensions and force values to define an unconstrained space.
210  _noConstraints = new Shape(*this);
212 
213  //BESDEBUG("ncml", "NCMLBaseArray: cached unconstrained shape=" << (*_noConstraints) << endl);
214  }
215 
216  void
218  {
219  // We had better have a template or else the width() calls will be wrong.
220  NCML_ASSERT(var());
221 
222  // First call, make sure we grab unconstrained state.
223  if (!_noConstraints)
224  {
226  }
227 
228  // Subclasses will handle this
230  }
231 
232 
233  void
234  NCMLBaseArray::copyLocalRepFrom(const NCMLBaseArray& proto)
235  {
236  // Avoid unnecessary finagling
237  if (&proto == this)
238  {
239  return;
240  }
241 
242  // Blow away any old data before copying new
243  destroy();
244 
245  if (proto._noConstraints)
246  {
247  _noConstraints = new Shape(*(proto._noConstraints));
248  }
249 
250  if (proto._currentConstraints)
251  {
252  _currentConstraints = new Shape(*(proto._currentConstraints));
253  }
254  }
255 
257  void
258  NCMLBaseArray::destroy() throw ()
259  {
260  delete _noConstraints; _noConstraints=0;
262  }
263 
264 }
virtual Shape getSuperShape() const
Get the current dimensions of our superclass Array as a Shape object.
virtual bool read()
If there are no constraints and this is the first call to read(), we will do nothing, assuming the sueprclasses have everything under control.
virtual bool read_p()
Override to return false if we have uncomputed constraints and only true if the current constraints m...
virtual bool isConstrained() const
Return whether the superclass Array has been constrained along any dimensions.
#define NCML_ASSERT(cond)
Definition: NCMLDebug.h:80
An abstract superclass for NCMLArray that handles the non-parameterized functionality and allows u...
virtual void cacheSuperclassStateIfNeeded()
Required by subclasses to copy the original data values locally.
#define NCML_ASSERT_MSG(cond, msg)
Definition: NCMLDebug.h:83
void setToUnconstrained()
Go through and set all the values to be the unconstrained values.
Definition: Shape.cc:119
A wrapper class for a vector of Array::dimension structs.
Definition: Shape.h:59
virtual void cacheUnconstrainedDimensions()
NCMLBaseArray & operator=(const NCMLBaseArray &rhs)
bool isConstrained() const
Are there constraints on the dimension?
Definition: Shape.cc:103
virtual void cacheValuesIfNeeded()=0
Must copy the unconstrained current values of the proper type within Vector into the local instance...
static std::auto_ptr< libdap::BaseType > makeVariable(const libdap::Type &type, const string &name)
Return a new variable of the given type.
virtual void set_read_p(bool state)
Override to disable setting of this flag.
#define VALID_PTR(ptr)
Definition: NCMLDebug.h:88
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
virtual void createAndSetConstrainedValueBuffer()=0
Given the current Shape of the Array, generate the constrained value buffer and set it into the Vecto...
virtual void cacheCurrentConstraints()
Store the current super Array shape as the current constraints so we remember.
virtual bool haveConstraintsChangedSinceLastRead() const
Return whether the constraints used to create Vector._buf for the last read() have changed...
static auto_ptr< NCMLBaseArray > createFromArray(const libdap::Array &proto)
Make a new NCMLArray from the given proto, using the Array interface.