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