diff options
Diffstat (limited to 'sys/xdr')
-rw-r--r-- | sys/xdr/xdr_mem.c | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/sys/xdr/xdr_mem.c b/sys/xdr/xdr_mem.c index 2dd5b73..74bab3b 100644 --- a/sys/xdr/xdr_mem.c +++ b/sys/xdr/xdr_mem.c @@ -66,7 +66,8 @@ static u_int xdrmem_getpos(XDR *); static bool_t xdrmem_setpos(XDR *, u_int); static int32_t *xdrmem_inline_aligned(XDR *, u_int); static int32_t *xdrmem_inline_unaligned(XDR *, u_int); - +static bool_t xdrmem_control(XDR *xdrs, int request, void *info); + static const struct xdr_ops xdrmem_ops_aligned = { xdrmem_getlong_aligned, xdrmem_putlong_aligned, @@ -75,7 +76,8 @@ static const struct xdr_ops xdrmem_ops_aligned = { xdrmem_getpos, xdrmem_setpos, xdrmem_inline_aligned, - xdrmem_destroy + xdrmem_destroy, + xdrmem_control }; static const struct xdr_ops xdrmem_ops_unaligned = { @@ -86,7 +88,8 @@ static const struct xdr_ops xdrmem_ops_unaligned = { xdrmem_getpos, xdrmem_setpos, xdrmem_inline_unaligned, - xdrmem_destroy + xdrmem_destroy, + xdrmem_control }; /* @@ -228,3 +231,45 @@ xdrmem_inline_unaligned(XDR *xdrs, u_int len) return (0); } + +static bool_t +xdrmem_control(XDR *xdrs, int request, void *info) +{ + xdr_bytesrec *xptr; + int32_t *l; + int len; + + switch (request) { + + case XDR_GET_BYTES_AVAIL: + xptr = (xdr_bytesrec *)info; + xptr->xc_is_last_record = TRUE; + xptr->xc_num_avail = xdrs->x_handy; + return (TRUE); + + case XDR_PEEK: + /* + * Return the next 4 byte unit in the XDR stream. + */ + if (xdrs->x_handy < sizeof (int32_t)) + return (FALSE); + l = (int32_t *)info; + *l = (int32_t)ntohl((uint32_t) + (*((int32_t *)(xdrs->x_private)))); + return (TRUE); + + case XDR_SKIPBYTES: + /* + * Skip the next N bytes in the XDR stream. + */ + l = (int32_t *)info; + len = RNDUP((int)(*l)); + if (xdrs->x_handy < len) + return (FALSE); + xdrs->x_handy -= len; + xdrs->x_private = (char *)xdrs->x_private + len; + return (TRUE); + + } + return (FALSE); +} |