/*
 *  Copyright (c) 2008 Sun Microsystems, Inc.
 *  Written by Ricardo Correia <Ricardo.M.Correia@Sun.COM>
 *
 *  This file is part of the SPL, Solaris Porting Layer.
 *  For details, see <http://zfsonlinux.org/>.
 *
 *  The SPL is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; either version 2 of the License, or (at your
 *  option) any later version.
 *
 *  The SPL is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _SPL_RPC_XDR_H
#define	_SPL_RPC_XDR_H

#include <sys/types.h>

typedef int bool_t;

/*
 * XDR enums and types.
 */
enum xdr_op {
	XDR_ENCODE,
	XDR_DECODE
};

struct xdr_ops;

typedef struct {
	struct xdr_ops	*x_ops;	/* Let caller know xdrmem_create() succeeds */
	caddr_t		x_addr;	/* Current buffer addr */
	caddr_t		x_addr_end;	/* End of the buffer */
	enum xdr_op	x_op;	/* Stream direction */
} XDR;

typedef bool_t (*xdrproc_t)(XDR *xdrs, void *ptr);

struct xdr_ops {
	bool_t (*xdr_control)(XDR *, int, void *);

	bool_t (*xdr_char)(XDR *, char *);
	bool_t (*xdr_u_short)(XDR *, unsigned short *);
	bool_t (*xdr_u_int)(XDR *, unsigned *);
	bool_t (*xdr_u_longlong_t)(XDR *, u_longlong_t *);

	bool_t (*xdr_opaque)(XDR *, caddr_t, const uint_t);
	bool_t (*xdr_string)(XDR *, char **, const uint_t);
	bool_t (*xdr_array)(XDR *, caddr_t *, uint_t *, const uint_t,
	    const uint_t, const xdrproc_t);
};

/*
 * XDR control operator.
 */
#define	XDR_GET_BYTES_AVAIL 1

struct xdr_bytesrec {
	bool_t xc_is_last_record;
	size_t xc_num_avail;
};

/*
 * XDR functions.
 */
void xdrmem_create(XDR *xdrs, const caddr_t addr, const uint_t size,
    const enum xdr_op op);

/* Currently not needed. If needed later, we'll add it to struct xdr_ops */
#define	xdr_destroy(xdrs) ((void) 0)

#define	xdr_control(xdrs, req, info) \
	(xdrs)->x_ops->xdr_control((xdrs), (req), (info))

/*
 * For precaution, the following are defined as static inlines instead of macros
 * to get some amount of type safety.
 *
 * Also, macros wouldn't work in the case where typecasting is done, because it
 * must be possible to reference the functions' addresses by these names.
 */
static inline bool_t xdr_char(XDR *xdrs, char *cp)
{
	return (xdrs->x_ops->xdr_char(xdrs, cp));
}

static inline bool_t xdr_u_short(XDR *xdrs, unsigned short *usp)
{
	return (xdrs->x_ops->xdr_u_short(xdrs, usp));
}

static inline bool_t xdr_short(XDR *xdrs, short *sp)
{
	BUILD_BUG_ON(sizeof (short) != 2);
	return (xdrs->x_ops->xdr_u_short(xdrs, (unsigned short *) sp));
}

static inline bool_t xdr_u_int(XDR *xdrs, unsigned *up)
{
	return (xdrs->x_ops->xdr_u_int(xdrs, up));
}

static inline bool_t xdr_int(XDR *xdrs, int *ip)
{
	BUILD_BUG_ON(sizeof (int) != 4);
	return (xdrs->x_ops->xdr_u_int(xdrs, (unsigned *)ip));
}

static inline bool_t xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp)
{
	return (xdrs->x_ops->xdr_u_longlong_t(xdrs, ullp));
}

static inline bool_t xdr_longlong_t(XDR *xdrs, longlong_t *llp)
{
	BUILD_BUG_ON(sizeof (longlong_t) != 8);
	return (xdrs->x_ops->xdr_u_longlong_t(xdrs, (u_longlong_t *)llp));
}

/*
 * Fixed-length opaque data.
 */
static inline bool_t xdr_opaque(XDR *xdrs, caddr_t cp, const uint_t cnt)
{
	return (xdrs->x_ops->xdr_opaque(xdrs, cp, cnt));
}

/*
 * Variable-length string.
 * The *sp buffer must have (maxsize + 1) bytes.
 */
static inline bool_t xdr_string(XDR *xdrs, char **sp, const uint_t maxsize)
{
	return (xdrs->x_ops->xdr_string(xdrs, sp, maxsize));
}

/*
 * Variable-length arrays.
 */
static inline bool_t xdr_array(XDR *xdrs, caddr_t *arrp, uint_t *sizep,
    const uint_t maxsize, const uint_t elsize, const xdrproc_t elproc)
{
	return xdrs->x_ops->xdr_array(xdrs, arrp, sizep, maxsize, elsize,
	    elproc);
}

#endif /* SPL_RPC_XDR_H */
