[BACK]Return to out_raw.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpz

Annotation of OpenXM_contrib/gmp/mpz/out_raw.c, Revision 1.1.1.3

1.1.1.3 ! ohara       1: /* mpz_out_raw -- write an mpz_t in raw format.
1.1       maekawa     2:
1.1.1.3 ! ohara       3: Copyright 2001, 2002 Free Software Foundation, Inc.
1.1       maekawa     4:
                      5: This file is part of the GNU MP Library.
                      6:
                      7: The GNU MP Library is free software; you can redistribute it and/or modify
1.1.1.2   maekawa     8: it under the terms of the GNU Lesser General Public License as published by
                      9: the Free Software Foundation; either version 2.1 of the License, or (at your
1.1       maekawa    10: option) any later version.
                     11:
                     12: The GNU MP Library is distributed in the hope that it will be useful, but
                     13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1.1.1.2   maekawa    14: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
1.1       maekawa    15: License for more details.
                     16:
1.1.1.2   maekawa    17: You should have received a copy of the GNU Lesser General Public License
1.1       maekawa    18: along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
                     19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     20: MA 02111-1307, USA. */
                     21:
                     22: #include <stdio.h>
                     23: #include "gmp.h"
                     24: #include "gmp-impl.h"
1.1.1.3 ! ohara      25: #include "longlong.h"
1.1       maekawa    26:
1.1.1.3 ! ohara      27:
        !            28: /* HTON_LIMB_STORE takes a normal host byte order limb and stores it as
        !            29:    network byte order (ie. big endian). */
        !            30:
        !            31: #if HAVE_LIMB_BIG_ENDIAN
        !            32: #define HTON_LIMB_STORE(dst, limb)  do { *(dst) = (limb); } while (0)
        !            33: #endif
        !            34:
        !            35: /* The generic implementations below very likely come out as lots of
        !            36:    separate byte stores, so if we know the host is little endian then
        !            37:    instead use a purely arithmetic BSWAP_LIMB and a single store.  */
        !            38: #if HAVE_LIMB_LITTLE_ENDIAN
        !            39: #define HTON_LIMB_STORE(dst, limb)  BSWAP_LIMB_STORE (dst, limb)
        !            40: #endif
        !            41:
        !            42: #if ! defined (HTON_LIMB_STORE)
        !            43: #if BITS_PER_MP_LIMB == 8
        !            44: #define HTON_LIMB_STORE(dst, limb)  do { *(dst) = (limb); } while (0)
        !            45: #endif
        !            46: #if BITS_PER_MP_LIMB == 16
        !            47: #define HTON_LIMB_STORE(dst, limb)      \
        !            48:   do {                                  \
        !            49:     mp_limb_t  __limb = (limb);         \
        !            50:     char  *__p = (char *) (dst);        \
        !            51:     __p[1] = (__limb);                  \
        !            52:     __p[0] = (__limb) >> 8;             \
        !            53:   } while (0)
        !            54: #endif
        !            55: #if BITS_PER_MP_LIMB == 32
        !            56: #define HTON_LIMB_STORE(dst, limb)      \
        !            57:   do {                                  \
        !            58:     mp_limb_t  __limb = (limb);         \
        !            59:     char  *__p = (char *) (dst);        \
        !            60:     __p[3] = (__limb);                  \
        !            61:     __p[2] = (__limb) >> 8;             \
        !            62:     __p[1] = (__limb) >> 16;            \
        !            63:     __p[0] = (__limb) >> 24;            \
        !            64:   } while (0)
        !            65: #endif
        !            66: #if BITS_PER_MP_LIMB == 64
        !            67: #define HTON_LIMB_STORE(dst, limb)      \
        !            68:   do {                                  \
        !            69:     mp_limb_t  __limb = (limb);         \
        !            70:     char  *__p = (char *) (dst);        \
        !            71:     __p[7] = (__limb);                  \
        !            72:     __p[6] = (__limb) >> 8;             \
        !            73:     __p[5] = (__limb) >> 16;            \
        !            74:     __p[4] = (__limb) >> 24;            \
        !            75:     __p[3] = (__limb) >> 32;            \
        !            76:     __p[2] = (__limb) >> 40;            \
        !            77:     __p[1] = (__limb) >> 48;            \
        !            78:     __p[0] = (__limb) >> 56;            \
        !            79:   } while (0)
1.1       maekawa    80: #endif
1.1.1.3 ! ohara      81: #endif
        !            82:
        !            83:
        !            84: size_t
        !            85: mpz_out_raw (FILE *fp, mpz_srcptr x)
