XDRStreamMarshaller.cc

Go to the documentation of this file.
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 

Generated on Wed May 13 18:06:39 2009 for libdap++ by  doxygen 1.4.7