libdap  Updated for version 3.17.0
D4Opaque.cc
00001 // -*- mode: c++; c-basic-offset:4 -*-
00002 
00003 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00004 // Access Protocol.
00005 
00006 // Copyright (c) 2013 OPeNDAP, Inc.
00007 // Author: James Gallagher <jgallagher@opendap.org>
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 //
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin D4Opaqueeet, Fifth Floor, Boston, MA  02110-1301  USA
00022 //
00023 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00024 
00025 
00026 #include "config.h"
00027 
00028 #include <sstream>
00029 #include <iterator>
00030 
00031 #include "D4Opaque.h"
00032 
00033 #include "DMR.h"
00034 #include "D4StreamMarshaller.h"
00035 #include "D4StreamUnMarshaller.h"
00036 
00037 #include "util.h"
00038 #include "crc.h"
00039 
00040 #include "debug.h"
00041 
00042 #undef CLEAR_LOCAL_DATA
00043 
00044 using namespace std;
00045 
00046 namespace libdap {
00047 
00048 D4Opaque &
00049 D4Opaque::operator=(const D4Opaque &rhs)
00050 {
00051     if (this == &rhs)
00052         return *this;
00053 
00054     // Call BaseType::operator=
00055     dynamic_cast<BaseType &>(*this) = rhs;
00056 
00057     d_buf = rhs.d_buf;
00058 
00059     return *this;
00060 }
00061 
00062 void
00063 D4Opaque::clear_local_data()
00064 {
00065     if (!d_buf.empty()) {
00066         d_buf.erase(d_buf.begin(), d_buf.end());
00067         d_buf.resize(0);
00068     }
00069 
00070     set_read_p(false);
00071 }
00072 
00073 void
00074 D4Opaque::compute_checksum(Crc32 &checksum)
00075 {
00076         checksum.AddData(&d_buf[0], d_buf.size());
00077 }
00078 
00079 void
00080 D4Opaque::serialize(D4StreamMarshaller &m, DMR &, bool)
00081 {
00082     if (!read_p())
00083         read();          // read() throws Error
00084 
00085     m.put_opaque_dap4( reinterpret_cast<char*>(&d_buf[0]), d_buf.size() ) ;
00086 
00087 #ifdef CLEAR_LOCAL_DATA
00088     clear_local_data();
00089 #endif
00090 
00091 }
00092 
00093 void
00094 D4Opaque::deserialize(D4StreamUnMarshaller &um, DMR &)
00095 {
00096     um.get_opaque_dap4( d_buf ) ;
00097 }
00098 
00099 unsigned int
00100 D4Opaque::buf2val(void **val)
00101 {
00102         assert(val);
00103 
00104     // If *val is null, then the caller has not allocated storage for the
00105     // value; we must. If there is storage there, assume it is a vector<uint8_t>
00106         // (i.e., dods_opaque) and assign d_buf's value to that storage.
00107     if (!*val)
00108         *val = new vector<uint8_t>;
00109     else
00110         *static_cast<vector<uint8_t>*>(*val) = d_buf;
00111 
00112     return sizeof(vector<uint8_t>*);
00113 }
00114 
00115 unsigned int
00116 D4Opaque::val2buf(void *val, bool)
00117 {
00118     assert(val);
00119 
00120     d_buf = *static_cast<dods_opaque*>(val);
00121 
00122     return sizeof(dods_opaque*);
00123 }
00124 
00129 bool
00130 D4Opaque::set_value(const dods_opaque &value)
00131 {
00132     d_buf = value;
00133     set_read_p(true);
00134 
00135     return true;
00136 }
00137 
00140 D4Opaque::dods_opaque
00141 D4Opaque::value() const
00142 {
00143     return d_buf;
00144 }
00145 
00146 void
00147 D4Opaque::print_val(ostream &out, string space, bool print_decl_p)
00148 {
00149         if (print_decl_p) print_decl(out, space, false);
00150 
00151         if (d_buf.size()) {
00152                 // end() - 1 is only OK if size() is > 0
00153                 std::ostream_iterator<unsigned int> out_it(out, ",");
00154                 std::copy(d_buf.begin(), d_buf.end() - 1, out_it);
00155                 out << (unsigned int) d_buf.back(); // can also use: *(d_buf.end()-1);
00156         }
00157 
00158         if (print_decl_p) out << ";" << endl;
00159 }
00160 
00161 void
00162 D4Opaque::dump(ostream &strm) const
00163 {
00164     strm << DapIndent::LMarg << "D4Opaque::dump - ("
00165     << (void *)this << ")" << endl ;
00166     DapIndent::Indent() ;
00167     BaseType::dump(strm) ;
00168     //strm << DapIndent::LMarg << "value: " << d_buf << endl ;
00169     ostream_iterator<uint8_t> out_it (strm," ");
00170     std::copy ( d_buf.begin(), d_buf.end(), out_it );
00171 
00172     DapIndent::UnIndent() ;
00173 }
00174 
00175 } // namespace libdap
00176