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 #include "config.h"
00033 #include "XDRStreamUnMarshaller.h"
00034
00035 #include <cstring>
00036 #include <string>
00037 #include <sstream>
00038
00039 #define DODS_DEBUG2 1
00040 #define DODS_DEBUG 1
00041
00042 #include "Str.h"
00043 #include "Vector.h"
00044 #include "Array.h"
00045 #include "util.h"
00046 #include "InternalErr.h"
00047 #include "debug.h"
00048
00049 namespace libdap {
00050
00051 char *XDRStreamUnMarshaller::_buf = 0 ;
00052
00053 XDRStreamUnMarshaller::XDRStreamUnMarshaller( istream &in )
00054 : _source( 0 ), _in( in )
00055 {
00056 if (!_buf)
00057 _buf = (char *) malloc(XDR_DAP_BUFF_SIZE);
00058 if (!_buf)
00059 throw Error("Failed to allocate memory for data serialization.");
00060
00061 _source = new XDR;
00062 xdrmem_create(_source, _buf, XDR_DAP_BUFF_SIZE, XDR_DECODE);
00063 }
00064
00065 XDRStreamUnMarshaller::XDRStreamUnMarshaller()
00066 : UnMarshaller(), _source( 0 ), _in( cin )
00067 {
00068 throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ;
00069 }
00070
00071 XDRStreamUnMarshaller::XDRStreamUnMarshaller( const XDRStreamUnMarshaller &um )
00072 : UnMarshaller( um ), _source( 0 ), _in( cin )
00073 {
00074 throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ;
00075 }
00076
00077 XDRStreamUnMarshaller &
00078 XDRStreamUnMarshaller::operator=( const XDRStreamUnMarshaller & )
00079 {
00080 throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ;
00081
00082 return *this ;
00083 }
00084
00085 XDRStreamUnMarshaller::~XDRStreamUnMarshaller( )
00086 {
00087 if ( _source )
00088 delete_xdrstdio( _source ) ;
00089 _source = 0;
00090 }
00091
00092 void
00093 XDRStreamUnMarshaller::get_byte( dods_byte &val )
00094 {
00095 if (xdr_setpos( _source, 0 ) < 0)
00096 throw Error("Failed to reposition input stream");
00097 if (!(_in.read( _buf, 4 ))) {
00098 if (_in.eof())
00099 throw Error("Premature EOF in input stream");
00100 else {
00101 ostringstream ss("Error reading from input stream: ");
00102 ss << _in.rdstate();
00103 throw Error(ss.str());
00104 }
00105 }
00106
00107 DBG2( std::cerr << "_in.gcount(): " << _in.gcount() << std::endl );
00108 DBG2( std::cerr << "_in.tellg(): " << _in.tellg() << std::endl );
00109 DBG2( std::cerr << "_buf[0]: " << hex << _buf[0] << "; _buf[1]: " << _buf[1]
00110 << "; _buf[2]: " << _buf[2] << "; _buf[3]: " << _buf[3]
00111 << dec << std::endl );
00112
00113 if( !xdr_char( _source, (char *)&val ) )
00114 throw Error("Network I/O Error. Could not read byte data.");
00115
00116 DBG2(std::cerr << "get_byte: " << val << std::endl );
00117 }
00118
00119 void
00120 XDRStreamUnMarshaller::get_int16( dods_int16 &val )
00121 {
00122 xdr_setpos( _source, 0 );
00123 _in.read( _buf, 4 );
00124
00125 if( !XDR_INT16( _source, &val ) )
00126 throw Error("Network I/O Error. Could not read int 16 data.");
00127 }
00128
00129 void
00130 XDRStreamUnMarshaller::get_int32( dods_int32 &val )
00131 {
00132 xdr_setpos( _source, 0 );
00133 _in.read( _buf, 4 );
00134
00135 if( !XDR_INT32( _source, &val ) )
00136 throw Error("Network I/O Error. Could not read int 32 data.");
00137 }
00138
00139 void
00140 XDRStreamUnMarshaller::get_float32( dods_float32 &val )
00141 {
00142 xdr_setpos( _source, 0 );
00143 _in.read( _buf, 4 );
00144
00145 if( !xdr_float( _source, &val ) )
00146 throw Error("Network I/O Error. Could not read float 32 data.");
00147 }
00148
00149 void
00150 XDRStreamUnMarshaller::get_float64( dods_float64 &val )
00151 {
00152 xdr_setpos( _source, 0 );
00153 _in.read( _buf, 8 );
00154
00155 if( !xdr_double( _source, &val ) )
00156 throw Error("Network I/O Error. Could not read float 64 data.");
00157 }
00158
00159 void
00160 XDRStreamUnMarshaller::get_uint16( dods_uint16 &val )
00161 {
00162 xdr_setpos( _source, 0 );
00163 _in.read( _buf, 4 );
00164
00165 if( !XDR_UINT16( _source, &val ) )
00166 throw Error("Network I/O Error. Could not read uint 16 data.");
00167 }
00168
00169 void
00170 XDRStreamUnMarshaller::get_uint32( dods_uint32 &val )
00171 {
00172 xdr_setpos( _source, 0 );
00173 _in.read( _buf, 4 );
00174
00175 if( !XDR_UINT32( _source, &val ) )
00176 throw Error("Network I/O Error. Could not read uint 32 data.");
00177 }
00178
00179 void
00180 XDRStreamUnMarshaller::get_str( string &val )
00181 {
00182 int i;
00183 get_int( i ) ;
00184 DBG(std::cerr << "i: " << i << std::endl);
00185
00186
00187 i = ( ( i + 3 ) / 4 ) * 4;
00188 DBG(std::cerr << "i: " << i << std::endl);
00189
00190 char *in_tmp = 0;
00191 char *buf = 0;
00192 XDR *source = 0;
00193
00194 if ( i + 4 > XDR_DAP_BUFF_SIZE ) {
00195 source = new XDR;
00196 buf = (char *) malloc( i + 4 );
00197 xdrmem_create(source, buf, i + 4, XDR_DECODE);
00198 memcpy( buf, _buf, 4 );
00199
00200 _in.read( buf + 4, i );
00201
00202 xdr_setpos( source, 0 );
00203 if( !xdr_string( source, &in_tmp, max_str_len ) )
00204 throw Error("Network I/O Error. Could not read string data.");
00205
00206 delete_xdrstdio( source );
00207 }
00208 else {
00209 _in.read( _buf + 4, i );
00210
00211 xdr_setpos( _source, 0 );
00212 if( !xdr_string( _source, &in_tmp, max_str_len ) )
00213 throw Error("Network I/O Error. Could not read string data.");
00214 }
00215
00216 val = in_tmp ;
00217
00218 free( in_tmp ) ;
00219 }
00220
00221 void
00222 XDRStreamUnMarshaller::get_url( string &val )
00223 {
00224 get_str( val ) ;
00225 }
00226
00227 void
00228 XDRStreamUnMarshaller::get_opaque( char *val, unsigned int len )
00229 {
00230 xdr_setpos( _source, 0 );
00231
00232
00233
00234 len += len&3;
00235 if ( static_cast<int>(len) > XDR_DAP_BUFF_SIZE )
00236 throw Error("Network I/O Error. Length of opaque data larger than allowed");
00237
00238 _in.read( _buf, len );
00239
00240 xdr_opaque( _source, val, len ) ;
00241 }
00242
00243 void
00244 XDRStreamUnMarshaller::get_int( int &val )
00245 {
00246 xdr_setpos( _source, 0 );
00247 _in.read( _buf, 4 );
00248
00249 if( !xdr_int( _source, &val ) )
00250 throw Error("Network I/O Error(1).");
00251
00252 DBG(std::cerr << "get_int: " << val << std::endl);
00253 }
00254
00255 void
00256 XDRStreamUnMarshaller::get_vector( char **val, unsigned int &num, Vector & )
00257 {
00258 int i;
00259 get_int( i ) ;
00260 DBG(std::cerr << "i: " << i << std::endl);
00261
00262
00263 i += i&3;
00264 DBG(std::cerr << "i: " << i << std::endl);
00265
00266 char *buf = 0;
00267 XDR *source = 0;
00268
00269 if ( i + 4 > XDR_DAP_BUFF_SIZE ) {
00270 source = new XDR;
00271 buf = (char *) malloc( i + 4 );
00272 xdrmem_create(source, buf, i + 4, XDR_DECODE);
00273 memcpy( buf, _buf, 4 );
00274
00275 _in.read( buf + 4, i );
00276 DBG2(cerr << "bytes read: " << _in.gcount() << endl);
00277
00278 xdr_setpos( source, 0 );
00279 if( !xdr_bytes( _source, val, &num, DODS_MAX_ARRAY) )
00280 throw Error("Network I/O Error. Could not read byte array data.");
00281
00282 delete_xdrstdio( source );
00283 }
00284 else {
00285 _in.read( _buf + 4, i );
00286 DBG2(cerr << "bytes read: " << _in.gcount() << endl);
00287
00288 xdr_setpos( _source, 0 );
00289 if( !xdr_bytes( _source, val, &num, DODS_MAX_ARRAY) )
00290 throw Error("Network I/O Error. Could not read byte array data.");
00291 }
00292 }
00293
00294 void
00295 XDRStreamUnMarshaller::get_vector( char **val, unsigned int &num, int width, Vector &vec )
00296 {
00297 int i;
00298 get_int( i ) ;
00299 DBG(std::cerr << "i: " << i << std::endl);
00300
00301 width += width&3;
00302 DBG(std::cerr << "width: " << width << std::endl);
00303
00304 char *buf = 0;
00305 XDR *source = 0;
00306 int size = i * width;
00307 BaseType *var = vec.var();
00308
00309
00310 if (size > XDR_DAP_BUFF_SIZE) {
00311 source = new XDR;
00312 buf = (char *) malloc( size + 4 );
00313 xdrmem_create(source, buf, size + 4, XDR_DECODE);
00314 DBG2(cerr << "size: " << size << endl);
00315 memcpy(buf, _buf, 4);
00316
00317 _in.read(buf + 4, size);
00318 DBG2(cerr << "bytes read: " << _in.gcount() << endl);
00319
00320 xdr_setpos( source, 0 );
00321 if (!xdr_array( source, val, &num, DODS_MAX_ARRAY, width,
00322 XDRUtils::xdr_coder( var->type() ) ) )
00323 throw Error("Network I/O Error. Could not read array data.");
00324
00325 delete_xdrstdio(source);
00326 }
00327 else {
00328 _in.read(_buf + 4, size);
00329 DBG2(cerr << "bytes read: " << _in.gcount() << endl);
00330
00331 xdr_setpos( _source, 0 );
00332 if (!xdr_array( _source, val, &num, DODS_MAX_ARRAY, width,
00333 XDRUtils::xdr_coder( var->type() ) ) )
00334 throw Error("Network I/O Error. Could not read array data.");
00335 }
00336 }
00337
00338 void
00339 XDRStreamUnMarshaller::dump(ostream &strm) const
00340 {
00341 strm << DapIndent::LMarg << "XDRStreamUnMarshaller::dump - ("
00342 << (void *)this << ")" << endl ;
00343 }
00344
00345 }
00346