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>