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 free(str_buf);
00208 throw Error("Failed to allocate memory for string data serialization.");
00209 }
00210
00211 XDR *str_sink = new XDR ;
00212 xdrmem_create( str_sink, str_buf, size, XDR_ENCODE ) ;
00213
00214 if( !xdr_setpos( str_sink, 0 ) ) {
00215 delete_xdrstdio( str_sink ) ;
00216 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.");
00217 }
00218
00219 const char *out_tmp = val.c_str() ;
00220 if( !xdr_string( str_sink, (char **)&out_tmp, size ) ) {
00221 delete_xdrstdio( str_sink ) ;
00222 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.");
00223 }
00224
00225 unsigned int bytes_written = xdr_getpos( str_sink ) ;
00226 if( !bytes_written ) {
00227 delete_xdrstdio( str_sink ) ;
00228 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.");
00229 }
00230
00231 _out.write( str_buf, bytes_written ) ;
00232
00233 delete_xdrstdio( str_sink ) ;
00234 free( str_buf ) ;
00235 }
00236
00237 void
00238 XDRStreamMarshaller::put_url( const string &val )
00239 {
00240 put_str( val ) ;
00241 }
00242
00243 void
00244 XDRStreamMarshaller::put_opaque( char *val, unsigned int len )
00245 {
00246 if( len > XDR_DAP_BUFF_SIZE )
00247 throw Error("Network I/O Error. Could not send opaque data - length of opaque data larger than allowed");
00248
00249 if( !xdr_setpos( _sink, 0 ) )
00250 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.");
00251
00252 if( !xdr_opaque( _sink, val, len ) )
00253 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.");
00254
00255 unsigned int bytes_written = xdr_getpos( _sink ) ;
00256 if( !bytes_written )
00257 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.");
00258
00259 _out.write( _buf, bytes_written ) ;
00260 }
00261
00262 void
00263 XDRStreamMarshaller::put_int( int val )
00264 {
00265 if( !xdr_setpos( _sink, 0 ) )
00266 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.");
00267
00268 if( !xdr_int( _sink, &val) )
00269 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.");
00270
00271 unsigned int bytes_written = xdr_getpos( _sink ) ;
00272 if( !bytes_written )
00273 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.");
00274
00275 _out.write( _buf, bytes_written ) ;
00276 }
00277
00278 void
00279 XDRStreamMarshaller::put_vector( char *val, int num, Vector & )
00280 {
00281 if (!val)
00282 throw InternalErr(__FILE__, __LINE__, "Could not send byte vector data. Buffer pointer is not set.");
00283
00284
00285 put_int( num ) ;
00286
00287
00288 unsigned int add_to = 8 ;
00289
00290 char *byte_buf = (char *)malloc( num + add_to ) ;
00291 if ( !byte_buf ) {
00292 free(byte_buf);
00293 throw Error("Failed to allocate memory for byte vector data serialization.");
00294 }
00295
00296 XDR *byte_sink = new XDR ;
00297 xdrmem_create( byte_sink, byte_buf, num + add_to, XDR_ENCODE ) ;
00298
00299 if( !xdr_setpos( byte_sink, 0 ) ) {
00300 delete_xdrstdio( byte_sink ) ;
00301 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.");
00302 }
00303
00304 if( !xdr_bytes( byte_sink, (char **)&val, (unsigned int *) &num,
00305 num + add_to ) )
00306 {
00307 delete_xdrstdio( byte_sink ) ;
00308 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.");
00309 }
00310
00311 unsigned int bytes_written = xdr_getpos( byte_sink ) ;
00312 if( !bytes_written ) {
00313 delete_xdrstdio( byte_sink ) ;
00314 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.");
00315 }
00316
00317 _out.write( byte_buf, bytes_written ) ;
00318
00319 delete_xdrstdio( byte_sink ) ;
00320 free( byte_buf ) ;
00321 }
00322
00323 void
00324 XDRStreamMarshaller::put_vector( char *val, int num, int width, Vector &vec )
00325 {
00326 if (!val)
00327 throw InternalErr(__FILE__, __LINE__,
00328 "Buffer pointer is not set.");
00329
00330 put_int( num ) ;
00331
00332 int use_width = width ;
00333 if( use_width < 4 )
00334 use_width = 4 ;
00335
00336
00337
00338 int size = ( num * use_width ) + 4 ;
00339
00340
00341 char *vec_buf = (char *)malloc( size ) ;
00342 if ( !vec_buf ) {
00343 free(vec_buf);
00344 throw Error("Failed to allocate memory for vector data serialization.");
00345 }
00346
00347 XDR *vec_sink = new XDR ;
00348 xdrmem_create( vec_sink, vec_buf, size, XDR_ENCODE ) ;
00349
00350
00351 if( !xdr_setpos( vec_sink, 0 ) ) {
00352 delete_xdrstdio( vec_sink ) ;
00353 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.");
00354 }
00355
00356 BaseType *var = vec.var() ;
00357
00358
00359 if( !xdr_array( vec_sink, (char **)&val,
00360 (unsigned int *) & num,
00361 size, width,
00362 XDRUtils::xdr_coder( var->type() ) ) )
00363 {
00364 delete_xdrstdio( vec_sink ) ;
00365 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.");
00366 }
00367
00368
00369 unsigned int bytes_written = xdr_getpos( vec_sink ) ;
00370 if( !bytes_written ) {
00371 delete_xdrstdio( vec_sink ) ;
00372 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.");
00373 }
00374
00375
00376 _out.write( vec_buf, bytes_written ) ;
00377
00378 delete_xdrstdio( vec_sink ) ;
00379 free( vec_buf ) ;
00380 }
00381
00382 void
00383 XDRStreamMarshaller::dump(ostream &strm) const
00384 {
00385 strm << DapIndent::LMarg << "XDRStreamMarshaller::dump - ("
00386 << (void *)this << ")" << endl ;
00387 }
00388
00389 }
00390