00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "XDRStreamMarshaller.h"
00034
00035
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
00291 put_int( num ) ;
00292
00293
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
00338 put_int( num ) ;
00339
00340 int use_width = width ;
00341 if( use_width < 4 )
00342 use_width = 4 ;
00343
00344
00345
00346 int size = ( num * use_width ) + 4 ;
00347
00348
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
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
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
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
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 }
00401