1 /* PortableXDR - a free, portable XDR implementation.
2 * Copyright (C) 2009 Red Hat Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifndef PORTABLEXDR_XDR_INTERNAL_H
20 #define PORTABLEXDR_XDR_INTERNAL_H
22 #include <rpc/types.h>
31 #define __GNUC_PREREQ(maj,min) 0
33 #ifndef ATTRIBUTE_UNUSED
34 #define ATTRIBUTE_UNUSED __attribute__((__unused__))
37 #define ATTRIBUTE_UNUSED
40 /* Here we get into what could be termed the "internals" of XDR. Most
41 * callers can get away with only ever using the basic XDR types and
42 * functions (see <rpc/xdr.h>. Sometimes, particularly for
43 * compatibility with Sun XDR code, you need to delve into the
53 /* Operations available on an XDR data stream (file, socket or memory
54 * area). Callers shouldn't normally use these, but Sun's XDR
55 * implementation exposes these operations, so we do too.
58 /* Get/put "long" (ie. 32 bit quantity). */
59 bool_t (*x_getlong) (XDR *, int32_t *);
60 bool_t (*x_putlong) (XDR *, int32_t *);
62 bool_t (*x_getbytes) (XDR *, void *, size_t);
63 bool_t (*x_putbytes) (XDR *, void *, size_t);
64 /* Get or seek within the stream (offsets from beginning of stream). */
65 off_t (*x_getpostn) (XDR *);
66 bool_t (*x_setpostn) (XDR *, off_t);
67 /* Returns a pointer to the next n bytes in the stream. */
68 void * (*x_inline) (XDR *, size_t);
69 /* Free the stream. */
70 void (*x_destroy) (XDR *);
74 /* Calling code can read the operation field, but should not update it. */
75 enum xdr_op x_op; /* operation (encode/decode/free) */
77 /* Calling code may use this pointer for any purpose, eg.
78 * to point to their own data.
84 /* The remaining fields are private and could change in any
85 * future release. Calling code should not use or modify them.
90 /* Define wrapper functions around the x_ops. */
92 xdr_getlong (XDR *xdrs, int32_t *v)
94 return xdrs->x_ops->x_getlong (xdrs, v);
97 xdr_putlong (XDR *xdrs, int32_t *v)
99 return xdrs->x_ops->x_putlong (xdrs, v);
102 xdr_getbytes (XDR *xdrs, void *p, size_t len)
104 return xdrs->x_ops->x_getbytes (xdrs, p, len);
107 xdr_putbytes (XDR *xdrs, void *p, size_t len)
109 return xdrs->x_ops->x_putbytes (xdrs, p, len);
112 xdr_getpos (XDR *xdrs)
114 return xdrs->x_ops->x_getpostn (xdrs);
117 xdr_setpos (XDR *xdrs, off_t v)
119 return xdrs->x_ops->x_setpostn (xdrs, v);
122 xdr_inline (XDR *xdrs, size_t len)
124 return xdrs->x_ops->x_inline (xdrs, len);
127 xdr_destroy (XDR *xdrs)
129 return xdrs->x_ops->x_destroy (xdrs);
132 /* For compatibility with Sun XDR. */
133 #define XDR_GETLONG xdr_getlong
134 #define XDR_PUTLONG xdr_putlong
135 #define XDR_GETBYTES xdr_getbytes
136 #define XDR_PUTBYTES xdr_putbytes
137 #define XDR_GETPOS xdr_getpos
138 #define XDR_SETPOS xdr_setpos
139 #define XDR_INLINE xdr_inline
140 #define XDR_DESTROY xdr_destroy
142 /* Also seen in the wild ... */
143 #define XDR_GETINT32 xdr_getlong
144 #define XDR_PUTINT32 xdr_putlong
146 /* These are the "inline" versions of the macros. These are used
147 * in SunRPC for some primitive optimizations. For example, suppose
148 * you have to parse 4 integers from the stream. You could
149 * optimize using these macros by doing:
151 * if (xdr->x_op == XDR_DECODE) {
152 * void *buf = xdr_inline (xdr, 4 * BYTES_PER_XDR_UNIT);
154 * i0 = IXDR_GET_LONG (buf); // NB. Macro autoincrements buf.
155 * i1 = IXDR_GET_LONG (buf);
156 * i2 = IXDR_GET_LONG (buf);
157 * i3 = IXDR_GET_LONG (buf);
161 * else if (xdr->x_op == XDR_ENCODE) {
162 * // Similar code required for encoding.
165 * if (!xdr_int (xdr, &i0)) return FALSE;
166 * if (!xdr_int (xdr, &i1)) return FALSE;
167 * if (!xdr_int (xdr, &i2)) return FALSE;
168 * if (!xdr_int (xdr, &i3)) return FALSE;
171 * Note that you have to fallback in the case when xdr_inline
172 * returns NULL. This is NOT an error case.
174 * Whether this optimization is really worth it or not is left as
175 * an exercise in benchmarking. In any case, PortableXDR's rpcgen
176 * does NOT perform this optimization.
179 #define BYTES_PER_XDR_UNIT 4
181 #define IXDR_GET_LONG(buf) ((int32_t) ntohl (*((int32_t *)(buf))++))
182 #define IXDR_GET_BOOL(buf) ((bool_t) IXDR_GET_LONG ((buf)))
183 #define IXDR_GET_ENUM(buf,type) ((type) IXDR_GET_LONG ((buf)))
184 #define IXDR_GET_U_LONG(buf) ((uint32_t) IXDR_GET_LONG ((buf)))
185 #define IXDR_GET_SHORT(buf) ((int16_t) IXDR_GET_LONG ((buf)))
186 #define IXDR_GET_U_SHORT(buf) ((uint16_t) IXDR_GET_LONG ((buf)))
187 #define IXDR_GET_INT32 IXDR_GET_LONG
189 #define IXDR_PUT_LONG(buf,v) ((*((int32_t *)(buf))++) = htonl ((v)))
190 #define IXDR_PUT_BOOL(buf,v) IXDR_PUT_LONG((buf), (int32_t) (v))
191 #define IXDR_PUT_ENUM(buf,v) IXDR_PUT_LONG((buf), (int32_t) (v))
192 #define IXDR_PUT_U_LONG(buf,v) IXDR_PUT_LONG((buf), (int32_t) (v))
193 #define IXDR_PUT_SHORT(buf,v) IXDR_PUT_LONG((buf), (int32_t) (v))
194 #define IXDR_PUT_U_SHORT(buf,v) IXDR_PUT_LONG((buf), (int32_t) (v))
195 #define IXDR_PUT_INT32 IXDR_PUT_LONG
201 #endif /* PORTABLEXDR_XDR_INTERNAL_H */