Blame Array.h

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