1 // XDRUtils.cc
2 
3 // -*- mode: c++; c-basic-offset:4 -*-
4 
5 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
6 // Access Protocol.
7 
8 // Copyright (c) 2002,2003 OPeNDAP, Inc.
9 // Author: Patrick West <pwest@ucar.edu>
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 //
25 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
26 
27 // (c) COPYRIGHT URI/MIT 1994-1999
28 // Please read the full copyright statement in the file COPYRIGHT_URI.
29 //
30 // Authors:
31 //      pwest       Patrick West <pwest@ucar.edu>
32 
33 #include "config.h"
34 
35 #include "XDRUtils.h"
36 #include "debug.h"
37 #include "Str.h"
38 
39 using namespace libdap ;
40 
41 // This function is used to allocate memory for, and initialize, a new XDR
42 // pointer. It sets the stream associated with the (XDR *) to STREAM.
43 //
44 // NB: STREAM is not one of the C++/libg++ iostream classes; it is a (FILE
45 // *).
46 
47 //  These func's moved to xdrutil_ppc.* under the PPC as explained there
48 #ifndef __POWERPC__
49 XDR *
new_xdrstdio(FILE * stream,enum xdr_op xop)50 new_xdrstdio(FILE *stream, enum xdr_op xop)
51 {
52     XDR *xdr = new XDR;
53 
54     xdrstdio_create(xdr, stream, xop);
55 
56     return xdr;
57 }
58 
59 XDR *
set_xdrstdio(XDR * xdr,FILE * stream,enum xdr_op xop)60 set_xdrstdio(XDR *xdr, FILE *stream, enum xdr_op xop)
61 {
62     xdrstdio_create(xdr, stream, xop);
63 
64     return xdr;
65 }
66 
67 // Delete an XDR pointer allocated using the above function. Do not close the
68 // associated FILE pointer.
69 
70 void
delete_xdrstdio(XDR * xdr)71 delete_xdrstdio(XDR *xdr)
72 {
73     xdr_destroy(xdr);
74 
75     delete xdr; xdr = 0;
76 }
77 #endif
78 
79 // This function is used to en/decode Str and Url type variables. It is
80 // defined as extern C since it is passed via function pointers to routines
81 // in the xdr library where it is executed. This function is defined so
82 // that Str and Url have an en/decoder which takes exactly two arguments: an
83 // XDR * and a string reference.
84 //
85 // NB: this function is *not* used for arrays (i.e., it is not the function
86 // referenced by BaseType's _xdr_coder field when the object is a Str or Url.
87 // Also note that \e max_str_len is an obese number but that really does not
88 // matter; xdr_string() would never actually allocate that much memory unless
89 // a string that size was sent from the server.
90 // Returns: XDR's bool_t; TRUE if no errors are detected, FALSE
91 // otherwise. The formal parameter BUF is modified as a side effect.
92 
93 extern "C" bool_t
xdr_str(XDR * xdrs,string & buf)94 xdr_str(XDR *xdrs, string &buf)
95 {
96     DBG(cerr << "In xdr_str, xdrs: " << xdrs << endl);
97 
98     switch (xdrs->x_op) {
99     case XDR_ENCODE: { // BUF is a pointer to a (string *)
100             const char *out_tmp = buf.c_str();
101 
102             return xdr_string(xdrs, (char **)&out_tmp, max_str_len);
103         }
104 
105     case XDR_DECODE: {
106             char *in_tmp = NULL;
107 
108             bool_t stat = xdr_string(xdrs, &in_tmp, max_str_len);
109             if (!stat)
110                 return stat;
111 
112             buf = in_tmp;
113 
114             free(in_tmp);
115 
116             return stat;
117         }
118 
119     default:
120         return 0;
121     }
122 }
123 
124 namespace libdap {
125 
126 /** The <tt>xdr_coder</tt> function (also "filter primitive") is used to
127     encode and decode each element in a multiple element data
128     structure.  These functions are used to convert data to and from
129     its local representation to the XDR representation, which is
130     used to transmit and receive the data.  See <tt>man xdr</tt> for more
131     information about the available XDR filter primitives.
132 
133     \note This class data is only used for multiple element data
134     types.  The simple data types (Int, Float, and so on), are
135     translated directly.
136 
137     \note Even though Byte is a cardinal type, xdr_char is <i>not</i>
138     used to transport Byte arrays over the network. Instead, Byte is
139     a special case handled in Array.
140 
141     @brief Returns a function used to encode elements of an array.
142     @return A C function used to encode data in the XDR format.
143 */
144 xdrproc_t
xdr_coder(const Type & t)145 XDRUtils::xdr_coder(const Type &t)
146 {
147     switch (t) {
148     case dods_int16_c:
149         return (xdrproc_t) XDR_INT16;
150     case dods_uint16_c:
151         return (xdrproc_t) XDR_UINT16;
152     case dods_int32_c:
153         return (xdrproc_t) XDR_INT32;
154     case dods_uint32_c:
155         return (xdrproc_t) XDR_UINT32;
156     case dods_float32_c:
157         return (xdrproc_t) XDR_FLOAT32;
158     case dods_float64_c:
159         return (xdrproc_t) XDR_FLOAT64;
160     case dods_byte_c:
161     case dods_str_c:
162     case dods_url_c:
163     case dods_array_c:
164     case dods_structure_c:
165     case dods_sequence_c:
166     case dods_grid_c:
167     default:
168         break;
169     }
170 
171     return NULL;
172 }
173 
174 } // namespace libdap
175 
176