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