|
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 _d4sequence_h
|
|
Packit |
a4aae4 |
#define _d4sequence_h 1
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "Constructor.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// DAP2 Sequence supported subsetting using the array notation. This might
|
|
Packit |
a4aae4 |
// be introduced into DAP4 later on.
|
|
Packit |
a4aae4 |
#define INDEX_SUBSETTING 0
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
class Crc32;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
class BaseType;
|
|
Packit |
a4aae4 |
class D4FilterClauseList;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** The type BaseTypeRow is used to store single rows of values in an
|
|
Packit |
a4aae4 |
instance of D4Sequence. Values are stored in instances of BaseType. */
|
|
Packit |
a4aae4 |
typedef vector<BaseType *> D4SeqRow;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** This type holds all of the values of a D4Sequence. */
|
|
Packit |
a4aae4 |
typedef vector<D4SeqRow *> D4SeqValues;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** The type BaseTypeRow is used to store single rows of values in an
|
|
Packit |
a4aae4 |
instance of Sequence. Values are stored in instances of BaseType. */
|
|
Packit |
a4aae4 |
typedef vector<BaseType *> BaseTypeRow;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** This type holds all of the values of a Sequence. */
|
|
Packit |
a4aae4 |
typedef vector<BaseTypeRow *> SequenceValues;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** This is the interface for the class D4Sequence. A sequence contains
|
|
Packit |
a4aae4 |
a single set of variables, all at the same lexical level just like
|
|
Packit |
a4aae4 |
a Structure. Like a Structure, a D4Sequence may contain other
|
|
Packit |
a4aae4 |
compound types, including other D4Sequences. Unlike a Structure, a
|
|
Packit |
a4aae4 |
D4Sequence defines a pattern that is repeated N times for a sequence
|
|
Packit |
a4aae4 |
of N elements. It is useful to think of a D4Sequence as representing
|
|
Packit |
a4aae4 |
a table of values (like a relational database), with each row of
|
|
Packit |
a4aae4 |
the table corresponding to a D4Sequence ``instance.'' (This usage
|
|
Packit |
a4aae4 |
can be confusing, since ``instance'' also refers to a particular
|
|
Packit |
a4aae4 |
item of class D4Sequence.) For example:
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Sequence {
|
|
Packit |
a4aae4 |
String name;
|
|
Packit |
a4aae4 |
Int32 age;
|
|
Packit |
a4aae4 |
} person;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
This represents a Sequence of ``person'' records, each instance of
|
|
Packit |
a4aae4 |
which contains a name and an age:
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Fred 34
|
|
Packit |
a4aae4 |
Ralph 23
|
|
Packit |
a4aae4 |
Andrea 29
|
|
Packit |
a4aae4 |
...
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
A D4Sequence can be arbitrarily long, which is to say that its
|
|
Packit |
a4aae4 |
length is not part of its declaration. A D4Sequence can contain
|
|
Packit |
a4aae4 |
other D4Sequences:
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Sequence {
|
|
Packit |
a4aae4 |
String name;
|
|
Packit |
a4aae4 |
Int32 age;
|
|
Packit |
a4aae4 |
D4Sequence {
|
|
Packit |
a4aae4 |
String friend;
|
|
Packit |
a4aae4 |
} friend_list;
|
|
Packit |
a4aae4 |
} person;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Fred 34 Norman
|
|
Packit |
a4aae4 |
Andrea
|
|
Packit |
a4aae4 |
Ralph
|
|
Packit |
a4aae4 |
Lisa
|
|
Packit |
a4aae4 |
Ralph 23 Norman
|
|
Packit |
a4aae4 |
Andrea
|
|
Packit |
a4aae4 |
Lisa
|
|
Packit |
a4aae4 |
Marth
|
|
Packit |
a4aae4 |
Throckmorton
|
|
Packit |
a4aae4 |
Helga
|
|
Packit |
a4aae4 |
Millicent
|
|
Packit |
a4aae4 |
Andrea 29 Ralph
|
|
Packit |
a4aae4 |
Natasha
|
|
Packit |
a4aae4 |
Norman
|
|
Packit |
a4aae4 |
... .. ...
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Internally, the D4Sequence is represented by a vector of vectors. The
|
|
Packit |
a4aae4 |
members of the outer vector are the members of the D4Sequence. This
|
|
Packit |
a4aae4 |
includes the nested D4Sequences, as in the above example.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Because the length of a D4Sequence is indeterminate, there are
|
|
Packit |
a4aae4 |
changes to the behavior of the functions to read this class of
|
|
Packit |
a4aae4 |
data. The <tt>read()</tt> function for D4Sequence must be written so that
|
|
Packit |
a4aae4 |
successive calls return values for successive rows of the D4Sequence.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Similar to a C structure, you refer to members of D4Sequence
|
|
Packit |
a4aae4 |
elements with a ``.'' notation. For example, if the D4Sequence has
|
|
Packit |
a4aae4 |
a member D4Sequence called ``Tom'' and Tom has a member Float32
|
|
Packit |
a4aae4 |
called ``shoe_size'', you can refer to Tom's shoe size as
|
|
Packit |
a4aae4 |
``Tom.shoe_size''.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@brief Holds a sequence. */
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
class D4Sequence: public Constructor
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
private:
|
|
Packit |
a4aae4 |
// This may be zero (nullptr) but the accessor (clauses()) allocates an
|
|
Packit |
a4aae4 |
// instance if that is the case.
|
|
Packit |
a4aae4 |
D4FilterClauseList *d_clauses;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Use this to control if ptr_duplicate(), ..., copy the filter clauses.
|
|
Packit |
a4aae4 |
// Because the values of a child sequence are held in copies of the Seq
|
|
Packit |
a4aae4 |
// object they clauses will bound to the 'master' instance will be copied
|
|
Packit |
a4aae4 |
// but the copies will never be used. This field can be used to control
|
|
Packit |
a4aae4 |
// that. ...purely an optimization.
|
|
Packit |
a4aae4 |
bool d_copy_clauses;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
protected:
|
|
Packit |
a4aae4 |
// This holds the values of the sequence. Values are stored in
|
|
Packit |
a4aae4 |
// instances of BaseTypeRow objects which hold instances of BaseType.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Allow these values to be accessed by subclasses
|
|
Packit |
a4aae4 |
D4SeqValues d_values;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
int64_t d_length; // How many elements are in the sequence; -1 if not currently known
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if INDEX_SUBSETTING
|
|
Packit |
a4aae4 |
int d_starting_row_number;
|
|
Packit |
a4aae4 |
int d_row_stride;
|
|
Packit |
a4aae4 |
int d_ending_row_number;
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void m_duplicate(const D4Sequence &s);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Specialize this if you have a data source that requires read()
|
|
Packit |
a4aae4 |
// recursively call itself for child sequences.
|
|
Packit |
a4aae4 |
void read_sequence_values(bool filter);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
friend class D4SequenceTest;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Sequence(const string &n);
|
|
Packit |
a4aae4 |
D4Sequence(const string &n, const string &d);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Sequence(const D4Sequence &rhs;;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual ~D4Sequence();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Sequence &operator=(const D4Sequence &rhs;;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual BaseType *ptr_duplicate();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void clear_local_data();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief The number of elements in a Sequence object.
|
|
Packit |
a4aae4 |
* @note This is not the number of items in a row, but the number
|
|
Packit |
a4aae4 |
* of rows in the complete sequence object.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @return 0 if the number of elements is unknown, else
|
|
Packit |
a4aae4 |
* return the number of elements.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
virtual int length() const { return (int)d_length; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Set the length of the sequence.
|
|
Packit |
a4aae4 |
* @param count
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
virtual void set_length(int count) { d_length = (int64_t)count; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual bool read_next_instance(bool filter);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void intern_data(ConstraintEvaluator &, DDS &) {
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
virtual bool serialize(ConstraintEvaluator &, DDS &, Marshaller &, bool ) {
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
virtual bool deserialize(UnMarshaller &, DDS *, bool ) {
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// DAP4
|
|
Packit |
a4aae4 |
virtual void intern_data(/*Crc32 &checksum, DMR &dmr, ConstraintEvaluator &eval*/);
|
|
Packit |
a4aae4 |
virtual void serialize(D4StreamMarshaller &m, DMR &dmr, /*ConstraintEvaluator &eval,*/ bool filter = false);
|
|
Packit |
a4aae4 |
virtual void deserialize(D4StreamUnMarshaller &um, DMR &dmr);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4FilterClauseList &clauses();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if INDEX_SUBSETTING
|
|
Packit |
a4aae4 |
/** Return the starting row number if the sequence was constrained using
|
|
Packit |
a4aae4 |
row numbers (instead of, or in addition to, a relational constraint).
|
|
Packit |
a4aae4 |
If a relational constraint was also given, the row number corresponds
|
|
Packit |
a4aae4 |
to the row number of the sequence after applying the relational
|
|
Packit |
a4aae4 |
constraint.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
If the bracket notation was not used to constrain this sequence, this
|
|
Packit |
a4aae4 |
method returns -1.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@brief Get the starting row number.
|
|
Packit |
a4aae4 |
@return The starting row number. */
|
|
Packit |
a4aae4 |
virtual int get_starting_row_number() const { return d_starting_row_number; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Return the row stride number if the sequence was constrained using
|
|
Packit |
a4aae4 |
row numbers (instead of, or in addition to, a relational constraint).
|
|
Packit |
a4aae4 |
If a relational constraint was also given, the row stride is applied
|
|
Packit |
a4aae4 |
to the sequence after applying the relational constraint.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
If the bracket notation was not used to constrain this sequence, this
|
|
Packit |
a4aae4 |
method returns -1.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@brief Get the row stride.
|
|
Packit |
a4aae4 |
@return The row stride. */
|
|
Packit |
a4aae4 |
virtual int get_row_stride() const { return d_row_stride; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Return the ending row number if the sequence was constrained using
|
|
Packit |
a4aae4 |
row numbers (instead of, or in addition to, a relational constraint).
|
|
Packit |
a4aae4 |
If a relational constraint was also given, the row number corresponds
|
|
Packit |
a4aae4 |
to the row number of the sequence after applying the
|
|
Packit |
a4aae4 |
relational constraint.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
If the bracket notation was not used to constrain this sequence, this
|
|
Packit |
a4aae4 |
method returns -1.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@brief Get the ending row number.
|
|
Packit |
a4aae4 |
@return The ending row number. */
|
|
Packit |
a4aae4 |
virtual int get_ending_row_number() const { return d_ending_row_number; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void set_row_number_constraint(int start, int stop, int stride = 1);
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Set the internal value.
|
|
Packit |
a4aae4 |
* The 'values' of a D4Sequence is a vector of vectors of BaseType* objects.
|
|
Packit |
a4aae4 |
* Using this method does not perform a deep copy; the BaseType*s are
|
|
Packit |
a4aae4 |
* copied so the caller should not free them. Note that this does set
|
|
Packit |
a4aae4 |
* d_length but the read_p flag for the BaseTypes should all be set to
|
|
Packit |
a4aae4 |
* keep the serializer from trying to read each of them.
|
|
Packit |
a4aae4 |
* @param values
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
virtual void set_value(D4SeqValues &values) { d_values = values; d_length = d_values.size(); }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Get the values for this D4Sequence
|
|
Packit |
a4aae4 |
* This method returns a reference to the values held by the instance.
|
|
Packit |
a4aae4 |
* You should make sure that the instance really holds values before
|
|
Packit |
a4aae4 |
* calling it! Do not free the BaseType*s contained in the vector of
|
|
Packit |
a4aae4 |
* vectors.
|
|
Packit |
a4aae4 |
* @return A reference tp the vector of vector of BaseType*
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
virtual D4SeqValues value() const { return d_values; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Get the sequence values by reference
|
|
Packit |
a4aae4 |
* This method returns a reference to the D4Sequence's values,
|
|
Packit |
a4aae4 |
* eliminating the copy of all the pointers. For large sequences,
|
|
Packit |
a4aae4 |
* that could be a substantial number of values (even though
|
|
Packit |
a4aae4 |
* they are 'just' pointers).
|
|
Packit |
a4aae4 |
* @return A reference to the vector of vector of BaseType*
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
virtual D4SeqValues &value_ref() { return d_values; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual D4SeqRow *row_value(size_t row);
|
|
Packit |
a4aae4 |
virtual BaseType *var_value(size_t row, const string &name);
|
|
Packit |
a4aae4 |
virtual BaseType *var_value(size_t row, size_t i);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_one_row(ostream &out, int row, string space,
|
|
Packit |
a4aae4 |
bool print_row_num = false);
|
|
Packit |
a4aae4 |
virtual void print_val_by_rows(ostream &out, string space = "",
|
|
Packit |
a4aae4 |
bool print_decl_p = true,
|
|
Packit |
a4aae4 |
bool print_row_numbers = true);
|
|
Packit |
a4aae4 |
virtual void print_val(ostream &out, string space = "",
|
|
Packit |
a4aae4 |
bool print_decl_p = true);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void dump(ostream &strm) const ;
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#endif //_sequence_h
|