42 #include "InternalErr.h" 43 #include "D4StreamUnMarshaller.h" 45 #include "DapIndent.h" 59 D4StreamUnMarshaller::D4StreamUnMarshaller(istream &in,
bool twiddle_bytes) : d_in( in ), d_twiddle_bytes(twiddle_bytes)
61 assert(
sizeof(std::streamsize) >=
sizeof(int64_t));
63 #if USE_XDR_FOR_IEEE754_ENCODING 65 xdrmem_create(&d_source, d_buf,
sizeof(dods_float64), XDR_DECODE);
70 d_in.exceptions(istream::failbit | istream::badbit);
80 D4StreamUnMarshaller::D4StreamUnMarshaller(istream &in) : d_in( in ), d_twiddle_bytes(false)
82 assert(
sizeof(std::streamsize) >=
sizeof(int64_t));
84 #if USE_XDR_FOR_IEEE754_ENCODING 86 xdrmem_create(&d_source, d_buf,
sizeof(dods_float64), XDR_DECODE);
91 d_in.exceptions(istream::failbit | istream::badbit);
94 D4StreamUnMarshaller::~D4StreamUnMarshaller( )
96 #if USE_XDR_FOR_IEEE754_ENCODING 97 xdr_destroy(&d_source);
101 Crc32::checksum D4StreamUnMarshaller::get_checksum()
104 d_in.read(reinterpret_cast<char*>(&c),
sizeof(Crc32::checksum));
109 string D4StreamUnMarshaller::get_checksum_str()
112 oss.setf(ios::hex, ios::basefield);
113 oss << setfill(
'0') << setw(8) << get_checksum();
119 D4StreamUnMarshaller::get_byte( dods_byte &val )
121 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_byte));
125 D4StreamUnMarshaller::get_int8( dods_int8 &val )
127 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_int8));
131 D4StreamUnMarshaller::get_int16( dods_int16 &val )
133 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_int16));
139 D4StreamUnMarshaller::get_int32( dods_int32 &val )
141 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_int32));
147 D4StreamUnMarshaller::get_int64( dods_int64 &val )
149 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_int64));
155 D4StreamUnMarshaller::get_float32( dods_float32 &val )
157 #if !USE_XDR_FOR_IEEE754_ENCODING 158 assert(std::numeric_limits<float>::is_iec559);
160 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_float32));
161 if (d_twiddle_bytes) {
162 dods_int32 *i =
reinterpret_cast<dods_int32*
>(&val);
167 if (std::numeric_limits<float>::is_iec559) {
168 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_float32));
169 if (d_twiddle_bytes) {
170 dods_int32 *i =
reinterpret_cast<dods_int32*
>(&val);
176 xdr_setpos( &d_source, 0);
177 d_in.read(d_buf,
sizeof(dods_float32));
179 if (!xdr_float(&d_source, &val))
180 throw Error(
"Network I/O Error. Could not read float 64 data.");
186 D4StreamUnMarshaller::get_float64( dods_float64 &val )
188 #if !USE_XDR_FOR_IEEE754_ENCODING 189 assert(std::numeric_limits<double>::is_iec559);
191 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_float64));
192 if (d_twiddle_bytes) {
193 dods_int64 *i =
reinterpret_cast<dods_int64*
>(&val);
198 if (std::numeric_limits<float>::is_iec559) {
199 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_float64));
200 if (d_twiddle_bytes) {
201 dods_int64 *i =
reinterpret_cast<dods_int64*
>(&val);
206 xdr_setpos( &d_source, 0);
207 d_in.read(d_buf,
sizeof(dods_float64));
209 if (!xdr_double(&d_source, &val))
210 throw Error(
"Network I/O Error. Could not read float 64 data.");
216 D4StreamUnMarshaller::get_uint16( dods_uint16 &val )
218 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_uint16));
224 D4StreamUnMarshaller::get_uint32( dods_uint32 &val )
226 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_uint32));
232 D4StreamUnMarshaller::get_uint64( dods_uint64 &val )
234 d_in.read(reinterpret_cast<char*>(&val),
sizeof(dods_uint64));
240 D4StreamUnMarshaller::get_str(
string &val )
243 d_in.read(reinterpret_cast<char*>(&len),
sizeof(int64_t));
246 d_in.read(&val[0], len);
250 D4StreamUnMarshaller::get_url(
string &val )
267 d_in.read(reinterpret_cast<char*>(&count),
sizeof(count));
282 d_in.read(reinterpret_cast<char*>(&len),
sizeof(len));
284 *val =
new char[len];
285 d_in.read(*val, len);
293 d_in.read(reinterpret_cast<char*>(&len),
sizeof(len));
296 d_in.read(reinterpret_cast<char*>(&val[0]), len);
300 D4StreamUnMarshaller::get_vector(
char *val, int64_t bytes )
302 d_in.read(val, bytes);
305 #if USE_XDR_FOR_IEEE754_ENCODING 306 void D4StreamUnMarshaller::m_deserialize_reals(
char *val, int64_t num,
int width,
Type type)
308 int64_t size = num * width;
310 vector<char> buf(size);
312 xdrmem_create(&xdr, &buf[0], size, XDR_DECODE);
314 xdr_setpos(&d_source, 0);
315 d_in.read(&buf[0], size);
318 throw InternalErr(__FILE__, __LINE__,
"Error deserializing a Float64 array");
320 if (xdr_getpos(&xdr) != size)
321 throw InternalErr(__FILE__, __LINE__,
"Error deserializing a Float64 array");
331 void D4StreamUnMarshaller::m_twidle_vector_elements(
char *vals, int64_t num,
int width)
335 dods_int16 *local =
reinterpret_cast<dods_int16*
>(vals);
337 *local = bswap_16(*local);
343 dods_int32 *local =
reinterpret_cast<dods_int32*
>(vals);;
345 *local = bswap_32(*local);
351 dods_int64 *local =
reinterpret_cast<dods_int64*
>(vals);;
353 *local = bswap_64(*local);
359 throw InternalErr(__FILE__, __LINE__,
"Unrecognized word size.");
364 D4StreamUnMarshaller::get_vector(
char *val, int64_t num_elem,
int elem_size)
366 assert(std::numeric_limits<float>::is_iec559);
367 assert(std::numeric_limits<double>::is_iec559);
369 assert(num_elem >= 0);
370 assert(elem_size > 0);
376 assert(!
"Don't call this method for bytes, use put_vector(val, bytes) instead");
381 assert(!(num_elem & 0x4000000000000000));
382 bytes = num_elem << 1;
385 assert(!(num_elem & 0x6000000000000000));
386 bytes = num_elem << 2;
389 assert(!(num_elem & 0x7000000000000000));
390 bytes = num_elem << 3;
393 bytes = num_elem * elem_size;
397 d_in.read(val, bytes);
400 m_twidle_vector_elements(val, num_elem, elem_size);
404 D4StreamUnMarshaller::get_vector_float32(
char *val, int64_t num_elem)
406 #if !USE_XDR_FOR_IEEE754_ENCODING 407 assert(std::numeric_limits<float>::is_iec559);
409 assert(num_elem >= 0);
410 assert(!(num_elem & 0x6000000000000000));
412 int64_t bytes = num_elem << 2;
414 d_in.read(val, bytes);
417 m_twidle_vector_elements(val, num_elem,
sizeof(dods_float32));
420 if (type == dods_float32_c && !std::numeric_limits<float>::is_iec559) {
422 m_deserialize_reals(val, num, 4, type);
424 else if (type == dods_float64_c && !std::numeric_limits<double>::is_iec559) {
425 m_deserialize_reals(val, num, 8, type);
428 d_in.read(val, num * width);
430 m_twidle_vector_elements(val, num, width);
436 D4StreamUnMarshaller::get_vector_float64(
char *val, int64_t num_elem)
438 #if !USE_XDR_FOR_IEEE754_ENCODING 439 assert(std::numeric_limits<float>::is_iec559);
441 assert(num_elem >= 0);
442 assert(!(num_elem & 0x7000000000000000));
444 int64_t bytes = num_elem << 3;
446 d_in.read(val, bytes);
449 m_twidle_vector_elements(val, num_elem,
sizeof(dods_float64));
452 if (type == dods_float32_c && !std::numeric_limits<float>::is_iec559) {
454 m_deserialize_reals(val, num, 4, type);
456 else if (type == dods_float64_c && !std::numeric_limits<double>::is_iec559) {
457 m_deserialize_reals(val, num, 8, type);
460 d_in.read(val, num * width);
462 m_twidle_vector_elements(val, num, width);
470 strm << DapIndent::LMarg <<
"D4StreamUnMarshaller::dump - (" 471 << (
void *)
this <<
")" << endl ;
virtual void dump(ostream &strm) const
dump the contents of this object to the specified ostream
Type
Identifies the data type.
top level DAP object to house generic methods
virtual void get_opaque_dap4(char **val, int64_t &len)
A class for software fault reporting.
static xdrproc_t xdr_coder(const Type &t)
Returns a function used to encode elements of an array.
A class for error processing.