libdap Updated for version 3.21.1
libdap4 is an implementation of OPeNDAP's DAP protocol.
XDRStreamUnMarshaller.cc
Go to the documentation of this file.
1// XDRStreamUnMarshaller.cc
2
3// -*- mode: c++; c-basic-offset:4 -*-
4
5// This file is part of libdap, A C++ implementation of the OPeNDAP Data
6// Access Protocol.
7
8// Copyright (c) 2002,2003 OPeNDAP, Inc.
9// Author: Patrick West <pwest@ucar.edu>
10//
11// This library is free software; you can redistribute it and/or
12// modify it under the terms of the GNU Lesser General Public
13// License as published by the Free Software Foundation; either
14// version 2.1 of the License, or (at your option) any later version.
15//
16// This library is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19// Lesser General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public
22// License along with this library; if not, write to the Free Software
23// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24//
25// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
26
27// (c) COPYRIGHT URI/MIT 1994-1999
28// Please read the full copyright statement in the file COPYRIGHT_URI.
29//
30// Authors:
31// pwest Patrick West <pwest@ucar.edu>
33#include "config.h"
34
35#include <cstring> // for memcpy
36#include <sstream>
37#include <string>
38
39// #define DODS_DEBUG2 1
40// #define DODS_DEBUG 1
41
42#include "Array.h"
43#include "DapIndent.h"
44#include "InternalErr.h"
45#include "Str.h"
46#include "debug.h"
47#include "util.h"
48
49namespace libdap {
50
51char *XDRStreamUnMarshaller::d_buf = 0;
52
53XDRStreamUnMarshaller::XDRStreamUnMarshaller(istream &in)
54 : /*&d_source( 0 ),*/
55 d_in(in) {
56 if (!d_buf)
57 d_buf = (char *)malloc(XDR_DAP_BUFF_SIZE);
58 if (!d_buf)
59 throw Error(internal_error, "Failed to allocate memory for data serialization.");
60
61 //&d_source = new XDR;
62 xdrmem_create(&d_source, d_buf, XDR_DAP_BUFF_SIZE, XDR_DECODE);
63}
64
65XDRStreamUnMarshaller::XDRStreamUnMarshaller() : UnMarshaller(), /*&d_source( 0 ),*/ d_in(cin) {
66 throw InternalErr(__FILE__, __LINE__, "Default constructor not implemented.");
67}
68
69XDRStreamUnMarshaller::XDRStreamUnMarshaller(const XDRStreamUnMarshaller &um)
70 : UnMarshaller(um), /*&d_source( 0 ),*/ d_in(cin) {
71 throw InternalErr(__FILE__, __LINE__, "Copy constructor not implemented.");
72}
73
74XDRStreamUnMarshaller &XDRStreamUnMarshaller::operator=(const XDRStreamUnMarshaller &) {
75 throw InternalErr(__FILE__, __LINE__, "Copy operator not implemented.");
76}
77
79 xdr_destroy(&d_source);
80 //&d_source = 0;
81}
82
84 if (xdr_setpos(&d_source, 0) < 0)
85 throw Error("Failed to reposition input stream");
86 if (!(d_in.read(d_buf, 4))) {
87 if (d_in.eof())
88 throw Error("Premature EOF in input stream");
89 else {
90 ostringstream ss("Error reading from input stream: ");
91 ss << d_in.rdstate();
92 throw Error(ss.str());
93 }
94 }
95
96 DBG2(std::cerr << "_in.gcount(): " << d_in.gcount() << std::endl);
97 DBG2(std::cerr << "_in.tellg(): " << d_in.tellg() << std::endl);
98 DBG2(std::cerr << "_buf[0]: " << hex << d_buf[0] << "; _buf[1]: " << d_buf[1] << "; _buf[2]: " << d_buf[2]
99 << "; _buf[3]: " << d_buf[3] << dec << std::endl);
100
101 if (!xdr_char(&d_source, (char *)&val))
102 throw Error("Network I/O Error. Could not read byte data.");
103
104 DBG2(std::cerr << "get_byte: " << val << std::endl);
105}
106
108 xdr_setpos(&d_source, 0);
109 d_in.read(d_buf, 4);
110
111 if (!XDR_INT16(&d_source, &val))
112 throw Error("Network I/O Error. Could not read int 16 data.");
113}
114
116 xdr_setpos(&d_source, 0);
117 d_in.read(d_buf, 4);
118
119 if (!XDR_INT32(&d_source, &val))
120 throw Error("Network I/O Error. Could not read int 32 data.");
121}
122
124 xdr_setpos(&d_source, 0);
125 d_in.read(d_buf, 4);
126
127 if (!xdr_float(&d_source, &val))
128 throw Error("Network I/O Error. Could not read float 32 data.");
129}
130
132 xdr_setpos(&d_source, 0);
133 d_in.read(d_buf, 8);
134
135 if (!xdr_double(&d_source, &val))
136 throw Error("Network I/O Error. Could not read float 64 data.");
137}
138
140 xdr_setpos(&d_source, 0);
141 d_in.read(d_buf, 4);
142
143 if (!XDR_UINT16(&d_source, &val))
144 throw Error("Network I/O Error. Could not read uint 16 data.");
145}
146
148 xdr_setpos(&d_source, 0);
149 d_in.read(d_buf, 4);
150
151 if (!XDR_UINT32(&d_source, &val))
152 throw Error("Network I/O Error. Could not read uint 32 data.");
153}
154
156 int i;
157 get_int(i);
158 DBG(std::cerr << "i: " << i << std::endl);
159
160 // Must round up string size to next 4
161 i = ((i + 3) / 4) * 4;
162 DBG(std::cerr << "i: " << i << std::endl);
163
164 char *in_tmp = 0;
165 // char *buf = 0;
166 // XDR *source = 0;
167 // Must address the case where the string is larger than the buffer
168 if (i + 4 > XDR_DAP_BUFF_SIZE) {
169#if 0
170 char *buf = (char *) malloc(i + 4);
171 if (!buf)
172 throw InternalErr(__FILE__, __LINE__, "Error allocating memory");
173#endif
174 vector<char> buf(i + 4);
175
176 XDR source; // = new XDR;
177 xdrmem_create(&source, buf.data(), i + 4, XDR_DECODE);
178 memcpy(buf.data(), d_buf, 4);
179
180 d_in.read(buf.data() + 4, i);
181
182 xdr_setpos(&source, 0);
183 if (!xdr_string(&source, &in_tmp, max_str_len)) {
184 xdr_destroy(&source);
185 throw Error("Network I/O Error. Could not read string data.");
186 }
187
188 xdr_destroy(&source);
189 } else {
190 d_in.read(d_buf + 4, i);
191
192 xdr_setpos(&d_source, 0);
193 if (!xdr_string(&d_source, &in_tmp, max_str_len))
194 throw Error("Network I/O Error. Could not read string data.");
195 }
196
197 val = in_tmp;
198
199 free(in_tmp);
200}
201
202void XDRStreamUnMarshaller::get_url(string &val) { get_str(val); }
203
204void XDRStreamUnMarshaller::get_opaque(char *val, unsigned int len) {
205 xdr_setpos(&d_source, 0);
206
207 // Round len up to the next multiple of 4. There is also the RNDUP()
208 // macro in xdr.h, at least on OS/X.
209 len += len & 3;
210 if (static_cast<int>(len) > XDR_DAP_BUFF_SIZE)
211 throw Error("Network I/O Error. Length of opaque data larger than allowed");
212
213 d_in.read(d_buf, len);
214
215 xdr_opaque(&d_source, val, len);
216}
217
219 xdr_setpos(&d_source, 0);
220 d_in.read(d_buf, 4);
221
222 if (!xdr_int(&d_source, &val))
223 throw Error("Network I/O Error(1).");
224
225 DBG(std::cerr << "get_int: " << val << std::endl);
226}
227
228void XDRStreamUnMarshaller::get_vector(char **val, unsigned int &num, Vector &) {
229 int i;
230 get_int(i); // This leaves the XDR encoded value in d_buf; used later
231 DBG(std::cerr << "i: " << i << std::endl);
232
233 // Must round up string size to next 4
234 i += i & 3;
235 DBG(std::cerr << "i: " << i << std::endl);
236
237 // char *buf = 0;
238 // XDR *source = 0;
239 // Must address the case where the string is larger than the buffer
240 if (i + 4 > XDR_DAP_BUFF_SIZE) {
241 vector<char> buf(i + 4);
242 XDR source;
243 xdrmem_create(&source, buf.data(), i + 4, XDR_DECODE);
244 memcpy(buf.data(), d_buf, 4);
245
246 d_in.read(buf.data() + 4, i);
247 DBG2(cerr << "bytes read: " << d_in.gcount() << endl);
248
249 xdr_setpos(&source, 0);
250 if (!xdr_bytes(&d_source, val, &num, DODS_MAX_ARRAY)) {
251 xdr_destroy(&source);
252 throw Error("Network I/O Error. Could not read byte array data.");
253 }
254
255 xdr_destroy(&source);
256 } else {
257 d_in.read(d_buf + 4, i);
258 DBG2(cerr << "bytes read: " << d_in.gcount() << endl);
259
260 xdr_setpos(&d_source, 0);
261 if (!xdr_bytes(&d_source, val, &num, DODS_MAX_ARRAY))
262 throw Error("Network I/O Error. Could not read byte array data.");
263 }
264}
265
266void XDRStreamUnMarshaller::get_vector(char **val, unsigned int &num, int width, Vector &vec) {
267 get_vector(val, num, width, vec.var()->type());
268}
269
270void XDRStreamUnMarshaller::get_vector(char **val, unsigned int &num, int width, Type type) {
271 int i;
272 get_int(i); // This leaves the XDR encoded value in d_buf; used later
273 DBG(std::cerr << "i: " << i << std::endl);
274
275 width += width & 3;
276 DBG(std::cerr << "width: " << width << std::endl);
277
278 int size = i * width; // + 4; // '+ 4' to hold the int already read
279
280 // Must address the case where the string is larger than the buffer
281 if (size > XDR_DAP_BUFF_SIZE) {
282 vector<char> buf(size + 4);
283 XDR source;
284 xdrmem_create(&source, buf.data(), size + 4, XDR_DECODE);
285 DBG(cerr << "size: " << size << endl);
286 memcpy(buf.data(), d_buf, 4);
287
288 d_in.read(buf.data() + 4, size); // +4 for the int already read
289 DBG(cerr << "bytes read: " << d_in.gcount() << endl);
290
291 xdr_setpos(&source, 0);
292 if (!xdr_array(&source, val, &num, DODS_MAX_ARRAY, width, XDRUtils::xdr_coder(type))) {
293 xdr_destroy(&source);
294 throw Error("Network I/O Error. Could not read array data.");
295 }
296
297 xdr_destroy(&source);
298 } else {
299 d_in.read(d_buf + 4, size);
300 DBG(cerr << "bytes read (2): " << d_in.gcount() << endl);
301
302 xdr_setpos(&d_source, 0);
303 if (!xdr_array(&d_source, val, &num, DODS_MAX_ARRAY, width, XDRUtils::xdr_coder(type)))
304 throw Error("Network I/O Error. Could not read array data.");
305 }
306}
307
308void XDRStreamUnMarshaller::dump(ostream &strm) const {
309 strm << DapIndent::LMarg << "XDRStreamUnMarshaller::dump - (" << (void *)this << ")" << endl;
310}
311
312} // namespace libdap
#define internal_error
Internal server error (500)
Definition Error.h:63
virtual Type type() const
Returns the type of the class instance.
Definition BaseType.cc:329
static ostream & LMarg(ostream &strm)
Definition DapIndent.cc:61
A class for error processing.
Definition Error.h:92
A class for software fault reporting.
Definition InternalErr.h:61
abstract base class used to unmarshall/deserialize dap data objects
Holds a one-dimensional collection of DAP2 data types.
Definition Vector.h:81
BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=nullptr) override
Definition Vector.cc:469
unmarshaller that knows how to unmarshall/deserialize dap objects using XDR from a file
virtual void get_str(string &val)
virtual void get_int32(dods_int32 &val)
virtual void get_byte(dods_byte &val)
virtual void get_int16(dods_int16 &val)
virtual void get_uint16(dods_uint16 &val)
virtual void get_url(string &val)
virtual void get_uint32(dods_uint32 &val)
virtual void get_float64(dods_float64 &val)
virtual void dump(ostream &strm) const
dump the contents of this object to the specified ostream
virtual void get_opaque(char *val, unsigned int len)
virtual void get_float32(dods_float32 &val)
virtual void get_vector(char **val, unsigned int &num, Vector &vec)
static xdrproc_t xdr_coder(const Type &t)
Returns a function used to encode elements of an array.
Definition XDRUtils.cc:137
#define XDR_UINT16
Definition config.h:1128
#define XDR_INT16
Definition config.h:1122
#define XDR_INT32
Definition config.h:1125
#define XDR_UINT32
Definition config.h:1131
#define DBG(x)
Definition debug.h:58
#define DBG2(x)
Definition debug.h:74
top level DAP object to house generic methods
Definition AISConnect.cc:30
Type
Identifies the data type.
Definition Type.h:94
const int DODS_MAX_ARRAY
Definition Array.h:60
uint32_t dods_uint32
const unsigned int max_str_len
Definition Str.h:53
uint16_t dods_uint16