xdr_sizeof.c revision 303975
1204076Spjd/*- 2204076Spjd * Copyright (c) 2010, Oracle America, Inc. 3211877Spjd * 4204076Spjd * Redistribution and use in source and binary forms, with or without 5204076Spjd * modification, are permitted provided that the following conditions are 6204076Spjd * met: 7204076Spjd * 8204076Spjd * * Redistributions of source code must retain the above copyright 9204076Spjd * notice, this list of conditions and the following disclaimer. 10204076Spjd * * Redistributions in binary form must reproduce the above 11204076Spjd * copyright notice, this list of conditions and the following 12204076Spjd * disclaimer in the documentation and/or other materials 13204076Spjd * provided with the distribution. 14204076Spjd * * Neither the name of the "Oracle America, Inc." nor the names of its 15204076Spjd * contributors may be used to endorse or promote products derived 16204076Spjd * from this software without specific prior written permission. 17204076Spjd * 18204076Spjd * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19204076Spjd * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20204076Spjd * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21204076Spjd * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22204076Spjd * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23204076Spjd * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24204076Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 25204076Spjd * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26204076Spjd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27204076Spjd * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28204076Spjd * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29204076Spjd * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30204076Spjd */ 31204076Spjd/* 32204076Spjd * xdr_sizeof.c 33204076Spjd * 34204076Spjd * General purpose routine to see how much space something will use 35204076Spjd * when serialized using XDR. 36204076Spjd */ 37204076Spjd 38204076Spjd#include <sys/cdefs.h> 39204076Spjd__FBSDID("$FreeBSD: releng/11.0/lib/libc/xdr/xdr_sizeof.c 283835 2015-05-31 19:09:24Z rodrigc $"); 40204076Spjd 41204076Spjd#include "namespace.h" 42204076Spjd#include <rpc/types.h> 43204076Spjd#include <rpc/xdr.h> 44204076Spjd#include <sys/types.h> 45204076Spjd#include <stdlib.h> 46213009Spjd#include "un-namespace.h" 47204076Spjd 48204076Spjd/* ARGSUSED */ 49204076Spjdstatic bool_t 50204076Spjdx_putlong(XDR *xdrs, const long *longp) 51204076Spjd{ 52204076Spjd xdrs->x_handy += BYTES_PER_XDR_UNIT; 53204076Spjd return (TRUE); 54204076Spjd} 55204076Spjd 56204076Spjd/* ARGSUSED */ 57204076Spjdstatic bool_t 58212038Spjdx_putbytes(XDR *xdrs, const char *bp, u_int len) 59204076Spjd{ 60204076Spjd xdrs->x_handy += len; 61204076Spjd return (TRUE); 62211977Spjd} 63204076Spjd 64204076Spjdstatic u_int 65204076Spjdx_getpostn(XDR *xdrs) 66204076Spjd{ 67204076Spjd return (xdrs->x_handy); 68204076Spjd} 69204076Spjd 70204076Spjd/* ARGSUSED */ 71204076Spjdstatic bool_t 72204076Spjdx_setpostn(XDR *xdrs, u_int pos) 73204076Spjd{ 74204076Spjd /* This is not allowed */ 75204076Spjd return (FALSE); 76204076Spjd} 77204076Spjd 78204076Spjdstatic int32_t * 79211984Spjdx_inline(XDR *xdrs, u_int len) 80211984Spjd{ 81204076Spjd if (len == 0) { 82204076Spjd return (NULL); 83204076Spjd } 84204076Spjd if (xdrs->x_op != XDR_ENCODE) { 85204076Spjd return (NULL); 86204076Spjd } 87204076Spjd if (len < (u_int)(uintptr_t)xdrs->x_base) { 88204076Spjd /* x_private was already allocated */ 89204076Spjd xdrs->x_handy += len; 90204076Spjd return ((int32_t *) xdrs->x_private); 91204076Spjd } else { 92204076Spjd /* Free the earlier space and allocate new area */ 93204076Spjd if (xdrs->x_private) 94204076Spjd free(xdrs->x_private); 95204076Spjd if ((xdrs->x_private = (caddr_t) malloc(len)) == NULL) { 96204076Spjd xdrs->x_base = 0; 97204076Spjd return (NULL); 98204076Spjd } 99204076Spjd xdrs->x_base = (caddr_t)(uintptr_t)len; 100204076Spjd xdrs->x_handy += len; 101204076Spjd return ((int32_t *) xdrs->x_private); 102204076Spjd } 103204076Spjd} 104204076Spjd 105204076Spjdstatic int 106204076Spjdharmless(void) 107204076Spjd{ 108204076Spjd /* Always return FALSE/NULL, as the case may be */ 109204076Spjd return (0); 110204076Spjd} 111211877Spjd 112211877Spjdstatic void 113211877Spjdx_destroy(XDR *xdrs) 114211877Spjd{ 115211877Spjd xdrs->x_handy = 0; 116211877Spjd xdrs->x_base = 0; 117211877Spjd if (xdrs->x_private) { 118211877Spjd free(xdrs->x_private); 119211877Spjd xdrs->x_private = NULL; 120211877Spjd } 121211877Spjd return; 122211877Spjd} 123211877Spjd 124211877Spjdunsigned long 125211877Spjdxdr_sizeof(xdrproc_t func, void *data) 126211877Spjd{ 127211877Spjd XDR x; 128211877Spjd struct xdr_ops ops; 129211877Spjd bool_t stat; 130211877Spjd /* to stop ANSI-C compiler from complaining */ 131204076Spjd typedef bool_t (* dummyfunc1)(XDR *, long *); 132204076Spjd typedef bool_t (* dummyfunc2)(XDR *, caddr_t, u_int); 133204076Spjd 134204076Spjd ops.x_putlong = x_putlong; 135204076Spjd ops.x_putbytes = x_putbytes; 136204076Spjd ops.x_inline = x_inline; 137204076Spjd ops.x_getpostn = x_getpostn; 138204076Spjd ops.x_setpostn = x_setpostn; 139204076Spjd ops.x_destroy = x_destroy; 140204076Spjd 141204076Spjd /* the other harmless ones */ 142204076Spjd ops.x_getlong = (dummyfunc1) harmless; 143204076Spjd ops.x_getbytes = (dummyfunc2) harmless; 144204076Spjd 145204076Spjd x.x_op = XDR_ENCODE; 146204076Spjd x.x_ops = &ops; 147204076Spjd x.x_handy = 0; 148204076Spjd x.x_private = (caddr_t) NULL; 149204076Spjd x.x_base = (caddr_t) 0; 150204076Spjd 151204076Spjd stat = func(&x, data); 152204076Spjd if (x.x_private) 153204076Spjd free(x.x_private); 154204076Spjd return (stat == TRUE ? (unsigned) x.x_handy: 0); 155204076Spjd} 156210879Spjd