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 
32 using std::cerr;
33 using 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 
57 const char *DAP_SCHEMA = "http://xml.opendap.org/ns/dap/3.3#";
58 
59 using namespace libdap;
60 
61 #define MODULE "xml_data"
62 #define prolog string("get_xml_data::").append(__func__).append("() - ")
63 
64 namespace xml_data {
65 
73 void 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 
105 DDS *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 
131 BaseType *
132 basetype_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