Check-in of original version of ONCRPC library (and headers) from
[shibboleth/cpp-sp.git] / oncrpc / xdr_floa.c
1 /*********************************************************************
2  * RPC for the Windows NT Operating System
3  * 1993 by Martin F. Gergeleit
4  * Users may use, copy or modify Sun RPC for the Windows NT Operating 
5  * System according to the Sun copyright below.
6  *
7  * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
8  * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
9  * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
10  *********************************************************************/
11
12 /* @(#)xdr_float.c      2.1 88/07/29 4.0 RPCSRC */
13 /*
14  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
15  * unrestricted use provided that this legend is included on all tape
16  * media and as a part of the software program in whole or part.  Users
17  * may copy or modify Sun RPC without charge, but are not authorized
18  * to license or distribute it to anyone else except as part of a product or
19  * program developed by the user.
20  * 
21  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
22  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
24  * 
25  * Sun RPC is provided with no support and without any obligation on the
26  * part of Sun Microsystems, Inc. to assist in its use, correction,
27  * modification or enhancement.
28  * 
29  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
30  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
31  * OR ANY PART THEREOF.
32  * 
33  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
34  * or profits or other special, indirect and consequential damages, even if
35  * Sun has been advised of the possibility of such damages.
36  * 
37  * Sun Microsystems, Inc.
38  * 2550 Garcia Avenue
39  * Mountain View, California  94043
40  */
41 #if !defined(lint) && defined(SCCSIDS)
42 static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
43 #endif
44
45 /*
46  * xdr_float.c, Generic XDR routines impelmentation.
47  *
48  * Copyright (C) 1984, Sun Microsystems, Inc.
49  *
50  * These are the "floating point" xdr routines used to (de)serialize
51  * most common data items.  See xdr.h for more info on the interface to
52  * xdr.
53  */
54
55 #include <stdio.h>
56
57 #include <rpc/types.h>
58 #include <rpc/xdr.h>
59
60 /*
61  * NB: Not portable.
62  * This routine works on Suns (Sky / 68000's) and Vaxen.
63  */
64
65 #ifdef vax
66
67 /* What IEEE single precision floating point looks like on a Vax */
68 struct  ieee_single {
69         unsigned int    mantissa: 23;
70         unsigned int    exp     : 8;
71         unsigned int    sign    : 1;
72 };
73
74 /* Vax single precision floating point */
75 struct  vax_single {
76         unsigned int    mantissa1 : 7;
77         unsigned int    exp       : 8;
78         unsigned int    sign      : 1;
79         unsigned int    mantissa2 : 16;
80 };
81
82 #define VAX_SNG_BIAS    0x81
83 #define IEEE_SNG_BIAS   0x7f
84
85 static struct sgl_limits {
86         struct vax_single s;
87         struct ieee_single ieee;
88 } sgl_limits[2] = {
89         {{ 0x7f, 0xff, 0x0, 0xffff },   /* Max Vax */
90         { 0x0, 0xff, 0x0 }},            /* Max IEEE */
91         {{ 0x0, 0x0, 0x0, 0x0 },        /* Min Vax */
92         { 0x0, 0x0, 0x0 }}              /* Min IEEE */
93 };
94 #endif /* vax */
95
96 bool_t
97 xdr_float(xdrs, fp)
98         register XDR *xdrs;
99         register float *fp;
100 {
101
102 #ifdef WIN32
103 #ifdef _PPC_
104 /*Motorola PowerPC is same endian for NT as Intel so...*/
105 #define _X86_
106 #endif
107
108 #ifdef _ALPHA_
109 /*also DEC ALPHA is same endian for NT as Intel so...*/
110 #define _X86_
111 #endif
112 #endif
113
114 #if !defined(mc68000) && !defined(sparc) && !defined(mips) && !defined(mmax) && !defined(_X86_)
115         struct ieee_single is;
116         struct vax_single vs, *vsp;
117         struct sgl_limits *lim;
118         int i;
119 #endif
120         switch (xdrs->x_op) {
121
122         case XDR_ENCODE:
123 #if defined(mc68000) || defined(sparc) || defined(mips) || defined(mmax) || defined(_X86_)
124                 return (XDR_PUTLONG(xdrs, (long *)fp));
125 #else
126                 vs = *((struct vax_single *)fp);
127                 for (i = 0, lim = sgl_limits;
128                         i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
129                         i++, lim++) {
130                         if ((vs.mantissa2 == lim->s.mantissa2) &&
131                                 (vs.exp == lim->s.exp) &&
132                                 (vs.mantissa1 == lim->s.mantissa1)) {
133                                 is = lim->ieee;
134                                 goto shipit;
135                         }
136                 }
137                 is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
138                 is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
139         shipit:
140                 is.sign = vs.sign;
141                 return (XDR_PUTLONG(xdrs, (long *)&is));
142 #endif
143
144         case XDR_DECODE:
145 #if defined(mc68000) || defined(sparc) || defined(mips) || defined(mmax) || defined(_X86_)
146                 return (XDR_GETLONG(xdrs, (long *)fp));
147 #else
148                 vsp = (struct vax_single *)fp;
149                 if (!XDR_GETLONG(xdrs, (long *)&is))
150                         return (FALSE);
151                 for (i = 0, lim = sgl_limits;
152                         i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
153                         i++, lim++) {
154                         if ((is.exp == lim->ieee.exp) &&
155                                 (is.mantissa == lim->ieee.mantissa)) {
156                                 *vsp = lim->s;
157                                 goto doneit;
158                         }
159                 }
160                 vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
161                 vsp->mantissa2 = is.mantissa;
162                 vsp->mantissa1 = (is.mantissa >> 16);
163         doneit:
164                 vsp->sign = is.sign;
165                 return (TRUE);
166 #endif
167
168         case XDR_FREE:
169                 return (TRUE);
170         }
171         return (FALSE);
172 }
173
174 /*
175  * This routine works on Suns (Sky / 68000's) and Vaxen.
176  */
177
178 #ifdef vax
179 /* What IEEE double precision floating point looks like on a Vax */
180 struct  ieee_double {
181         unsigned int    mantissa1 : 20;
182         unsigned int    exp       : 11;
183         unsigned int    sign      : 1;
184         unsigned int    mantissa2 : 32;
185 };
186
187 /* Vax double precision floating point */
188 struct  vax_double {
189         unsigned int    mantissa1 : 7;
190         unsigned int    exp       : 8;
191         unsigned int    sign      : 1;
192         unsigned int    mantissa2 : 16;
193         unsigned int    mantissa3 : 16;
194         unsigned int    mantissa4 : 16;
195 };
196
197 #define VAX_DBL_BIAS    0x81
198 #define IEEE_DBL_BIAS   0x3ff
199 #define MASK(nbits)     ((1 << nbits) - 1)
200
201 static struct dbl_limits {
202         struct  vax_double d;
203         struct  ieee_double ieee;
204 } dbl_limits[2] = {
205         {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },   /* Max Vax */
206         { 0x0, 0x7ff, 0x0, 0x0 }},                      /* Max IEEE */
207         {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},               /* Min Vax */
208         { 0x0, 0x0, 0x0, 0x0 }}                         /* Min IEEE */
209 };
210
211 #endif /* vax */
212
213
214 bool_t
215 xdr_double(xdrs, dp)
216         register XDR *xdrs;
217         double *dp;
218 {
219         register long *lp;
220 #if !defined(mc68000) && !defined(sparc) && !defined(mips) && !defined(mmax) && !defined(_X86_)
221         struct  ieee_double id;
222         struct  vax_double vd;
223         register struct dbl_limits *lim;
224         int i;
225 #endif
226
227         switch (xdrs->x_op) {
228
229         case XDR_ENCODE:
230 #if defined(mc68000) || defined(sparc) || defined(mips) || defined(mmax) || defined(_X86_)
231                 lp = (long *)dp;
232 #else
233                 vd = *((struct vax_double *)dp);
234                 for (i = 0, lim = dbl_limits;
235                         i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
236                         i++, lim++) {
237                         if ((vd.mantissa4 == lim->d.mantissa4) &&
238                                 (vd.mantissa3 == lim->d.mantissa3) &&
239                                 (vd.mantissa2 == lim->d.mantissa2) &&
240                                 (vd.mantissa1 == lim->d.mantissa1) &&
241                                 (vd.exp == lim->d.exp)) {
242                                 id = lim->ieee;
243                                 goto shipit;
244                         }
245                 }
246                 id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
247                 id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
248                 id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
249                                 (vd.mantissa3 << 13) |
250                                 ((vd.mantissa4 >> 3) & MASK(13));
251         shipit:
252                 id.sign = vd.sign;
253                 lp = (long *)&id;
254 #endif
255 #if defined(_X86_)
256                 return (XDR_PUTLONG(xdrs, lp+1) && XDR_PUTLONG(xdrs, lp));
257 #else
258                 return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
259 #endif
260         case XDR_DECODE:
261 #if defined(mc68000) || defined(sparc) || defined(mips) || defined(mmax) || defined(_X86_)
262                 lp = (long *)dp;
263 #if defined(_X86_)
264                 return (XDR_GETLONG(xdrs, lp+1) && XDR_GETLONG(xdrs, lp));
265 #else
266                 return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
267 #endif
268 #else
269                 lp = (long *)&id;
270                 if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
271                         return (FALSE);
272                 for (i = 0, lim = dbl_limits;
273                         i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
274                         i++, lim++) {
275                         if ((id.mantissa2 == lim->ieee.mantissa2) &&
276                                 (id.mantissa1 == lim->ieee.mantissa1) &&
277                                 (id.exp == lim->ieee.exp)) {
278                                 vd = lim->d;
279                                 goto doneit;
280                         }
281                 }
282                 vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
283                 vd.mantissa1 = (id.mantissa1 >> 13);
284                 vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
285                                 (id.mantissa2 >> 29);
286                 vd.mantissa3 = (id.mantissa2 >> 13);
287                 vd.mantissa4 = (id.mantissa2 << 3);
288         doneit:
289                 vd.sign = id.sign;
290                 *dp = *((double *)&vd);
291                 return (TRUE);
292 #endif
293
294         case XDR_FREE:
295                 return (TRUE);
296         }
297         return (FALSE);
298 }