libdap  Updated for version 3.17.0
D4Dimensions.cc
00001 // -*- mode: c++; c-basic-offset:4 -*-
00002 
00003 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00004 // Access Protocol.
00005 
00006 // Copyright (c) 2013 OPeNDAP, Inc.
00007 // Author: James Gallagher <jgallagher@opendap.org>
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 //
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00024 
00025 #include "config.h"
00026 
00027 #include <sstream>
00028 
00029 #include "XMLWriter.h"
00030 #include "D4Dimensions.h"
00031 #include "D4Group.h"
00032 
00033 #include "Error.h"
00034 #include "InternalErr.h"
00035 
00036 namespace libdap {
00037 
00038 void
00039 D4Dimension::set_size(const string &size)
00040 {
00041         unsigned long value = 0;
00042         istringstream iss(size);
00043         iss >> value;
00044 
00045         // First test if the stream is OK, then look to see if we read all
00046         // of the chars.
00047         if (!iss || !iss.eof()) throw Error("Invalid value '" + size + "' passed to D4Dimension::set_size.");
00048         set_size(value);
00049 }
00050 
00055 string
00056 D4Dimension::fully_qualified_name() const
00057 {
00058         string name = d_name;
00059 
00060         // d_parent is the D4Dimensions container and its parent is the Group where
00061         // this Dimension is defined.
00062         D4Group *grp = d_parent->parent();
00063         while (grp) {
00064                 // The root group is named "/" (always); this avoids '//name'
00065                 name = (grp->name() == "/") ? "/" + name : grp->name() + "/" + name;
00066 
00067                 if (grp->get_parent())
00068                         grp = static_cast<D4Group*>(grp->get_parent());
00069                 else
00070                         grp = 0;
00071         }
00072 
00073         return name;
00074 }
00075 
00082 void
00083 D4Dimension::print_dap4(XMLWriter &xml) const
00084 {
00085         if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Dimension") < 0)
00086                 throw InternalErr(__FILE__, __LINE__, "Could not write Dimension element");
00087 
00088         if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
00089                 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
00090 #if 0
00091         // Use FQNs when things are referenced, not when they are defined
00092         if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)fully_qualified_name().c_str()) < 0)
00093                 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
00094 #endif
00095         ostringstream oss;
00096         if (d_constrained)
00097             oss << (d_c_stop - d_c_start) / d_c_stride + 1;
00098         else
00099             oss << d_size;
00100         if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "size", (const xmlChar*) oss.str().c_str()) < 0)
00101                 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for size");
00102 
00103         if (xmlTextWriterEndElement(xml.get_writer()) < 0)
00104                 throw InternalErr(__FILE__, __LINE__, "Could not end Dimension element");
00105 }
00106 
00107 // Note that in order for this to work the second argument must not be a reference.
00108 // jhrg 8/20/13
00109 static bool
00110 dim_name_eq(D4Dimension *d, const string name)
00111 {
00112         return d->name() == name;
00113 }
00114 
00115 D4Dimension *
00116 D4Dimensions::find_dim(const string &name)
00117 {
00118         D4DimensionsIter d = find_if(d_dims.begin(), d_dims.end(), bind2nd(ptr_fun(dim_name_eq), name));
00119         return (d != d_dims.end()) ? *d: 0;
00120 }
00121 
00122 void
00123 D4Dimensions::print_dap4(XMLWriter &xml, bool constrained) const
00124 {
00125     D4DimensionsCIter i = d_dims.begin();
00126     while (i != d_dims.end()) {
00127 #if 0
00128         if (!constrained || parent()->find_first_var_that_uses_dimension(*i))
00129             (*i)->print_dap4(xml);
00130 #endif
00131         if (constrained) {
00132                 if ((*i)->used_by_projected_var())
00133                     (*i)->print_dap4(xml);
00134         }
00135         else {
00136                 (*i)->print_dap4(xml);
00137         }
00138         ++i;
00139     }
00140 }
00141 
00142 } /* namespace libdap */