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

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

1.1.1.3 ! ohara       1: /* mpz_inp_raw -- read 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"
                     25:
1.1.1.3 ! ohara      26:
        !            27: /* NTOH_LIMB_FETCH fetches a limb which is in network byte order (ie. big
        !            28:    endian) and produces a normal host byte order result. */
        !            29:
        !            30: #if HAVE_LIMB_BIG_ENDIAN
        !            31: #define NTOH_LIMB_FETCH(limb, src)  do { (limb) = *(src); } while (0)
1.1       maekawa    32: #endif
                     33:
1.1.1.3 ! ohara      34: /* The generic implementations below very likely come out as lots of
        !            35:    separate byte fetches, so if we know the host is little endian then
        !            36:    instead use a single load and a purely arithmetic BSWAP_LIMB.  */
        !            37: #if HAVE_LIMB_LITTLE_ENDIAN
        !            38: #define NTOH_LIMB_FETCH(limb, src)  BSWAP_LIMB_FETCH (limb, src)
        !            39: #endif
1.1       maekawa    40:
1.1.1.3 ! ohara      41: #if ! defined (NTOH_LIMB_FETCH)
        !            42: #if BITS_PER_MP_LIMB == 8
        !            43: #define NTOH_LIMB_FETCH(limb, src)  do { (limb) = *(src); } while (0)
        !            44: #endif
        !            45: #if BITS_PER_MP_LIMB == 16
        !            46: #define NTOH_LIMB_FETCH(limb, src)                              \
        !            47:   do {                                                          \
        !            48:     const unsigned char  *__p = (const unsigned char *) (src);  \
        !            49:     (limb) =                                                    \
        !            50:       ( (mp_limb_t) __p[0] << 8)                                \
        !            51:       + (mp_limb_t) __p[1];                                     \
        !            52:   } while (0)
        !            53: #endif
        !            54: #if BITS_PER_MP_LIMB == 32
        !            55: #define NTOH_LIMB_FETCH(limb, src)                              \
        !            56:   do {                                                          \
        !            57:     const unsigned char  *__p = (const unsigned char *) (src);  \
        !            58:     (limb) =                                                    \
        !            59:       (  (mp_limb_t) __p[0] << 24)                              \
        !            60:       + ((mp_limb_t) __p[1] << 16)                              \
        !            61:       + ((mp_limb_t) __p[2] << 8)                               \
        !            62:       +  (mp_limb_t) __p[3];                                    \
        !            63:   } while (0)
        !            64: #endif
        !            65: #if ! defined (NTOH_LIMB_FETCH) && BITS_PER_MP_LIMB == 64
        !            66: #define NTOH_LIMB_FETCH(limb, src)                              \
        !            67:   do {                                                          \
        !            68:     const unsigned char  *__p = (const unsigned char *) (src);  \
        !            69:     (limb) =                                                    \
        !            70:       (  (mp_limb_t) __p[0] << 56)                              \
        !            71:       + ((mp_limb_t) __p[1] << 48)                              \
        !            72:       + ((mp_limb_t) __p[2] << 40)                              \
        !            73:       + ((mp_limb_t) __p[3] << 32)                              \
        !            74:       + ((mp_limb_t) __p[4] << 24)                              \
        !            75:       + ((mp_limb_t) __p[5] << 16)                              \
        !            76:       + ((mp_limb_t) __p[6] << 8)                               \
        !            77:       +  (mp_limb_t) __p[7];                                    \
        !            78:   } while (0)
        !            79: #endif
        !            80: #endif
1.1       maekawa    81:
                     82:
