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