// -*- mode: c++; c-basic-offset:4 -*-
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.
// Copyright (c) 2013 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin D4Opaqueeet, Fifth Floor, Boston, MA 02110-1301 USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
//#define DODS_DEBUG
#include "config.h"
#include <sstream>
#include <iterator>
#include "D4Opaque.h"
#include "DMR.h"
#include "D4StreamMarshaller.h"
#include "D4StreamUnMarshaller.h"
#include "util.h"
#include "crc.h"
#include "debug.h"
#undef CLEAR_LOCAL_DATA
using namespace std;
namespace libdap {
D4Opaque &
D4Opaque::operator=(const D4Opaque &rhs)
{
if (this == &rhs)
return *this;
// Call BaseType::operator=
dynamic_cast<BaseType &>(*this) = rhs;
d_buf = rhs.d_buf;
return *this;
}
void
D4Opaque::clear_local_data()
{
if (!d_buf.empty()) {
d_buf.erase(d_buf.begin(), d_buf.end());
d_buf.resize(0);
}
set_read_p(false);
}
void
D4Opaque::compute_checksum(Crc32 &checksum)
{
checksum.AddData(&d_buf[0], d_buf.size());
}
void
D4Opaque::serialize(D4StreamMarshaller &m, DMR &, bool)
{
if (!read_p())
read(); // read() throws Error
m.put_opaque_dap4( reinterpret_cast<char*>(&d_buf[0]), d_buf.size() ) ;
#ifdef CLEAR_LOCAL_DATA
clear_local_data();
#endif
}
void
D4Opaque::deserialize(D4StreamUnMarshaller &um, DMR &)
{
um.get_opaque_dap4( d_buf ) ;
}
unsigned int
D4Opaque::buf2val(void **val)
{
assert(val);
// If *val is null, then the caller has not allocated storage for the
// value; we must. If there is storage there, assume it is a vector<uint8_t>
// (i.e., dods_opaque) and assign d_buf's value to that storage.
if (!*val)
*val = new vector<uint8_t>;
else
*static_cast<vector<uint8_t>*>(*val) = d_buf;
return sizeof(vector<uint8_t>*);
}
unsigned int
D4Opaque::val2buf(void *val, bool)
{
assert(val);
d_buf = *static_cast<dods_opaque*>(val);
return sizeof(dods_opaque*);
}
/** Set the value of this instance.
@param value The value
@return Always returns true; the return type of bool is for compatibility
with the Passive* subclasses written by HAO. */
bool
D4Opaque::set_value(const dods_opaque &value)
{
d_buf = value;
set_read_p(true);
return true;
}
/** Get the value of this instance.
@return The value. */
D4Opaque::dods_opaque
D4Opaque::value() const
{
return d_buf;
}
std::vector<BaseType *> *
D4Opaque::transform_to_dap2(AttrTable *){
DBG(cerr << __func__ << "() - Transform not implemented DAP4 Opaque type." << endl;);
return NULL;
}
void
D4Opaque::print_val(ostream &out, string space, bool print_decl_p)
{
if (print_decl_p) print_decl(out, space, false);
if (d_buf.size()) {
// end() - 1 is only OK if size() is > 0
std::ostream_iterator<unsigned int> out_it(out, ",");
std::copy(d_buf.begin(), d_buf.end() - 1, out_it);
out << (unsigned int) d_buf.back(); // can also use: *(d_buf.end()-1);
}
if (print_decl_p) out << ";" << endl;
}
void
D4Opaque::dump(ostream &strm) const
{
strm << DapIndent::LMarg << "D4Opaque::dump - ("
<< (void *)this << ")" << endl ;
DapIndent::Indent() ;
BaseType::dump(strm) ;
//strm << DapIndent::LMarg << "value: " << d_buf << endl ;
ostream_iterator<uint8_t> out_it (strm," ");
std::copy ( d_buf.begin(), d_buf.end(), out_it );
DapIndent::UnIndent() ;
}
} // namespace libdap