45#include <libdap/InternalErr.h>
46#include <libdap/escaping.h>
47#include <libdap/util.h>
48#include <libdap/debug.h>
51#include "get_xml_data.h"
53using namespace xml_data;
56XDArray::ptr_duplicate()
58 return new XDArray(*
this);
61XDArray::XDArray(
const string &n, BaseType *v) : Array(n, v)
65XDArray::XDArray( Array *bt )
66 : Array(bt->name(), 0),
XDOutput( bt )
71 BaseType *abt = basetype_to_xd( bt->var() ) ;
77 Dim_iter p = bt->dim_begin();
78 while ( p != bt->dim_end() ) {
79 append_dim(bt->dimension_size(p,
true), bt->dimension_name(p));
87 set_send_p(bt->send_p());
102 if (var()->is_simple_type()) {
103 if (dimensions(
true) > 1) {
105 m_print_xml_array(writer,
"Map");
108 m_print_xml_vector(writer,
"Map");
112 throw InternalErr(__FILE__, __LINE__,
"A Map must be a simple type.");
116void XDArray::print_xml_data(XMLWriter *writer,
bool )
throw(InternalErr)
118 BESDEBUG(
"xd",
"Entering XDArray::print_xml_data" << endl);
120 if (var()->is_simple_type()) {
121 if (dimensions(
true) > 1)
122 m_print_xml_array(writer,
"Array");
124 m_print_xml_vector(writer,
"Array");
127 m_print_xml_complex_array(writer,
"Array");
131class PrintArrayDimXML :
public unary_function<Array::dimension&, void>
137 PrintArrayDimXML(XMLWriter *writer,
bool c)
138 : d_writer(writer), d_constrained(c)
141 void operator()(Array::dimension &d)
143 int size = d_constrained ? d.c_size : d.size;
144 if (d.name.empty()) {
145 if (xmlTextWriterStartElement(d_writer->get_writer(), (
const xmlChar*)
"dimension") < 0)
146 throw InternalErr(__FILE__, __LINE__,
"Could not write dimension element");
147 if (xmlTextWriterWriteFormatAttribute(d_writer->get_writer(), (
const xmlChar*)
"size",
"%d", size) < 0)
148 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for size");
149 if (xmlTextWriterEndElement(d_writer->get_writer()) < 0)
150 throw InternalErr(__FILE__, __LINE__,
"Could not end dimension element");
153 string id_name = id2xml(d.name);
154 if (xmlTextWriterStartElement(d_writer->get_writer(), (
const xmlChar*)
"dimension") < 0)
155 throw InternalErr(__FILE__, __LINE__,
"Could not write dimension element");
156 if (xmlTextWriterWriteAttribute(d_writer->get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)id_name.c_str()) < 0)
157 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
158 if (xmlTextWriterWriteFormatAttribute(d_writer->get_writer(), (
const xmlChar*)
"size",
"%d", size) < 0)
159 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for size");
160 if (xmlTextWriterEndElement(d_writer->get_writer()) < 0)
161 throw InternalErr(__FILE__, __LINE__,
"Could not end dimension element");
166void XDArray::start_xml_declaration(XMLWriter *writer,
const char *element)
throw(InternalErr)
169 if (xmlTextWriterStartElement(writer->get_writer(), (element != 0) ? (
const xmlChar*)element : (
const xmlChar*)
"Array") < 0)
170 throw InternalErr(__FILE__, __LINE__,
"Could not write Array element '" + ((element != 0) ?
string(element):
string(
"Array")) +
"' for " + name());
171 if (xmlTextWriterWriteAttribute(writer->get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)name().c_str()) < 0)
172 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for " + name());
175 dynamic_cast<XDOutput&
>(*var()).start_xml_declaration(writer);
177 end_xml_declaration(writer);
179 for_each(dim_begin(), dim_end(), PrintArrayDimXML(writer,
true));
183void XDArray::m_print_xml_vector(XMLWriter *writer,
const char *element)
185 BESDEBUG(
"xd",
"Entering XDArray::m_print_xml_vector" << endl);
187 start_xml_declaration(writer, element);
190 int end = dimension_size(dim_begin(),
true);
191 m_print_xml_row(writer, 0, end);
193 end_xml_declaration(writer);
196void XDArray::m_print_xml_array(XMLWriter *writer,
const char *element)
198 BESDEBUG(
"xd",
"Entering XDArray::m_print_xml_array" << endl);
200 int dims = dimensions(
true);
202 throw InternalErr(__FILE__, __LINE__,
"Dimension count is <= 1 while printing multidimensional array.");
204 start_xml_declaration(writer, element);
215 vector < int >state(dims - 1, 0);
220 for (
int i = 0; i < dims - 1; ++i) {
221 if (xmlTextWriterStartElement(writer->get_writer(), (
const xmlChar*)
"dim") < 0)
222 throw InternalErr(__FILE__, __LINE__,
"Could not write Array element for " + name());
223 if (xmlTextWriterWriteFormatAttribute(writer->get_writer(), (
const xmlChar*)
"number",
"%d", i) < 0)
224 throw InternalErr(__FILE__, __LINE__,
"Could not write number attribute for " + name() +
": " + long_to_string(i));
225 if (xmlTextWriterWriteFormatAttribute(writer->get_writer(), (
const xmlChar*)
"index",
"%d", state[i]) < 0)
226 throw InternalErr(__FILE__, __LINE__,
"Could not write index attribute for " + name());
229 index = m_print_xml_row(writer, index, rightmost_dim_size);
231 for (
int i = 0; i < dims - 1; ++i) {
232 if (xmlTextWriterEndElement(writer->get_writer()) < 0)
233 throw InternalErr(__FILE__, __LINE__,
"Could not end element for " + name());
236 more_indices = increment_state(&state, shape);
237 }
while (more_indices);
239 end_xml_declaration(writer);
269int XDArray::m_print_xml_row(XMLWriter *writer,
int index,
int number)
271 Array *a =
dynamic_cast<Array*
>(d_redirect);
277 throw InternalErr(__FILE__, __LINE__,
"d_redirect is null");
280 BESDEBUG(
"xd",
"Entering XDArray::m_print_xml_row" << endl);
281 for (
int i = 0; i < number; ++i) {
283 BaseType *curr_var = basetype_to_xd(a->var(index++));
284 dynamic_cast < XDOutput &
>(*curr_var).print_xml_data(writer,
false);
294int XDArray::m_get_index(vector < int >indices)
throw(InternalErr)
296 if (indices.size() != dimensions(
true)) {
297 throw InternalErr(__FILE__, __LINE__,
298 "Index vector is the wrong size!");
305 vector < int >shape = get_shape_vector(indices.size());
308 reverse(indices.begin(), indices.end());
309 reverse(shape.begin(), shape.end());
311 vector < int >::iterator indices_iter = indices.begin();
312 vector < int >::iterator shape_iter = shape.begin();
314 int index = *indices_iter++;
316 while (indices_iter != indices.end()) {
317 multiplier *= *shape_iter++;
318 index += multiplier * *indices_iter++;
334 if (n < 1 || n > dimensions(
true)) {
335 string msg =
"Attempt to get ";
336 msg += long_to_string(n) +
" dimensions from " + name()
337 +
" which has only " + long_to_string(dimensions(
true))
340 throw InternalErr(__FILE__, __LINE__, msg);
344 Array::Dim_iter p = dim_begin();
345 for (
unsigned i = 0; i < n && p != dim_end(); ++i, ++p) {
346 shape.push_back(dimension_size(p,
true));
357 if (n > dimensions(
true) - 1) {
358 string msg =
"Attempt to get dimension ";
360 long_to_string(n + 1) +
" from `" + name() +
361 "' which has " + long_to_string(dimensions(
true)) +
363 throw InternalErr(__FILE__, __LINE__, msg);
366 return dimension_size(dim_begin() + n,
true);
369void XDArray::m_print_xml_complex_array(XMLWriter *writer,
const char *element)
371 start_xml_declaration(writer, element);
373 int dims = dimensions(
true);
375 throw InternalErr(__FILE__, __LINE__,
"Dimension count is < 1 while printing an array.");
381 vector < int >state(dims, 0);
383 bool more_indices =
true;
385 for (
int i = 0; i < dims - 1; ++i) {
386 if (xmlTextWriterStartElement(writer->get_writer(), (
const xmlChar*)
"dim") < 0)
387 throw InternalErr(__FILE__, __LINE__,
"Could not write Array element for " + name());
388 if (xmlTextWriterWriteFormatAttribute(writer->get_writer(), (
const xmlChar*)
"number",
"%d", i) < 0)
389 throw InternalErr(__FILE__, __LINE__,
"Could not write number attribute for " + name() +
": " + long_to_string(i));
390 if (xmlTextWriterWriteFormatAttribute(writer->get_writer(), (
const xmlChar*)
"index",
"%d", state[i]) < 0)
391 throw InternalErr(__FILE__, __LINE__,
"Could not write index attribute for " + name());
394 BaseType *curr_var = basetype_to_xd(var(m_get_index(state)));
395 dynamic_cast < XDOutput &
>(*curr_var).print_xml_data(writer,
true);
399 for (
int i = 0; i < dims - 1; ++i) {
400 if (xmlTextWriterEndElement(writer->get_writer()) < 0)
401 throw InternalErr(__FILE__, __LINE__,
"Could not end element for " + name());
404 more_indices = increment_state(&state, shape);
406 }
while (more_indices);
408 end_xml_declaration(writer);
void print_xml_map_data(XMLWriter *writer, bool show_type)
vector< int > get_shape_vector(size_t n)
int get_nth_dim_size(size_t n)
XDOutput(libdap::BaseType *bt)