|
Packit |
a4aae4 |
|
|
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) 2002,2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// (c) COPYRIGHT URI/MIT 1994-1999
|
|
Packit |
a4aae4 |
// Please read the full copyright statement in the file COPYRIGHT_URI.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Authors:
|
|
Packit |
a4aae4 |
// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Class for array variables. The dimensions of the array are stored in the
|
|
Packit |
a4aae4 |
// list SHAPE.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// jhrg 9/6/94
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef _array_h
|
|
Packit |
a4aae4 |
#define _array_h 1
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <string>
|
|
Packit |
a4aae4 |
#include <vector>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef _dods_limits_h
|
|
Packit |
a4aae4 |
#include "dods-limits.h"
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef _vector_h
|
|
Packit |
a4aae4 |
#include "Vector.h"
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
//#include "D4Dimensions.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
class D4Group;
|
|
Packit |
a4aae4 |
class D4Maps;
|
|
Packit |
a4aae4 |
class XMLWriter;
|
|
Packit |
a4aae4 |
class D4Dimension;
|
|
Packit |
a4aae4 |
class D4Dimensions;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
const int DODS_MAX_ARRAY = DODS_INT_MAX;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** This class is used to hold arrays of data. The elements of the array can
|
|
Packit |
a4aae4 |
be simple or compound data types. There is no limit on the number of
|
|
Packit |
a4aae4 |
dimensions an array can have, or on the size of each dimension.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
If desired, the user can give each dimension of an array a name. You can,
|
|
Packit |
a4aae4 |
for example, have a 360x180 array of temperatures, covering the whole
|
|
Packit |
a4aae4 |
globe with one-degree squares. In this case, you could name the first
|
|
Packit |
a4aae4 |
dimension \e Longitude and the second dimension \e Latitude. This can
|
|
Packit |
a4aae4 |
help prevent a great deal of confusion.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
The Array is used as part of the Grid class, where the dimension names
|
|
Packit |
a4aae4 |
are crucial to its structure. The dimension names correspond to \e Map
|
|
Packit |
a4aae4 |
vectors, holding the actual values for that column of the array.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
In DAP4, the Array may be a Coverage or a simple Array. In the former case
|
|
Packit |
a4aae4 |
the Array will have both named dimensions and maps, where the maps (instances
|
|
Packit |
a4aae4 |
of D4Map) are what make the Array a Coverage. Coverages are a generalization
|
|
Packit |
a4aae4 |
of DAP2 Grids.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Each array dimension carries with it its own projection information. The
|
|
Packit |
a4aae4 |
projection information takes the form of three integers: the start, stop,
|
|
Packit |
a4aae4 |
and stride values. This is clearest with an example. Consider a
|
|
Packit |
a4aae4 |
one-dimensional array 10 elements long. If the start value of the
|
|
Packit |
a4aae4 |
dimension constraint is 3, then the constrained array appears to be seven
|
|
Packit |
a4aae4 |
elements long. If the stop value is changed to 7, then the array appears
|
|
Packit |
a4aae4 |
to be five elements long. If the stride is changed to two, the array will
|
|
Packit |
a4aae4 |
appear to be 3 elements long. Array constraints are written as:
|
|
Packit |
a4aae4 |
[start:stride:stop].
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
\verbatim
|
|
Packit |
a4aae4 |
A = [1 2 3 4 5 6 7 8 9 10]
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
A[3::] = [4 5 6 7 8 9 10]
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
A[3::7] = [4 5 6 7 8]
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
A[3:2:7] = [4 6 8]
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
A[0:3:9] = [1 4 7 10]
|
|
Packit |
a4aae4 |
\endverbatim
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@note Arrays use zero-based indexing.
|
|
Packit |
a4aae4 |
@note This class is used for both DAP2 and DAP4.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@brief A multidimensional array of identical data types.
|
|
Packit |
a4aae4 |
@see Grid
|
|
Packit |
a4aae4 |
@see Vector
|
|
Packit |
a4aae4 |
@see dimension */
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
class Array: public Vector
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
/** Information about a dimension. Each Array has one or more dimensions.
|
|
Packit |
a4aae4 |
For each of an Array's dimensions, a corresponding instance of this
|
|
Packit |
a4aae4 |
struct holds the natural size, name, constraint information and
|
|
Packit |
a4aae4 |
constrained size.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@note Instead of using this struct's fields directly, use Array's
|
|
Packit |
a4aae4 |
dimension accessor methods.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@note This struct is public because its type is used in public
|
|
Packit |
a4aae4 |
typedefs. */
|
|
Packit |
a4aae4 |
struct dimension
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
// In DAP2, the name and size of a dimension is stored here, along
|
|
Packit |
a4aae4 |
// with information about any constraint. In DAP4, either the name
|
|
Packit |
a4aae4 |
// and size are stored in the two fields below _or_ the name and
|
|
Packit |
a4aae4 |
// size information comes from a dimension object defined in a
|
|
Packit |
a4aae4 |
// group that is referenced by the 'dim' pointer. Do not free this
|
|
Packit |
a4aae4 |
// pointer; it is shared between the array and the Group where the
|
|
Packit |
a4aae4 |
// Dimension is defined. To keep Array manageable to implement, size
|
|
Packit |
a4aae4 |
// will be set here using the value from 'dim' if it is not null.
|
|
Packit |
a4aae4 |
int size; ///< The unconstrained dimension size.
|
|
Packit |
a4aae4 |
string name; ///< The name of this dimension.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Dimension *dim; ///< If not null, a weak pointer to the D4Dimension
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// when a DMR is printed for a data response, if an array uses shared
|
|
Packit |
a4aae4 |
// dimensions and those sdims have been sliced, make sure to use those
|
|
Packit |
a4aae4 |
// and get the syntax correct. That's what this field does - in every
|
|
Packit |
a4aae4 |
// case the array records the sizes of its dimensions and their slices
|
|
Packit |
a4aae4 |
// regardless of whether they were provided explicitly in a CE or inherited
|
|
Packit |
a4aae4 |
// from a sliced sdim.
|
|
Packit |
a4aae4 |
bool use_sdim_for_slice; ///< Used to control printing the DMR in data responses
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
int start; ///< The constraint start index
|
|
Packit |
a4aae4 |
int stop; ///< The constraint end index
|
|
Packit |
a4aae4 |
int stride; ///< The constraint stride
|
|
Packit |
a4aae4 |
int c_size; ///< Size of dimension once constrained
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
dimension() : size(0), name(""), dim(0), use_sdim_for_slice(false) {
|
|
Packit |
a4aae4 |
// this information changes with each constraint expression
|
|
Packit |
a4aae4 |
start = 0;
|
|
Packit |
a4aae4 |
stop = 0;
|
|
Packit |
a4aae4 |
stride = 1;
|
|
Packit |
a4aae4 |
c_size = size;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
dimension(unsigned long s, string n) : size(s), name(n), dim(0), use_sdim_for_slice(false) {
|
|
Packit |
a4aae4 |
start = 0;
|
|
Packit |
a4aae4 |
stop = size - 1;
|
|
Packit |
a4aae4 |
stride = 1;
|
|
Packit |
a4aae4 |
c_size = size;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
dimension(D4Dimension *d);
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Maps *d_maps;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
private:
|
|
Packit |
a4aae4 |
std::vector<dimension> _shape; // list of dimensions (i.e., the shape)
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void update_dimension_pointers(D4Dimensions *old_dims, D4Dimensions *new_dims);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
friend class ArrayTest;
|
|
Packit |
a4aae4 |
friend class D4Group;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool is_dap2_grid();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
protected:
|
|
Packit |
a4aae4 |
void _duplicate(const Array &a);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
unsigned int print_array(FILE *out, unsigned int index,
|
|
Packit |
a4aae4 |
unsigned int dims, unsigned int shape[]);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
unsigned int print_array(ostream &out, unsigned int index,
|
|
Packit |
a4aae4 |
unsigned int dims, unsigned int shape[]);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
/** A constant iterator used to access the various dimensions of an
|
|
Packit |
a4aae4 |
Array.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@see dim_begin()
|
|
Packit |
a4aae4 |
@see dim_end() */
|
|
Packit |
a4aae4 |
typedef std::vector<dimension>::const_iterator Dim_citer;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** An iterator used to access the various dimensions of an
|
|
Packit |
a4aae4 |
Array. Most of the methods that access various properties of a
|
|
Packit |
a4aae4 |
dimension use an instance of Dim_iter.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@see dim_begin()
|
|
Packit |
a4aae4 |
@see dim_end() */
|
|
Packit |
a4aae4 |
typedef std::vector<dimension>::iterator Dim_iter;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Array(const string &n, BaseType *v, bool is_dap4 = false);
|
|
Packit |
a4aae4 |
Array(const string &n, const string &d, BaseType *v, bool is_dap4 = false);
|
|
Packit |
a4aae4 |
Array(const Array &rhs;;
|
|
Packit |
a4aae4 |
virtual ~Array();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Array &operator=(const Array &rhs;;
|
|
Packit |
a4aae4 |
virtual BaseType *ptr_duplicate();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void transform_to_dap4(D4Group *root, Constructor *container);
|
|
Packit |
a4aae4 |
virtual std::vector<BaseType *> *transform_to_dap2(AttrTable *parent_attr_table);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void add_var(BaseType *v, Part p = nil);
|
|
Packit |
a4aae4 |
void add_var_nocopy(BaseType *v, Part p = nil);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void append_dim(int size, const string &name = "");
|
|
Packit |
a4aae4 |
void append_dim(D4Dimension *dim);
|
|
Packit |
a4aae4 |
void prepend_dim(int size, const string& name = "");
|
|
Packit |
a4aae4 |
void prepend_dim(D4Dimension *dim);
|
|
Packit |
a4aae4 |
void clear_all_dims();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void add_constraint(Dim_iter i, int start, int stride, int stop);
|
|
Packit |
a4aae4 |
virtual void add_constraint(Dim_iter i, D4Dimension *dim);
|
|
Packit |
a4aae4 |
virtual void reset_constraint();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void clear_constraint(); // deprecated
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void update_length(int size = 0); // should be used internally only
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Dim_iter dim_begin() ;
|
|
Packit |
a4aae4 |
Dim_iter dim_end() ;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual int dimension_size(Dim_iter i, bool constrained = false);
|
|
Packit |
a4aae4 |
virtual int dimension_start(Dim_iter i, bool constrained = false);
|
|
Packit |
a4aae4 |
virtual int dimension_stop(Dim_iter i, bool constrained = false);
|
|
Packit |
a4aae4 |
virtual int dimension_stride(Dim_iter i, bool constrained = false);
|
|
Packit |
a4aae4 |
virtual string dimension_name(Dim_iter i);
|
|
Packit |
a4aae4 |
virtual D4Dimension *dimension_D4dim(Dim_iter i);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual unsigned int dimensions(bool constrained = false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual D4Maps *maps();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_dap4(XMLWriter &xml, bool constrained = false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// These are all DAP2 output methods
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_decl(ostream &out, string space = " ",
|
|
Packit |
a4aae4 |
bool print_semi = true,
|
|
Packit |
a4aae4 |
bool constraint_info = false,
|
|
Packit |
a4aae4 |
bool constrained = false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_xml(ostream &out, string space = " ",
|
|
Packit |
a4aae4 |
bool constrained = false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_xml_writer(XMLWriter &xml, bool constrained = false);
|
|
Packit |
a4aae4 |
virtual void print_xml_writer_core(XMLWriter &out, bool constrained, string tag);
|
|
Packit |
a4aae4 |
virtual void print_as_map_xml_writer(XMLWriter &xml, bool constrained);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_xml_core(FILE *out, string space, bool constrained, string tag);
|
|
Packit |
a4aae4 |
virtual void print_xml_core(ostream &out, string space, bool constrained, string tag);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// not used (?)
|
|
Packit |
a4aae4 |
virtual void print_as_map_xml(ostream &out, string space = " ",
|
|
Packit |
a4aae4 |
bool constrained = false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_val(ostream &out, string space = "",
|
|
Packit |
a4aae4 |
bool print_decl_p = true);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_xml(FILE *out, string space = " ",
|
|
Packit |
a4aae4 |
bool constrained = false);
|
|
Packit |
a4aae4 |
virtual void print_as_map_xml(FILE *out, string space = " ",
|
|
Packit |
a4aae4 |
bool constrained = false);
|
|
Packit |
a4aae4 |
virtual void print_val(FILE *out, string space = "",
|
|
Packit |
a4aae4 |
bool print_decl_p = true);
|
|
Packit |
a4aae4 |
virtual void print_decl(FILE *out, string space = " ",
|
|
Packit |
a4aae4 |
bool print_semi = true,
|
|
Packit |
a4aae4 |
bool constraint_info = false,
|
|
Packit |
a4aae4 |
bool constrained = false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual bool check_semantics(string &msg, bool all = false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void dump(ostream &strm) const ;
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#endif // _array_h
|