|
Packit |
a4aae4 |
// -*- mode: c++; c-basic-offset:4 -*-
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
|
|
Packit |
a4aae4 |
// Access Protocol.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Copyright (c) 2013 OPeNDAP, Inc.
|
|
Packit |
a4aae4 |
// Author: James Gallagher <jgallagher@opendap.org>
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is free software; you can redistribute it and/or
|
|
Packit |
a4aae4 |
// modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License as published by the Free Software Foundation; either
|
|
Packit |
a4aae4 |
// version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is distributed in the hope that it will be useful,
|
|
Packit |
a4aae4 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a4aae4 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a4aae4 |
// Lesser General Public License for more details.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License along with this library; if not, write to the Free Software
|
|
Packit |
a4aae4 |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef D4DIMENSIONS_H_
|
|
Packit |
a4aae4 |
#define D4DIMENSIONS_H_
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <string>
|
|
Packit |
a4aae4 |
#include <vector>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// #include "XMLWriter.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
using namespace std;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
class D4Group;
|
|
Packit |
a4aae4 |
class D4Dimensions;
|
|
Packit |
a4aae4 |
class XMLWriter;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
class D4Dimension {
|
|
Packit |
a4aae4 |
string d_name;
|
|
Packit |
a4aae4 |
unsigned long d_size;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Dimensions *d_parent; // This is used to get the Dimensions and then the Group object
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool d_constrained;
|
|
Packit |
a4aae4 |
unsigned long long d_c_start, d_c_stride, d_c_stop;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool d_used_by_projected_var;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
D4Dimension() : d_name(""), d_size(0), d_parent(0), d_constrained(false), d_c_start(0), d_c_stride(0),
|
|
Packit |
a4aae4 |
d_c_stop(0), d_used_by_projected_var(false) {}
|
|
Packit |
a4aae4 |
D4Dimension(const string &name, unsigned long size, D4Dimensions *d = 0) : d_name(name), d_size(size), d_parent(d),
|
|
Packit |
a4aae4 |
d_constrained(false), d_c_start(0), d_c_stride(0), d_c_stop(0), d_used_by_projected_var(false) {}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
string name() const {return d_name;}
|
|
Packit |
a4aae4 |
void set_name(const string &name) { d_name = name; }
|
|
Packit |
a4aae4 |
string fully_qualified_name() const;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
unsigned long size() const { return d_size; }
|
|
Packit |
a4aae4 |
void set_size(unsigned long size) { d_size = size; }
|
|
Packit |
a4aae4 |
// Because we build these in the XML parser and it's all text...
|
|
Packit |
a4aae4 |
void set_size(const string &size);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Dimensions *parent() const { return d_parent; }
|
|
Packit |
a4aae4 |
void set_parent(D4Dimensions *d) { d_parent = d; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool constrained() const { return d_constrained; }
|
|
Packit |
a4aae4 |
unsigned long long c_start() const { return d_c_start; }
|
|
Packit |
a4aae4 |
unsigned long long c_stride() const { return d_c_stride; }
|
|
Packit |
a4aae4 |
unsigned long long c_stop() const { return d_c_stop; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool used_by_projected_var() const { return d_used_by_projected_var; }
|
|
Packit |
a4aae4 |
void set_used_by_projected_var(bool state) { d_used_by_projected_var = state; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Set this Shared Diemension's constraint. While an Array Dimension object uses a
|
|
Packit |
a4aae4 |
* stop value of -1 to indicate the end of the dimension, this method does not support
|
|
Packit |
a4aae4 |
* that; the caller will have to sort out the correct end value for 'stop'.
|
|
Packit |
a4aae4 |
* @param start Starting index (zero-based)
|
|
Packit |
a4aae4 |
* @param stride The stride for the slice
|
|
Packit |
a4aae4 |
* @param stop The stopping index (never greater than size -1)
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void set_constraint(unsigned long long start, unsigned long long stride, unsigned long long stop) {
|
|
Packit |
a4aae4 |
d_c_start = start;
|
|
Packit |
a4aae4 |
d_c_stride = stride;
|
|
Packit |
a4aae4 |
d_c_stop = stop;
|
|
Packit |
a4aae4 |
d_constrained = true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void print_dap4(XMLWriter &xml) const;
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* This class holds information about dimensions. This can be used to store
|
|
Packit |
a4aae4 |
* actual dimension information in an instance of BaseType and it can be
|
|
Packit |
a4aae4 |
* used to store the definition of a dimension in an instance of Group.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
class D4Dimensions {
|
|
Packit |
a4aae4 |
vector<D4Dimension*> d_dims;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Group *d_parent; // the group that holds this set of D4Dimensions; weak pointer, don't delete
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
protected:
|
|
Packit |
a4aae4 |
// Note Code in Array depends on the order of these 'new' dimensions
|
|
Packit |
a4aae4 |
// matching the 'old' dimensions they are derived from. See
|
|
Packit |
a4aae4 |
// Array::update_dimension_pointers. jhrg 8/25/14
|
|
Packit |
a4aae4 |
void m_duplicate(const D4Dimensions &rhs) {
|
|
Packit |
a4aae4 |
D4DimensionsCIter i = rhs.d_dims.begin();
|
|
Packit |
a4aae4 |
while (i != rhs.d_dims.end()) {
|
|
Packit |
a4aae4 |
d_dims.push_back(new D4Dimension(**i++)); // deep copy
|
|
Packit |
a4aae4 |
d_dims.back()->set_parent(this); // Set the Dimension's parent
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
d_parent = rhs.d_parent;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
/// Iterator used for D4Dimensions
|
|
Packit |
a4aae4 |
typedef vector<D4Dimension*>::iterator D4DimensionsIter;
|
|
Packit |
a4aae4 |
typedef vector<D4Dimension*>::const_iterator D4DimensionsCIter;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Dimensions() : d_parent(0) {}
|
|
Packit |
a4aae4 |
D4Dimensions(D4Group *g) : d_parent(g) {}
|
|
Packit |
a4aae4 |
D4Dimensions(const D4Dimensions &rhs) : d_parent(0) { m_duplicate(rhs); }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual ~D4Dimensions() {
|
|
Packit |
a4aae4 |
D4DimensionsIter i = d_dims.begin();
|
|
Packit |
a4aae4 |
while (i != d_dims.end())
|
|
Packit |
a4aae4 |
delete *i++;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Dimensions &operator=(const D4Dimensions &rhs) {
|
|
Packit |
a4aae4 |
if (this == &rhs) return *this;
|
|
Packit |
a4aae4 |
m_duplicate(rhs);
|
|
Packit |
a4aae4 |
return *this;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/// Does this D4Dimensions object actually have dimensions?
|
|
Packit |
a4aae4 |
bool empty() const { return d_dims.empty(); }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Group *parent() const { return d_parent;}
|
|
Packit |
a4aae4 |
void set_parent(D4Group *g) { d_parent = g; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Append a new dimension.
|
|
Packit |
a4aae4 |
* In DAP4 dimensions are either of a known size or are varying. For
|
|
Packit |
a4aae4 |
* fixed-size dimensions, the value of varying should be false. For varying
|
|
Packit |
a4aae4 |
* dimensions the value of 'size' will be ignored - any value can be used
|
|
Packit |
a4aae4 |
* when called this method.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param dim Pointer to the D4Dimension object to add; deep copy
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void add_dim(D4Dimension *dim) { add_dim_nocopy(new D4Dimension(*dim)); }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Append a new dimension.
|
|
Packit |
a4aae4 |
* @param dim Pointer to the D4Dimension object to add; copies the pointer
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void add_dim_nocopy(D4Dimension *dim) { dim->set_parent(this); d_dims.push_back(dim); }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/// Get an iterator to the start of the dimensions
|
|
Packit |
a4aae4 |
D4DimensionsIter dim_begin() { return d_dims.begin(); }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/// Get an iterator to the end of the dimensions
|
|
Packit |
a4aae4 |
D4DimensionsIter dim_end() { return d_dims.end(); }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Dimension *find_dim(const string &name);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Insert a dimension.
|
|
Packit |
a4aae4 |
* Insert a dimension before the position specified by the iterator.
|
|
Packit |
a4aae4 |
* @note Calling this method invalidates all iterators that reference this
|
|
Packit |
a4aae4 |
* D4Dimension object.
|
|
Packit |
a4aae4 |
* @param dim Inserted before i; deep copy
|
|
Packit |
a4aae4 |
* @param i iterator
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void insert_dim(D4Dimension *dim, D4DimensionsIter i) {
|
|
Packit |
a4aae4 |
insert_dim_nocopy(new D4Dimension(*dim), i);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Insert a dimension.
|
|
Packit |
a4aae4 |
* @param dim Inserted before i; pointer copy
|
|
Packit |
a4aae4 |
* @param i iterator
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void insert_dim_nocopy(D4Dimension *dim, D4DimensionsIter i) {
|
|
Packit |
a4aae4 |
dim->set_parent(this);
|
|
Packit |
a4aae4 |
d_dims.insert(i, dim);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void print_dap4(XMLWriter &xml, bool constrained = false) const;
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} /* namespace libdap */
|
|
Packit |
a4aae4 |
#endif /* D4DIMENSIONS_H_ */
|