|
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 |
#include "config.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <sstream>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "XMLWriter.h"
|
|
Packit |
a4aae4 |
#include "D4Dimensions.h"
|
|
Packit |
a4aae4 |
#include "D4Group.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "Error.h"
|
|
Packit |
a4aae4 |
#include "InternalErr.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4Dimension::set_size(const string &size)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
unsigned long value = 0;
|
|
Packit |
a4aae4 |
istringstream iss(size);
|
|
Packit |
a4aae4 |
iss >> value;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// First test if the stream is OK, then look to see if we read all
|
|
Packit |
a4aae4 |
// of the chars.
|
|
Packit |
a4aae4 |
if (!iss || !iss.eof()) throw Error("Invalid value '" + size + "' passed to D4Dimension::set_size.");
|
|
Packit |
a4aae4 |
set_size(value);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Get the FQN for the dimension
|
|
Packit |
a4aae4 |
* @return The D4Dimension as a fully qualified name.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
string
|
|
Packit |
a4aae4 |
D4Dimension::fully_qualified_name() const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
string name = d_name;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// d_parent is the D4Dimensions container and its parent is the Group where
|
|
Packit |
a4aae4 |
// this Dimension is defined.
|
|
Packit |
a4aae4 |
D4Group *grp = d_parent->parent();
|
|
Packit |
a4aae4 |
while (grp) {
|
|
Packit |
a4aae4 |
// The root group is named "/" (always); this avoids '//name'
|
|
Packit |
a4aae4 |
name = (grp->name() == "/") ? "/" + name : grp->name() + "/" + name;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (grp->get_parent())
|
|
Packit |
a4aae4 |
grp = static_cast<D4Group*>(grp->get_parent());
|
|
Packit |
a4aae4 |
else
|
|
Packit |
a4aae4 |
grp = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return name;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Print the Dimension declaration.
|
|
Packit |
a4aae4 |
* Print the Dimension in a form suitable for use in a Group definition/declaration.
|
|
Packit |
a4aae4 |
* @see print_dap4(XMLWriter &xml, bool print_fqn)
|
|
Packit |
a4aae4 |
* @param xml Print to this XMLWriter instance
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4Dimension::print_dap4(XMLWriter &xml) const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Dimension") < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not write Dimension element");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
// Use FQNs when things are referenced, not when they are defined
|
|
Packit |
a4aae4 |
if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)fully_qualified_name().c_str()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
ostringstream oss;
|
|
Packit |
a4aae4 |
if (d_constrained)
|
|
Packit |
a4aae4 |
oss << (d_c_stop - d_c_start) / d_c_stride + 1;
|
|
Packit |
a4aae4 |
else
|
|
Packit |
a4aae4 |
oss << d_size;
|
|
Packit |
a4aae4 |
if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "size", (const xmlChar*) oss.str().c_str()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not write attribute for size");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (xmlTextWriterEndElement(xml.get_writer()) < 0)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Could not end Dimension element");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Note that in order for this to work the second argument must not be a reference.
|
|
Packit |
a4aae4 |
// jhrg 8/20/13
|
|
Packit |
a4aae4 |
static bool
|
|
Packit |
a4aae4 |
dim_name_eq(D4Dimension *d, const string name)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return d->name() == name;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4Dimension *
|
|
Packit |
a4aae4 |
D4Dimensions::find_dim(const string &name)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
D4DimensionsIter d = find_if(d_dims.begin(), d_dims.end(), bind2nd(ptr_fun(dim_name_eq), name));
|
|
Packit |
a4aae4 |
return (d != d_dims.end()) ? *d: 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4Dimensions::print_dap4(XMLWriter &xml, bool constrained) const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
D4DimensionsCIter i = d_dims.begin();
|
|
Packit |
a4aae4 |
while (i != d_dims.end()) {
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
if (!constrained || parent()->find_first_var_that_uses_dimension(*i))
|
|
Packit |
a4aae4 |
(*i)->print_dap4(xml);
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
if (constrained) {
|
|
Packit |
a4aae4 |
if ((*i)->used_by_projected_var())
|
|
Packit |
a4aae4 |
(*i)->print_dap4(xml);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
(*i)->print_dap4(xml);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
++i;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} /* namespace libdap */
|