1*7f2fe78bSCy Schubert /* @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert * Copyright (c) 2010, Oracle America, Inc.
4*7f2fe78bSCy Schubert *
5*7f2fe78bSCy Schubert * All rights reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Redistribution and use in source and binary forms, with or without
8*7f2fe78bSCy Schubert * modification, are permitted provided that the following conditions are met:
9*7f2fe78bSCy Schubert *
10*7f2fe78bSCy Schubert * * Redistributions of source code must retain the above copyright
11*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer.
12*7f2fe78bSCy Schubert *
13*7f2fe78bSCy Schubert * * Redistributions in binary form must reproduce the above copyright
14*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer in
15*7f2fe78bSCy Schubert * the documentation and/or other materials provided with the
16*7f2fe78bSCy Schubert * distribution.
17*7f2fe78bSCy Schubert *
18*7f2fe78bSCy Schubert * * Neither the name of the "Oracle America, Inc." nor the names of
19*7f2fe78bSCy Schubert * its contributors may be used to endorse or promote products
20*7f2fe78bSCy Schubert * derived from this software without specific prior written permission.
21*7f2fe78bSCy Schubert *
22*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23*7f2fe78bSCy Schubert * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24*7f2fe78bSCy Schubert * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25*7f2fe78bSCy Schubert * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26*7f2fe78bSCy Schubert * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27*7f2fe78bSCy Schubert * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28*7f2fe78bSCy Schubert * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29*7f2fe78bSCy Schubert * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30*7f2fe78bSCy Schubert * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31*7f2fe78bSCy Schubert * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*7f2fe78bSCy Schubert * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*7f2fe78bSCy Schubert */
34*7f2fe78bSCy Schubert #if !defined(lint) && defined(SCCSIDS)
35*7f2fe78bSCy Schubert static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
36*7f2fe78bSCy Schubert #endif
37*7f2fe78bSCy Schubert
38*7f2fe78bSCy Schubert /*
39*7f2fe78bSCy Schubert * xdr_float.c, Generic XDR routines impelmentation.
40*7f2fe78bSCy Schubert *
41*7f2fe78bSCy Schubert * These are the "floating point" xdr routines used to (de)serialize
42*7f2fe78bSCy Schubert * most common data items. See xdr.h for more info on the interface to
43*7f2fe78bSCy Schubert * xdr.
44*7f2fe78bSCy Schubert */
45*7f2fe78bSCy Schubert
46*7f2fe78bSCy Schubert #include <stdio.h>
47*7f2fe78bSCy Schubert
48*7f2fe78bSCy Schubert #include <gssrpc/types.h>
49*7f2fe78bSCy Schubert #include <gssrpc/xdr.h>
50*7f2fe78bSCy Schubert
51*7f2fe78bSCy Schubert /*
52*7f2fe78bSCy Schubert * NB: Not portable.
53*7f2fe78bSCy Schubert * This routine works on Suns (Sky / 68000's) and Vaxen.
54*7f2fe78bSCy Schubert */
55*7f2fe78bSCy Schubert #ifdef IGNORE
56*7f2fe78bSCy Schubert
57*7f2fe78bSCy Schubert #ifdef vax
58*7f2fe78bSCy Schubert
59*7f2fe78bSCy Schubert /* What IEEE single precision floating point looks like on a Vax */
60*7f2fe78bSCy Schubert struct ieee_single {
61*7f2fe78bSCy Schubert unsigned int mantissa: 23;
62*7f2fe78bSCy Schubert unsigned int exp : 8;
63*7f2fe78bSCy Schubert unsigned int sign : 1;
64*7f2fe78bSCy Schubert };
65*7f2fe78bSCy Schubert
66*7f2fe78bSCy Schubert /* Vax single precision floating point */
67*7f2fe78bSCy Schubert struct vax_single {
68*7f2fe78bSCy Schubert unsigned int mantissa1 : 7;
69*7f2fe78bSCy Schubert unsigned int exp : 8;
70*7f2fe78bSCy Schubert unsigned int sign : 1;
71*7f2fe78bSCy Schubert unsigned int mantissa2 : 16;
72*7f2fe78bSCy Schubert };
73*7f2fe78bSCy Schubert
74*7f2fe78bSCy Schubert #define VAX_SNG_BIAS 0x81
75*7f2fe78bSCy Schubert #define IEEE_SNG_BIAS 0x7f
76*7f2fe78bSCy Schubert
77*7f2fe78bSCy Schubert static struct sgl_limits {
78*7f2fe78bSCy Schubert struct vax_single s;
79*7f2fe78bSCy Schubert struct ieee_single ieee;
80*7f2fe78bSCy Schubert } sgl_limits[2] = {
81*7f2fe78bSCy Schubert {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
82*7f2fe78bSCy Schubert { 0x0, 0xff, 0x0 }}, /* Max IEEE */
83*7f2fe78bSCy Schubert {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
84*7f2fe78bSCy Schubert { 0x0, 0x0, 0x0 }} /* Min IEEE */
85*7f2fe78bSCy Schubert };
86*7f2fe78bSCy Schubert #endif /* vax */
87*7f2fe78bSCy Schubert
88*7f2fe78bSCy Schubert bool_t
xdr_float(XDR * xdrs,float * fp)89*7f2fe78bSCy Schubert xdr_float(XDR *xdrs, float *fp)
90*7f2fe78bSCy Schubert {
91*7f2fe78bSCy Schubert #if defined(vax)
92*7f2fe78bSCy Schubert struct ieee_single is;
93*7f2fe78bSCy Schubert struct vax_single vs, *vsp;
94*7f2fe78bSCy Schubert struct sgl_limits *lim;
95*7f2fe78bSCy Schubert int i;
96*7f2fe78bSCy Schubert #endif
97*7f2fe78bSCy Schubert long lg;
98*7f2fe78bSCy Schubert
99*7f2fe78bSCy Schubert switch (xdrs->x_op) {
100*7f2fe78bSCy Schubert
101*7f2fe78bSCy Schubert case XDR_ENCODE:
102*7f2fe78bSCy Schubert #if !defined(vax)
103*7f2fe78bSCy Schubert lg = * (int_32 *) fp;
104*7f2fe78bSCy Schubert return (XDR_PUTLONG(xdrs, &lg));
105*7f2fe78bSCy Schubert #else
106*7f2fe78bSCy Schubert vs = *((struct vax_single *)fp);
107*7f2fe78bSCy Schubert for (i = 0, lim = sgl_limits;
108*7f2fe78bSCy Schubert i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
109*7f2fe78bSCy Schubert i++, lim++) {
110*7f2fe78bSCy Schubert if ((vs.mantissa2 == lim->s.mantissa2) &&
111*7f2fe78bSCy Schubert (vs.exp == lim->s.exp) &&
112*7f2fe78bSCy Schubert (vs.mantissa1 == lim->s.mantissa1)) {
113*7f2fe78bSCy Schubert is = lim->ieee;
114*7f2fe78bSCy Schubert goto shipit;
115*7f2fe78bSCy Schubert }
116*7f2fe78bSCy Schubert }
117*7f2fe78bSCy Schubert is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
118*7f2fe78bSCy Schubert is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
119*7f2fe78bSCy Schubert shipit:
120*7f2fe78bSCy Schubert is.sign = vs.sign;
121*7f2fe78bSCy Schubert return (XDR_PUTLONG(xdrs, (int32_t *)&is));
122*7f2fe78bSCy Schubert #endif
123*7f2fe78bSCy Schubert
124*7f2fe78bSCy Schubert case XDR_DECODE:
125*7f2fe78bSCy Schubert #if !defined(vax)
126*7f2fe78bSCy Schubert if (!(XDR_GETLONG(xdrs, &lg))) {
127*7f2fe78bSCy Schubert return (FALSE);
128*7f2fe78bSCy Schubert }
129*7f2fe78bSCy Schubert *fp = (float) ((int) lg);
130*7f2fe78bSCy Schubert return (TRUE);
131*7f2fe78bSCy Schubert #else
132*7f2fe78bSCy Schubert vsp = (struct vax_single *)fp;
133*7f2fe78bSCy Schubert if (!XDR_GETLONG(xdrs, (int32_t *)&is))
134*7f2fe78bSCy Schubert return (FALSE);
135*7f2fe78bSCy Schubert for (i = 0, lim = sgl_limits;
136*7f2fe78bSCy Schubert i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
137*7f2fe78bSCy Schubert i++, lim++) {
138*7f2fe78bSCy Schubert if ((is.exp == lim->ieee.exp) &&
139*7f2fe78bSCy Schubert (is.mantissa == lim->ieee.mantissa)) {
140*7f2fe78bSCy Schubert *vsp = lim->s;
141*7f2fe78bSCy Schubert goto doneit;
142*7f2fe78bSCy Schubert }
143*7f2fe78bSCy Schubert }
144*7f2fe78bSCy Schubert vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
145*7f2fe78bSCy Schubert vsp->mantissa2 = is.mantissa;
146*7f2fe78bSCy Schubert vsp->mantissa1 = (is.mantissa >> 16);
147*7f2fe78bSCy Schubert doneit:
148*7f2fe78bSCy Schubert vsp->sign = is.sign;
149*7f2fe78bSCy Schubert return (TRUE);
150*7f2fe78bSCy Schubert #endif
151*7f2fe78bSCy Schubert
152*7f2fe78bSCy Schubert case XDR_FREE:
153*7f2fe78bSCy Schubert return (TRUE);
154*7f2fe78bSCy Schubert }
155*7f2fe78bSCy Schubert return (FALSE);
156*7f2fe78bSCy Schubert }
157*7f2fe78bSCy Schubert
158*7f2fe78bSCy Schubert /*
159*7f2fe78bSCy Schubert * This routine works on Suns (Sky / 68000's) and Vaxen.
160*7f2fe78bSCy Schubert */
161*7f2fe78bSCy Schubert
162*7f2fe78bSCy Schubert #ifdef vax
163*7f2fe78bSCy Schubert /* What IEEE double precision floating point looks like on a Vax */
164*7f2fe78bSCy Schubert struct ieee_double {
165*7f2fe78bSCy Schubert unsigned int mantissa1 : 20;
166*7f2fe78bSCy Schubert unsigned int exp : 11;
167*7f2fe78bSCy Schubert unsigned int sign : 1;
168*7f2fe78bSCy Schubert unsigned int mantissa2 : 32;
169*7f2fe78bSCy Schubert };
170*7f2fe78bSCy Schubert
171*7f2fe78bSCy Schubert /* Vax double precision floating point */
172*7f2fe78bSCy Schubert struct vax_double {
173*7f2fe78bSCy Schubert unsigned int mantissa1 : 7;
174*7f2fe78bSCy Schubert unsigned int exp : 8;
175*7f2fe78bSCy Schubert unsigned int sign : 1;
176*7f2fe78bSCy Schubert unsigned int mantissa2 : 16;
177*7f2fe78bSCy Schubert unsigned int mantissa3 : 16;
178*7f2fe78bSCy Schubert unsigned int mantissa4 : 16;
179*7f2fe78bSCy Schubert };
180*7f2fe78bSCy Schubert
181*7f2fe78bSCy Schubert #define VAX_DBL_BIAS 0x81
182*7f2fe78bSCy Schubert #define IEEE_DBL_BIAS 0x3ff
183*7f2fe78bSCy Schubert #define MASK(nbits) ((1 << nbits) - 1)
184*7f2fe78bSCy Schubert
185*7f2fe78bSCy Schubert static struct dbl_limits {
186*7f2fe78bSCy Schubert struct vax_double d;
187*7f2fe78bSCy Schubert struct ieee_double ieee;
188*7f2fe78bSCy Schubert } dbl_limits[2] = {
189*7f2fe78bSCy Schubert {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
190*7f2fe78bSCy Schubert { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
191*7f2fe78bSCy Schubert {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
192*7f2fe78bSCy Schubert { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
193*7f2fe78bSCy Schubert };
194*7f2fe78bSCy Schubert
195*7f2fe78bSCy Schubert #endif /* vax */
196*7f2fe78bSCy Schubert
197*7f2fe78bSCy Schubert
198*7f2fe78bSCy Schubert bool_t
xdr_double(XDR * xdrs,double * dp)199*7f2fe78bSCy Schubert xdr_double(XDR *xdrs, double *dp)
200*7f2fe78bSCy Schubert {
201*7f2fe78bSCy Schubert int32_t *lp;
202*7f2fe78bSCy Schubert #if defined(vax)
203*7f2fe78bSCy Schubert struct ieee_double id;
204*7f2fe78bSCy Schubert struct vax_double vd;
205*7f2fe78bSCy Schubert struct dbl_limits *lim;
206*7f2fe78bSCy Schubert int i;
207*7f2fe78bSCy Schubert #endif
208*7f2fe78bSCy Schubert
209*7f2fe78bSCy Schubert switch (xdrs->x_op) {
210*7f2fe78bSCy Schubert
211*7f2fe78bSCy Schubert case XDR_ENCODE:
212*7f2fe78bSCy Schubert #if !defined(vax)
213*7f2fe78bSCy Schubert lp = (int32_t *)dp;
214*7f2fe78bSCy Schubert if (sizeof(int32_t) == sizeof(long)) {
215*7f2fe78bSCy Schubert return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
216*7f2fe78bSCy Schubert } else {
217*7f2fe78bSCy Schubert long lg1 = *lp++;;
218*7f2fe78bSCy Schubert long lg2 = *lp;
219*7f2fe78bSCy Schubert return (XDR_PUTLONG(xdrs, &lg1) && XDR_PUTLONG(xdrs, &lg2));
220*7f2fe78bSCy Schubert }
221*7f2fe78bSCy Schubert #else
222*7f2fe78bSCy Schubert vd = *((struct vax_double *)dp);
223*7f2fe78bSCy Schubert for (i = 0, lim = dbl_limits;
224*7f2fe78bSCy Schubert i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
225*7f2fe78bSCy Schubert i++, lim++) {
226*7f2fe78bSCy Schubert if ((vd.mantissa4 == lim->d.mantissa4) &&
227*7f2fe78bSCy Schubert (vd.mantissa3 == lim->d.mantissa3) &&
228*7f2fe78bSCy Schubert (vd.mantissa2 == lim->d.mantissa2) &&
229*7f2fe78bSCy Schubert (vd.mantissa1 == lim->d.mantissa1) &&
230*7f2fe78bSCy Schubert (vd.exp == lim->d.exp)) {
231*7f2fe78bSCy Schubert id = lim->ieee;
232*7f2fe78bSCy Schubert goto shipit;
233*7f2fe78bSCy Schubert }
234*7f2fe78bSCy Schubert }
235*7f2fe78bSCy Schubert id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
236*7f2fe78bSCy Schubert id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
237*7f2fe78bSCy Schubert id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
238*7f2fe78bSCy Schubert (vd.mantissa3 << 13) |
239*7f2fe78bSCy Schubert ((vd.mantissa4 >> 3) & MASK(13));
240*7f2fe78bSCy Schubert shipit:
241*7f2fe78bSCy Schubert id.sign = vd.sign;
242*7f2fe78bSCy Schubert lp = (int32_t *)&id;
243*7f2fe78bSCy Schubert return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
244*7f2fe78bSCy Schubert #endif
245*7f2fe78bSCy Schubert
246*7f2fe78bSCy Schubert case XDR_DECODE:
247*7f2fe78bSCy Schubert #if !defined(vax)
248*7f2fe78bSCy Schubert lp = (int32_t *)dp;
249*7f2fe78bSCy Schubert if (sizeof(int32_t) == sizeof(long)) {
250*7f2fe78bSCy Schubert return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
251*7f2fe78bSCy Schubert } else {
252*7f2fe78bSCy Schubert long lg1, lg2;
253*7f2fe78bSCy Schubert bool_t flag =
254*7f2fe78bSCy Schubert (XDR_GETLONG(xdrs, &lg1) && XDR_GETLONG(xdrs, &lg2));
255*7f2fe78bSCy Schubert *lp++ = lg1;
256*7f2fe78bSCy Schubert *lp = lg2;
257*7f2fe78bSCy Schubert return flag;
258*7f2fe78bSCy Schubert }
259*7f2fe78bSCy Schubert #else
260*7f2fe78bSCy Schubert lp = (int32_t *)&id;
261*7f2fe78bSCy Schubert if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
262*7f2fe78bSCy Schubert return (FALSE);
263*7f2fe78bSCy Schubert for (i = 0, lim = dbl_limits;
264*7f2fe78bSCy Schubert i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
265*7f2fe78bSCy Schubert i++, lim++) {
266*7f2fe78bSCy Schubert if ((id.mantissa2 == lim->ieee.mantissa2) &&
267*7f2fe78bSCy Schubert (id.mantissa1 == lim->ieee.mantissa1) &&
268*7f2fe78bSCy Schubert (id.exp == lim->ieee.exp)) {
269*7f2fe78bSCy Schubert vd = lim->d;
270*7f2fe78bSCy Schubert goto doneit;
271*7f2fe78bSCy Schubert }
272*7f2fe78bSCy Schubert }
273*7f2fe78bSCy Schubert vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
274*7f2fe78bSCy Schubert vd.mantissa1 = (id.mantissa1 >> 13);
275*7f2fe78bSCy Schubert vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
276*7f2fe78bSCy Schubert (id.mantissa2 >> 29);
277*7f2fe78bSCy Schubert vd.mantissa3 = (id.mantissa2 >> 13);
278*7f2fe78bSCy Schubert vd.mantissa4 = (id.mantissa2 << 3);
279*7f2fe78bSCy Schubert doneit:
280*7f2fe78bSCy Schubert vd.sign = id.sign;
281*7f2fe78bSCy Schubert *dp = *((double *)&vd);
282*7f2fe78bSCy Schubert return (TRUE);
283*7f2fe78bSCy Schubert #endif
284*7f2fe78bSCy Schubert
285*7f2fe78bSCy Schubert case XDR_FREE:
286*7f2fe78bSCy Schubert return (TRUE);
287*7f2fe78bSCy Schubert }
288*7f2fe78bSCy Schubert return (FALSE);
289*7f2fe78bSCy Schubert }
290*7f2fe78bSCy Schubert
291*7f2fe78bSCy Schubert #endif /* IGNORE */
292