/*
 * xdr_mem.c, XDR implementation using memory buffers.
 *
 * Copyright (c) 2010, Oracle America, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials
 *       provided with the distribution.
 *     * Neither the name of the "Oracle America, Inc." nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * If you have some data to be interpreted as external data representation
 * or to be converted to external data representation in a memory buffer,
 * then this is the package for you.
 */

#include <string.h>
#include <limits.h>
#include <rpc/rpc.h>

static bool_t xdrmem_getlong (XDR *, long *);
static bool_t xdrmem_putlong (XDR *, const long *);
static bool_t xdrmem_getbytes (XDR *, caddr_t, u_int);
static bool_t xdrmem_putbytes (XDR *, const char *, u_int);
static u_int xdrmem_getpos (const XDR *);
static bool_t xdrmem_setpos (XDR *, u_int);
static int32_t *xdrmem_inline (XDR *, u_int);
static void xdrmem_destroy (XDR *);
static bool_t xdrmem_getint32 (XDR *, int32_t *);
static bool_t xdrmem_putint32 (XDR *, const int32_t *);

static const struct xdr_ops xdrmem_ops =
{
  xdrmem_getlong,
  xdrmem_putlong,
  xdrmem_getbytes,
  xdrmem_putbytes,
  xdrmem_getpos,
  xdrmem_setpos,
  xdrmem_inline,
  xdrmem_destroy,
  xdrmem_getint32,
  xdrmem_putint32
};

/*
 * The procedure xdrmem_create initializes a stream descriptor for a
 * memory buffer.
 */
void
xdrmem_create (XDR *xdrs, const caddr_t addr, u_int size, enum xdr_op op)
{
  xdrs->x_op = op;
  /* We have to add the const since the `struct xdr_ops' in `struct XDR'
     is not `const'.  */
  xdrs->x_ops = (struct xdr_ops *) &xdrmem_ops;
  xdrs->x_private = xdrs->x_base = addr;
  xdrs->x_handy = size;
}
#ifdef EXPORT_RPC_SYMBOLS
libc_hidden_def (xdrmem_create)
#else
libc_hidden_nolink_sunrpc (xdrmem_create, GLIBC_2_0)
#endif

/*
 * Nothing needs to be done for the memory case.  The argument is clearly
 * const.
 */

static void
xdrmem_destroy (XDR *xdrs)
{
}

/*
 * Gets the next word from the memory referenced by xdrs and places it
 * in the long pointed to by lp.  It then increments the private word to
 * point at the next element.  Neither object pointed to is const
 */
static bool_t
xdrmem_getlong (XDR *xdrs, long *lp)
{
  if (xdrs->x_handy < 4)
    return FALSE;
  xdrs->x_handy -= 4;
  *lp = (int32_t) ntohl ((*((int32_t *) (xdrs->x_private))));
  xdrs->x_private += 4;
  return TRUE;
}

/*
 * Puts the long pointed to by lp in the memory referenced by xdrs.  It
 * then increments the private word to point at the next element.  The
 * long pointed at is const
 */
static bool_t
xdrmem_putlong (XDR *xdrs, const long *lp)
{
  if (xdrs->x_handy < 4)
    return FALSE;
  xdrs->x_handy -= 4;
  *(int32_t *) xdrs->x_private = htonl (*lp);
  xdrs->x_private += 4;
  return TRUE;
}

/*
 * Gets an unaligned number of bytes from the xdrs structure and writes them
 * to the address passed in addr.  Be very careful when calling this routine
 * as it could leave the xdrs pointing to an unaligned structure which is not
 * a good idea.  None of the things pointed to are const.
 */
static bool_t
xdrmem_getbytes (XDR *xdrs, caddr_t addr, u_int len)
{
  if (xdrs->x_handy < len)
    return FALSE;
  xdrs->x_handy -= len;
  memcpy (addr, xdrs->x_private, len);
  xdrs->x_private += len;
  return TRUE;
}

/*
 * The complementary function to the above.  The same warnings apply about
 * unaligned data.  The source address is const.
 */
static bool_t
xdrmem_putbytes (XDR *xdrs, const char *addr, u_int len)
{
  if (xdrs->x_handy < len)
    return FALSE;
  xdrs->x_handy -= len;
  memcpy (xdrs->x_private, addr, len);
  xdrs->x_private += len;
  return TRUE;
}

/*
 * Not sure what this one does.  But it clearly doesn't modify the contents
 * of xdrs.  **FIXME** does this not assume u_int == u_long?
 */
static u_int
xdrmem_getpos (const XDR *xdrs)
{
  return (u_long) xdrs->x_private - (u_long) xdrs->x_base;
}

/*
 * xdrs modified
 */
static bool_t
xdrmem_setpos (xdrs, pos)
     XDR *xdrs;
     u_int pos;
{
  caddr_t newaddr = xdrs->x_base + pos;
  caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
  size_t handy = lastaddr - newaddr;

  if (newaddr > lastaddr
      || newaddr < xdrs->x_base
      || handy != (u_int) handy)
    return FALSE;

  xdrs->x_private = newaddr;
  xdrs->x_handy = (u_int) handy;
  return TRUE;
}

/*
 * xdrs modified
 */
static int32_t *
xdrmem_inline (XDR *xdrs, u_int len)
{
  int32_t *buf = 0;

  if (xdrs->x_handy >= len)
    {
      xdrs->x_handy -= len;
      buf = (int32_t *) xdrs->x_private;
      xdrs->x_private += len;
    }
  return buf;
}

/*
 * Gets the next word from the memory referenced by xdrs and places it
 * in the int pointed to by ip.  It then increments the private word to
 * point at the next element.  Neither object pointed to is const
 */
static bool_t
xdrmem_getint32 (XDR *xdrs, int32_t *ip)
{
  if (xdrs->x_handy < 4)
    return FALSE;
  xdrs->x_handy -= 4;
  *ip = ntohl ((*((int32_t *) (xdrs->x_private))));
  xdrs->x_private += 4;
  return TRUE;
}

/*
 * Puts the long pointed to by lp in the memory referenced by xdrs.  It
 * then increments the private word to point at the next element.  The
 * long pointed at is const
 */
static bool_t
xdrmem_putint32 (XDR *xdrs, const int32_t *ip)
{
  if (xdrs->x_handy < 4)
    return FALSE;
  xdrs->x_handy -= 4;
  *(int32_t *) xdrs->x_private = htonl (*ip);
  xdrs->x_private += 4;
  return TRUE;
}
