|
Packit |
a4aae4 |
// D4StreamUnMarshaller.cc
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// -*- mode: c++; c-basic-offset:4 -*-
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
|
|
Packit |
a4aae4 |
// Access Protocol.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Copyright (c) 2012 OPeNDAP, Inc.
|
|
Packit |
a4aae4 |
// Author: James Gallagher <jgallagher@opendap.org>
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is free software; you can redistribute it and/or
|
|
Packit |
a4aae4 |
// modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License as published by the Free Software Foundation; either
|
|
Packit |
a4aae4 |
// version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is distributed in the hope that it will be useful,
|
|
Packit |
a4aae4 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a4aae4 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a4aae4 |
// Lesser General Public License for more details.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License along with this library; if not, write to the Free Software
|
|
Packit |
a4aae4 |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "config.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <byteswap.h>
|
|
Packit |
a4aae4 |
#include <cassert>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <iostream>
|
|
Packit |
a4aae4 |
#include <iomanip>
|
|
Packit |
a4aae4 |
#include <limits>
|
|
Packit |
a4aae4 |
#include <string>
|
|
Packit |
a4aae4 |
#include <sstream>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
//#define DODS_DEBUG2 1
|
|
Packit |
a4aae4 |
//#define DODS_DEBUG 1
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "util.h"
|
|
Packit |
a4aae4 |
//#include "XDRUtils.h"
|
|
Packit |
a4aae4 |
#include "InternalErr.h"
|
|
Packit |
a4aae4 |
#include "D4StreamUnMarshaller.h"
|
|
Packit |
a4aae4 |
#include "debug.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* @brief Build a DAP4 Stream unMarshaller.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* Build a DAP4 Stream UnMarshaller initialed to read from am istream object.
|
|
Packit |
a4aae4 |
* Figure out if the words read for values need to be 'twiddled' based on the
|
|
Packit |
a4aae4 |
* byte-order of the stream an this host (see set_twiddle_bytes()).
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param in Read from this input stream
|
|
Packit |
a4aae4 |
* @param is_stream_bigendian The byte order of the data in the stream
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::D4StreamUnMarshaller(istream &in, bool twiddle_bytes) : d_in( in ), d_twiddle_bytes(twiddle_bytes)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
assert(sizeof(std::streamsize) >= sizeof(int64_t));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
// XDR is used to handle transforming non-ieee754 reals, nothing else.
|
|
Packit |
a4aae4 |
xdrmem_create(&d_source, d_buf, sizeof(dods_float64), XDR_DECODE);
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This will cause exceptions to be thrown on i/o errors. The exception
|
|
Packit |
a4aae4 |
// will be ostream::failure
|
|
Packit |
a4aae4 |
d_in.exceptions(istream::failbit | istream::badbit);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* When using this constructor, set_twiddle_bytes() should be called
|
|
Packit |
a4aae4 |
* before data are processed.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param in
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::D4StreamUnMarshaller(istream &in) : d_in( in ), d_twiddle_bytes(false)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
assert(sizeof(std::streamsize) >= sizeof(int64_t));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
// XDR is used to handle transforming non-ieee754 reals, nothing else.
|
|
Packit |
a4aae4 |
xdrmem_create(&d_source, d_buf, sizeof(dods_float64), XDR_DECODE);
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This will cause exceptions to be thrown on i/o errors. The exception
|
|
Packit |
a4aae4 |
// will be ostream::failure
|
|
Packit |
a4aae4 |
d_in.exceptions(istream::failbit | istream::badbit);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::~D4StreamUnMarshaller( )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
#if USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
xdr_destroy(&d_source);
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Crc32::checksum D4StreamUnMarshaller::get_checksum()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
Crc32::checksum c;
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&c), sizeof(Crc32::checksum));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return c;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
string D4StreamUnMarshaller::get_checksum_str()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
ostringstream oss;
|
|
Packit |
a4aae4 |
oss.setf(ios::hex, ios::basefield);
|
|
Packit |
a4aae4 |
oss << setfill('0') << setw(8) << get_checksum();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return oss.str();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_byte( dods_byte &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_byte));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_int8( dods_int8 &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int8));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_int16( dods_int16 &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int16));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
val = bswap_16(val);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_int32( dods_int32 &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int32));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
val = bswap_32(val);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_int64( dods_int64 &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_int64));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
val = bswap_64(val);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_float32( dods_float32 &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
#if !USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
assert(std::numeric_limits<float>::is_iec559);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float32));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes) {
|
|
Packit |
a4aae4 |
dods_int32 *i = reinterpret_cast<dods_int32*>(&val;;
|
|
Packit |
a4aae4 |
*i = bswap_32(*i);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#else
|
|
Packit |
a4aae4 |
if (std::numeric_limits<float>::is_iec559) {
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float32));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes) {
|
|
Packit |
a4aae4 |
dods_int32 *i = reinterpret_cast<dods_int32*>(&val;;
|
|
Packit |
a4aae4 |
*i = bswap_32(*i);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
xdr_setpos( &d_source, 0);
|
|
Packit |
a4aae4 |
d_in.read(d_buf, sizeof(dods_float32));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (!xdr_float(&d_source, &val))
|
|
Packit |
a4aae4 |
throw Error("Network I/O Error. Could not read float 64 data.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_float64( dods_float64 &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
#if !USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
assert(std::numeric_limits<double>::is_iec559);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float64));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes) {
|
|
Packit |
a4aae4 |
dods_int64 *i = reinterpret_cast<dods_int64*>(&val;;
|
|
Packit |
a4aae4 |
*i = bswap_64(*i);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#else
|
|
Packit |
a4aae4 |
if (std::numeric_limits<float>::is_iec559) {
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_float64));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes) {
|
|
Packit |
a4aae4 |
dods_int64 *i = reinterpret_cast<dods_int64*>(&val;;
|
|
Packit |
a4aae4 |
*i = bswap_64(*i);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
xdr_setpos( &d_source, 0);
|
|
Packit |
a4aae4 |
d_in.read(d_buf, sizeof(dods_float64));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (!xdr_double(&d_source, &val))
|
|
Packit |
a4aae4 |
throw Error("Network I/O Error. Could not read float 64 data.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_uint16( dods_uint16 &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_uint16));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
val = bswap_16(val);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_uint32( dods_uint32 &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_uint32));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
val = bswap_32(val);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_uint64( dods_uint64 &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val), sizeof(dods_uint64));
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
val = bswap_64(val);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_str( string &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
int64_t len;
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&len), sizeof(int64_t));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
val.resize(len);
|
|
Packit |
a4aae4 |
d_in.read(&val[0], len);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_url( string &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
get_str( val ) ;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Read a count value from the stream. This is used with D4Sequence
|
|
Packit |
a4aae4 |
* which needs to use various other 'get' methods to read its fields.
|
|
Packit |
a4aae4 |
* Methods like get_opaque_dap4() handle reading their count values
|
|
Packit |
a4aae4 |
* themselves.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param count The number of elements to follow.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
int64_t
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_count()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
int64_t count;
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&count), sizeof(count));
|
|
Packit |
a4aae4 |
return count;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Get opaque data when the size of the data to be read is not known in
|
|
Packit |
a4aae4 |
* advance.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param val Value-result parameter for the data; caller must delete.
|
|
Packit |
a4aae4 |
* @param len value-result parameter for the length of the data
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_opaque_dap4( char **val, int64_t &len )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
//len = get_length_prefix();
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&len), sizeof(len));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
*val = new char[len];
|
|
Packit |
a4aae4 |
d_in.read(*val, len);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_opaque_dap4( vector<uint8_t> &val )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
//len = get_length_prefix();
|
|
Packit |
a4aae4 |
int64_t len;
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&len), sizeof(len));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
val.resize(len);
|
|
Packit |
a4aae4 |
d_in.read(reinterpret_cast<char*>(&val[0]), len);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_vector( char *val, int64_t bytes )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_in.read(val, bytes);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
void D4StreamUnMarshaller::m_deserialize_reals(char *val, int64_t num, int width, Type type)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
int64_t size = num * width;
|
|
Packit |
a4aae4 |
// char *buf = (char*)malloc(size); jhrg 7/23/13
|
|
Packit |
a4aae4 |
vector<char> buf(size);
|
|
Packit |
a4aae4 |
XDR xdr;
|
|
Packit |
a4aae4 |
xdrmem_create(&xdr, &buf[0], size, XDR_DECODE);
|
|
Packit |
a4aae4 |
try {
|
|
Packit |
a4aae4 |
xdr_setpos(&d_source, 0);
|
|
Packit |
a4aae4 |
d_in.read(&buf[0], size);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if(!xdr_array(&xdr, &val, (unsigned int *)&num, size, width, XDRUtils::xdr_coder(type)))
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Error deserializing a Float64 array");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (xdr_getpos(&xdr) != size)
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Error deserializing a Float64 array");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
catch (...) {
|
|
Packit |
a4aae4 |
xdr_destroy(&xdr;;
|
|
Packit |
a4aae4 |
throw;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
xdr_destroy(&xdr;;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void D4StreamUnMarshaller::m_twidle_vector_elements(char *vals, int64_t num, int width)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
switch (width) {
|
|
Packit |
a4aae4 |
case 2: {
|
|
Packit |
a4aae4 |
dods_int16 *local = reinterpret_cast<dods_int16*>(vals);
|
|
Packit |
a4aae4 |
while (num--) {
|
|
Packit |
a4aae4 |
*local = bswap_16(*local);
|
|
Packit |
a4aae4 |
local++;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
case 4: {
|
|
Packit |
a4aae4 |
dods_int32 *local = reinterpret_cast<dods_int32*>(vals);;
|
|
Packit |
a4aae4 |
while (num--) {
|
|
Packit |
a4aae4 |
*local = bswap_32(*local);
|
|
Packit |
a4aae4 |
local++;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
case 8: {
|
|
Packit |
a4aae4 |
dods_int64 *local = reinterpret_cast<dods_int64*>(vals);;
|
|
Packit |
a4aae4 |
while (num--) {
|
|
Packit |
a4aae4 |
*local = bswap_64(*local);
|
|
Packit |
a4aae4 |
local++;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Unrecognized word size.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_vector(char *val, int64_t num_elem, int elem_size)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
assert(std::numeric_limits<float>::is_iec559);
|
|
Packit |
a4aae4 |
assert(std::numeric_limits<double>::is_iec559);
|
|
Packit |
a4aae4 |
assert(val);
|
|
Packit |
a4aae4 |
assert(num_elem >= 0);
|
|
Packit |
a4aae4 |
assert(elem_size > 0);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
int64_t bytes;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
switch (elem_size) {
|
|
Packit |
a4aae4 |
case 1:
|
|
Packit |
a4aae4 |
assert(!"Don't call this method for bytes, use put_vector(val, bytes) instead");
|
|
Packit |
a4aae4 |
bytes = num_elem;
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
case 2:
|
|
Packit |
a4aae4 |
// Don't bother testing the sign bit
|
|
Packit |
a4aae4 |
assert(!(num_elem & 0x4000000000000000)); // 0x 40 00 --> 0100 0000
|
|
Packit |
a4aae4 |
bytes = num_elem << 1;
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
case 4:
|
|
Packit |
a4aae4 |
assert(!(num_elem & 0x6000000000000000)); // 0x 60 00 --> 0110 0000
|
|
Packit |
a4aae4 |
bytes = num_elem << 2;
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
case 8:
|
|
Packit |
a4aae4 |
assert(!(num_elem & 0x7000000000000000)); // 0111 0000
|
|
Packit |
a4aae4 |
bytes = num_elem << 3;
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
bytes = num_elem * elem_size;
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
d_in.read(val, bytes);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
m_twidle_vector_elements(val, num_elem, elem_size);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_vector_float32(char *val, int64_t num_elem)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
#if !USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
assert(std::numeric_limits<float>::is_iec559);
|
|
Packit |
a4aae4 |
assert(val);
|
|
Packit |
a4aae4 |
assert(num_elem >= 0);
|
|
Packit |
a4aae4 |
assert(!(num_elem & 0x6000000000000000)); // 0x 60 00 --> 0110 0000
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
int64_t bytes = num_elem << 2;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
d_in.read(val, bytes);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
m_twidle_vector_elements(val, num_elem, sizeof(dods_float32));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#else
|
|
Packit |
a4aae4 |
if (type == dods_float32_c && !std::numeric_limits<float>::is_iec559) {
|
|
Packit |
a4aae4 |
// If not using IEEE 754, use XDR to get it that way.
|
|
Packit |
a4aae4 |
m_deserialize_reals(val, num, 4, type);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if (type == dods_float64_c && !std::numeric_limits<double>::is_iec559) {
|
|
Packit |
a4aae4 |
m_deserialize_reals(val, num, 8, type);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
d_in.read(val, num * width);
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
m_twidle_vector_elements(val, num, width);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::get_vector_float64(char *val, int64_t num_elem)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
#if !USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
assert(std::numeric_limits<float>::is_iec559);
|
|
Packit |
a4aae4 |
assert(val);
|
|
Packit |
a4aae4 |
assert(num_elem >= 0);
|
|
Packit |
a4aae4 |
assert(!(num_elem & 0x7000000000000000)); // 0x 70 00 --> 0111 0000
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
int64_t bytes = num_elem << 3;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
d_in.read(val, bytes);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
m_twidle_vector_elements(val, num_elem, sizeof(dods_float64));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#else
|
|
Packit |
a4aae4 |
if (type == dods_float32_c && !std::numeric_limits<float>::is_iec559) {
|
|
Packit |
a4aae4 |
// If not using IEEE 754, use XDR to get it that way.
|
|
Packit |
a4aae4 |
m_deserialize_reals(val, num, 4, type);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if (type == dods_float64_c && !std::numeric_limits<double>::is_iec559) {
|
|
Packit |
a4aae4 |
m_deserialize_reals(val, num, 8, type);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
d_in.read(val, num * width);
|
|
Packit |
a4aae4 |
if (d_twiddle_bytes)
|
|
Packit |
a4aae4 |
m_twidle_vector_elements(val, num, width);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void
|
|
Packit |
a4aae4 |
D4StreamUnMarshaller::dump(ostream &strm) const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
strm << DapIndent::LMarg << "D4StreamUnMarshaller::dump - ("
|
|
Packit |
a4aae4 |
<< (void *)this << ")" << endl ;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|
|
Packit |
a4aae4 |
|