libdap++ Updated for version 3.8.2
|
00001 // XDRStreamMarshaller.cc 00002 00003 // -*- mode: c++; c-basic-offset:4 -*- 00004 00005 // This file is part of libdap, A C++ implementation of the OPeNDAP Data 00006 // Access Protocol. 00007 00008 // Copyright (c) 2002,2003 OPeNDAP, Inc. 00009 // Author: Patrick West <pwest@ucar.edu> 00010 // 00011 // This library is free software; you can redistribute it and/or 00012 // modify it under the terms of the GNU Lesser General Public 00013 // License as published by the Free Software Foundation; either 00014 // version 2.1 of the License, or (at your option) any later version. 00015 // 00016 // This library is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 // Lesser General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Lesser General Public 00022 // License along with this library; if not, write to the Free Software 00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00024 // 00025 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 00026 00027 // (c) COPYRIGHT URI/MIT 1994-1999 00028 // Please read the full copyright statement in the file COPYRIGHT_URI. 00029 // 00030 // Authors: 00031 // pwest Patrick West <pwest@ucar.edu> 00032 00033 #include "XDRStreamMarshaller.h" 00034 00035 //#define DODS_DEBUG 1 00036 00037 #include "Vector.h" 00038 #include "util.h" 00039 #include "debug.h" 00040 00041 namespace libdap { 00042 00043 char *XDRStreamMarshaller::_buf = 0 ; 00044 00045 #define XDR_DAP_BUFF_SIZE 256 00046 00047 XDRStreamMarshaller::XDRStreamMarshaller( ostream &out ) 00048 : _sink( 0 ), 00049 _out( out ) 00050 { 00051 if( !_buf ) 00052 _buf = (char *)malloc( XDR_DAP_BUFF_SIZE ) ; 00053 if ( !_buf ) 00054 throw Error("Failed to allocate memory for data serialization."); 00055 00056 _sink = new XDR ; 00057 xdrmem_create( _sink, _buf, XDR_DAP_BUFF_SIZE, XDR_ENCODE ) ; 00058 } 00059 00060 XDRStreamMarshaller::XDRStreamMarshaller() 00061 : Marshaller(), 00062 _sink( 0 ), 00063 _out( cout ) 00064 { 00065 throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ; 00066 } 00067 00068 XDRStreamMarshaller::XDRStreamMarshaller( const XDRStreamMarshaller &m ) 00069 : Marshaller( m ), 00070 _sink( 0 ), 00071 _out( cout ) 00072 { 00073 throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ; 00074 } 00075 00076 XDRStreamMarshaller & 00077 XDRStreamMarshaller::operator=( const XDRStreamMarshaller & ) 00078 { 00079 throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ; 00080 00081 return *this ; 00082 } 00083 00084 XDRStreamMarshaller::~XDRStreamMarshaller( ) 00085 { 00086 if( _sink ) 00087 delete_xdrstdio( _sink ) ; 00088 _sink = 0 ; 00089 } 00090 00091 void 00092 XDRStreamMarshaller::put_byte( dods_byte val ) 00093 { 00094 DBG( std::cerr << "put_byte: " << val << std::endl ); 00095 if( !xdr_setpos( _sink, 0 ) ) 00096 throw Error("Network I/O Error. Could not send byte data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00097 00098 if( !xdr_char( _sink, (char *)&val ) ) 00099 throw Error("Network I/O Error. Could not send byte data.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00100 00101 unsigned int bytes_written = xdr_getpos( _sink ) ; 00102 if( !bytes_written ) 00103 throw Error("Network I/O Error. Could not send byte data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00104 00105 _out.write( _buf, bytes_written ) ; 00106 } 00107 00108 void 00109 XDRStreamMarshaller::put_int16( dods_int16 val ) 00110 { 00111 if( !xdr_setpos( _sink, 0 ) ) 00112 throw Error("Network I/O Error. Could not send int 16 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00113 00114 if( !XDR_INT16( _sink, &val ) ) 00115 throw Error("Network I/O Error. Could not send int 16 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection."); 00116 00117 unsigned int bytes_written = xdr_getpos( _sink ) ; 00118 if( !bytes_written ) 00119 throw Error("Network I/O Error. Could not send int 16 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00120 00121 _out.write( _buf, bytes_written ) ; 00122 } 00123 00124 void 00125 XDRStreamMarshaller::put_int32( dods_int32 val ) 00126 { 00127 if( !xdr_setpos( _sink, 0 ) ) 00128 throw Error("Network I/O Error. Could not send int 32 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00129 00130 if( !XDR_INT32( _sink, &val ) ) 00131 throw Error("Network I/O Error. Culd not read int 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection."); 00132 00133 unsigned int bytes_written = xdr_getpos( _sink ) ; 00134 if( !bytes_written ) 00135 throw Error("Network I/O Error. Could not send int 32 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00136 00137 _out.write( _buf, bytes_written ) ; 00138 } 00139 00140 void 00141 XDRStreamMarshaller::put_float32( dods_float32 val ) 00142 { 00143 if( !xdr_setpos( _sink, 0 ) ) 00144 throw Error("Network I/O Error. Could not send float 32 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00145 00146 if( !xdr_float( _sink, &val ) ) 00147 throw Error("Network I/O Error. Could not send float 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection."); 00148 00149 unsigned int bytes_written = xdr_getpos( _sink ) ; 00150 if( !bytes_written ) 00151 throw Error("Network I/O Error. Could not send float 32 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00152 00153 _out.write( _buf, bytes_written ) ; 00154 } 00155 00156 void 00157 XDRStreamMarshaller::put_float64( dods_float64 val ) 00158 { 00159 if( !xdr_setpos( _sink, 0 ) ) 00160 throw Error("Network I/O Error. Could not send float 64 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00161 00162 if( !xdr_double( _sink, &val ) ) 00163 throw Error("Network I/O Error. Could not send float 64 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection."); 00164 00165 unsigned int bytes_written = xdr_getpos( _sink ) ; 00166 if( !bytes_written ) 00167 throw Error("Network I/O Error. Could not send float 64 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00168 00169 _out.write( _buf, bytes_written ) ; 00170 } 00171 00172 void 00173 XDRStreamMarshaller::put_uint16( dods_uint16 val ) 00174 { 00175 if( !xdr_setpos( _sink, 0 ) ) 00176 throw Error("Network I/O Error. Could not send uint 16 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00177 00178 if( !XDR_UINT16( _sink, &val ) ) 00179 throw Error("Network I/O Error. Could not send uint 16 data. This may be due to a\nbug in libdap or a problem with the network connection."); 00180 00181 unsigned int bytes_written = xdr_getpos( _sink ) ; 00182 if( !bytes_written ) 00183 throw Error("Network I/O Error. Could not send uint 16 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00184 00185 _out.write( _buf, bytes_written ) ; 00186 } 00187 00188 void 00189 XDRStreamMarshaller::put_uint32( dods_uint32 val ) 00190 { 00191 if( !xdr_setpos( _sink, 0 ) ) 00192 throw Error("Network I/O Error. Could not send uint 32 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00193 00194 if( !XDR_UINT32( _sink, &val ) ) 00195 throw Error("Network I/O Error. Could not send uint 32 data. This may be due to a\nbug in libdap or a problem with the network connection."); 00196 00197 unsigned int bytes_written = xdr_getpos( _sink ) ; 00198 if( !bytes_written ) 00199 throw Error("Network I/O Error. Could not send uint 32 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00200 00201 _out.write( _buf, bytes_written ) ; 00202 } 00203 00204 void 00205 XDRStreamMarshaller::put_str( const string &val ) 00206 { 00207 int size = val.length() + 8 ; 00208 char *str_buf = (char *)malloc( size ) ; 00209 00210 if ( !str_buf ) { 00211 throw Error("Failed to allocate memory for string data serialization."); 00212 } 00213 00214 XDR *str_sink = new XDR ; 00215 xdrmem_create( str_sink, str_buf, size, XDR_ENCODE ) ; 00216 00217 if( !xdr_setpos( str_sink, 0 ) ) { 00218 delete_xdrstdio( str_sink ) ; 00219 free( str_buf ) ; 00220 throw Error("Network I/O Error. Could not send string data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00221 } 00222 00223 const char *out_tmp = val.c_str() ; 00224 if( !xdr_string( str_sink, (char **)&out_tmp, size ) ) { 00225 delete_xdrstdio( str_sink ) ; 00226 free( str_buf ) ; 00227 throw Error("Network I/O Error. Could not send string data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection."); 00228 } 00229 00230 unsigned int bytes_written = xdr_getpos( str_sink ) ; 00231 if( !bytes_written ) { 00232 delete_xdrstdio( str_sink ) ; 00233 free( str_buf ) ; 00234 throw Error("Network I/O Error. Could not send string data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00235 } 00236 00237 _out.write( str_buf, bytes_written ) ; 00238 00239 delete_xdrstdio( str_sink ) ; 00240 free( str_buf ) ; 00241 } 00242 00243 void 00244 XDRStreamMarshaller::put_url( const string &val ) 00245 { 00246 put_str( val ) ; 00247 } 00248 00249 void 00250 XDRStreamMarshaller::put_opaque( char *val, unsigned int len ) 00251 { 00252 if( len > XDR_DAP_BUFF_SIZE ) 00253 throw Error("Network I/O Error. Could not send opaque data - length of opaque data larger than allowed"); 00254 00255 if( !xdr_setpos( _sink, 0 ) ) 00256 throw Error("Network I/O Error. Could not send opaque data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00257 00258 if( !xdr_opaque( _sink, val, len ) ) 00259 throw Error("Network I/O Error. Could not send opaque data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection."); 00260 00261 unsigned int bytes_written = xdr_getpos( _sink ) ; 00262 if( !bytes_written ) 00263 throw Error("Network I/O Error. Could not send opaque data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00264 00265 _out.write( _buf, bytes_written ) ; 00266 } 00267 00268 void 00269 XDRStreamMarshaller::put_int( int val ) 00270 { 00271 if( !xdr_setpos( _sink, 0 ) ) 00272 throw Error("Network I/O Error. Could not send int data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00273 00274 if( !xdr_int( _sink, &val) ) 00275 throw Error("Network I/O Error(1). Could not send int data.\nThis may be due to a bug in libdap or a\nproblem with the network connection."); 00276 00277 unsigned int bytes_written = xdr_getpos( _sink ) ; 00278 if( !bytes_written ) 00279 throw Error("Network I/O Error. Could not send int data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00280 00281 _out.write( _buf, bytes_written ) ; 00282 } 00283 00284 void 00285 XDRStreamMarshaller::put_vector( char *val, int num, Vector & ) 00286 { 00287 if (!val) 00288 throw InternalErr(__FILE__, __LINE__, "Could not send byte vector data. Buffer pointer is not set."); 00289 00290 // write the number of members of the array being written and then set the position to 0 00291 put_int( num ) ; 00292 00293 // this is the word boundary for writing xdr bytes in a vector. 00294 unsigned int add_to = 8 ; 00295 00296 char *byte_buf = (char *)malloc( num + add_to ) ; 00297 if ( !byte_buf ) { 00298 throw Error("Failed to allocate memory for byte vector data serialization."); 00299 } 00300 00301 XDR *byte_sink = new XDR ; 00302 xdrmem_create( byte_sink, byte_buf, num + add_to, XDR_ENCODE ) ; 00303 00304 if( !xdr_setpos( byte_sink, 0 ) ) { 00305 delete_xdrstdio( byte_sink ) ; 00306 free(byte_buf); 00307 throw Error("Network I/O Error. Could not send byte vector data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00308 } 00309 00310 if( !xdr_bytes( byte_sink, (char **)&val, (unsigned int *) &num, 00311 num + add_to ) ) 00312 { 00313 delete_xdrstdio( byte_sink ) ; 00314 free(byte_buf); 00315 throw Error("Network I/O Error(2). Could not send byte vector data.\nThis may be due to a bug in libdap or a\nproblem with the network connection."); 00316 } 00317 00318 unsigned int bytes_written = xdr_getpos( byte_sink ) ; 00319 if( !bytes_written ) { 00320 delete_xdrstdio( byte_sink ) ; 00321 free(byte_buf); 00322 throw Error("Network I/O Error. Could not send byte vector data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00323 } 00324 00325 _out.write( byte_buf, bytes_written ) ; 00326 00327 delete_xdrstdio( byte_sink ) ; 00328 free( byte_buf ) ; 00329 } 00330 00331 void 00332 XDRStreamMarshaller::put_vector( char *val, int num, int width, Vector &vec ) 00333 { 00334 if (!val) 00335 throw InternalErr(__FILE__, __LINE__, 00336 "Buffer pointer is not set."); 00337 // write the number of array members being written, then set the position back to 0 00338 put_int( num ) ; 00339 00340 int use_width = width ; 00341 if( use_width < 4 ) 00342 use_width = 4 ; 00343 00344 // the size is the number of elements num times the width of each 00345 // element, then add 4 bytes for the number of elements 00346 int size = ( num * use_width ) + 4 ; 00347 00348 // allocate enough memory for the elements 00349 char *vec_buf = (char *)malloc( size ) ; 00350 if ( !vec_buf ) { 00351 free(vec_buf); 00352 throw Error("Failed to allocate memory for vector data serialization."); 00353 } 00354 00355 XDR *vec_sink = new XDR ; 00356 xdrmem_create( vec_sink, vec_buf, size, XDR_ENCODE ) ; 00357 00358 // set the position of the sink to 0, we're starting at the beginning 00359 if( !xdr_setpos( vec_sink, 0 ) ) { 00360 delete_xdrstdio( vec_sink ) ; 00361 free(vec_buf); 00362 throw Error("Network I/O Error. Could not send vector data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00363 } 00364 00365 BaseType *var = vec.var() ; 00366 00367 // write the array to the buffer 00368 if( !xdr_array( vec_sink, (char **)&val, 00369 (unsigned int *) & num, 00370 size, width, 00371 XDRUtils::xdr_coder( var->type() ) ) ) 00372 { 00373 delete_xdrstdio( vec_sink ) ; 00374 free(vec_buf); 00375 throw Error("Network I/O Error(2). Could not send vector data.\nThis may be due to a bug in libdap or a\nproblem with the network connection."); 00376 } 00377 00378 // how much was written to the buffer 00379 unsigned int bytes_written = xdr_getpos( vec_sink ) ; 00380 if( !bytes_written ) { 00381 delete_xdrstdio( vec_sink ) ; 00382 free(vec_buf); 00383 throw Error("Network I/O Error. Could not send vector data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection."); 00384 } 00385 00386 // write that much out to the output stream 00387 _out.write( vec_buf, bytes_written ) ; 00388 00389 delete_xdrstdio( vec_sink ) ; 00390 free( vec_buf ) ; 00391 } 00392 00393 void 00394 XDRStreamMarshaller::dump(ostream &strm) const 00395 { 00396 strm << DapIndent::LMarg << "XDRStreamMarshaller::dump - (" 00397 << (void *)this << ")" << endl ; 00398 } 00399 00400 } // namespace libdap 00401