b91e9a6191dae87fb1fbcd2b1c1ebba63a009cb8
[platform/upstream/libtirpc.git] / src / xdr_sizeof.c
1 /*
2  * Copyright (c) 2009, Sun Microsystems, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * - Redistributions of source code must retain the above copyright notice,
8  *   this list of conditions and the following disclaimer.
9  * - Redistributions in binary form must reproduce the above copyright notice,
10  *   this list of conditions and the following disclaimer in the documentation
11  *   and/or other materials provided with the distribution.
12  * - Neither the name of Sun Microsystems, Inc. nor the names of its
13  *   contributors may be used to endorse or promote products derived
14  *   from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 /*
29  * xdr_sizeof.c
30  *
31  * Copyright 1990 Sun Microsystems, Inc.
32  *
33  * General purpose routine to see how much space something will use
34  * when serialized using XDR.
35  */
36
37 #include <sys/cdefs.h>
38
39 #include "namespace.h"
40 #include <rpc/types.h>
41 #include <rpc/xdr.h>
42 #include <sys/types.h>
43 #include <stdlib.h>
44 #include "un-namespace.h"
45
46 /* ARGSUSED */
47 static bool_t
48 x_putlong(xdrs, longp)
49         XDR *xdrs;
50         long *longp;
51 {
52         xdrs->x_handy += BYTES_PER_XDR_UNIT;
53         return (TRUE);
54 }
55
56 /* ARGSUSED */
57 static bool_t
58 x_putbytes(xdrs, bp, len)
59         XDR *xdrs;
60         char  *bp;
61         u_int len;
62 {
63         xdrs->x_handy += len;
64         return (TRUE);
65 }
66
67 static u_int
68 x_getpostn(xdrs)
69         XDR *xdrs;
70 {
71         return (xdrs->x_handy);
72 }
73
74 /* ARGSUSED */
75 static bool_t
76 x_setpostn(xdrs, pos)
77         XDR *xdrs;
78         u_int pos;
79 {
80         /* This is not allowed */
81         return (FALSE);
82 }
83
84 static int32_t *
85 x_inline(xdrs, len)
86         XDR *xdrs;
87         u_int len;
88 {
89         if (len == 0) {
90                 return (NULL);
91         }
92         if (xdrs->x_op != XDR_ENCODE) {
93                 return (NULL);
94         }
95         if (len < (u_int)xdrs->x_base) {
96                 /* x_private was already allocated */
97                 xdrs->x_handy += len;
98                 return ((int32_t *) xdrs->x_private);
99         } else {
100                 /* Free the earlier space and allocate new area */
101                 if (xdrs->x_private)
102                         free(xdrs->x_private);
103                 if ((xdrs->x_private = (caddr_t) malloc(len)) == NULL) {
104                         xdrs->x_base = 0;
105                         return (NULL);
106                 }
107                 xdrs->x_base = (caddr_t) len;
108                 xdrs->x_handy += len;
109                 return ((int32_t *) xdrs->x_private);
110         }
111 }
112
113 static int
114 harmless()
115 {
116         /* Always return FALSE/NULL, as the case may be */
117         return (0);
118 }
119
120 static void
121 x_destroy(xdrs)
122         XDR *xdrs;
123 {
124         xdrs->x_handy = 0;
125         xdrs->x_base = 0;
126         if (xdrs->x_private) {
127                 free(xdrs->x_private);
128                 xdrs->x_private = NULL;
129         }
130         return;
131 }
132
133 unsigned long
134 xdr_sizeof(func, data)
135         xdrproc_t func;
136         void *data;
137 {
138         XDR x;
139         struct xdr_ops ops;
140         bool_t stat;
141         /* to stop ANSI-C compiler from complaining */
142         typedef  bool_t (* dummyfunc1)(XDR *, long *);
143         typedef  bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);
144
145         ops.x_putlong = x_putlong;
146         ops.x_putbytes = x_putbytes;
147         ops.x_inline = x_inline;
148         ops.x_getpostn = x_getpostn;
149         ops.x_setpostn = x_setpostn;
150         ops.x_destroy = x_destroy;
151
152         /* the other harmless ones */
153         ops.x_getlong =  (dummyfunc1) harmless;
154         ops.x_getbytes = (dummyfunc2) harmless;
155
156         x.x_op = XDR_ENCODE;
157         x.x_ops = &ops;
158         x.x_handy = 0;
159         x.x_private = (caddr_t) NULL;
160         x.x_base = (caddr_t) 0;
161
162         stat = func(&x, data);
163         if (x.x_private)
164                 free(x.x_private);
165         return (stat == TRUE ? (unsigned) x.x_handy: 0);
166 }