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         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     // write the number of members of the array being written and then set the position to 0
00285     put_int( num ) ;
00286 
00287     // this is the word boundary for writing xdr bytes in a vector.
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     // write the number of array members being written, then set the position back to 0
00330     put_int( num ) ;
00331 
00332     int use_width = width ;
00333     if( use_width < 4 )
00334         use_width = 4 ;
00335 
00336     // the size is the number of elements num times the width of each
00337     // element, then add 4 bytes for the number of elements
00338     int size = ( num * use_width ) + 4 ;
00339 
00340     // allocate enough memory for the elements
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     // set the position of the sink to 0, we're starting at the beginning
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     // write the array to the buffer
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     // how much was written to the buffer
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     // write that much out to the output stream
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 } // namespace libdap
00390 

Generated on Wed Mar 5 15:27:11 2008 for libdap++ by  doxygen 1.5.4