libdap  Updated for version 3.20.6
libdap4 is an implementation of OPeNDAP's DAP protocol.
D4Dimensions.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2013 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 #include "config.h"
26 
27 #include <sstream>
28 
29 #include "XMLWriter.h"
30 #include "D4Dimensions.h"
31 #include "D4Group.h"
32 
33 #include "Error.h"
34 #include "InternalErr.h"
35 
36 namespace libdap {
37 
38 void
39 D4Dimension::set_size(const string &size)
40 {
41  unsigned long value = 0;
42  istringstream iss(size);
43  iss >> value;
44 
45  // First test if the stream is OK, then look to see if we read all
46  // of the chars.
47  if (!iss || !iss.eof()) throw Error("Invalid value '" + size + "' passed to D4Dimension::set_size.");
48  set_size(value);
49 }
50 
55 string
57 {
58  string name = d_name;
59 
60  // d_parent is the D4Dimensions container and its parent is the Group where
61  // this Dimension is defined.
62  D4Group *grp = d_parent->parent();
63  while (grp) {
64  // The root group is named "/" (always); this avoids '//name'
65  name = (grp->name() == "/") ? "/" + name : grp->name() + "/" + name;
66 
67  if (grp->get_parent())
68  grp = static_cast<D4Group*>(grp->get_parent());
69  else
70  grp = 0;
71  }
72 
73  return name;
74 }
75 
82 void
84 {
85  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Dimension") < 0)
86  throw InternalErr(__FILE__, __LINE__, "Could not write Dimension element");
87 
88  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
89  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
90 #if 0
91  // Use FQNs when things are referenced, not when they are defined
92  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)fully_qualified_name().c_str()) < 0)
93  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
94 #endif
95  ostringstream oss;
96  if (d_constrained)
97  oss << (d_c_stop - d_c_start) / d_c_stride + 1;
98  else
99  oss << d_size;
100  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "size", (const xmlChar*) oss.str().c_str()) < 0)
101  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for size");
102 
103  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
104  throw InternalErr(__FILE__, __LINE__, "Could not end Dimension element");
105 }
106 
107 // Note that in order for this to work the second argument must not be a reference.
108 // jhrg 8/20/13
109 static bool
110 dim_name_eq(D4Dimension *d, const string name)
111 {
112  return d->name() == name;
113 }
114 
115 D4Dimension *
116 D4Dimensions::find_dim(const string &name)
117 {
118  D4DimensionsIter d = find_if(d_dims.begin(), d_dims.end(), bind2nd(ptr_fun(dim_name_eq), name));
119  return (d != d_dims.end()) ? *d: 0;
120 }
121 
122 void
123 D4Dimensions::print_dap4(XMLWriter &xml, bool constrained) const
124 {
125  D4DimensionsCIter i = d_dims.begin();
126  while (i != d_dims.end()) {
127 #if 0
128  if (!constrained || parent()->find_first_var_that_uses_dimension(*i))
129  (*i)->print_dap4(xml);
130 #endif
131  if (constrained) {
132  if ((*i)->used_by_projected_var())
133  (*i)->print_dap4(xml);
134  }
135  else {
136  (*i)->print_dap4(xml);
137  }
138  ++i;
139  }
140 }
141 
142 } /* namespace libdap */
virtual string name() const
Returns the name of the class instance.
Definition: BaseType.cc:320
top level DAP object to house generic methods
Definition: AISConnect.cc:30
A class for software fault reporting.
Definition: InternalErr.h:64
string fully_qualified_name() const
Get the FQN for the dimension.
Definition: D4Dimensions.cc:56
virtual BaseType * get_parent() const
Definition: BaseType.cc:751
void print_dap4(XMLWriter &xml) const
Print the Dimension declaration. Print the Dimension in a form suitable for use in a Group definition...
Definition: D4Dimensions.cc:83