1.1.1.3 ! ohara      83: /* Enhancement: The byte swap loop ought to be safe to vectorize on Cray
        !            84:    etc, but someone who knows what they're doing needs to check it.  */
        !            85:
        !            86: size_t
        !            87: mpz_inp_raw (mpz_ptr x, FILE *fp)
        !            88: {
        !            89:   unsigned char  csize_bytes[4];
        !            90:   mp_size_t      csize, abs_xsize, i;
        !            91:   size_t         abs_csize;
        !            92:   char           *cp;
        !            93:   mp_ptr         xp, sp, ep;
        !            94:   mp_limb_t      slimb, elimb;
        !            95:
        !            96:   if (fp == 0)
        !            97:     fp = stdin;
        !            98:
        !            99:   /* 4 bytes for size */
        !           100:   if (fread (csize_bytes, sizeof (csize_bytes), 1, fp) != 1)
        !           101:     return 0;
        !           102:
        !           103:   csize =
        !           104:     (  (mp_size_t) csize_bytes[0] << 24)
        !           105:     + ((mp_size_t) csize_bytes[1] << 16)
        !           106:     + ((mp_size_t) csize_bytes[2] << 8)
        !           107:     + ((mp_size_t) csize_bytes[3]);
        !           108:
        !           109:   /* Sign extend if necessary.
        !           110:      Could write "csize -= ((csize & 0x80000000L) << 1)", but that tickles a
        !           111:      bug in gcc 3.0 for powerpc64 on AIX.  */
        !           112:   if (sizeof (csize) > 4 && csize & 0x80000000L)
        !           113:     csize -= 0x80000000L << 1;
        !           114:
        !           115:   abs_csize = ABS (csize);
1.1       maekawa   116:
1.1.1.3 ! ohara     117:   /* round up to a multiple of limbs */
        !           118:   abs_xsize = (abs_csize*8 + GMP_NUMB_BITS-1) / GMP_NUMB_BITS;
        !           119:
        !           120:   if (abs_xsize != 0)
1.1       maekawa   121:     {
1.1.1.3 ! ohara     122:       MPZ_REALLOC (x, abs_xsize);
        !           123:       xp = PTR(x);
1.1       maekawa   124:
1.1.1.3 ! ohara     125:       /* Get limb boundaries right in the read, for the benefit of the
        !           126:          non-nails case.  */
        !           127:       xp[0] = 0;
        !           128:       cp = (char *) (xp + abs_xsize) - abs_csize;
        !           129:       if (fread (cp, abs_csize, 1, fp) != 1)
        !           130:         return 0;
        !           131:
        !           132:       if (GMP_NAIL_BITS == 0)
        !           133:         {
        !           134:           /* Reverse limbs to least significant first, and byte swap.  If
        !           135:              abs_xsize is odd then on the last iteration elimb and slimb are
        !           136:              the same.  It doesn't seem extra code to handle that case
        !           137:              separately, to save an NTOH.  */
        !           138:           sp = xp;
        !           139:           ep = xp + abs_xsize-1;
        !           140:           for (i = 0; i < (abs_xsize+1)/2; i++)
        !           141:             {
        !           142:               NTOH_LIMB_FETCH (elimb, ep);
        !           143:               NTOH_LIMB_FETCH (slimb, sp);
        !           144:               *sp++ = elimb;
        !           145:               *ep-- = slimb;
        !           146:             }
        !           147:         }
        !           148:       else
        !           149:         {
        !           150:           /* It ought to be possible to do the transformation in-place, but
        !           151:              for now it's easier to use an extra temporary area.  */
        !           152:           mp_limb_t  byte, limb;
        !           153:           int        bits;
        !           154:           mp_size_t  tpos;
        !           155:           mp_ptr     tp;
        !           156:           TMP_DECL (marker);
        !           157:
        !           158:           TMP_MARK (marker);
        !           159:           tp = TMP_ALLOC_LIMBS (abs_xsize);
        !           160:           limb = 0;
        !           161:           bits = 0;
        !           162:           tpos = 0;
        !           163:           for (i = abs_csize-1; i >= 0; i--)
        !           164:             {
        !           165:               byte = (unsigned char) cp[i];
        !           166:               limb |= (byte << bits);
        !           167:               bits += 8;
        !           168:               if (bits >= GMP_NUMB_BITS)
        !           169:                 {
        !           170:                   ASSERT (tpos < abs_xsize);
        !           171:                   tp[tpos++] = limb & GMP_NUMB_MASK;
        !           172:                   bits -= GMP_NUMB_BITS;
        !           173:                   ASSERT (bits < 8);
        !           174:                   limb = byte >> (8 - bits);
        !           175:                 }
        !           176:             }
        !           177:           if (bits != 0)
        !           178:             {
        !           179:               ASSERT (tpos < abs_xsize);
        !           180:               tp[tpos++] = limb;
        !           181:             }
        !           182:           ASSERT (tpos == abs_xsize);
        !           183:
        !           184:           MPN_COPY (xp, tp, abs_xsize);
        !           185:           TMP_FREE (marker);
        !           186:         }
        !           187:
        !           188:       /* GMP 1.x mpz_out_raw wrote high zero bytes, strip any high zero
        !           189:          limbs resulting from this.  Should be a non-zero value here, but
        !           190:          for safety don't assume that. */
        !           191:       MPN_NORMALIZE (xp, abs_xsize);
        !           192:     }
1.1       maekawa   193:
1.1.1.3 ! ohara     194:   SIZ(x) = (csize >= 0 ? abs_xsize : -abs_xsize);
        !           195:   return abs_csize + 4;
1.1       maekawa   196: }

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