33#include <libdap/DMR.h>
34#include <libdap/BaseType.h>
35#include <libdap/Structure.h>
36#include <libdap/Array.h>
37#include <libdap/D4Sequence.h>
38#include <libdap/D4Enum.h>
39#include <libdap/D4Opaque.h>
40#include <libdap/D4Group.h>
41#include <libdap/crc.h>
42#include <libdap/InternalErr.h>
44#include "get_ascii_dap4.h"
46namespace dap_asciival {
48using namespace libdap;
53static void print_values_as_ascii(BaseType *btp,
bool print_name, ostream &strm, Crc32 &checksum);
54static void print_sequence_header(D4Sequence *s, ostream &strm);
55static void print_val_by_rows(D4Sequence *seq, ostream &strm, Crc32 &checksum);
67static void print_array_vector(Array *a, ostream &strm,
bool print_name)
70 strm << a->FQN() <<
", " ;
75 if (a->dimension_size_ll(a->dim_begin(),
true) > 0) {
76 int64_t end = a->dimension_size_ll(a->dim_begin(),
true) - 1;
78 for (int64_t i = 0; i < end; ++i) {
79 a->var_ll(i)->print_val(strm,
"",
false );
82 a->var(end)->print_val(strm,
"",
false );
97static int print_array_row(Array *a, ostream &strm,
int index,
int number)
101 for (
int i = 0; i < number; ++i) {
102 a->var(index++)->print_val(strm,
"",
false );
106 a->var(index++)->print_val(strm,
"",
false );
118static bool increment_state(vector<int> *state,
const vector<int> &shape)
120 vector < int >::reverse_iterator state_riter;
121 vector < int >::const_reverse_iterator shape_riter;
122 for (state_riter = state->rbegin(), shape_riter = shape.rbegin();
123 state_riter < state->rend(); state_riter++, shape_riter++) {
124 if (*state_riter == *shape_riter - 1) {
128 *state_riter = *state_riter + 1;
136static vector <int> get_shape_vector(Array *a,
size_t n)
138 if (n < 1 || n > a->dimensions(
true)) {
140 oss <<
"Attempt to get " << n <<
" dimensions from " << a->name() <<
" which has " << a->dimensions(
true) <<
" dimensions";
141 throw InternalErr(__FILE__, __LINE__, oss.str());
145 Array::Dim_iter p = a->dim_begin();
146 for (
unsigned i = 0; i < n && p != a->dim_end(); ++i, ++p) {
147 shape.push_back(a->dimension_size(p,
true));
156static int get_nth_dim_size(Array *a,
size_t n)
158 if (n > a->dimensions(
true) - 1) {
160 oss <<
"Attempt to get dimension " << n <<
" from " << a->name() <<
" which has " << a->dimensions(
true) <<
" dimensions";
161 throw InternalErr(__FILE__, __LINE__, oss.str());
164 return a->dimension_size(a->dim_begin() + n,
true);
167static void print_ndim_array(Array *a, ostream &strm,
bool )
170 int dims = a->dimensions(
true);
172 throw InternalErr(__FILE__, __LINE__,
"Dimension count is <= 1 while printing multidimensional array.");
176 vector<int> shape = get_shape_vector(a, dims - 1);
177 int rightmost_dim_size = get_nth_dim_size(a, dims - 1);
183 vector<int> state(dims - 1, 0);
191 for (
int i = 0; i < dims - 1; ++i) {
192 strm <<
"[" << state[i] <<
"]" ;
196 index = print_array_row(a, strm, index, rightmost_dim_size - 1);
197 more_indices = increment_state(&state, shape);
201 }
while (more_indices);
204static int get_index(Array *a, vector<int> indices)
206 if (indices.size() != a->dimensions(
true))
207 throw InternalErr(__FILE__, __LINE__,
"Index vector is the wrong size!");
213 vector < int >shape = get_shape_vector(a, indices.size());
216 reverse(indices.begin(), indices.end());
217 reverse(shape.begin(), shape.end());
219 vector<int>::iterator indices_iter = indices.begin();
220 vector<int>::iterator shape_iter = shape.begin();
222 int index = *indices_iter++;
224 while (indices_iter != indices.end()) {
225 multiplier *= *shape_iter++;
226 index += multiplier * *indices_iter++;
241static void print_complex_array(Array *a, ostream &strm,
bool print_name, Crc32 &checksum)
243 int dims = a->dimensions(
true);
245 throw InternalErr(__FILE__, __LINE__,
"Dimension count is <= 1 while printing multidimensional array.");
249 vector<int> shape = get_shape_vector(a, dims);
251 vector<int> state(dims, 0);
258 for (
int i = 0; i < dims; ++i) {
259 strm <<
"[" << state[i] <<
"]" ;
263 print_values_as_ascii(a->var(get_index(a, state)), print_name, strm, checksum);
265 more_indices = increment_state(&state, shape);
270 }
while (more_indices);
282static void print_values_as_ascii(Array *a,
bool print_name, ostream &strm, Crc32 &checksum)
284 if (a->var()->is_simple_type()) {
285 if (a->dimensions(
true) > 1) {
286 print_ndim_array(a, strm, print_name);
289 print_array_vector(a, strm, print_name);
293 print_complex_array(a, strm, print_name, checksum);
297static void print_structure_header(Structure *s, ostream &strm)
299 Constructor::Vars_iter p = s->var_begin(), e = s->var_end();
300 bool needs_comma =
false;
303 if ((*p)->is_simple_type())
304 strm << (needs_comma?
", ":
"") << (*p)->FQN();
305 else if ((*p)->type() == dods_structure_c)
306 print_structure_header(
static_cast<Structure*
>(*p), strm);
307 else if ((*p)->type() == dods_sequence_c)
308 print_sequence_header(
static_cast<D4Sequence*
>(*p), strm);
310 throw InternalErr(__FILE__, __LINE__,
"Unknown or unsupported type.");
317static void print_structure_ascii(Structure *s, ostream &strm,
bool print_name, Crc32 &checksum)
319 if (s->is_linear()) {
321 print_structure_header(s, strm);
325 Constructor::Vars_iter p = s->var_begin(), e = s->var_end();
328 if ((*p)->send_p()) print_values_as_ascii(*p,
false , strm, checksum);
330 if (++p != e) strm <<
", ";
334 for (Constructor::Vars_iter p = s->var_begin(), e = s->var_end(); p != e; ++p) {
335 if ((*p)->send_p()) {
336 print_values_as_ascii(*p, print_name, strm, checksum);
346static void print_values_as_ascii(Structure *v,
bool print_name, ostream &strm, Crc32 &checksum)
348 print_structure_ascii(v, strm, print_name, checksum);
351static void print_one_row(D4Sequence *seq, ostream &strm, Crc32 &checksum,
int row)
353 int elements = seq->element_count();
356 bool first_val =
true;
358 while (j < elements) {
359 btp = seq->var_value(row, j++);
364 if (btp->type() == dods_sequence_c)
365 print_val_by_rows(
static_cast<D4Sequence*
>(btp), strm, checksum);
367 print_values_as_ascii(btp,
false, strm, checksum);
372static void print_val_by_rows(D4Sequence *seq, ostream &strm, Crc32 &checksum)
374 if (seq->length() != 0) {
375 int rows = seq->length() ;
376 for (
int i = 0; i < rows; ++i) {
377 print_one_row(seq, strm, checksum, i);
383static void print_sequence_header(D4Sequence *s, ostream &strm)
385 Constructor::Vars_iter p = s->var_begin(), e = s->var_end();
386 bool needs_comma =
false;
389 if((*p)->is_simple_type())
390 strm << (needs_comma?
", ":
"") << (*p)->FQN();
391 else if ((*p)->type() == dods_structure_c)
392 print_structure_header(
static_cast<Structure*
>((*p)), strm);
393 else if ((*p)->type() == dods_sequence_c)
394 print_sequence_header(
static_cast<D4Sequence*
>((*p)), strm);
396 throw InternalErr(__FILE__, __LINE__,
"Unknown or unsupported type.");
405static void print_values_as_ascii(D4Sequence *v,
bool print_name, ostream &strm, Crc32 &checksum)
408 print_sequence_header(v, strm);
412 print_val_by_rows(v, strm, checksum);
415static void print_values_as_ascii(D4Opaque *v,
bool print_name, ostream &strm, Crc32 &)
418 strm << v->FQN() <<
", ";
419 strm << v->value().size() <<
" bytes" << endl;
422static void print_values_as_ascii(D4Group *group,
bool print_name, ostream &strm, Crc32 &checksum)
424 for (D4Group::groupsIter g = group->grp_begin(), e = group->grp_end(); g != e; ++g)
425 print_values_as_ascii(*g, print_name, strm, checksum);
434 for (Constructor::Vars_iter i = group->var_begin(), e = group->var_end(); i != e; ++i) {
436 if ((*i)->send_p()) {
439 print_values_as_ascii((*i), print_name, strm, checksum);
454static void print_values_as_ascii(BaseType *btp,
bool print_name, ostream &strm, Crc32 &checksum)
456 switch (btp->type()) {
458 throw InternalErr(__FILE__, __LINE__,
"Unknown type");
479 if (print_name) strm << btp->FQN() <<
", ";
480 btp->print_val(strm,
"" ,
false );
484 print_values_as_ascii(
static_cast<D4Opaque*
>(btp), print_name, strm, checksum);
488 print_values_as_ascii(
static_cast<Array*
>(btp), print_name, strm, checksum);
491 case dods_structure_c:
492 print_values_as_ascii(
static_cast<Structure*
>(btp), print_name, strm, checksum);
495 case dods_sequence_c:
496 print_values_as_ascii(
static_cast<D4Sequence*
>(btp), print_name, strm, checksum);
500 print_values_as_ascii(
static_cast<D4Group*
>(btp), print_name, strm, checksum);
505 throw InternalErr(__FILE__, __LINE__,
"Unsupported type");
516void print_values_as_ascii(DMR *dmr, ostream &strm)
520 strm <<
"Dataset: " << dmr->name() << endl;
522 print_values_as_ascii(dmr->root(),
true , strm, checksum);