xdr_sizeof.c revision 1219:f89f56c2d9ac
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23/* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28#pragma ident "%Z%%M% %I% %E% SMI" 29 30/* 31 * General purpose routine to see how much space something will use 32 * when serialized using XDR. 33 */ 34#include "mt.h" 35#include <rpc/types.h> 36#include <rpc/xdr.h> 37#include <sys/types.h> 38#include <stdlib.h> 39 40/* ARGSUSED1 */ 41static bool_t 42x_putlong(XDR *xdrs, long *ip) 43{ 44 xdrs->x_handy += BYTES_PER_XDR_UNIT; 45 return (TRUE); 46} 47 48#if defined(_LP64) 49/* ARGSUSED1 */ 50static bool_t 51x_putint32_t(XDR *xdrs, int32_t *ip) 52{ 53 xdrs->x_handy += BYTES_PER_XDR_UNIT; 54 return (TRUE); 55} 56#endif 57 58/* ARGSUSED */ 59static bool_t 60x_putbytes(XDR *xdrs, char *bp, int len) 61{ 62 xdrs->x_handy += len; 63 return (TRUE); 64} 65 66static uint_t 67x_getpostn(XDR *xdrs) 68{ 69 return (xdrs->x_handy); 70} 71 72/* ARGSUSED */ 73static bool_t 74x_setpostn(XDR *xdrs, uint_t pos) 75{ 76 /* This is not allowed */ 77 return (FALSE); 78} 79 80static rpc_inline_t * 81x_inline(XDR *xdrs, int len) 82{ 83 if (len == 0) 84 return (NULL); 85 if (xdrs->x_op != XDR_ENCODE) 86 return (NULL); 87 if (len < (intptr_t)xdrs->x_base) { 88 /* x_private was already allocated */ 89 xdrs->x_handy += len; 90 /* LINTED pointer cast */ 91 return ((rpc_inline_t *)xdrs->x_private); 92 } 93 /* Free the earlier space and allocate new area */ 94 if (xdrs->x_private) 95 free(xdrs->x_private); 96 if ((xdrs->x_private = malloc(len)) == NULL) { 97 xdrs->x_base = 0; 98 return (NULL); 99 } 100 xdrs->x_base = (caddr_t)(intptr_t)len; 101 xdrs->x_handy += len; 102 /* LINTED pointer cast */ 103 return ((rpc_inline_t *)xdrs->x_private); 104} 105 106static int 107harmless(void) 108{ 109 /* Always return FALSE/NULL, as the case may be */ 110 return (0); 111} 112 113static void 114x_destroy(XDR *xdrs) 115{ 116 xdrs->x_handy = 0; 117 xdrs->x_base = 0; 118 if (xdrs->x_private) { 119 free(xdrs->x_private); 120 xdrs->x_private = NULL; 121 } 122} 123 124uint_t 125xdr_sizeof(xdrproc_t func, void *data) 126{ 127 XDR x; 128 struct xdr_ops ops; 129 bool_t stat; 130 /* to stop ANSI-C compiler from complaining */ 131 typedef bool_t (* dummyfunc1)(XDR *, long *); 132 typedef bool_t (* dummyfunc2)(XDR *, caddr_t, int); 133 typedef bool_t (* dummyfunc3)(XDR *, int32_t *); 134 135 ops.x_putlong = x_putlong; 136 ops.x_getlong = (dummyfunc1) harmless; 137 ops.x_putbytes = x_putbytes; 138 ops.x_inline = x_inline; 139 ops.x_getpostn = x_getpostn; 140 ops.x_setpostn = x_setpostn; 141 ops.x_destroy = x_destroy; 142#if defined(_LP64) 143 ops.x_getint32 = (dummyfunc3) harmless; 144 ops.x_putint32 = x_putint32_t; 145#endif 146 147 /* the other harmless ones */ 148 ops.x_getbytes = (dummyfunc2) harmless; 149 150 x.x_op = XDR_ENCODE; 151 x.x_ops = &ops; 152 x.x_handy = 0; 153 x.x_private = NULL; 154 x.x_base = NULL; 155 156 stat = func(&x, data); 157 if (x.x_private) 158 free(x.x_private); 159 return (stat == TRUE ? (uint_t)x.x_handy : 0); 160} 161