bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
AsciiSequence.cc
1// -*- mode: c++; c-basic-offset:4 -*-
2
3// This file is part of asciival, software which can return an ASCII
4// representation of the data read from a DAP server.
5
6// Copyright (c) 2002,2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22//
23// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24
25// (c) COPYRIGHT URI/MIT 1998,2000
26// Please read the full copyright statement in the file COPYRIGHT_URI.
27//
28// Authors:
29// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
30
31// Implementation for the class AsciiStructure. See AsciiByte.cc
32//
33// 3/12/98 jhrg
34
35#include "config.h"
36
37#include <iostream>
38#include <string>
39
40#include <BESDebug.h>
41
42#include <libdap/InternalErr.h>
43#include "AsciiSequence.h"
44#include "AsciiStructure.h"
45#include "get_ascii.h"
46#include <libdap/debug.h>
47
48using std::endl;
49using namespace dap_asciival;
50
51BaseType *
52AsciiSequence::ptr_duplicate()
53{
54 return new AsciiSequence(*this);
55}
56
57AsciiSequence::AsciiSequence(const string &n) :
58 Sequence(n)
59{
60}
61
62AsciiSequence::AsciiSequence(Sequence * bt) :
63 Sequence(bt->name()), AsciiOutput(bt)
64{
65 // Let's make the alternative structure of Ascii types now so that we
66 // don't have to do it on the fly.
67 Vars_iter p = bt->var_begin();
68 while (p != bt->var_end()) {
69 BaseType *new_bt = basetype_to_asciitype(*p);
70 add_var(new_bt);
71 delete new_bt;
72 p++;
73 }
74
75 BaseType::set_send_p(bt->send_p());
76}
77
78AsciiSequence::~AsciiSequence()
79{
80}
81
82int AsciiSequence::size() const
83{
84 return -1;
85}
86
87// This specialization is different from the Sequence version only in that
88// it tests '(*iter)->send_p()' before incrementing 'i' by
89// '(*iter)->element_count(true)'.
90int AsciiSequence::element_count(bool leaves)
91{
92 if (!leaves)
93 return d_vars.size();
94 else {
95 int i = 0;
96 for (Vars_iter iter = d_vars.begin(); iter != d_vars.end(); iter++) {
97 if ((*iter)->send_p()) i += (*iter)->element_count(true);
98 }
99 return i;
100 }
101}
102
103void AsciiSequence::print_ascii_row(ostream &strm, int row, BaseTypeRow outer_vars)
104{
105 BESDEBUG("ascii", " In AsciiSequence::print_ascii_row" << endl);
106
107 Sequence *seq = dynamic_cast<Sequence *>(_redirect);
108 if (!seq) seq = this;
109
110 // Print the values from this sequence.
111 // AsciiSequence::element_count() returns only vars with send_p() set.
112 const int elements = element_count();
113 bool first_var = true; // used to control printing the comma separator
114 int j = 0;
115 do {
116 BaseType *bt_ptr = seq->var_value(row, j);
117 if (bt_ptr) { // Check for data.
118 BaseType *abt_ptr = basetype_to_asciitype(bt_ptr);
119 if (abt_ptr->type() == dods_sequence_c) {
120 if (abt_ptr->send_p()) {
121 if (!first_var)
122 strm << ", ";
123 else
124 first_var = false;
125
126 dynamic_cast<AsciiSequence&>(*abt_ptr).print_ascii_rows(strm, outer_vars);
127 }
128 }
129 else {
130 // push the real base type pointer instead of the ascii one.
131 // We can cast it again later from the outer_vars vector.
132 outer_vars.push_back(bt_ptr);
133 if (abt_ptr->send_p()) {
134 if (!first_var)
135 strm << ", ";
136 else
137 first_var = false;
138
139 dynamic_cast<AsciiOutput&>(*abt_ptr).print_ascii(strm, false);
140 }
141 }
142
143 // we only need the ascii type here, so delete it
144 delete abt_ptr;
145 }
146
147 ++j;
148 } while (j < elements);
149}
150
151void AsciiSequence::print_leading_vars(ostream &strm, BaseTypeRow & outer_vars)
152{
153 BESDEBUG("ascii", " In AsciiSequence::print_leading_vars" << endl);
154
155 bool first_var = true;
156 BaseTypeRow::iterator BTR_iter = outer_vars.begin();
157 while (BTR_iter != outer_vars.end()) {
158 BaseType *abt_ptr = basetype_to_asciitype(*BTR_iter);
159 if (!first_var)
160 strm << ", ";
161 else
162 first_var = false;
163 dynamic_cast<AsciiOutput&>(*abt_ptr).print_ascii(strm, false);
164 delete abt_ptr;
165
166 ++BTR_iter;
167 }
168
169 BESDEBUG("ascii", " Out AsciiSequence::print_leading_vars" << endl);
170}
171
172void AsciiSequence::print_ascii_rows(ostream &strm, BaseTypeRow outer_vars)
173{
174 Sequence *seq = dynamic_cast<Sequence *>(_redirect);
175 if (!seq) seq = this;
176
177 const int rows = seq->number_of_rows() - 1;
178 int i = 0;
179 bool done = false;
180 do {
181 if (i > 0 && !outer_vars.empty()) print_leading_vars(strm, outer_vars);
182
183 print_ascii_row(strm, i++, outer_vars);
184
185 if (i > rows)
186 done = true;
187 else
188 strm << "\n";
189 } while (!done);
190
191 BESDEBUG("ascii", " Out AsciiSequence::print_ascii_rows" << endl);
192}
193
194void AsciiSequence::print_header(ostream &strm)
195{
196 bool first_var = true; // Print commas as separators
197 Vars_iter p = var_begin();
198 while (p != var_end()) {
199 if ((*p)->send_p()) {
200 if (!first_var)
201 strm << ", ";
202 else
203 first_var = false;
204
205 if ((*p)->is_simple_type())
206 strm << dynamic_cast<AsciiOutput *>(*p)->get_full_name();
207 else if ((*p)->type() == dods_sequence_c)
208 dynamic_cast<AsciiSequence *>(*p)->print_header(strm);
209 else if ((*p)->type() == dods_structure_c)
210 dynamic_cast<AsciiStructure *>(*p)->print_header(strm);
211 else
212 throw InternalErr(
213 __FILE__,
214 __LINE__,
215 "This method should only be called by instances for which `is_simple_sequence' returns true.");
216 }
217
218 ++p;
219 }
220}
221
222void AsciiSequence::print_ascii(ostream &strm, bool print_name) throw (InternalErr)
223{
224 BESDEBUG("ascii", "In AsciiSequence::print_ascii" << endl);
225 Sequence *seq = dynamic_cast<Sequence *>(_redirect);
226 if (!seq) seq = this;
227
228 if (seq->is_linear()) {
229 if (print_name) {
230 print_header(strm);
231 strm << "\n";
232 }
233
234 BaseTypeRow outer_vars(0);
235 print_ascii_rows(strm, outer_vars);
236 }
237 else {
238 const int rows = seq->number_of_rows() - 1;
239 const int elements = seq->element_count() - 1;
240
241 // For each row of the Sequence...
242 bool rows_done = false;
243 int i = 0;
244 do {
245 // For each variable of the row...
246 bool vars_done = false;
247 int j = 0;
248 do {
249 BaseType *bt_ptr = seq->var_value(i, j++);
250 BaseType *abt_ptr = basetype_to_asciitype(bt_ptr);
251 dynamic_cast<AsciiOutput&>(*abt_ptr).print_ascii(strm, true);
252 // abt_ptr is not stored for future use, so delete it
253 delete abt_ptr;
254
255 if (j > elements)
256 vars_done = true;
257 else
258 strm << "\n";
259 } while (!vars_done);
260
261 i++;
262 if (i > rows)
263 rows_done = true;
264 else
265 strm << "\n";
266 } while (!rows_done);
267 }
268}
virtual void print_ascii(ostream &strm, bool print_name)