1695feaf5893a64b55f54c3bbf941e9d19d52c65
[kopensolaris-gnu/glibc.git] / sunrpc / xdr_mem.c
1 /*
2  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3  * unrestricted use provided that this legend is included on all tape
4  * media and as a part of the software program in whole or part.  Users
5  * may copy or modify Sun RPC without charge, but are not authorized
6  * to license or distribute it to anyone else except as part of a product or
7  * program developed by the user.
8  *
9  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12  *
13  * Sun RPC is provided with no support and without any obligation on the
14  * part of Sun Microsystems, Inc. to assist in its use, correction,
15  * modification or enhancement.
16  *
17  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19  * OR ANY PART THEREOF.
20  *
21  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22  * or profits or other special, indirect and consequential damages, even if
23  * Sun has been advised of the possibility of such damages.
24  *
25  * Sun Microsystems, Inc.
26  * 2550 Garcia Avenue
27  * Mountain View, California  94043
28  */
29
30 /*
31  * xdr_mem.h, XDR implementation using memory buffers.
32  *
33  * Copyright (C) 1984, Sun Microsystems, Inc.
34  *
35  * If you have some data to be interpreted as external data representation
36  * or to be converted to external data representation in a memory buffer,
37  * then this is the package for you.
38  *
39  */
40
41 #include <string.h>
42 #include <rpc/rpc.h>
43
44 static bool_t xdrmem_getlong (XDR *, long *);
45 static bool_t xdrmem_putlong (XDR *, const long *);
46 static bool_t xdrmem_getbytes (XDR *, caddr_t, u_int);
47 static bool_t xdrmem_putbytes (XDR *, const char *, u_int);
48 static u_int xdrmem_getpos (const XDR *);
49 static bool_t xdrmem_setpos (XDR *, u_int);
50 static int32_t *xdrmem_inline (XDR *, int);
51 static void xdrmem_destroy (XDR *);
52 static bool_t xdrmem_getint32 (XDR *, int32_t *);
53 static bool_t xdrmem_putint32 (XDR *, const int32_t *);
54
55 static const struct xdr_ops xdrmem_ops =
56 {
57   xdrmem_getlong,
58   xdrmem_putlong,
59   xdrmem_getbytes,
60   xdrmem_putbytes,
61   xdrmem_getpos,
62   xdrmem_setpos,
63   xdrmem_inline,
64   xdrmem_destroy,
65   xdrmem_getint32,
66   xdrmem_putint32
67 };
68
69 /*
70  * The procedure xdrmem_create initializes a stream descriptor for a
71  * memory buffer.
72  */
73 void
74 xdrmem_create (XDR *xdrs, const caddr_t addr, u_int size, enum xdr_op op)
75 {
76   xdrs->x_op = op;
77   /* We have to add the const since the `struct xdr_ops' in `struct XDR'
78      is not `const'.  */
79   xdrs->x_ops = (struct xdr_ops *) &xdrmem_ops;
80   xdrs->x_private = xdrs->x_base = addr;
81   xdrs->x_handy = size;
82 }
83 INTDEF(xdrmem_create)
84
85 /*
86  * Nothing needs to be done for the memory case.  The argument is clearly
87  * const.
88  */
89
90 static void
91 xdrmem_destroy (XDR *xdrs)
92 {
93 }
94
95 /*
96  * Gets the next word from the memory referenced by xdrs and places it
97  * in the long pointed to by lp.  It then increments the private word to
98  * point at the next element.  Neither object pointed to is const
99  */
100 static bool_t
101 xdrmem_getlong (XDR *xdrs, long *lp)
102 {
103   if ((xdrs->x_handy -= 4) < 0)
104     return FALSE;
105   *lp = (int32_t) ntohl ((*((int32_t *) (xdrs->x_private))));
106   xdrs->x_private += 4;
107   return TRUE;
108 }
109
110 /*
111  * Puts the long pointed to by lp in the memory referenced by xdrs.  It
112  * then increments the private word to point at the next element.  The
113  * long pointed at is const
114  */
115 static bool_t
116 xdrmem_putlong (XDR *xdrs, const long *lp)
117 {
118   if ((xdrs->x_handy -= 4) < 0)
119     return FALSE;
120   *(int32_t *) xdrs->x_private = htonl (*lp);
121   xdrs->x_private += 4;
122   return TRUE;
123 }
124
125 /*
126  * Gets an unaligned number of bytes from the xdrs structure and writes them
127  * to the address passed in addr.  Be very careful when calling this routine
128  * as it could leave the xdrs pointing to an unaligned structure which is not
129  * a good idea.  None of the things pointed to are const.
130  */
131 static bool_t
132 xdrmem_getbytes (XDR *xdrs, caddr_t addr, u_int len)
133 {
134   if ((xdrs->x_handy -= len) < 0)
135     return FALSE;
136   memcpy (addr, xdrs->x_private, len);
137   xdrs->x_private += len;
138   return TRUE;
139 }
140
141 /*
142  * The complementary function to the above.  The same warnings apply about
143  * unaligned data.  The source address is const.
144  */
145 static bool_t
146 xdrmem_putbytes (XDR *xdrs, const char *addr, u_int len)
147 {
148   if ((xdrs->x_handy -= len) < 0)
149     return FALSE;
150   memcpy (xdrs->x_private, addr, len);
151   xdrs->x_private += len;
152   return TRUE;
153 }
154
155 /*
156  * Not sure what this one does.  But it clearly doesn't modify the contents
157  * of xdrs.  **FIXME** does this not assume u_int == u_long?
158  */
159 static u_int
160 xdrmem_getpos (const XDR *xdrs)
161 {
162   return (u_long) xdrs->x_private - (u_long) xdrs->x_base;
163 }
164
165 /*
166  * xdrs modified
167  */
168 static bool_t
169 xdrmem_setpos (xdrs, pos)
170      XDR *xdrs;
171      u_int pos;
172 {
173   caddr_t newaddr = xdrs->x_base + pos;
174   caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
175
176   if ((long) newaddr > (long) lastaddr)
177     return FALSE;
178   xdrs->x_private = newaddr;
179   xdrs->x_handy = (long) lastaddr - (long) newaddr;
180   return TRUE;
181 }
182
183 /*
184  * xdrs modified
185  */
186 static int32_t *
187 xdrmem_inline (XDR *xdrs, int len)
188 {
189   int32_t *buf = 0;
190
191   if (xdrs->x_handy >= len)
192     {
193       xdrs->x_handy -= len;
194       buf = (int32_t *) xdrs->x_private;
195       xdrs->x_private += len;
196     }
197   return buf;
198 }
199
200 /*
201  * Gets the next word from the memory referenced by xdrs and places it
202  * in the int pointed to by ip.  It then increments the private word to
203  * point at the next element.  Neither object pointed to is const
204  */
205 static bool_t
206 xdrmem_getint32 (XDR *xdrs, int32_t *ip)
207 {
208   if ((xdrs->x_handy -= 4) < 0)
209     return FALSE;
210   *ip = ntohl ((*((int32_t *) (xdrs->x_private))));
211   xdrs->x_private += 4;
212   return TRUE;
213 }
214
215 /*
216  * Puts the long pointed to by lp in the memory referenced by xdrs.  It
217  * then increments the private word to point at the next element.  The
218  * long pointed at is const
219  */
220 static bool_t
221 xdrmem_putint32 (XDR *xdrs, const int32_t *ip)
222 {
223   if ((xdrs->x_handy -= 4) < 0)
224     return FALSE;
225   *(int32_t *) xdrs->x_private = htonl (*ip);
226   xdrs->x_private += 4;
227   return TRUE;
228 }