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