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 #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
00290 put_int( num ) ;
00291
00292
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
00340 put_int( num ) ;
00341
00342 int use_width = width ;
00343 if( use_width < 4 )
00344 use_width = 4 ;
00345
00346
00347
00348 int size = ( num * use_width ) + 4 ;
00349
00350
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
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
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
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
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 }
00403