Imported Upstream version 0.2.5
[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 <rpc/types.h>
40 #include <rpc/xdr.h>
41 #include <sys/types.h>
42 #include <stdlib.h>
43 #include "un-namespace.h"
44
45 /* ARGSUSED */
46 static bool_t
47 x_putlong(xdrs, longp)
48         XDR *xdrs;
49         long *longp;
50 {
51         xdrs->x_handy += BYTES_PER_XDR_UNIT;
52         return (TRUE);
53 }
54
55 /* ARGSUSED */
56 static bool_t
57 x_putbytes(xdrs, bp, len)
58         XDR *xdrs;
59         char  *bp;
60         u_int len;
61 {
62         xdrs->x_handy += len;
63         return (TRUE);
64 }
65
66 static u_int
67 x_getpostn(xdrs)
68         XDR *xdrs;
69 {
70         return (xdrs->x_handy);
71 }
72
73 /* ARGSUSED */
74 static bool_t
75 x_setpostn(xdrs, pos)
76         XDR *xdrs;
77         u_int pos;
78 {
79         /* This is not allowed */
80         return (FALSE);
81 }
82
83 static int32_t *
84 x_inline(xdrs, len)
85         XDR *xdrs;
86         u_int len;
87 {
88         if (len == 0) {
89                 return (NULL);
90         }
91         if (xdrs->x_op != XDR_ENCODE) {
92                 return (NULL);
93         }
94         if (len < (u_int)xdrs->x_base) {
95                 /* x_private was already allocated */
96                 xdrs->x_handy += len;
97                 return ((int32_t *) xdrs->x_private);
98         } else {
99                 /* Free the earlier space and allocate new area */
100                 if (xdrs->x_private)
101                         free(xdrs->x_private);
102                 if ((xdrs->x_private = (caddr_t) malloc(len)) == NULL) {
103                         xdrs->x_base = 0;
104                         return (NULL);
105                 }
106                 xdrs->x_base = (caddr_t) len;
107                 xdrs->x_handy += len;
108                 return ((int32_t *) xdrs->x_private);
109         }
110 }
111
112 static int
113 harmless()
114 {
115         /* Always return FALSE/NULL, as the case may be */
116         return (0);
117 }
118
119 static void
120 x_destroy(xdrs)
121         XDR *xdrs;
122 {
123         xdrs->x_handy = 0;
124         xdrs->x_base = 0;
125         if (xdrs->x_private) {
126                 free(xdrs->x_private);
127                 xdrs->x_private = NULL;
128         }
129         return;
130 }
131
132 unsigned long
133 xdr_sizeof(func, data)
134         xdrproc_t func;
135         void *data;
136 {
137         XDR x;
138         struct xdr_ops ops;
139         bool_t stat;
140         /* to stop ANSI-C compiler from complaining */
141         typedef  bool_t (* dummyfunc1)(XDR *, long *);
142         typedef  bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);
143
144         ops.x_putlong = x_putlong;
145         ops.x_putbytes = x_putbytes;
146         ops.x_inline = x_inline;
147         ops.x_getpostn = x_getpostn;
148         ops.x_setpostn = x_setpostn;
149         ops.x_destroy = x_destroy;
150
151         /* the other harmless ones */
152         ops.x_getlong =  (dummyfunc1) harmless;
153         ops.x_getbytes = (dummyfunc2) harmless;
154
155         x.x_op = XDR_ENCODE;
156         x.x_ops = &ops;
157         x.x_handy = 0;
158         x.x_private = (caddr_t) NULL;
159         x.x_base = (caddr_t) 0;
160
161         stat = func(&x, data);
162         if (x.x_private)
163                 free(x.x_private);
164         return (stat == TRUE ? (unsigned) x.x_handy: 0);
165 }