1139749Simp/*-
2156000Smjacob * Copyright (c) 2010, Oracle America, Inc.
3101704Smjacob *
4101704Smjacob * Redistribution and use in source and binary forms, with or without
5101704Smjacob * modification, are permitted provided that the following conditions are
6101704Smjacob * met:
7101704Smjacob *
8101704Smjacob *     * Redistributions of source code must retain the above copyright
9101704Smjacob *       notice, this list of conditions and the following disclaimer.
10101704Smjacob *     * Redistributions in binary form must reproduce the above
11101704Smjacob *       copyright notice, this list of conditions and the following
12101704Smjacob *       disclaimer in the documentation and/or other materials
13101704Smjacob *       provided with the distribution.
14101704Smjacob *     * Neither the name of the "Oracle America, Inc." nor the names of its
15101704Smjacob *       contributors may be used to endorse or promote products derived
16101704Smjacob *       from this software without specific prior written permission.
17101704Smjacob *
18101704Smjacob *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19101704Smjacob *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20101704Smjacob *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21101704Smjacob *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22101704Smjacob *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23101704Smjacob *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24101704Smjacob *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25101704Smjacob *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26101704Smjacob *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27156000Smjacob *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28156000Smjacob *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29156000Smjacob *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30156000Smjacob */
31156104Smjacob/*
32156000Smjacob * xdr_sizeof.c
33156000Smjacob *
34156000Smjacob * General purpose routine to see how much space something will use
35156000Smjacob * when serialized using XDR.
36156000Smjacob */
37156000Smjacob
38156000Smjacob#include <sys/cdefs.h>
39156000Smjacob__FBSDID("$FreeBSD$");
40156000Smjacob
41156000Smjacob#include "namespace.h"
42156000Smjacob#include <rpc/types.h>
43156000Smjacob#include <rpc/xdr.h>
44156000Smjacob#include <sys/types.h>
45156104Smjacob#include <stdlib.h>
46156000Smjacob#include "un-namespace.h"
47156000Smjacob
48156000Smjacob/* ARGSUSED */
49156000Smjacobstatic bool_t
50156000Smjacobx_putlong(xdrs, longp)
51156000Smjacob	XDR *xdrs;
52156000Smjacob	long *longp;
53156000Smjacob{
54156000Smjacob	xdrs->x_handy += BYTES_PER_XDR_UNIT;
55156000Smjacob	return (TRUE);
56156000Smjacob}
57147883Sscottl
58156000Smjacob/* ARGSUSED */
59156000Smjacobstatic bool_t
60101704Smjacobx_putbytes(xdrs, bp, len)
61156000Smjacob	XDR *xdrs;
62147883Sscottl	char  *bp;
63147883Sscottl	u_int len;
64147883Sscottl{
65147883Sscottl	xdrs->x_handy += len;
66156104Smjacob	return (TRUE);
67147883Sscottl}
68147883Sscottl
69147883Sscottlstatic u_int
70147883Sscottlx_getpostn(xdrs)
71147883Sscottl	XDR *xdrs;
72147883Sscottl{
73147883Sscottl	return (xdrs->x_handy);
74147883Sscottl}
75147883Sscottl
76147883Sscottl/* ARGSUSED */
77148679Sgibbsstatic bool_t
78148679Sgibbsx_setpostn(xdrs, pos)
79148679Sgibbs	XDR *xdrs;
80156104Smjacob	u_int pos;
81147883Sscottl{
82147883Sscottl	/* This is not allowed */
83147883Sscottl	return (FALSE);
84147883Sscottl}
85147883Sscottl
86147883Sscottlstatic int32_t *
87147883Sscottlx_inline(xdrs, len)
88147883Sscottl	XDR *xdrs;
89147883Sscottl	u_int len;
90147883Sscottl{
91147883Sscottl	if (len == 0) {
92101704Smjacob		return (NULL);
93101704Smjacob	}
94134123Sobrien	if (xdrs->x_op != XDR_ENCODE) {
95134123Sobrien		return (NULL);
96134123Sobrien	}
97147883Sscottl	if (len < (u_int)(uintptr_t)xdrs->x_base) {
98147883Sscottl		/* x_private was already allocated */
99147883Sscottl		xdrs->x_handy += len;
100102199Smjacob		return ((int32_t *) xdrs->x_private);
101147883Sscottl	} else {
102147883Sscottl		/* Free the earlier space and allocate new area */
103157117Smjacob		if (xdrs->x_private)
104157117Smjacob			free(xdrs->x_private);
105147883Sscottl		if ((xdrs->x_private = (caddr_t) malloc(len)) == NULL) {
106147883Sscottl			xdrs->x_base = 0;
107147883Sscottl			return (NULL);
108101704Smjacob		}
109101704Smjacob		xdrs->x_base = (caddr_t)(uintptr_t)len;
110101704Smjacob		xdrs->x_handy += len;
111101704Smjacob		return ((int32_t *) xdrs->x_private);
112101704Smjacob	}
113101704Smjacob}
114101704Smjacob
115147883Sscottlstatic int
116147883Sscottlharmless()
117101704Smjacob{
118147883Sscottl	/* Always return FALSE/NULL, as the case may be */
119147883Sscottl	return (0);
120147883Sscottl}
121147883Sscottl
122147883Sscottlstatic void
123147883Sscottlx_destroy(xdrs)
124155521Smjacob	XDR *xdrs;
125147883Sscottl{
126147883Sscottl	xdrs->x_handy = 0;
127147883Sscottl	xdrs->x_base = 0;
128157117Smjacob	if (xdrs->x_private) {
129147883Sscottl		free(xdrs->x_private);
130147883Sscottl		xdrs->x_private = NULL;
131147883Sscottl	}
132147883Sscottl	return;
133147883Sscottl}
134147883Sscottl
135147883Sscottlunsigned long
136147883Sscottlxdr_sizeof(func, data)
137147883Sscottl	xdrproc_t func;
138147883Sscottl	void *data;
139147883Sscottl{
140147883Sscottl	XDR x;
141147883Sscottl	struct xdr_ops ops;
142147883Sscottl	bool_t stat;
143101704Smjacob	/* to stop ANSI-C compiler from complaining */
144147883Sscottl	typedef  bool_t (* dummyfunc1)(XDR *, long *);
145147883Sscottl	typedef  bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);
146147883Sscottl
147147883Sscottl	ops.x_putlong = x_putlong;
148147883Sscottl	ops.x_putbytes = x_putbytes;
149147883Sscottl	ops.x_inline = x_inline;
150147883Sscottl	ops.x_getpostn = x_getpostn;
151147883Sscottl	ops.x_setpostn = x_setpostn;
152147883Sscottl	ops.x_destroy = x_destroy;
153147883Sscottl
154147883Sscottl	/* the other harmless ones */
155157117Smjacob	ops.x_getlong =  (dummyfunc1) harmless;
156147883Sscottl	ops.x_getbytes = (dummyfunc2) harmless;
157147883Sscottl
158147883Sscottl	x.x_op = XDR_ENCODE;
159147883Sscottl	x.x_ops = &ops;
160147883Sscottl	x.x_handy = 0;
161147883Sscottl	x.x_private = (caddr_t) NULL;
162147883Sscottl	x.x_base = (caddr_t) 0;
163147883Sscottl
164147883Sscottl	stat = func(&x, data);
165147883Sscottl	if (x.x_private)
166147883Sscottl		free(x.x_private);
167147883Sscottl	return (stat == TRUE ? (unsigned) x.x_handy: 0);
168147883Sscottl}
169147883Sscottl