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 #include "Vector.h" 00036 #include "util.h" 00037 00038 namespace libdap { 00039 00040 char *XDRStreamMarshaller::_buf = 0 ; 00041 00042 #define XDR_DAP_BUFF_SIZE 256 00043 00044 XDRStreamMarshaller::XDRStreamMarshaller( ostream &out ) 00045 : _sink( 0 ), 00046 _out( out ) 00047 { 00048 if( !_buf ) 00049 _buf = (char *)malloc( XDR_DAP_BUFF_SIZE ) ; 00050 if ( !_buf ) 00051 throw Error("Failed to allocate memory for data serialization."); 00052 00053 _sink = new XDR ; 00054 xdrmem_create( _sink, _buf, XDR_DAP_BUFF_SIZE, XDR_ENCODE ) ; 00055 } 00056 00057 XDRStreamMarshaller::XDRStreamMarshaller() 00058 : Marshaller(), 00059 _sink( 0 ), 00060 _out( cout ) 00061 { 00062 throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ; 00063 } 00064 00065 XDRStreamMarshaller::XDRStreamMarshaller( const XDRStreamMarshaller &m ) 00066 : Marshaller( m ), 00067 _sink( 0 ), 00068 _out( cout ) 00069 { 00070 throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ; 00071 } 00072 00073 XDRStreamMarshaller & 00074 XDRStreamMarshaller::operator=( const XDRStreamMarshaller & ) 00075 { 00076 throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ; 00077 00078 return *this ; 00079 } 00080 00081 XDRStreamMarshaller::~XDRStreamMarshaller( ) 00082 { 00083 if( _sink ) 00084 delete_xdrstdio( _sink ) ; 00085 _sink = 0 ; 00086 } 00087 00088 void 00089 XDRStreamMarshaller::put_byte( dods_byte val ) 00090 { 00091 if( !xdr_setpos( _sink, 0 ) ) 00092 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."); 00093 00094 if( !xdr_char( _sink, (char *)&val ) ) 00095 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."); 00096 00097 unsigned int bytes_written = xdr_getpos( _sink ) ; 00098 if( !bytes_written ) 00099 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."); 00100 00101 _out.write( _buf, bytes_written ) ; 00102 } 00103 00104 void 00105 XDRStreamMarshaller::put_int16( dods_int16 val ) 00106 { 00107 if( !xdr_setpos( _sink, 0 ) ) 00108 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."); 00109 00110 if( !XDR_INT16( _sink, &val ) ) 00111 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."); 00112 00113 unsigned int bytes_written = xdr_getpos( _sink ) ; 00114 if( !bytes_written ) 00115 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."); 00116 00117 _out.write( _buf, bytes_written ) ; 00118 } 00119 00120 void 00121 XDRStreamMarshaller::put_int32( dods_int32 val ) 00122 { 00123 if( !xdr_setpos( _sink, 0 ) ) 00124 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."); 00125 00126 if( !XDR_INT32( _sink, &val ) ) 00127 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."); 00128 00129 unsigned int bytes_written = xdr_getpos( _sink ) ; 00130 if( !bytes_written ) 00131 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."); 00132 00133 _out.write( _buf, bytes_written ) ; 00134 } 00135 00136 void 00137 XDRStreamMarshaller::put_float32( dods_float32 val ) 00138 { 00139 if( !xdr_setpos( _sink, 0 ) ) 00140 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."); 00141 00142 if( !xdr_float( _sink, &val ) ) 00143 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."); 00144 00145 unsigned int bytes_written = xdr_getpos( _sink ) ; 00146 if( !bytes_written ) 00147 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."); 00148 00149 _out.write( _buf, bytes_written ) ; 00150 } 00151 00152 void 00153 XDRStreamMarshaller::put_float64( dods_float64 val ) 00154 { 00155 if( !xdr_setpos( _sink, 0 ) ) 00156 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."); 00157 00158 if( !xdr_double( _sink, &val ) ) 00159 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."); 00160 00161 unsigned int bytes_written = xdr_getpos( _sink ) ; 00162 if( !bytes_written ) 00163 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."); 00164 00165 _out.write( _buf, bytes_written ) ; 00166 } 00167 00168 void 00169 XDRStreamMarshaller::put_uint16( dods_uint16 val ) 00170 { 00171 if( !xdr_setpos( _sink, 0 ) ) 00172 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."); 00173 00174 if( !XDR_UINT16( _sink, &val ) ) 00175 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."); 00176 00177 unsigned int bytes_written = xdr_getpos( _sink ) ; 00178 if( !bytes_written ) 00179 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."); 00180 00181 _out.write( _buf, bytes_written ) ; 00182 } 00183 00184 void 00185 XDRStreamMarshaller::put_uint32( dods_uint32 val ) 00186 { 00187 if( !xdr_setpos( _sink, 0 ) ) 00188 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."); 00189 00190 if( !XDR_UINT32( _sink, &val ) ) 00191 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."); 00192 00193 unsigned int bytes_written = xdr_getpos( _sink ) ; 00194 if( !bytes_written ) 00195 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."); 00196 00197 _out.write( _buf, bytes_written ) ; 00198 } 00199 00200 void 00201 XDRStreamMarshaller::put_str( const string &val ) 00202 { 00203 int size = val.length() + 8 ; 00204 char *str_buf = (char *)malloc( size ) ; 00205 00206 if ( !str_buf ) { 00207 #if 0 00208 free(str_buf); 00209 #endif 00210 throw Error("Failed to allocate memory for string data serialization."); 00211 } 00212 00213 XDR *str_sink = new XDR ; 00214 xdrmem_create( str_sink, str_buf, size, XDR_ENCODE ) ; 00215 00216 if( !xdr_setpos( str_sink, 0 ) ) { 00217 delete_xdrstdio( str_sink ) ; 00218 free( str_buf ) ; 00219 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."); 00220 } 00221 00222 const char *out_tmp = val.c_str() ; 00223 if( !xdr_string( str_sink, (char **)&out_tmp, size ) ) { 00224 delete_xdrstdio( str_sink ) ; 00225 free( str_buf ) ; 00226 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."); 00227 } 00228 00229 unsigned int bytes_written = xdr_getpos( str_sink ) ; 00230 if( !bytes_written ) { 00231 delete_xdrstdio( str_sink ) ; 00232 free( str_buf ) ; 00233 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."); 00234 } 00235 00236 _out.write( str_buf, bytes_written ) ; 00237 00238 delete_xdrstdio( str_sink ) ; 00239 free( str_buf ) ; 00240 } 00241 00242 void 00243 XDRStreamMarshaller::put_url( const string &val ) 00244 { 00245 put_str( val ) ; 00246 } 00247 00248 void 00249 XDRStreamMarshaller::put_opaque( char *val, unsigned int len ) 00250 { 00251 if( len > XDR_DAP_BUFF_SIZE ) 00252 throw Error("Network I/O Error. Could not send opaque data - length of opaque data larger than allowed"); 00253 00254 if( !xdr_setpos( _sink, 0 ) ) 00255 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."); 00256 00257 if( !xdr_opaque( _sink, val, len ) ) 00258 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."); 00259 00260 unsigned int bytes_written = xdr_getpos( _sink ) ; 00261 if( !bytes_written ) 00262 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."); 00263 00264 _out.write( _buf, bytes_written ) ; 00265 } 00266 00267 void 00268 XDRStreamMarshaller::put_int( int val ) 00269 { 00270 if( !xdr_setpos( _sink, 0 ) ) 00271 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."); 00272 00273 if( !xdr_int( _sink, &val) ) 00274 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."); 00275 00276 unsigned int bytes_written = xdr_getpos( _sink ) ; 00277 if( !bytes_written ) 00278 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."); 00279 00280 _out.write( _buf, bytes_written ) ; 00281 } 00282 00283 void 00284 XDRStreamMarshaller::put_vector( char *val, int num, Vector & ) 00285 { 00286 if (!val) 00287 throw InternalErr(__FILE__, __LINE__, "Could not send byte vector data. Buffer pointer is not set."); 00288 00289 // write the number of members of the array being written and then set the position to 0 00290 put_int( num ) ; 00291 00292 // this is the word boundary for writing xdr bytes in a vector. 00293 unsigned int add_to = 8 ; 00294 00295 char *byte_buf = (char *)malloc( num + add_to ) ; 00296 if ( !byte_buf ) { 00297 #if 0 00298 free(byte_buf); 00299 #endif 00300 throw Error("Failed to allocate memory for byte vector data serialization."); 00301 } 00302 00303 XDR *byte_sink = new XDR ; 00304 xdrmem_create( byte_sink, byte_buf, num + add_to, XDR_ENCODE ) ; 00305 00306 if( !xdr_setpos( byte_sink, 0 ) ) { 00307 delete_xdrstdio( byte_sink ) ; 00308 free(byte_buf); 00309 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."); 00310 } 00311 00312 if( !xdr_bytes( byte_sink, (char **)&val, (unsigned int *) &num, 00313 num + add_to ) ) 00314 { 00315 delete_xdrstdio( byte_sink ) ; 00316 free(byte_buf); 00317 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."); 00318 } 00319 00320 unsigned int bytes_written = xdr_getpos( byte_sink ) ; 00321 if( !bytes_written ) { 00322 delete_xdrstdio( byte_sink ) ; 00323 free(byte_buf); 00324 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."); 00325 } 00326 00327 _out.write( byte_buf, bytes_written ) ; 00328 00329 delete_xdrstdio( byte_sink ) ; 00330 free( byte_buf ) ; 00331 } 00332 00333 void 00334 XDRStreamMarshaller::put_vector( char *val, int num, int width, Vector &vec ) 00335 { 00336 if (!val) 00337 throw InternalErr(__FILE__, __LINE__, 00338 "Buffer pointer is not set."); 00339 // write the number of array members being written, then set the position back to 0 00340 put_int( num ) ; 00341 00342 int use_width = width ; 00343 if( use_width < 4 ) 00344 use_width = 4 ; 00345 00346 // the size is the number of elements num times the width of each 00347 // element, then add 4 bytes for the number of elements 00348 int size = ( num * use_width ) + 4 ; 00349 00350 // allocate enough memory for the elements 00351 char *vec_buf = (char *)malloc( size ) ; 00352 if ( !vec_buf ) { 00353 free(vec_buf); 00354 throw Error("Failed to allocate memory for vector data serialization."); 00355 } 00356 00357 XDR *vec_sink = new XDR ; 00358 xdrmem_create( vec_sink, vec_buf, size, XDR_ENCODE ) ; 00359 00360 // set the position of the sink to 0, we're starting at the beginning 00361 if( !xdr_setpos( vec_sink, 0 ) ) { 00362 delete_xdrstdio( vec_sink ) ; 00363 free(vec_buf); 00364 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."); 00365 } 00366 00367 BaseType *var = vec.var() ; 00368 00369 // write the array to the buffer 00370 if( !xdr_array( vec_sink, (char **)&val, 00371 (unsigned int *) & num, 00372 size, width, 00373 XDRUtils::xdr_coder( var->type() ) ) ) 00374 { 00375 delete_xdrstdio( vec_sink ) ; 00376 free(vec_buf); 00377 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."); 00378 } 00379 00380 // how much was written to the buffer 00381 unsigned int bytes_written = xdr_getpos( vec_sink ) ; 00382 if( !bytes_written ) { 00383 delete_xdrstdio( vec_sink ) ; 00384 free(vec_buf); 00385 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."); 00386 } 00387 00388 // write that much out to the output stream 00389 _out.write( vec_buf, bytes_written ) ; 00390 00391 delete_xdrstdio( vec_sink ) ; 00392 free( vec_buf ) ; 00393 } 00394 00395 void 00396 XDRStreamMarshaller::dump(ostream &strm) const 00397 { 00398 strm << DapIndent::LMarg << "XDRStreamMarshaller::dump - (" 00399 << (void *)this << ")" << endl ; 00400 } 00401 00402 } // namespace libdap 00403