|
Packit |
a4aae4 |
// D4StreamMarshaller.h
|
|
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) 2002,2003,2012 OPeNDAP, Inc.
|
|
Packit |
a4aae4 |
// Author: Patrick West <pwest@ucar.edu>,
|
|
Packit |
a4aae4 |
// 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 |
#ifndef I_D4StreamMarshaller_h
|
|
Packit |
a4aae4 |
#define I_D4StreamMarshaller_h 1
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <iostream>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// By default, only support platforms that use IEEE754 for floating point values.
|
|
Packit |
a4aae4 |
// Hacked up code leftover from an older version of the class; largely untested.
|
|
Packit |
a4aae4 |
// jhrg 10/3/13
|
|
Packit |
a4aae4 |
#define USE_XDR_FOR_IEEE754_ENCODING 0
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
#ifdef WIN32
|
|
Packit |
a4aae4 |
#include <rpc.h>
|
|
Packit |
a4aae4 |
#include <winsock2.h>
|
|
Packit |
a4aae4 |
#include <xdr.h>
|
|
Packit |
a4aae4 |
#else
|
|
Packit |
a4aae4 |
#include <rpc/types.h>
|
|
Packit |
a4aae4 |
#include <netinet/in.h>
|
|
Packit |
a4aae4 |
#include <rpc/xdr.h>
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <stdint.h>
|
|
Packit |
a4aae4 |
#include "crc.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "Marshaller.h"
|
|
Packit |
a4aae4 |
#include "InternalErr.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
class Vector;
|
|
Packit |
a4aae4 |
class MarshallerThread;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** @brief Marshaller that knows how to marshal/serialize dap data objects
|
|
Packit |
a4aae4 |
* to a C++ iostream using DAP4's receiver-makes-right scheme. This code
|
|
Packit |
a4aae4 |
* adds checksums to the stream and uses the xdr library to encode real
|
|
Packit |
a4aae4 |
* values if the underlying representation is not IEEE 754. It also supports
|
|
Packit |
a4aae4 |
* computing the checksum only.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @note This class uses the Marshaller interface; it could be rewritten
|
|
Packit |
a4aae4 |
* to use far fewer methods since all of the put_*() methods take different
|
|
Packit |
a4aae4 |
* types.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
class D4StreamMarshaller: public Marshaller {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
private:
|
|
Packit |
a4aae4 |
#if USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
XDR d_scalar_sink;
|
|
Packit |
a4aae4 |
char d_ieee754_buf[sizeof(dods_float64)]; // used to serialize a float or double
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
ostream &d_out;
|
|
Packit |
a4aae4 |
bool d_write_data; // jhrg 1/27/12
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Crc32 d_checksum;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
MarshallerThread *tm;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// These are private so they won't ever get used.
|
|
Packit |
a4aae4 |
D4StreamMarshaller();
|
|
Packit |
a4aae4 |
D4StreamMarshaller(const D4StreamMarshaller &);
|
|
Packit |
a4aae4 |
D4StreamMarshaller & operator=(const D4StreamMarshaller &);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if USE_XDR_FOR_IEEE754_ENCODING
|
|
Packit |
a4aae4 |
void m_serialize_reals(char *val, int64_t num, int width, Type type);
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
D4StreamMarshaller(std::ostream &out, bool write_data = true);
|
|
Packit |
a4aae4 |
virtual ~D4StreamMarshaller();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void reset_checksum();
|
|
Packit |
a4aae4 |
virtual string get_checksum();
|
|
Packit |
a4aae4 |
virtual void checksum_update(const void *data, unsigned long len);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_checksum();
|
|
Packit |
a4aae4 |
virtual void put_count(int64_t count);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_byte(dods_byte val);
|
|
Packit |
a4aae4 |
virtual void put_int8(dods_int8 val);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_int16(dods_int16 val);
|
|
Packit |
a4aae4 |
virtual void put_int32(dods_int32 val);
|
|
Packit |
a4aae4 |
// Added
|
|
Packit |
a4aae4 |
virtual void put_int64(dods_int64 val);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_float32(dods_float32 val);
|
|
Packit |
a4aae4 |
virtual void put_float64(dods_float64 val);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_uint16(dods_uint16 val);
|
|
Packit |
a4aae4 |
virtual void put_uint32(dods_uint32 val);
|
|
Packit |
a4aae4 |
// Added
|
|
Packit |
a4aae4 |
virtual void put_uint64(dods_uint64 val);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_str(const string &val;;
|
|
Packit |
a4aae4 |
virtual void put_url(const string &val;;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_opaque(char *, unsigned int) {
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Not implemented for DAP4; use put_opaque_dap4() instead.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_opaque_dap4(const char *val, int64_t len);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Never use put_int() to send length information in DAP4.
|
|
Packit |
a4aae4 |
virtual void put_int(int) {
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Not Implemented; use put_length_prefix.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_vector(char *val, int64_t num_bytes);
|
|
Packit |
a4aae4 |
virtual void put_vector(char *val, int64_t num_elem, int elem_size);
|
|
Packit |
a4aae4 |
virtual void put_vector_float32(char *val, int64_t num_elem);
|
|
Packit |
a4aae4 |
virtual void put_vector_float64(char *val, int64_t num_elem);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_vector(char *, int , Vector &) {
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Not Implemented; use other put_vector() versions.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
virtual void put_vector(char *, int , int , Vector &) {
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "Not Implemented; use other put_vector() versions.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Prepare to send a single array/vector using a series of 'put' calls.
|
|
Packit |
a4aae4 |
* In DAP4 this does nothing because arrays are serialized using the server's
|
|
Packit |
a4aae4 |
* binary representation (i.e., using 'reader make right').
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param num Ignored
|
|
Packit |
a4aae4 |
* @see put_vector_part()
|
|
Packit |
a4aae4 |
* @see put_vector_end()
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
virtual void put_vector_start(int /*num*/) {
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void put_vector_part(char */*val*/, unsigned int /*num*/, int /*width*/, Type /*type*/);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Close a vector when its values are written using put_vector_part().
|
|
Packit |
a4aae4 |
* In DAP4 this does nothing because arrays are serialized using the server's
|
|
Packit |
a4aae4 |
* binary representation (i.e., using 'reader make right').
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @see put_vector_start()
|
|
Packit |
a4aae4 |
* @see put_vector_part()
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
virtual void put_vector_end() {
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void dump(std::ostream &strm) const;
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#endif // I_D4StreamMarshaller_h
|