Back to index

glibc  2.9
xdr_float.c
Go to the documentation of this file.
00001 /* @(#)xdr_float.c   2.1 88/07/29 4.0 RPCSRC */
00002 /*
00003  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00004  * unrestricted use provided that this legend is included on all tape
00005  * media and as a part of the software program in whole or part.  Users
00006  * may copy or modify Sun RPC without charge, but are not authorized
00007  * to license or distribute it to anyone else except as part of a product or
00008  * program developed by the user.
00009  *
00010  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00011  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00012  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00013  *
00014  * Sun RPC is provided with no support and without any obligation on the
00015  * part of Sun Microsystems, Inc. to assist in its use, correction,
00016  * modification or enhancement.
00017  *
00018  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00019  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00020  * OR ANY PART THEREOF.
00021  *
00022  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00023  * or profits or other special, indirect and consequential damages, even if
00024  * Sun has been advised of the possibility of such damages.
00025  *
00026  * Sun Microsystems, Inc.
00027  * 2550 Garcia Avenue
00028  * Mountain View, California  94043
00029  */
00030 #if !defined(lint) && defined(SCCSIDS)
00031 static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
00032 #endif
00033 
00034 /*
00035  * xdr_float.c, Generic XDR routines implementation.
00036  *
00037  * Copyright (C) 1984, Sun Microsystems, Inc.
00038  *
00039  * These are the "floating point" xdr routines used to (de)serialize
00040  * most common data items.  See xdr.h for more info on the interface to
00041  * xdr.
00042  */
00043 
00044 #include <stdio.h>
00045 #include <endian.h>
00046 
00047 #include <rpc/types.h>
00048 #include <rpc/xdr.h>
00049 
00050 /*
00051  * NB: Not portable.
00052  * This routine works on Suns (Sky / 68000's) and Vaxen.
00053  */
00054 
00055 #define LSW   (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
00056 
00057 #ifdef vax
00058 
00059 /* What IEEE single precision floating point looks like on a Vax */
00060 struct ieee_single {
00061        unsigned int  mantissa: 23;
00062        unsigned int  exp     : 8;
00063        unsigned int  sign    : 1;
00064 };
00065 
00066 /* Vax single precision floating point */
00067 struct vax_single {
00068        unsigned int  mantissa1 : 7;
00069        unsigned int  exp       : 8;
00070        unsigned int  sign      : 1;
00071        unsigned int  mantissa2 : 16;
00072 };
00073 
00074 #define VAX_SNG_BIAS 0x81
00075 #define IEEE_SNG_BIAS       0x7f
00076 
00077 static struct sgl_limits {
00078        struct vax_single s;
00079        struct ieee_single ieee;
00080 } sgl_limits[2] = {
00081        {{ 0x7f, 0xff, 0x0, 0xffff },      /* Max Vax */
00082        { 0x0, 0xff, 0x0 }},        /* Max IEEE */
00083        {{ 0x0, 0x0, 0x0, 0x0 },    /* Min Vax */
00084        { 0x0, 0x0, 0x0 }}          /* Min IEEE */
00085 };
00086 #endif /* vax */
00087 
00088 bool_t
00089 xdr_float(xdrs, fp)
00090      XDR *xdrs;
00091      float *fp;
00092 {
00093 #ifdef vax
00094        struct ieee_single is;
00095        struct vax_single vs, *vsp;
00096        struct sgl_limits *lim;
00097        int i;
00098 #endif
00099        switch (xdrs->x_op) {
00100 
00101        case XDR_ENCODE:
00102 #ifdef vax
00103               vs = *((struct vax_single *)fp);
00104               for (i = 0, lim = sgl_limits;
00105                      i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
00106                      i++, lim++) {
00107                      if ((vs.mantissa2 == lim->s.mantissa2) &&
00108                             (vs.exp == lim->s.exp) &&
00109                             (vs.mantissa1 == lim->s.mantissa1)) {
00110                             is = lim->ieee;
00111                             goto shipit;
00112                      }
00113               }
00114               is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
00115               is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
00116        shipit:
00117               is.sign = vs.sign;
00118               return (XDR_PUTLONG(xdrs, (long *)&is));
00119 #else
00120               if (sizeof(float) == sizeof(long))
00121                      return (XDR_PUTLONG(xdrs, (long *)fp));
00122               else if (sizeof(float) == sizeof(int)) {
00123                      long tmp = *(int *)fp;
00124                      return (XDR_PUTLONG(xdrs, &tmp));
00125               }
00126               break;
00127 #endif
00128 
00129        case XDR_DECODE:
00130 #ifdef vax
00131               vsp = (struct vax_single *)fp;
00132               if (!XDR_GETLONG(xdrs, (long *)&is))
00133                      return (FALSE);
00134               for (i = 0, lim = sgl_limits;
00135                      i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
00136                      i++, lim++) {
00137                      if ((is.exp == lim->ieee.exp) &&
00138                             (is.mantissa == lim->ieee.mantissa)) {
00139                             *vsp = lim->s;
00140                             goto doneit;
00141                      }
00142               }
00143               vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
00144               vsp->mantissa2 = is.mantissa;
00145               vsp->mantissa1 = (is.mantissa >> 16);
00146        doneit:
00147               vsp->sign = is.sign;
00148               return (TRUE);
00149 #else
00150               if (sizeof(float) == sizeof(long))
00151                      return (XDR_GETLONG(xdrs, (long *)fp));
00152               else if (sizeof(float) == sizeof(int)) {
00153                      long tmp;
00154                      if (XDR_GETLONG(xdrs, &tmp)) {
00155                             *(int *)fp = tmp;
00156                             return (TRUE);
00157                      }
00158               }
00159               break;
00160 #endif
00161 
00162        case XDR_FREE:
00163               return (TRUE);
00164        }
00165        return (FALSE);
00166 }
00167 
00168 /*
00169  * This routine works on Suns (Sky / 68000's) and Vaxen.
00170  */
00171 
00172 #ifdef vax
00173 /* What IEEE double precision floating point looks like on a Vax */
00174 struct ieee_double {
00175        unsigned int  mantissa1 : 20;
00176        unsigned int  exp       : 11;
00177        unsigned int  sign      : 1;
00178        unsigned int  mantissa2 : 32;
00179 };
00180 
00181 /* Vax double precision floating point */
00182 struct  vax_double {
00183        unsigned int  mantissa1 : 7;
00184        unsigned int  exp       : 8;
00185        unsigned int  sign      : 1;
00186        unsigned int  mantissa2 : 16;
00187        unsigned int  mantissa3 : 16;
00188        unsigned int  mantissa4 : 16;
00189 };
00190 
00191 #define VAX_DBL_BIAS 0x81
00192 #define IEEE_DBL_BIAS       0x3ff
00193 #define MASK(nbits)  ((1 << nbits) - 1)
00194 
00195 static struct dbl_limits {
00196        struct vax_double d;
00197        struct ieee_double ieee;
00198 } dbl_limits[2] = {
00199        {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },    /* Max Vax */
00200        { 0x0, 0x7ff, 0x0, 0x0 }},                /* Max IEEE */
00201        {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},         /* Min Vax */
00202        { 0x0, 0x0, 0x0, 0x0 }}                          /* Min IEEE */
00203 };
00204 
00205 #endif /* vax */
00206 
00207 
00208 bool_t
00209 xdr_double(xdrs, dp)
00210      XDR *xdrs;
00211      double *dp;
00212 {
00213 #ifdef vax
00214        struct ieee_double id;
00215        struct vax_double vd;
00216        register struct dbl_limits *lim;
00217        int i;
00218 #endif
00219 
00220        switch (xdrs->x_op) {
00221 
00222        case XDR_ENCODE:
00223 #ifdef vax
00224               vd = *((struct vax_double *)dp);
00225               for (i = 0, lim = dbl_limits;
00226                      i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
00227                      i++, lim++) {
00228                      if ((vd.mantissa4 == lim->d.mantissa4) &&
00229                             (vd.mantissa3 == lim->d.mantissa3) &&
00230                             (vd.mantissa2 == lim->d.mantissa2) &&
00231                             (vd.mantissa1 == lim->d.mantissa1) &&
00232                             (vd.exp == lim->d.exp)) {
00233                             id = lim->ieee;
00234                             goto shipit;
00235                      }
00236               }
00237               id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
00238               id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
00239               id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
00240                             (vd.mantissa3 << 13) |
00241                             ((vd.mantissa4 >> 3) & MASK(13));
00242        shipit:
00243               id.sign = vd.sign;
00244               dp = (double *)&id;
00245 #endif
00246               if (2*sizeof(long) == sizeof(double)) {
00247                      long *lp = (long *)dp;
00248                      return (XDR_PUTLONG(xdrs, lp+!LSW) &&
00249                             XDR_PUTLONG(xdrs, lp+LSW));
00250               } else if (2*sizeof(int) == sizeof(double)) {
00251                      int *ip = (int *)dp;
00252                      long tmp[2];
00253                      tmp[0] = ip[!LSW];
00254                      tmp[1] = ip[LSW];
00255                      return (XDR_PUTLONG(xdrs, tmp) &&
00256                             XDR_PUTLONG(xdrs, tmp+1));
00257               }
00258               break;
00259 
00260        case XDR_DECODE:
00261 #ifdef vax
00262               lp = (long *)&id;
00263               if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
00264                      return (FALSE);
00265               for (i = 0, lim = dbl_limits;
00266                      i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
00267                      i++, lim++) {
00268                      if ((id.mantissa2 == lim->ieee.mantissa2) &&
00269                             (id.mantissa1 == lim->ieee.mantissa1) &&
00270                             (id.exp == lim->ieee.exp)) {
00271                             vd = lim->d;
00272                             goto doneit;
00273                      }
00274               }
00275               vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
00276               vd.mantissa1 = (id.mantissa1 >> 13);
00277               vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
00278                             (id.mantissa2 >> 29);
00279               vd.mantissa3 = (id.mantissa2 >> 13);
00280               vd.mantissa4 = (id.mantissa2 << 3);
00281        doneit:
00282               vd.sign = id.sign;
00283               *dp = *((double *)&vd);
00284               return (TRUE);
00285 #else
00286               if (2*sizeof(long) == sizeof(double)) {
00287                      long *lp = (long *)dp;
00288                      return (XDR_GETLONG(xdrs, lp+!LSW) &&
00289                             XDR_GETLONG(xdrs, lp+LSW));
00290               } else if (2*sizeof(int) == sizeof(double)) {
00291                      int *ip = (int *)dp;
00292                      long tmp[2];
00293                      if (XDR_GETLONG(xdrs, tmp+!LSW) &&
00294                          XDR_GETLONG(xdrs, tmp+LSW)) {
00295                             ip[0] = tmp[0];
00296                             ip[1] = tmp[1];
00297                             return (TRUE);
00298                      }
00299               }
00300               break;
00301 #endif
00302 
00303        case XDR_FREE:
00304               return (TRUE);
00305        }
00306        return (FALSE);
00307 }