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 char *XDRStreamMarshaller::_buf = 0 ;
00039 
00040 #define XDR_DAP_BUFF_SIZE 256
00041 
00042 XDRStreamMarshaller::XDRStreamMarshaller( ostream &out )
00043     : _sink( 0 ),
00044       _out( out )
00045 {
00046     if( !_buf )
00047         _buf = (char *)malloc( XDR_DAP_BUFF_SIZE ) ;
00048     if ( !_buf )
00049         throw Error("Failed to allocate memory for data serialization.");
00050         
00051     _sink = new XDR ;
00052     xdrmem_create( _sink, _buf, XDR_DAP_BUFF_SIZE, XDR_ENCODE ) ;
00053 }
00054 
00055 XDRStreamMarshaller::XDRStreamMarshaller()
00056     : Marshaller(),
00057       _sink( 0 ),
00058       _out( cout )
00059 {
00060     throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ;
00061 }
00062 
00063 XDRStreamMarshaller::XDRStreamMarshaller( const XDRStreamMarshaller &m )
00064     : Marshaller( m ),
00065       _sink( 0 ),
00066       _out( cout )
00067 {
00068     throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ;
00069 }
00070 
00071 XDRStreamMarshaller &
00072 XDRStreamMarshaller::operator=( const XDRStreamMarshaller & )
00073 {
00074     throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ;
00075     
00076     return *this ;
00077 }
00078 
00079 XDRStreamMarshaller::~XDRStreamMarshaller( )
00080 {
00081     if( _sink )
00082         delete_xdrstdio( _sink ) ;
00083     _sink = 0 ;
00084 }
00085 
00086 void
00087 XDRStreamMarshaller::put_byte( dods_byte val )
00088 {
00089     if( !xdr_setpos( _sink, 0 ) )
00090         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.");
00091 
00092     if( !xdr_char( _sink, (char *)&val ) )
00093         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.");
00094 
00095     unsigned int bytes_written = xdr_getpos( _sink ) ;
00096     if( !bytes_written )
00097         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.");
00098 
00099     _out.write( _buf, bytes_written ) ;
00100 }
00101 
00102 void
00103 XDRStreamMarshaller::put_int16( dods_int16 val )
00104 {
00105     if( !xdr_setpos( _sink, 0 ) )
00106         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.");
00107 
00108     if( !XDR_INT16( _sink, &val ) )
00109         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.");
00110 
00111     unsigned int bytes_written = xdr_getpos( _sink ) ;
00112     if( !bytes_written )
00113         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.");
00114 
00115     _out.write( _buf, bytes_written ) ;
00116 }
00117 
00118 void
00119 XDRStreamMarshaller::put_int32( dods_int32 val )
00120 {
00121     if( !xdr_setpos( _sink, 0 ) )
00122         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.");
00123 
00124     if( !XDR_INT32( _sink, &val ) )
00125         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.");
00126 
00127     unsigned int bytes_written = xdr_getpos( _sink ) ;
00128     if( !bytes_written )
00129         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.");
00130 
00131     _out.write( _buf, bytes_written ) ;
00132 }
00133 
00134 void
00135 XDRStreamMarshaller::put_float32( dods_float32 val )
00136 {
00137     if( !xdr_setpos( _sink, 0 ) )
00138         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.");
00139 
00140     if( !xdr_float( _sink, &val ) )
00141         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.");
00142 
00143     unsigned int bytes_written = xdr_getpos( _sink ) ;
00144     if( !bytes_written )
00145         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.");
00146 
00147     _out.write( _buf, bytes_written ) ;
00148 }
00149 
00150 void
00151 XDRStreamMarshaller::put_float64( dods_float64 val )
00152 {
00153     if( !xdr_setpos( _sink, 0 ) )
00154         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.");
00155 
00156     if( !xdr_double( _sink, &val ) )
00157         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.");
00158 
00159     unsigned int bytes_written = xdr_getpos( _sink ) ;
00160     if( !bytes_written )
00161         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.");
00162 
00163     _out.write( _buf, bytes_written ) ;
00164 }
00165 
00166 void
00167 XDRStreamMarshaller::put_uint16( dods_uint16 val )
00168 {
00169     if( !xdr_setpos( _sink, 0 ) )
00170         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.");
00171 
00172     if( !XDR_UINT16( _sink, &val ) )
00173         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.");
00174 
00175     unsigned int bytes_written = xdr_getpos( _sink ) ;
00176     if( !bytes_written )
00177         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.");
00178 
00179     _out.write( _buf, bytes_written ) ;
00180 }
00181 
00182 void
00183 XDRStreamMarshaller::put_uint32( dods_uint32 val )
00184 {
00185     if( !xdr_setpos( _sink, 0 ) )
00186         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.");
00187 
00188     if( !XDR_UINT32( _sink, &val ) )
00189         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.");
00190 
00191     unsigned int bytes_written = xdr_getpos( _sink ) ;
00192     if( !bytes_written )
00193         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.");
00194 
00195     _out.write( _buf, bytes_written ) ;
00196 }
00197 
00198 void
00199 XDRStreamMarshaller::put_str( const string &val )
00200 {
00201     int size = val.length() + 8 ;
00202     char *str_buf = (char *)malloc( size ) ;
00203     if ( !str_buf )
00204         throw Error("Failed to allocate memory for string data serialization.");
00205         
00206     XDR *str_sink = new XDR ;
00207     xdrmem_create( str_sink, str_buf, size, XDR_ENCODE ) ;
00208 
00209     if( !xdr_setpos( str_sink, 0 ) )
00210         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.");
00211 
00212     const char *out_tmp = val.c_str() ;
00213     if( !xdr_string( str_sink, (char **)&out_tmp, size ) )
00214         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.");
00215 
00216     unsigned int bytes_written = xdr_getpos( str_sink ) ;
00217     if( !bytes_written )
00218         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.");
00219 
00220     _out.write( str_buf, bytes_written ) ;
00221 
00222     delete_xdrstdio( str_sink ) ;
00223     free( str_buf ) ;
00224 }
00225 
00226 void
00227 XDRStreamMarshaller::put_url( const string &val )
00228 {
00229     put_str( val ) ;
00230 }
00231 
00232 void
00233 XDRStreamMarshaller::put_opaque( char *val, unsigned int len )
00234 {
00235     if( len > XDR_DAP_BUFF_SIZE )
00236         throw Error("Network I/O Error. Could not send opaque data - length of opaque data larger than allowed");
00237 
00238     if( !xdr_setpos( _sink, 0 ) )
00239         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.");
00240 
00241     if( !xdr_opaque( _sink, val, len ) )
00242         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.");
00243 
00244     unsigned int bytes_written = xdr_getpos( _sink ) ;
00245     if( !bytes_written )
00246         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.");
00247 
00248     _out.write( _buf, bytes_written ) ;
00249 }
00250 
00251 void
00252 XDRStreamMarshaller::put_int( int val )
00253 {
00254     if( !xdr_setpos( _sink, 0 ) )
00255         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.");
00256 
00257     if( !xdr_int( _sink, &val) )
00258         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.");
00259 
00260     unsigned int bytes_written = xdr_getpos( _sink ) ;
00261     if( !bytes_written )
00262         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.");
00263 
00264     _out.write( _buf, bytes_written ) ;
00265 }
00266 
00267 void
00268 XDRStreamMarshaller::put_vector( char *val, int num, Vector & )
00269 {
00270     if (!val)
00271         throw InternalErr(__FILE__, __LINE__, "Could not send byte vector data. Buffer pointer is not set.");
00272 
00273     // write the number of members of the array being written and then set the position to 0
00274     put_int( num ) ;
00275 
00276     char *byte_buf = (char *)malloc( num + 4 ) ;
00277     if ( !byte_buf )
00278         throw Error("Failed to allocate memory for byte vector data serialization.");
00279         
00280     XDR *byte_sink = new XDR ;
00281     xdrmem_create( byte_sink, byte_buf, num + 4, XDR_ENCODE ) ;
00282 
00283     if( !xdr_setpos( byte_sink, 0 ) )
00284         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.");
00285 
00286     if( !xdr_bytes( byte_sink, (char **)&val,
00287                     (unsigned int *) &num,
00288                     num + 4 ) )
00289     {
00290         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.");
00291     }
00292 
00293     unsigned int bytes_written = xdr_getpos( byte_sink ) ;
00294     if( !bytes_written )
00295         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.");
00296     _out.write( byte_buf, bytes_written ) ;
00297 
00298     delete_xdrstdio( byte_sink ) ;
00299     free( byte_buf ) ;
00300 }
00301 
00302 void
00303 XDRStreamMarshaller::put_vector( char *val, int num, int width, Vector &vec )
00304 {
00305     if (!val)
00306         throw InternalErr(__FILE__, __LINE__,
00307                           "Buffer pointer is not set.");
00308     // write the number of array members being written, then set the position back to 0
00309     put_int( num ) ;
00310 
00311     int use_width = width ;
00312     if( use_width < 4 )
00313         use_width = 4 ;
00314 
00315     // the size is the number of elements num times the width of each
00316     // element, then add 4 bytes for the number of elements
00317     int size = ( num * use_width ) + 4 ;
00318 
00319     // allocate enough memory for the elements
00320     char *vec_buf = (char *)malloc( size ) ;
00321     if ( !vec_buf )
00322         throw Error("Failed to allocate memory for vector data serialization.");
00323         
00324     XDR *vec_sink = new XDR ;
00325     xdrmem_create( vec_sink, vec_buf, size, XDR_ENCODE ) ;
00326 
00327     // set the position of the sink to 0, we're starting at the beginning
00328     if( !xdr_setpos( vec_sink, 0 ) )
00329         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.");
00330 
00331     BaseType *var = vec.var() ;
00332 
00333     // write the array to the buffer
00334     if( !xdr_array( vec_sink, (char **)&val,
00335                     (unsigned int *) & num,
00336                     size, width,
00337                     XDRUtils::xdr_coder( var->type() ) ) )
00338     {
00339         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.");
00340     }
00341 
00342     // how much was written to the buffer
00343     unsigned int bytes_written = xdr_getpos( vec_sink ) ;
00344     if( !bytes_written )
00345         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.");
00346 
00347     // write that much out to the output stream
00348     _out.write( vec_buf, bytes_written ) ;
00349 
00350     delete_xdrstdio( vec_sink ) ;
00351     free( vec_buf ) ;
00352 }
00353 
00354 void
00355 XDRStreamMarshaller::dump(ostream &strm) const
00356 {
00357     strm << DapIndent::LMarg << "XDRStreamMarshaller::dump - ("
00358          << (void *)this << ")" << endl ;
00359 }
00360 

Generated on Sat Jan 19 04:05:27 2008 for libdap++ by  doxygen 1.5.4