home *** CD-ROM | disk | FTP | other *** search
/ Serving the Web / ServingTheWeb1995.disc1of1.iso / linux / slacksrce / d / libc / libc-4.6 / libc-4 / libc-linux / rpc / xdr_float.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-13  |  7.0 KB  |  287 lines

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