Back to index

glibc  2.9
xdr_mem.c
Go to the documentation of this file.
00001 /*
00002  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00003  * unrestricted use provided that this legend is included on all tape
00004  * media and as a part of the software program in whole or part.  Users
00005  * may copy or modify Sun RPC without charge, but are not authorized
00006  * to license or distribute it to anyone else except as part of a product or
00007  * program developed by the user.
00008  *
00009  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00010  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00011  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00012  *
00013  * Sun RPC is provided with no support and without any obligation on the
00014  * part of Sun Microsystems, Inc. to assist in its use, correction,
00015  * modification or enhancement.
00016  *
00017  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00018  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00019  * OR ANY PART THEREOF.
00020  *
00021  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00022  * or profits or other special, indirect and consequential damages, even if
00023  * Sun has been advised of the possibility of such damages.
00024  *
00025  * Sun Microsystems, Inc.
00026  * 2550 Garcia Avenue
00027  * Mountain View, California  94043
00028  */
00029 
00030 /*
00031  * xdr_mem.h, XDR implementation using memory buffers.
00032  *
00033  * Copyright (C) 1984, Sun Microsystems, Inc.
00034  *
00035  * If you have some data to be interpreted as external data representation
00036  * or to be converted to external data representation in a memory buffer,
00037  * then this is the package for you.
00038  *
00039  */
00040 
00041 #include <string.h>
00042 #include <limits.h>
00043 #include <rpc/rpc.h>
00044 
00045 static bool_t xdrmem_getlong (XDR *, long *);
00046 static bool_t xdrmem_putlong (XDR *, const long *);
00047 static bool_t xdrmem_getbytes (XDR *, caddr_t, u_int);
00048 static bool_t xdrmem_putbytes (XDR *, const char *, u_int);
00049 static u_int xdrmem_getpos (const XDR *);
00050 static bool_t xdrmem_setpos (XDR *, u_int);
00051 static int32_t *xdrmem_inline (XDR *, u_int);
00052 static void xdrmem_destroy (XDR *);
00053 static bool_t xdrmem_getint32 (XDR *, int32_t *);
00054 static bool_t xdrmem_putint32 (XDR *, const int32_t *);
00055 
00056 static const struct xdr_ops xdrmem_ops =
00057 {
00058   xdrmem_getlong,
00059   xdrmem_putlong,
00060   xdrmem_getbytes,
00061   xdrmem_putbytes,
00062   xdrmem_getpos,
00063   xdrmem_setpos,
00064   xdrmem_inline,
00065   xdrmem_destroy,
00066   xdrmem_getint32,
00067   xdrmem_putint32
00068 };
00069 
00070 /*
00071  * The procedure xdrmem_create initializes a stream descriptor for a
00072  * memory buffer.
00073  */
00074 void
00075 xdrmem_create (XDR *xdrs, const caddr_t addr, u_int size, enum xdr_op op)
00076 {
00077   xdrs->x_op = op;
00078   /* We have to add the const since the `struct xdr_ops' in `struct XDR'
00079      is not `const'.  */
00080   xdrs->x_ops = (struct xdr_ops *) &xdrmem_ops;
00081   xdrs->x_private = xdrs->x_base = addr;
00082   xdrs->x_handy = size;
00083 }
00084 INTDEF(xdrmem_create)
00085 
00086 /*
00087  * Nothing needs to be done for the memory case.  The argument is clearly
00088  * const.
00089  */
00090 
00091 static void
00092 xdrmem_destroy (XDR *xdrs)
00093 {
00094 }
00095 
00096 /*
00097  * Gets the next word from the memory referenced by xdrs and places it
00098  * in the long pointed to by lp.  It then increments the private word to
00099  * point at the next element.  Neither object pointed to is const
00100  */
00101 static bool_t
00102 xdrmem_getlong (XDR *xdrs, long *lp)
00103 {
00104   if (xdrs->x_handy < 4)
00105     return FALSE;
00106   xdrs->x_handy -= 4;
00107   *lp = (int32_t) ntohl ((*((int32_t *) (xdrs->x_private))));
00108   xdrs->x_private += 4;
00109   return TRUE;
00110 }
00111 
00112 /*
00113  * Puts the long pointed to by lp in the memory referenced by xdrs.  It
00114  * then increments the private word to point at the next element.  The
00115  * long pointed at is const
00116  */
00117 static bool_t
00118 xdrmem_putlong (XDR *xdrs, const long *lp)
00119 {
00120   if (xdrs->x_handy < 4)
00121     return FALSE;
00122   xdrs->x_handy -= 4;
00123   *(int32_t *) xdrs->x_private = htonl (*lp);
00124   xdrs->x_private += 4;
00125   return TRUE;
00126 }
00127 
00128 /*
00129  * Gets an unaligned number of bytes from the xdrs structure and writes them
00130  * to the address passed in addr.  Be very careful when calling this routine
00131  * as it could leave the xdrs pointing to an unaligned structure which is not
00132  * a good idea.  None of the things pointed to are const.
00133  */
00134 static bool_t
00135 xdrmem_getbytes (XDR *xdrs, caddr_t addr, u_int len)
00136 {
00137   if (xdrs->x_handy < len)
00138     return FALSE;
00139   xdrs->x_handy -= len;
00140   memcpy (addr, xdrs->x_private, len);
00141   xdrs->x_private += len;
00142   return TRUE;
00143 }
00144 
00145 /*
00146  * The complementary function to the above.  The same warnings apply about
00147  * unaligned data.  The source address is const.
00148  */
00149 static bool_t
00150 xdrmem_putbytes (XDR *xdrs, const char *addr, u_int len)
00151 {
00152   if (xdrs->x_handy < len)
00153     return FALSE;
00154   xdrs->x_handy -= len;
00155   memcpy (xdrs->x_private, addr, len);
00156   xdrs->x_private += len;
00157   return TRUE;
00158 }
00159 
00160 /*
00161  * Not sure what this one does.  But it clearly doesn't modify the contents
00162  * of xdrs.  **FIXME** does this not assume u_int == u_long?
00163  */
00164 static u_int
00165 xdrmem_getpos (const XDR *xdrs)
00166 {
00167   return (u_long) xdrs->x_private - (u_long) xdrs->x_base;
00168 }
00169 
00170 /*
00171  * xdrs modified
00172  */
00173 static bool_t
00174 xdrmem_setpos (xdrs, pos)
00175      XDR *xdrs;
00176      u_int pos;
00177 {
00178   caddr_t newaddr = xdrs->x_base + pos;
00179   caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
00180   size_t handy = lastaddr - newaddr;
00181 
00182   if (newaddr > lastaddr
00183       || newaddr < xdrs->x_base
00184       || handy != (u_int) handy)
00185     return FALSE;
00186 
00187   xdrs->x_private = newaddr;
00188   xdrs->x_handy = (u_int) handy;
00189   return TRUE;
00190 }
00191 
00192 /*
00193  * xdrs modified
00194  */
00195 static int32_t *
00196 xdrmem_inline (XDR *xdrs, u_int len)
00197 {
00198   int32_t *buf = 0;
00199 
00200   if (xdrs->x_handy >= len)
00201     {
00202       xdrs->x_handy -= len;
00203       buf = (int32_t *) xdrs->x_private;
00204       xdrs->x_private += len;
00205     }
00206   return buf;
00207 }
00208 
00209 /*
00210  * Gets the next word from the memory referenced by xdrs and places it
00211  * in the int pointed to by ip.  It then increments the private word to
00212  * point at the next element.  Neither object pointed to is const
00213  */
00214 static bool_t
00215 xdrmem_getint32 (XDR *xdrs, int32_t *ip)
00216 {
00217   if (xdrs->x_handy < 4)
00218     return FALSE;
00219   xdrs->x_handy -= 4;
00220   *ip = ntohl ((*((int32_t *) (xdrs->x_private))));
00221   xdrs->x_private += 4;
00222   return TRUE;
00223 }
00224 
00225 /*
00226  * Puts the long pointed to by lp in the memory referenced by xdrs.  It
00227  * then increments the private word to point at the next element.  The
00228  * long pointed at is const
00229  */
00230 static bool_t
00231 xdrmem_putint32 (XDR *xdrs, const int32_t *ip)
00232 {
00233   if (xdrs->x_handy < 4)
00234     return FALSE;
00235   xdrs->x_handy -= 4;
00236   *(int32_t *) xdrs->x_private = htonl (*ip);
00237   xdrs->x_private += 4;
00238   return TRUE;
00239 }