xref: /reactos/dll/3rdparty/libtirpc/src/xdr_mem.c (revision c2c66aff)
1 /*
2  * Copyright (c) 2009, Sun Microsystems, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * - Redistributions of source code must retain the above copyright notice,
8  *   this list of conditions and the following disclaimer.
9  * - Redistributions in binary form must reproduce the above copyright notice,
10  *   this list of conditions and the following disclaimer in the documentation
11  *   and/or other materials provided with the distribution.
12  * - Neither the name of Sun Microsystems, Inc. nor the names of its
13  *   contributors may be used to endorse or promote products derived
14  *   from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 //#include <sys/cdefs.h>
30 
31 /*
32  * xdr_mem.h, XDR implementation using memory buffers.
33  *
34  * Copyright (C) 1984, Sun Microsystems, Inc.
35  *
36  * If you have some data to be interpreted as external data representation
37  * or to be converted to external data representation in a memory buffer,
38  * then this is the package for you.
39  *
40  */
41 
42 #include <wintirpc.h>
43 #include "namespace.h"
44 #include <sys/types.h>
45 
46 //#include <netinet/in.h>
47 
48 #include <string.h>
49 
50 #include <rpc/types.h>
51 #include <rpc/xdr.h>
52 #include "un-namespace.h"
53 
54 static void xdrmem_destroy(XDR *);
55 static bool_t xdrmem_getlong_aligned(XDR *, long *);
56 static bool_t xdrmem_putlong_aligned(XDR *, const long *);
57 static bool_t xdrmem_getlong_unaligned(XDR *, long *);
58 static bool_t xdrmem_putlong_unaligned(XDR *, const long *);
59 static bool_t xdrmem_getbytes(XDR *, char *, u_int);
60 static bool_t xdrmem_putbytes(XDR *, const char *, u_int);
61 /* XXX: w/64-bit pointers, u_int not enough! */
62 static u_int xdrmem_getpos(XDR *);
63 static bool_t xdrmem_setpos(XDR *, u_int);
64 static int32_t *xdrmem_inline_aligned(XDR *, u_int);
65 static int32_t *xdrmem_inline_unaligned(XDR *, u_int);
66 
67 static const struct	xdr_ops xdrmem_ops_aligned = {
68 	xdrmem_getlong_aligned,
69 	xdrmem_putlong_aligned,
70 	xdrmem_getbytes,
71 	xdrmem_putbytes,
72 	xdrmem_getpos,
73 	xdrmem_setpos,
74 	xdrmem_inline_aligned,
75 	xdrmem_destroy
76 };
77 
78 static const struct	xdr_ops xdrmem_ops_unaligned = {
79 	xdrmem_getlong_unaligned,
80 	xdrmem_putlong_unaligned,
81 	xdrmem_getbytes,
82 	xdrmem_putbytes,
83 	xdrmem_getpos,
84 	xdrmem_setpos,
85 	xdrmem_inline_unaligned,
86 	xdrmem_destroy
87 };
88 
89 /*
90  * The procedure xdrmem_create initializes a stream descriptor for a
91  * memory buffer.
92  */
93 void
xdrmem_create(xdrs,addr,size,op)94 xdrmem_create(xdrs, addr, size, op)
95 	XDR *xdrs;
96 	char *addr;
97 	u_int size;
98 	enum xdr_op op;
99 {
100 
101 	xdrs->x_op = op;
102 	xdrs->x_ops = (PtrToUlong(addr) & (sizeof(int32_t) - 1))
103 	    ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
104 	xdrs->x_private = xdrs->x_base = addr;
105 	xdrs->x_handy = size;
106 }
107 
108 /*ARGSUSED*/
109 static void
xdrmem_destroy(xdrs)110 xdrmem_destroy(xdrs)
111 	XDR *xdrs;
112 {
113 
114 }
115 
116 static bool_t
xdrmem_getlong_aligned(xdrs,lp)117 xdrmem_getlong_aligned(xdrs, lp)
118 	XDR *xdrs;
119 	long *lp;
120 {
121 
122 	if (xdrs->x_handy < sizeof(int32_t))
123 		return (FALSE);
124 	xdrs->x_handy -= sizeof(int32_t);
125 	*lp = ntohl(*(u_int32_t *)xdrs->x_private);
126 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
127 	return (TRUE);
128 }
129 
130 static bool_t
xdrmem_putlong_aligned(xdrs,lp)131 xdrmem_putlong_aligned(xdrs, lp)
132 	XDR *xdrs;
133 	const long *lp;
134 {
135 
136 	if (xdrs->x_handy < sizeof(int32_t))
137 		return (FALSE);
138 	xdrs->x_handy -= sizeof(int32_t);
139 	*(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
140 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
141 	return (TRUE);
142 }
143 
144 static bool_t
xdrmem_getlong_unaligned(xdrs,lp)145 xdrmem_getlong_unaligned(xdrs, lp)
146 	XDR *xdrs;
147 	long *lp;
148 {
149 	u_int32_t l;
150 
151 	if (xdrs->x_handy < sizeof(int32_t))
152 		return (FALSE);
153 	xdrs->x_handy -= sizeof(int32_t);
154 	memmove(&l, xdrs->x_private, sizeof(int32_t));
155 	*lp = ntohl(l);
156 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
157 	return (TRUE);
158 }
159 
160 static bool_t
xdrmem_putlong_unaligned(xdrs,lp)161 xdrmem_putlong_unaligned(xdrs, lp)
162 	XDR *xdrs;
163 	const long *lp;
164 {
165 	u_int32_t l;
166 
167 	if (xdrs->x_handy < sizeof(int32_t))
168 		return (FALSE);
169 	xdrs->x_handy -= sizeof(int32_t);
170 	l = htonl((u_int32_t)*lp);
171 	memmove(xdrs->x_private, &l, sizeof(int32_t));
172 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
173 	return (TRUE);
174 }
175 
176 static bool_t
xdrmem_getbytes(xdrs,addr,len)177 xdrmem_getbytes(xdrs, addr, len)
178 	XDR *xdrs;
179 	char *addr;
180 	u_int len;
181 {
182 
183 	if (xdrs->x_handy < len)
184 		return (FALSE);
185 	xdrs->x_handy -= len;
186 	memmove(addr, xdrs->x_private, len);
187 	xdrs->x_private = (char *)xdrs->x_private + len;
188 	return (TRUE);
189 }
190 
191 static bool_t
xdrmem_putbytes(xdrs,addr,len)192 xdrmem_putbytes(xdrs, addr, len)
193 	XDR *xdrs;
194 	const char *addr;
195 	u_int len;
196 {
197 
198 	if (xdrs->x_handy < len)
199 		return (FALSE);
200 	xdrs->x_handy -= len;
201 	memmove(xdrs->x_private, addr, len);
202 	xdrs->x_private = (char *)xdrs->x_private + len;
203 	return (TRUE);
204 }
205 
206 static u_int
xdrmem_getpos(xdrs)207 xdrmem_getpos(xdrs)
208 	XDR *xdrs;
209 {
210 
211 	/* XXX w/64-bit pointers, u_int not enough! */
212 	return (u_int)(PtrToUlong(xdrs->x_private) - PtrToUlong(xdrs->x_base));
213 }
214 
215 static bool_t
xdrmem_setpos(xdrs,pos)216 xdrmem_setpos(xdrs, pos)
217 	XDR *xdrs;
218 	u_int pos;
219 {
220 	char *newaddr = xdrs->x_base + pos;
221 	char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy;
222 
223 	if (newaddr > lastaddr)
224 		return (FALSE);
225 	xdrs->x_private = newaddr;
226 	xdrs->x_handy = (u_int)(lastaddr - newaddr); /* XXX sizeof(u_int) <? sizeof(ptrdiff_t) */
227 	return (TRUE);
228 }
229 
230 static int32_t *
xdrmem_inline_aligned(xdrs,len)231 xdrmem_inline_aligned(xdrs, len)
232 	XDR *xdrs;
233 	u_int len;
234 {
235 	int32_t *buf = 0;
236 
237 	if (xdrs->x_handy >= len) {
238 		xdrs->x_handy -= len;
239 		buf = (int32_t *)xdrs->x_private;
240 		xdrs->x_private = (char *)xdrs->x_private + len;
241 	}
242 	return (buf);
243 }
244 
245 /* ARGSUSED */
246 static int32_t *
xdrmem_inline_unaligned(xdrs,len)247 xdrmem_inline_unaligned(xdrs, len)
248 	XDR *xdrs;
249 	u_int len;
250 {
251 
252 	return (0);
253 }
254