1.1       maekawa    86: {
1.1.1.3 ! ohara      87:   mp_size_t   xsize, abs_xsize, bytes, i;
        !            88:   mp_srcptr   xp;
        !            89:   char        *tp, *bp;
        !            90:   mp_limb_t   xlimb;
        !            91:   int         zeros;
        !            92:   size_t      tsize, ssize;
        !            93:
        !            94:   xsize = SIZ(x);
        !            95:   abs_xsize = ABS (xsize);
        !            96:   bytes = (abs_xsize * GMP_NUMB_BITS + 7) / 8;
        !            97:   tsize = ROUND_UP_MULTIPLE ((unsigned) 4, BYTES_PER_MP_LIMB) + bytes;
1.1       maekawa    98:
1.1.1.3 ! ohara      99:   tp = __GMP_ALLOCATE_FUNC_TYPE (tsize, char);
        !           100:   bp = tp + ROUND_UP_MULTIPLE ((unsigned) 4, BYTES_PER_MP_LIMB);
1.1       maekawa   101:
1.1.1.3 ! ohara     102:   if (bytes != 0)
1.1       maekawa   103:     {
1.1.1.3 ! ohara     104:       bp += bytes;
        !           105:       xp = PTR (x);
        !           106:       i = abs_xsize;
        !           107:
        !           108:       if (GMP_NAIL_BITS == 0)
        !           109:         {
        !           110:           /* reverse limb order, and byte swap if necessary */
        !           111: #ifdef _CRAY
        !           112:           _Pragma ("_CRI ivdep");
        !           113: #endif
        !           114:           do
        !           115:             {
        !           116:               bp -= BYTES_PER_MP_LIMB;
        !           117:               xlimb = *xp;
        !           118:               HTON_LIMB_STORE ((mp_ptr) bp, xlimb);
        !           119:               xp++;
        !           120:             }
        !           121:           while (--i > 0);
        !           122:
        !           123:           /* strip high zero bytes (without fetching from bp) */
        !           124:           count_leading_zeros (zeros, xlimb);
        !           125:           zeros /= 8;
        !           126:           bp += zeros;
        !           127:           bytes -= zeros;
        !           128:         }
        !           129:       else
        !           130:         {
        !           131:           mp_limb_t  new_xlimb;
        !           132:           int        bits;
        !           133:           ASSERT_CODE (char *bp_orig = bp - bytes);
        !           134:
        !           135:           ASSERT_ALWAYS (GMP_NUMB_BITS >= 8);
        !           136:
        !           137:           bits = 0;
        !           138:           xlimb = 0;
        !           139:           for (;;)
        !           140:             {
        !           141:               while (bits >= 8)
        !           142:                 {
        !           143:                   ASSERT (bp > bp_orig);
        !           144:                   *--bp = xlimb & 0xFF;
        !           145:                   xlimb >>= 8;
        !           146:                   bits -= 8;
        !           147:                 }
        !           148:
        !           149:               if (i == 0)
        !           150:                 break;
        !           151:
        !           152:               new_xlimb = *xp++;
        !           153:               i--;
        !           154:               ASSERT (bp > bp_orig);
        !           155:               *--bp = (xlimb | (new_xlimb << bits)) & 0xFF;
        !           156:               xlimb = new_xlimb >> (8 - bits);
        !           157:               bits += GMP_NUMB_BITS - 8;
        !           158:             }
        !           159:
        !           160:           if (bits != 0)
        !           161:             {
        !           162:               ASSERT (bp > bp_orig);
        !           163:               *--bp = xlimb;
        !           164:             }
        !           165:
        !           166:           ASSERT (bp == bp_orig);
        !           167:           while (*bp == 0)
        !           168:             {
        !           169:               bp++;
        !           170:               bytes--;
        !           171:             }
        !           172:         }
1.1       maekawa   173:     }
                    174:
1.1.1.3 ! ohara     175:   /* total bytes to be written */
        !           176:   ssize = 4 + bytes;
1.1       maekawa   177:
1.1.1.3 ! ohara     178:   /* twos complement negative for the size value */
        !           179:   bytes = (xsize >= 0 ? bytes : -bytes);
1.1       maekawa   180:
1.1.1.3 ! ohara     181:   /* so we don't rely on sign extension in ">>" */
        !           182:   ASSERT_ALWAYS (sizeof (bytes) >= 4);
        !           183:
        !           184:   bp[-4] = bytes >> 24;
        !           185:   bp[-3] = bytes >> 16;
        !           186:   bp[-2] = bytes >> 8;
        !           187:   bp[-1] = bytes;
        !           188:   bp -= 4;
        !           189:
        !           190:   if (fp == 0)
        !           191:     fp = stdout;
        !           192:   if (fwrite (bp, ssize, 1, fp) != 1)
        !           193:     ssize = 0;
        !           194:
        !           195:   (*__gmp_free_func) (tp, tsize);
        !           196:   return ssize;
1.1       maekawa   197: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>