bes Updated for version 3.20.13
get_xml_data.cc
1// -*- mode: c++; c-basic-offset:4 -*-
2
3// Copyright (c) 2006 OPeNDAP, Inc.
4// Author: James Gallagher <jgallagher@opendap.org>
5//
6// This is free software; you can redistribute it and/or modify it under the
7// terms of the GNU Lesser General Public License as published by the Free
8// Software Foundation; either version 2.1 of the License, or (at your
9// option) any later version.
10//
11// This is distributed in the hope that it will be useful, but WITHOUT ANY
12// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
14// more details.
15//
16// You should have received a copy of the GNU Lesser General Public
17// License along with this library; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19//
20// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
21
22// This file holds the interface for the 'get data as ascii' function of the
23// OPeNDAP/HAO data server. This function is called by the BES when it loads
24// this as a module. The functions in the file ascii_val.cc also use this, so
25// the same basic processing software can be used both by Hyrax and tie older
26// Server3.
27
28#include <stdio.h>
29
30#include <iostream>
31
32using std::cerr;
33using std::endl;
34
35#include <libdap/DDS.h>
36
37#include <BESDebug.h>
38#include <RequestServiceTimer.h>
39
40#include "get_xml_data.h"
41#include "XDOutput.h"
42
43#include "XDByte.h"
44#include "XDInt16.h"
45#include "XDUInt16.h"
46#include "XDInt32.h"
47#include "XDUInt32.h"
48#include "XDFloat32.h"
49#include "XDFloat64.h"
50#include "XDStr.h"
51#include "XDUrl.h"
52#include "XDArray.h"
53#include "XDStructure.h"
54#include "XDSequence.h"
55#include "XDGrid.h"
56
57const char *DAP_SCHEMA = "http://xml.opendap.org/ns/dap/3.3#";
58
59using namespace libdap;
60
61#define MODULE "xml_data"
62#define prolog string("get_xml_data::").append(__func__).append("() - ")
63
64namespace xml_data {
65
73void get_data_values_as_xml(DDS *dds, XMLWriter *writer)
74{
75 try {
76 /* Start an element named "Dataset". Since this is the first element,
77 * this will be the root element of the document */
78 if (xmlTextWriterStartElementNS(writer->get_writer(), NULL, (const xmlChar*)"Dataset", (const xmlChar*)DAP_SCHEMA) < 0)
79 throw InternalErr(__FILE__, __LINE__, "Error starting the Dataset element for response ");
80
81 DDS::Vars_iter i = dds->var_begin();
82 while (i != dds->var_end()) {
83 if ((*i)->send_p()) {
84 RequestServiceTimer::TheTimer()->throw_if_timeout_expired(prolog + "ERROR: bes-timeout expired before transmit " + (*i)->name() , __FILE__, __LINE__);
85
86 BESDEBUG("xd", "Printing the values for " << (*i)->name() << " (" << (*i)->type_name() << ")" << endl);
87 dynamic_cast<XDOutput &>(**i).print_xml_data(writer, true);
88 }
89 ++i;
90 }
91
92 if (xmlTextWriterEndElement(writer->get_writer()) < 0)
93 throw InternalErr(__FILE__, __LINE__, "Error ending Dataset element.");
94
95 }
96 catch (InternalErr &e) {
97 xmlErrorPtr error = xmlGetLastError();
98 if (error && error->message)
99 throw InternalErr(e.get_error_message() + "; libxml: " + error->message);
100 else
101 throw InternalErr(e.get_error_message() + "; libxml: no message");
102 }
103}
104
105DDS *dds_to_xd_dds(DDS * dds)
106{
107 BESDEBUG("xd", "In datadds_to_xd_datadds" << endl);
108 // Should the following use XDOutputFactory instead of the source DDS'
109 // factory class? It doesn't matter for the following since the function
110 // basetype_to_asciitype() doesn't use the factory. So long as no other
111 // code uses the DDS' factory, this is fine. jhrg 9/5/06
112 DDS *xd_dds = new DDS(dds->get_factory(), dds->get_dataset_name());
113
114 DDS::Vars_iter i = dds->var_begin();
115 while (i != dds->var_end()) {
116 BaseType *abt = basetype_to_xd(*i);
117 xd_dds->add_var(abt);
118 // add_var makes a copy of the base type passed to it, so delete
119 // it here
120 delete abt;
121 ++i;
122 }
123
124 // Calling tag_nested_sequences() makes it easier to figure out if a
125 // sequence has parent or child sequences or if it is a 'flat' sequence.
126 xd_dds->tag_nested_sequences();
127
128 return xd_dds;
129}
130
131BaseType *
132basetype_to_xd(BaseType *bt)
133{
134 if (!bt)
135 throw InternalErr(__FILE__, __LINE__, "Null BaseType to XD factory");
136
137 switch (bt->type()) {
138 case dods_byte_c:
139 return new XDByte(dynamic_cast<Byte *>(bt));
140
141 case dods_int16_c:
142 return new XDInt16(dynamic_cast<Int16 *>(bt));
143
144 case dods_uint16_c:
145 return new XDUInt16(dynamic_cast<UInt16 *>(bt));
146
147 case dods_int32_c:
148 return new XDInt32(dynamic_cast<Int32 *>(bt));
149
150 case dods_uint32_c:
151 return new XDUInt32(dynamic_cast<UInt32 *>(bt));
152
153 case dods_float32_c:
154 return new XDFloat32(dynamic_cast<Float32 *>(bt));
155
156 case dods_float64_c:
157 return new XDFloat64(dynamic_cast<Float64 *>(bt));
158
159 case dods_str_c:
160 return new XDStr(dynamic_cast<Str *>(bt));
161
162 case dods_url_c:
163 return new XDUrl(dynamic_cast<Url *>(bt));
164
165 case dods_array_c:
166 return new XDArray(dynamic_cast<Array *>(bt));
167
168 case dods_structure_c:
169 return new XDStructure(dynamic_cast<Structure *>(bt));
170
171 case dods_sequence_c:
172 return new XDSequence(dynamic_cast<Sequence *>(bt));
173
174 case dods_grid_c:
175 return new XDGrid(dynamic_cast<Grid *>(bt));
176
177 default:
178 throw InternalErr(__FILE__, __LINE__, "Unknown type");
179 }
180}
181
182} // namespace xml_data
static RequestServiceTimer * TheTimer()
Return a pointer to a singleton timer instance. If an instance does not exist it will create and init...
void throw_if_timeout_expired(const std::string &message, const std::string &file, const int line)
Checks the RequestServiceTimer to determine if the time spent servicing the request at this point has...
Definition: XDByte.h:35
Definition: XDGrid.h:39
Definition: XDStr.h:39
Definition: XDUrl.h:55