Blame Sequence.h

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
// Interface for the class Sequence. A sequence contains a single set
Packit a4aae4
// of variables, all at the same lexical level just like a structure
Packit a4aae4
// (and like a structure, it may contain other ctor types...). Unlike
Packit a4aae4
// a structure, a sequence defines a pattern that is repeated N times
Packit a4aae4
// for a sequence of N elements. Thus, Sequence { String name; Int32
Packit a4aae4
// age; } person; means a sequence of N persons where each contain a
Packit a4aae4
// name and age. The sequence can be arbitrarily long (i.e., you don't
Packit a4aae4
// know N by looking at the sequence declaration.
Packit a4aae4
//
Packit a4aae4
// jhrg 9/14/94
Packit a4aae4
Packit a4aae4
#ifndef _sequence_h
Packit a4aae4
#define _sequence_h 1
Packit a4aae4
Packit a4aae4
#include <stack>
Packit a4aae4
Packit a4aae4
#include "Constructor.h"
Packit a4aae4
Packit a4aae4
#ifndef S_XDRUtils_h
Packit a4aae4
#include "XDRUtils.h"
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
namespace libdap {
Packit a4aae4
Packit a4aae4
class BaseType;
Packit a4aae4
class ConstraintEvaluator;
Packit a4aae4
class D4Group;
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
/** This is the interface for the class Sequence. 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 Sequence may contain other
Packit a4aae4
 compound types, including other Sequences.  Unlike a Structure, a
Packit a4aae4
 Sequence defines a pattern that is repeated N times for a sequence
Packit a4aae4
 of N elements. It is useful to think of a Sequence as representing
Packit a4aae4
 a table of values (like a relational database), with each row of
Packit a4aae4
 the table corresponding to a Sequence ``instance.''  (This usage
Packit a4aae4
 can be confusing, since ``instance'' also refers to a particular
Packit a4aae4
 item of class Sequence.)  For example:
Packit a4aae4
Packit a4aae4
 
Packit a4aae4
 Sequence {
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 Sequence can be arbitrarily long, which is to say that its
Packit a4aae4
 length is not part of its declaration.  A Sequence can contain
Packit a4aae4
 other Sequences:
Packit a4aae4
Packit a4aae4
 
Packit a4aae4
 Sequence {
Packit a4aae4
 String name;
Packit a4aae4
 Int32 age;
Packit a4aae4
 Sequence {
Packit a4aae4
 String friend;
Packit a4aae4
 } friend_list;
Packit a4aae4
 } person;
Packit a4aae4
 
Packit a4aae4
Packit a4aae4
 This is still represented as a single table, but each row contains
Packit a4aae4
 the elements of both the main Sequence and the nested one:
Packit a4aae4
Packit a4aae4
 
Packit a4aae4
 Fred       34     Norman
Packit a4aae4
 Fred       34     Andrea
Packit a4aae4
 Fred       34     Ralph
Packit a4aae4
 Fred       34     Lisa
Packit a4aae4
 Ralph      23     Norman
Packit a4aae4
 Ralph      23     Andrea
Packit a4aae4
 Ralph      23     Lisa
Packit a4aae4
 Ralph      23     Marth
Packit a4aae4
 Ralph      23     Throckmorton
Packit a4aae4
 Ralph      23     Helga
Packit a4aae4
 Ralph      23     Millicent
Packit a4aae4
 Andrea     29     Ralph
Packit a4aae4
 Andrea     29     Natasha
Packit a4aae4
 Andrea     29     Norman
Packit a4aae4
 ...        ..     ...
Packit a4aae4
 
Packit a4aae4
Packit a4aae4
 Internally, the Sequence is represented by a vector of vectors. The
Packit a4aae4
 members of the outer vector are the members of the Sequence. This
Packit a4aae4
 includes the nested Sequences, as in the above example.
Packit a4aae4
Packit a4aae4
 NB: Note that in the past this class had a different behavior. It held
Packit a4aae4
 only one row at a time and the deserialize(...) method had to be called
Packit a4aae4
 from within a loop. This is no longer true. Now the
Packit a4aae4
 deserailize(...) method should be called once and will read the entire
Packit a4aae4
 sequence's values from the server. All the values are now stored in an
Packit a4aae4
 instance of Sequence, not just a single row's.
Packit a4aae4
Packit a4aae4
 Because the length of a Sequence 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 Sequence must be written so that
Packit a4aae4
 successive calls return values for successive rows of the Sequence.
Packit a4aae4
Packit a4aae4
 Similar to a C structure, you refer to members of Sequence
Packit a4aae4
 elements with a ``.'' notation.  For example, if the Sequence has
Packit a4aae4
 a member Sequence 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
 @note This class contains the 'logic' for both the server- and client-side
Packit a4aae4
 behavior. The field \e d_values is used by the client-side methods to store
Packit a4aae4
 the entire Sequence. On the server-side, the read() method uses an underlying
Packit a4aae4
 data system to read one row of data values which are then serialized using the
Packit a4aae4
 serialize() methods of each variable.
Packit a4aae4
Packit a4aae4
 @todo Add an isEmpty() method which returns true if the Sequence is
Packit a4aae4
 empty. This should work before and after calling deserialize().
Packit a4aae4
Packit a4aae4
 @brief Holds a sequence. */
Packit a4aae4
Packit a4aae4
class Sequence: public Constructor
Packit a4aae4
{
Packit a4aae4
private:
Packit a4aae4
    // This holds the values read off the wire. Values are stored in
Packit a4aae4
    // instances of BaseTypeRow objects which hold instances of BaseType.
Packit a4aae4
    SequenceValues d_values;
Packit a4aae4
Packit a4aae4
    // The number of the row that has just been deserialized. Before
Packit a4aae4
    // deserialized has been called, this field is -1.
Packit a4aae4
    int d_row_number;
Packit a4aae4
Packit a4aae4
    // If a client asks for certain rows of a sequence using the bracket
Packit a4aae4
    // notation (<tt>[<start>:<stride>:<stop>]</tt>) primarily intended for
Packit a4aae4
    // arrays
Packit a4aae4
    // and grids, record that information in the next three fields. This
Packit a4aae4
    // information can be used by the translation software. s.a. the accessor
Packit a4aae4
    // and mutator methods for these members. Values of -1 indicate that
Packit a4aae4
    // these have not yet been set.
Packit a4aae4
    int d_starting_row_number;
Packit a4aae4
    int d_row_stride;
Packit a4aae4
    int d_ending_row_number;
Packit a4aae4
Packit a4aae4
    // Used to track if data has not already been sent.
Packit a4aae4
    bool d_unsent_data;
Packit a4aae4
Packit a4aae4
    // Track if the Start Of Instance marker has been written. Needed to
Packit a4aae4
    // properly send EOS for only the outer Sequence when a selection
Packit a4aae4
    // returns an empty Sequence.
Packit a4aae4
    bool d_wrote_soi;
Packit a4aae4
Packit a4aae4
    // This signals whether the sequence is a leaf or parent.
Packit a4aae4
    bool d_leaf_sequence;
Packit a4aae4
Packit a4aae4
    // In a hierarchy of sequences, is this the top most?
Packit a4aae4
    bool d_top_most;
Packit a4aae4
Packit a4aae4
    bool is_end_of_rows(int i);
Packit a4aae4
Packit a4aae4
    friend class SequenceTest;
Packit a4aae4
Packit a4aae4
protected:
Packit a4aae4
    void m_duplicate(const Sequence &s);
Packit a4aae4
    typedef stack<SequenceValues*> sequence_values_stack_t;
Packit a4aae4
Packit a4aae4
    virtual bool serialize_parent_part_one(DDS &dds, ConstraintEvaluator &eval, Marshaller &m);
Packit a4aae4
    virtual void serialize_parent_part_two(DDS &dds, ConstraintEvaluator &eval, Marshaller &m);
Packit a4aae4
    virtual bool serialize_leaf(DDS &dds, ConstraintEvaluator &eval, Marshaller &m, bool ce_eval);
Packit a4aae4
Packit a4aae4
    virtual void intern_data_private(ConstraintEvaluator &eval, DDS &dds,
Packit a4aae4
            sequence_values_stack_t &sequence_values_stack);
Packit a4aae4
    virtual void intern_data_for_leaf(DDS &dds, ConstraintEvaluator &eval,
Packit a4aae4
            sequence_values_stack_t &sequence_values_stack);
Packit a4aae4
Packit a4aae4
    virtual void intern_data_parent_part_one(DDS &dds, ConstraintEvaluator &eval,
Packit a4aae4
            sequence_values_stack_t &sequence_values_stack);
Packit a4aae4
Packit a4aae4
    virtual void intern_data_parent_part_two(DDS &dds, ConstraintEvaluator &eval,
Packit a4aae4
            sequence_values_stack_t &sequence_values_stack);
Packit a4aae4
Packit a4aae4
public:
Packit a4aae4
Packit a4aae4
    Sequence(const string &n);
Packit a4aae4
    Sequence(const string &n, const string &d);
Packit a4aae4
Packit a4aae4
    Sequence(const Sequence &rhs;;
Packit a4aae4
Packit a4aae4
    virtual ~Sequence();
Packit a4aae4
Packit a4aae4
    Sequence &operator=(const Sequence &rhs;;
Packit a4aae4
Packit a4aae4
    virtual BaseType *ptr_duplicate();
Packit a4aae4
Packit a4aae4
    virtual void clear_local_data();
Packit a4aae4
Packit a4aae4
    virtual void transform_to_dap4(D4Group *root, Constructor *container);
Packit a4aae4
Packit a4aae4
    virtual bool is_dap2_only_type();
Packit a4aae4
Packit a4aae4
    virtual string toString();
Packit a4aae4
Packit a4aae4
    virtual bool is_linear();
Packit a4aae4
Packit a4aae4
    virtual int length() const;
Packit a4aae4
Packit a4aae4
    virtual int number_of_rows() const;
Packit a4aae4
Packit a4aae4
    virtual bool read_row(int row, DDS &dds, ConstraintEvaluator &eval, bool ce_eval = true);
Packit a4aae4
Packit a4aae4
    virtual void intern_data(ConstraintEvaluator &eval, DDS &dds;;
Packit a4aae4
    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval = true);
Packit a4aae4
    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
Packit a4aae4
Packit a4aae4
    /// Rest the row number counter
Packit a4aae4
    void reset_row_number();
Packit a4aae4
    // I added a second method instead of a param with a default value because I think
Packit a4aae4
    // this will result only in an addition to the ABI/API, not a change. 5/16/15 jhrg
Packit a4aae4
    void reset_row_number(bool recur);
Packit a4aae4
    void increment_row_number(unsigned int i) { d_row_number += i; }
Packit a4aae4
    int get_row_number() const { return d_row_number; }
Packit a4aae4
Packit a4aae4
    int get_starting_row_number();
Packit a4aae4
Packit a4aae4
    virtual int get_row_stride();
Packit a4aae4
Packit a4aae4
    virtual int get_ending_row_number();
Packit a4aae4
Packit a4aae4
    virtual void set_row_number_constraint(int start, int stop, int stride = 1);
Packit a4aae4
Packit a4aae4
    /// Get the unsent data property
Packit a4aae4
    bool get_unsent_data() const
Packit a4aae4
    {
Packit a4aae4
        return d_unsent_data;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    /// Set the unsent data property
Packit a4aae4
    void set_unsent_data(bool usd)
Packit a4aae4
    {
Packit a4aae4
        d_unsent_data = usd;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    virtual void set_value(SequenceValues &values);
Packit a4aae4
    virtual SequenceValues value();
Packit a4aae4
    virtual SequenceValues &value_ref();
Packit a4aae4
Packit a4aae4
    virtual BaseType *var_value(size_t row, const string &name);
Packit a4aae4
Packit a4aae4
    virtual BaseType *var_value(size_t row, size_t i);
Packit a4aae4
Packit a4aae4
    virtual BaseTypeRow *row_value(size_t row);
Packit a4aae4
    virtual void print_one_row(ostream &out, int row, string space, bool print_row_num = false);
Packit a4aae4
    virtual void print_val_by_rows(ostream &out, string space = "", bool print_decl_p = true, bool print_row_numbers =
Packit a4aae4
            true);
Packit a4aae4
    virtual void print_val(ostream &out, string space = "", bool print_decl_p = true);
Packit a4aae4
Packit a4aae4
    virtual void print_one_row(FILE *out, int row, string space, bool print_row_num = false);
Packit a4aae4
    virtual void print_val_by_rows(FILE *out, string space = "", bool print_decl_p = true,
Packit a4aae4
            bool print_row_numbers = true);
Packit a4aae4
    virtual void print_val(FILE *out, string space = "", bool print_decl_p = true);
Packit a4aae4
Packit a4aae4
    virtual void set_leaf_p(bool state);
Packit a4aae4
Packit a4aae4
    virtual bool is_leaf_sequence();
Packit a4aae4
Packit a4aae4
    virtual void set_leaf_sequence(int lvl = 1);
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