Blame Structure.cc

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
// Implementation for the class Structure
Packit a4aae4
//
Packit a4aae4
// jhrg 9/14/94
Packit a4aae4
Packit a4aae4
//#define DODS_DEBUG
Packit a4aae4
Packit a4aae4
#include "config.h"
Packit a4aae4
Packit a4aae4
#include <sstream>
Packit a4aae4
Packit a4aae4
#include "Byte.h"
Packit a4aae4
#include "Int16.h"
Packit a4aae4
#include "UInt16.h"
Packit a4aae4
#include "Int32.h"
Packit a4aae4
#include "UInt32.h"
Packit a4aae4
#include "Float32.h"
Packit a4aae4
#include "Float64.h"
Packit a4aae4
#include "Str.h"
Packit a4aae4
#include "Url.h"
Packit a4aae4
#include "Array.h"
Packit a4aae4
#include "Structure.h"
Packit a4aae4
#include "Sequence.h"
Packit a4aae4
#include "Grid.h"
Packit a4aae4
Packit a4aae4
#include "DDS.h"
Packit a4aae4
#include "ConstraintEvaluator.h"
Packit a4aae4
Packit a4aae4
#include "D4Attributes.h"
Packit a4aae4
#include "D4Group.h"
Packit a4aae4
Packit a4aae4
#include "XDRStreamMarshaller.h"
Packit a4aae4
#include "util.h"
Packit a4aae4
#include "debug.h"
Packit a4aae4
#include "InternalErr.h"
Packit a4aae4
#include "escaping.h"
Packit a4aae4
Packit a4aae4
using std::cerr;
Packit a4aae4
using std::endl;
Packit a4aae4
Packit a4aae4
namespace libdap {
Packit a4aae4
Packit a4aae4
#if 0
Packit a4aae4
/** This method is protected so it's hidden from the whole world, but
Packit a4aae4
 * available to direct child classes. Because of that, we need a glue-routine
Packit a4aae4
 * here so children of Structure can specialize it.
Packit a4aae4
 */
Packit a4aae4
void
Packit a4aae4
Structure::m_duplicate(const Structure &s)
Packit a4aae4
{
Packit a4aae4
    Constructor::m_duplicate(s);
Packit a4aae4
#if 0
Packit a4aae4
    Structure &cs = const_cast<Structure &>(s);
Packit a4aae4
Packit a4aae4
    DBG(cerr << "Copying structure: " << name() << endl);
Packit a4aae4
Packit a4aae4
    for (Vars_iter i = cs.d_vars.begin(); i != cs.d_vars.end(); i++) {
Packit a4aae4
        DBG(cerr << "Copying field: " << (*i)->name() << endl);
Packit a4aae4
        // Jose Garcia
Packit a4aae4
        // I think this assert here is part of a debugging
Packit a4aae4
        // process since it is going along with a DBG call
Packit a4aae4
        // I leave it here since it can be remove by defining NDEBUG.
Packit a4aae4
        // assert(*i);
Packit a4aae4
        BaseType *btp = (*i)->ptr_duplicate();
Packit a4aae4
        btp->set_parent(this);
Packit a4aae4
        d_vars.push_back(btp);
Packit a4aae4
    }
Packit a4aae4
#endif
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
/** The Structure constructor requires only the name of the variable
Packit a4aae4
    to be created. The name may be omitted, which will create a
Packit a4aae4
    nameless variable. This may be adequate for some applications.
Packit a4aae4
Packit a4aae4
    @param n A string containing the name of the variable to be
Packit a4aae4
    created.
Packit a4aae4
*/
Packit a4aae4
Structure::Structure(const string &n) : Constructor(n, dods_structure_c)
Packit a4aae4
{}
Packit a4aae4
Packit a4aae4
/** The Structure server-side constructor requires the name of the variable
Packit a4aae4
    to be created and the dataset name from which this variable is being
Packit a4aae4
    created. Used on server-side handlers.
Packit a4aae4
Packit a4aae4
    @param n A string containing the name of the variable to be
Packit a4aae4
    created.
Packit a4aae4
    @param d A string containing the name of the dataset from which this
Packit a4aae4
    variable is being created.
Packit a4aae4
*/
Packit a4aae4
Structure::Structure(const string &n, const string &d)
Packit a4aae4
    : Constructor(n, d, dods_structure_c)
Packit a4aae4
{}
Packit a4aae4
Packit a4aae4
/** The Structure copy constructor. */
Packit a4aae4
Structure::Structure(const Structure &rhs) : Constructor(rhs)
Packit a4aae4
{
Packit a4aae4
    DBG(cerr << "In Structure::copy_ctor for " << name() << endl);
Packit a4aae4
    //m_duplicate(rhs);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
Structure::~Structure()
Packit a4aae4
{
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
BaseType *
Packit a4aae4
Structure::ptr_duplicate()
Packit a4aae4
{
Packit a4aae4
    return new Structure(*this);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
/**
Packit a4aae4
 * Build a DAP4 Structure.
Packit a4aae4
 *
Packit a4aae4
 * This code must be subclassed for all but the most trivial cases.
Packit a4aae4
 *
Packit a4aae4
 * @param root
Packit a4aae4
 * @param container
Packit a4aae4
 * @return The new variable
Packit a4aae4
 */
Packit a4aae4
void
Packit a4aae4
Structure::transform_to_dap4(D4Group *root, Constructor *container)
Packit a4aae4
{
Packit a4aae4
    DBG(cerr << __func__ <<"() -  BEGIN" << endl;);
Packit a4aae4
	// Here we create a new Structure and then use it
Packit a4aae4
    // as the target container for the transformed versions of
Packit a4aae4
    // all the member variables by calling Constructor::transform_to_dap4() and
Packit a4aae4
    // passing our new target Structure in as the target container.
Packit a4aae4
	Structure *dest = new Structure(name());
Packit a4aae4
    DBG(cerr << __func__ <<"() -  Calling Constructor::transform_to_dap4("<<
Packit a4aae4
        "'" << root->name() << "':" << (void*)root << ","
Packit a4aae4
        "'" << dest->name() << "':" << (void*)dest << ")"
Packit a4aae4
        << endl; );
Packit a4aae4
	Constructor::transform_to_dap4(root, dest);
Packit a4aae4
	container->add_var_nocopy(dest);
Packit a4aae4
	DBG(cerr << __func__ <<"() -  Added new Structure '" << dest->name() << "' (" << (void*)dest <<
Packit a4aae4
	    ") to the container '" << container->name() <<"'" << endl;);
Packit a4aae4
    DBG(cerr << __func__ <<"() -  END"<< endl;);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
Packit a4aae4
/** @brief DAP4 to DAP2 transform
Packit a4aae4
 *
Packit a4aae4
 * Return a DAP2 'copy' of the variable.
Packit a4aae4
 *
Packit a4aae4
 * @return A pointer to the transformed variable
Packit a4aae4
 */
Packit a4aae4
vector<BaseType *> *
Packit a4aae4
Structure::transform_to_dap2(AttrTable *)
Packit a4aae4
{
Packit a4aae4
    DBG(cerr << " " << __func__ << " BEGIN" << endl);
Packit a4aae4
    Structure *dest = new Structure(name());
Packit a4aae4
Packit a4aae4
    // convert the Structure's d4 attributes to a dap2 attribute table.
Packit a4aae4
    AttrTable *attrs = this->attributes()->get_AttrTable(name());
Packit a4aae4
    dest->set_is_dap4(false);
Packit a4aae4
Packit a4aae4
    vector<BaseType *> dropped_vars;
Packit a4aae4
    for (Structure::Vars_citer i = var_begin(), e = var_end(); i != e; ++i) {
Packit a4aae4
        vector<BaseType *> *new_vars = (*i)->transform_to_dap2(attrs);
Packit a4aae4
        if (new_vars) {  // Might be un-mappable
Packit a4aae4
            // It's not so game on..
Packit a4aae4
            vector<BaseType*>::iterator vIter = new_vars->begin();
Packit a4aae4
            vector<BaseType*>::iterator end = new_vars->end();
Packit a4aae4
            for( ; vIter!=end ; vIter++ ){
Packit a4aae4
                BaseType *new_var = (*vIter);
Packit a4aae4
                new_var->set_parent(dest);
Packit a4aae4
                dest->add_var_nocopy(new_var);
Packit a4aae4
                (*vIter) = NULL;
Packit a4aae4
            }
Packit a4aae4
            delete new_vars;
Packit a4aae4
Packit a4aae4
        }
Packit a4aae4
        else {
Packit a4aae4
            // Got a NULL, so we are dropping this var.
Packit a4aae4
            dropped_vars.push_back(*i);
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    AttrTable *dv_attr_table = make_dropped_vars_attr_table(&dropped_vars);
Packit a4aae4
    if(dv_attr_table){
Packit a4aae4
        DBG(cerr << " " << __func__ << "() - Adding "<< dv_attr_table->get_name() << " AttrTable" << endl);
Packit a4aae4
        attrs->append_container(dv_attr_table,dv_attr_table->get_name());
Packit a4aae4
    }
Packit a4aae4
    DBG(attrs->print(cerr,"",true););
Packit a4aae4
    // Since this does a copy we gotta delete the attrs when done
Packit a4aae4
    dest->set_attr_table(*attrs);
Packit a4aae4
    delete attrs;
Packit a4aae4
Packit a4aae4
    vector<BaseType *> *result =  new vector<BaseType *>();
Packit a4aae4
    result->push_back(dest);
Packit a4aae4
    DBG(cerr << " " << __func__ << " END" << endl);
Packit a4aae4
    return result;
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
Packit a4aae4
Packit a4aae4
Packit a4aae4
Packit a4aae4
Structure &
Packit a4aae4
Structure::operator=(const Structure &rhs)
Packit a4aae4
{
Packit a4aae4
    DBG(cerr << "Entering Structure::operator=" << endl);
Packit a4aae4
    if (this == &rhs)
Packit a4aae4
        return *this;
Packit a4aae4
Packit a4aae4
    dynamic_cast<Constructor &>(*this) = rhs; // run Constructor=
Packit a4aae4
Packit a4aae4
    //m_duplicate(rhs);
Packit a4aae4
Packit a4aae4
    DBG(cerr << "Exiting Structure::operator=" << endl);
Packit a4aae4
    return *this;
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
#if 0
Packit a4aae4
int
Packit a4aae4
Structure::element_count(bool leaves)
Packit a4aae4
{
Packit a4aae4
    if (!leaves)
Packit a4aae4
        return d_vars.size();
Packit a4aae4
    else {
Packit a4aae4
        int i = 0;
Packit a4aae4
        for (Vars_iter j = d_vars.begin(); j != d_vars.end(); j++) {
Packit a4aae4
            i += (*j)->element_count(leaves);
Packit a4aae4
        }
Packit a4aae4
        return i;
Packit a4aae4
    }
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
bool
Packit a4aae4
Structure::is_linear()
Packit a4aae4
{
Packit a4aae4
    bool linear = true;
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); linear && i != d_vars.end(); i++) {
Packit a4aae4
        if ((*i)->type() == dods_structure_c)
Packit a4aae4
            linear = linear && static_cast<Structure*>((*i))->is_linear();
Packit a4aae4
        else
Packit a4aae4
            linear = linear && (*i)->is_simple_type();
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return linear;
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
#if 0
Packit a4aae4
void
Packit a4aae4
Structure::set_send_p(bool state)
Packit a4aae4
{
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        (*i)->set_send_p(state);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    BaseType::set_send_p(state);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
void
Packit a4aae4
Structure::set_read_p(bool state)
Packit a4aae4
{
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        (*i)->set_read_p(state);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    BaseType::set_read_p(state);
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
#if 0
Packit a4aae4
/** Set the \e in_selection property for this variable and all of its
Packit a4aae4
    children.
Packit a4aae4
Packit a4aae4
    @brief Set the \e in_selection property.
Packit a4aae4
    @param state Set the property value to \e state. */
Packit a4aae4
void
Packit a4aae4
Structure::set_in_selection(bool state)
Packit a4aae4
{
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        (*i)->set_in_selection(state);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    BaseType::set_in_selection(state);
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
/** @brief Traverse Structure, set Sequence leaf nodes. */
Packit a4aae4
void
Packit a4aae4
Structure::set_leaf_sequence(int level)
Packit a4aae4
{
Packit a4aae4
    for (Vars_iter i = var_begin(); i != var_end(); i++) {
Packit a4aae4
        if ((*i)->type() == dods_sequence_c)
Packit a4aae4
        	static_cast<Sequence&>(**i).set_leaf_sequence(++level);
Packit a4aae4
        else if ((*i)->type() == dods_structure_c)
Packit a4aae4
        	static_cast<Structure&>(**i).set_leaf_sequence(level);
Packit a4aae4
    }
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
#if 0
Packit a4aae4
/** Adds an element to a Structure.
Packit a4aae4
Packit a4aae4
    @param bt A pointer to the DAP2 type variable to add to this Structure.
Packit a4aae4
    @param part Not used by this class, defaults to nil */
Packit a4aae4
void
Packit a4aae4
Structure::add_var(BaseType *bt, Part)
Packit a4aae4
{
Packit a4aae4
    // Jose Garcia
Packit a4aae4
    // Passing and invalid pointer to an object is a developer's error.
Packit a4aae4
    if (!bt)
Packit a4aae4
        throw InternalErr(__FILE__, __LINE__, "The BaseType parameter cannot be null.");
Packit a4aae4
Packit a4aae4
    if (bt->is_dap4_only_type())
Packit a4aae4
        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Structure.");
Packit a4aae4
Packit a4aae4
    // Jose Garcia
Packit a4aae4
    // Now we add a copy of bt so the external user is able to destroy bt as
Packit a4aae4
    // he/she wishes. The policy is: "If it is allocated outside, it is
Packit a4aae4
    // deallocated outside, if it is allocated inside, it is deallocated
Packit a4aae4
    // inside"
Packit a4aae4
    BaseType *btp = bt->ptr_duplicate();
Packit a4aae4
    btp->set_parent(this);
Packit a4aae4
    d_vars.push_back(btp);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
/** Adds an element to a Structure.
Packit a4aae4
Packit a4aae4
    @param bt A pointer to the DAP2 type variable to add to this Structure.
Packit a4aae4
    @param part Not used by this class, defaults to nil */
Packit a4aae4
void
Packit a4aae4
Structure::add_var_nocopy(BaseType *bt, Part)
Packit a4aae4
{
Packit a4aae4
    if (!bt)
Packit a4aae4
        throw InternalErr(__FILE__, __LINE__, "The BaseType parameter cannot be null.");
Packit a4aae4
Packit a4aae4
    if (bt->is_dap4_only_type())
Packit a4aae4
        throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 Structure.");
Packit a4aae4
Packit a4aae4
    bt->set_parent(this);
Packit a4aae4
    d_vars.push_back(bt);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
Packit a4aae4
/** Removed an element from a Structure.
Packit a4aae4
Packit a4aae4
    @param n name of the variable to remove */
Packit a4aae4
void
Packit a4aae4
Structure::del_var(const string &n)
Packit a4aae4
{
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        if ((*i)->name() == n) {
Packit a4aae4
            BaseType *bt = *i ;
Packit a4aae4
            d_vars.erase(i) ;
Packit a4aae4
            delete bt ; bt = 0;
Packit a4aae4
            return;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
#if 0
Packit a4aae4
/** @brief simple implementation of read that iterates through vars
Packit a4aae4
 *  and calls read on them
Packit a4aae4
 *
Packit a4aae4
 * @return returns false to signify all has been read
Packit a4aae4
 */
Packit a4aae4
bool Structure::read()
Packit a4aae4
{
Packit a4aae4
    if (!read_p()) {
Packit a4aae4
        for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
            (*i)->read();
Packit a4aae4
        }
Packit a4aae4
        set_read_p(true);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return false;
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
#if 0
Packit a4aae4
// TODO Recode to use width(bool)
Packit a4aae4
unsigned int
Packit a4aae4
Structure::width()
Packit a4aae4
{
Packit a4aae4
    unsigned int sz = 0;
Packit a4aae4
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        sz += (*i)->width();
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return sz;
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
/** This version of width simply returns the same thing as width() for simple
Packit a4aae4
    types and Arrays. For Structure it returns the total size if constrained
Packit a4aae4
    is false, or the size of the elements in the current projection if true.
Packit a4aae4
Packit a4aae4
    @param constrained If true, return the size after applying a constraint.
Packit a4aae4
    @return  The number of bytes used by the variable.
Packit a4aae4
 */
Packit a4aae4
unsigned int
Packit a4aae4
Structure::width(bool constrained)
Packit a4aae4
{
Packit a4aae4
    unsigned int sz = 0;
Packit a4aae4
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
    	if (constrained) {
Packit a4aae4
    		if ((*i)->send_p())
Packit a4aae4
    			sz += (*i)->width(constrained);
Packit a4aae4
    	}
Packit a4aae4
    	else {
Packit a4aae4
    		sz += (*i)->width(constrained);
Packit a4aae4
    	}
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return sz;
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
#if 0
Packit a4aae4
void
Packit a4aae4
Structure::intern_data(ConstraintEvaluator & eval, DDS & dds)
Packit a4aae4
{
Packit a4aae4
    DBG(cerr << "Structure::intern_data: " << name() << endl);
Packit a4aae4
    if (!read_p())
Packit a4aae4
        read();          // read() throws Error and InternalErr
Packit a4aae4
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        if ((*i)->send_p()) {
Packit a4aae4
            (*i)->intern_data(eval, dds);
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
bool
Packit a4aae4
Structure::serialize(ConstraintEvaluator &eval, DDS &dds,
Packit a4aae4
                     Marshaller &m, bool ce_eval)
Packit a4aae4
{
Packit a4aae4
#if USE_LOCAL_TIMEOUT_SCHEME
Packit a4aae4
    dds.timeout_on();
Packit a4aae4
#endif
Packit a4aae4
    if (!read_p())
Packit a4aae4
        read();  // read() throws Error and InternalErr
Packit a4aae4
Packit a4aae4
#if EVAL
Packit a4aae4
    if (ce_eval && !eval.eval_selection(dds, dataset()))
Packit a4aae4
        return true;
Packit a4aae4
#endif
Packit a4aae4
#if USE_LOCAL_TIMEOUT_SCHEME
Packit a4aae4
    dds.timeout_off();
Packit a4aae4
#endif
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        if ((*i)->send_p()) {
Packit a4aae4
#ifdef CHECKSUMS
Packit a4aae4
            XDRStreamMarshaller *sm = dynamic_cast<XDRStreamMarshaller*>(&m);
Packit a4aae4
            if (sm && sm->checksums() && (*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
Packit a4aae4
                sm->reset_checksum();
Packit a4aae4
Packit a4aae4
            (*i)->serialize(eval, dds, m, false);
Packit a4aae4
Packit a4aae4
            if (sm && sm->checksums() && (*i)->type() != dods_structure_c && (*i)->type() != dods_grid_c)
Packit a4aae4
                sm->get_checksum();
Packit a4aae4
#else
Packit a4aae4
            (*i)->serialize(eval, dds, m, false);
Packit a4aae4
#endif
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return true;
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
bool
Packit a4aae4
Structure::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
Packit a4aae4
{
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        (*i)->deserialize(um, dds, reuse);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return false;
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
#if 0
Packit a4aae4
/**  @brief Never call this
Packit a4aae4
Packit a4aae4
     This method cannot be used to change values of a Structure since
Packit a4aae4
     the values of a Constructor type must be set using methods in
Packit a4aae4
     Constructor. See the Constructor::var_begin() and related
Packit a4aae4
     methods.
Packit a4aae4
Packit a4aae4
     @todo Make this throw an exception
Packit a4aae4
     @return Returns the size of the structure. */
Packit a4aae4
unsigned int
Packit a4aae4
Structure::val2buf(void *, bool)
Packit a4aae4
{
Packit a4aae4
    return sizeof(Structure);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
/** @brief Never call this
Packit a4aae4
    @see val2buf()
Packit a4aae4
    @return Returns the size of the structure. */
Packit a4aae4
unsigned int
Packit a4aae4
Structure::buf2val(void **)
Packit a4aae4
{
Packit a4aae4
    return sizeof(Structure);
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
#if 0
Packit a4aae4
BaseType *
Packit a4aae4
Structure::var(const string &name, bool exact_match, btp_stack *s)
Packit a4aae4
{
Packit a4aae4
    string n = www2id(name);
Packit a4aae4
Packit a4aae4
    if (exact_match)
Packit a4aae4
        return m_exact_match(n, s);
Packit a4aae4
    else
Packit a4aae4
        return m_leaf_match(n, s);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
/** @deprecated See comment in BaseType */
Packit a4aae4
BaseType *
Packit a4aae4
Structure::var(const string &n, btp_stack &s)
Packit a4aae4
{
Packit a4aae4
    string name = www2id(n);
Packit a4aae4
Packit a4aae4
    BaseType *btp = m_exact_match(name, &s);
Packit a4aae4
    if (btp)
Packit a4aae4
        return btp;
Packit a4aae4
Packit a4aae4
    return m_leaf_match(name, &s);
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
#if 0
Packit a4aae4
// Private method to find a variable using the shorthand name. This
Packit a4aae4
// should be moved to Constructor.
Packit a4aae4
BaseType *
Packit a4aae4
Structure::m_leaf_match(const string &name, btp_stack *s)
Packit a4aae4
{
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        if ((*i)->name() == name) {
Packit a4aae4
            if (s) {
Packit a4aae4
                DBG(cerr << "Pushing " << this->name() << endl);
Packit a4aae4
                s->push(static_cast<BaseType *>(this));
Packit a4aae4
            }
Packit a4aae4
            return *i;
Packit a4aae4
        }
Packit a4aae4
        if ((*i)->is_constructor_type()) {
Packit a4aae4
            BaseType *btp = (*i)->var(name, false, s);
Packit a4aae4
            if (btp) {
Packit a4aae4
                if (s) {
Packit a4aae4
                    DBG(cerr << "Pushing " << this->name() << endl);
Packit a4aae4
                    s->push(static_cast<BaseType *>(this));
Packit a4aae4
                }
Packit a4aae4
                return btp;
Packit a4aae4
            }
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return 0;
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
// Breadth-first search for NAME. If NAME contains one or more dots (.)
Packit a4aae4
// TODO The btp_stack is not needed since there are 'back pointers' in
Packit a4aae4
// BaseType.
Packit a4aae4
BaseType *
Packit a4aae4
Structure::m_exact_match(const string &name, btp_stack *s)
Packit a4aae4
{
Packit a4aae4
    // Look for name at the top level first.
Packit a4aae4
    for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
        if ((*i)->name() == name) {
Packit a4aae4
            if (s)
Packit a4aae4
                s->push(static_cast<BaseType *>(this));
Packit a4aae4
Packit a4aae4
            return *i;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    // If it was not found using the simple search, look for a dot and
Packit a4aae4
    // search the hierarchy.
Packit a4aae4
    string::size_type dot_pos = name.find("."); // zero-based index of `.'
Packit a4aae4
    if (dot_pos != string::npos) {
Packit a4aae4
        string aggregate = name.substr(0, dot_pos);
Packit a4aae4
        string field = name.substr(dot_pos + 1);
Packit a4aae4
Packit a4aae4
        BaseType *agg_ptr = var(aggregate);
Packit a4aae4
        if (agg_ptr) {
Packit a4aae4
            if (s)
Packit a4aae4
                s->push(static_cast<BaseType *>(this));
Packit a4aae4
Packit a4aae4
            return agg_ptr->var(field, true, s); // recurse
Packit a4aae4
        }
Packit a4aae4
        else
Packit a4aae4
            return 0;  // qualified names must be *fully* qualified
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return 0;
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
#if 0
Packit a4aae4
void
Packit a4aae4
Structure::print_val(FILE *out, string space, bool print_decl_p)
Packit a4aae4
{
Packit a4aae4
    ostringstream oss;
Packit a4aae4
    print_val(oss, space, print_decl_p);
Packit a4aae4
    fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
void
Packit a4aae4
Structure::print_val(ostream &out, string space, bool print_decl_p)
Packit a4aae4
{
Packit a4aae4
    if (print_decl_p) {
Packit a4aae4
        print_decl(out, space, false);
Packit a4aae4
	out << " = " ;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    out << "{ " ;
Packit a4aae4
    for (Vars_citer i = d_vars.begin(); i != d_vars.end();
Packit a4aae4
         i++, (void)(i != d_vars.end() && out << ", ")) {
Packit a4aae4
        (*i)->print_val(out, "", false);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    out << " }" ;
Packit a4aae4
Packit a4aae4
    if (print_decl_p)
Packit a4aae4
	out << ";\n" ;
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
#if 0
Packit a4aae4
bool
Packit a4aae4
Structure::check_semantics(string &msg, bool all)
Packit a4aae4
{
Packit a4aae4
    if (!BaseType::check_semantics(msg))
Packit a4aae4
        return false;
Packit a4aae4
Packit a4aae4
    bool status = true;
Packit a4aae4
Packit a4aae4
    if (!unique_names(d_vars, name(), type_name(), msg))
Packit a4aae4
        return false;
Packit a4aae4
Packit a4aae4
    if (all) {
Packit a4aae4
        for (Vars_iter i = d_vars.begin(); i != d_vars.end(); i++) {
Packit a4aae4
            //assert(*i);
Packit a4aae4
            if (!(*i)->check_semantics(msg, true)) {
Packit a4aae4
                status = false;
Packit a4aae4
                goto exit;
Packit a4aae4
            }
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
exit:
Packit a4aae4
    return status;
Packit a4aae4
}
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
/** @brief dumps information about this object
Packit a4aae4
 *
Packit a4aae4
 * Displays the pointer value of this instance and information about this
Packit a4aae4
 * instance.
Packit a4aae4
 *
Packit a4aae4
 * @param strm C++ i/o stream to dump the information to
Packit a4aae4
 * @return void
Packit a4aae4
 */
Packit a4aae4
void
Packit a4aae4
Structure::dump(ostream &strm) const
Packit a4aae4
{
Packit a4aae4
    strm << DapIndent::LMarg << "Structure::dump - ("
Packit a4aae4
    << (void *)this << ")" << endl ;
Packit a4aae4
    DapIndent::Indent() ;
Packit a4aae4
    Constructor::dump(strm) ;
Packit a4aae4
    DapIndent::UnIndent() ;
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
} // namespace libdap
Packit a4aae4