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

Annotation of OpenXM_contrib/gmp/mpz/import.c, Revision 1.1

1.1     ! ohara       1: /* mpz_import -- set mpz from word data.
        !             2:
        !             3: Copyright 2002 Free Software Foundation, Inc.
        !             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
        !             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
        !            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
        !            14: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
        !            15: License for more details.
        !            16:
        !            17: You should have received a copy of the GNU Lesser General Public License
        !            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>  /* for NULL */
        !            23: #include "gmp.h"
        !            24: #include "gmp-impl.h"
        !            25:
        !            26:
        !            27:
        !            28: #if HAVE_LIMB_BIG_ENDIAN
        !            29: #define HOST_ENDIAN     1
        !            30: #endif
        !            31: #if HAVE_LIMB_LITTLE_ENDIAN
        !            32: #define HOST_ENDIAN     (-1)
        !            33: #endif
        !            34: #ifndef HOST_ENDIAN
        !            35: static const mp_limb_t  endian_test = (CNST_LIMB(1) << (GMP_LIMB_BITS-7)) - 1;
        !            36: #define HOST_ENDIAN     (* (signed char *) &endian_test)
        !            37: #endif
        !            38:
        !            39:
        !            40: void
        !            41: mpz_import (mpz_ptr z, size_t count, int order,
        !            42:             size_t size, int endian, size_t nail, const void *data)
        !            43: {
        !            44:   mp_size_t  zsize;
        !            45:   mp_ptr     zp;
        !            46:
        !            47:   ASSERT (order == 1 || order == -1);
        !            48:   ASSERT (endian == 1 || endian == 0 || endian == -1);
        !            49:   ASSERT (nail <= 8*size);
        !            50:
        !            51:   zsize = (count * (8*size - nail) + GMP_NUMB_BITS-1) / GMP_NUMB_BITS;
        !            52:   MPZ_REALLOC (z, zsize);
        !            53:   zp = PTR(z);
        !            54:
        !            55:   if (endian == 0)
        !            56:     endian = HOST_ENDIAN;
        !            57:
        !            58:   /* Can't use these special cases with nails currently, since they don't
        !            59:      mask out the nail bits in the input data.  */
        !            60:   if (nail == 0 && GMP_NAIL_BITS == 0)
        !            61:     {
        !            62:       unsigned  align = ((char *) data - (char *) NULL) % sizeof (mp_limb_t);
        !            63:
        !            64:       if (order == -1
        !            65:           && size == sizeof (mp_limb_t)
        !            66:           && endian == HOST_ENDIAN
        !            67:           && align == 0)
        !            68:         {
        !            69:           MPN_COPY (zp, (mp_srcptr) data, (mp_size_t) count);
        !            70:           goto done;
        !            71:         }
        !            72:
        !            73:       if (order == -1
        !            74:           && size == sizeof (mp_limb_t)
        !            75:           && endian == - HOST_ENDIAN
        !            76:           && align == 0)
        !            77:         {
        !            78:           MPN_BSWAP (zp, (mp_srcptr) data, (mp_size_t) count);
        !            79:           goto done;
        !            80:         }
        !            81:
        !            82:       if (order == 1
        !            83:           && size == sizeof (mp_limb_t)
        !            84:           && endian == HOST_ENDIAN
        !            85:           && align == 0)
        !            86:         {
        !            87:           MPN_REVERSE (zp, (mp_srcptr) data, (mp_size_t) count);
        !            88:           goto done;
        !            89:         }
        !            90:     }
        !            91:
        !            92:   {
        !            93:     mp_limb_t      limb, byte, wbitsmask;
        !            94:     size_t         i, j, numb, wbytes;
        !            95:     mp_size_t      woffset;
        !            96:     unsigned char  *dp;
        !            97:     int            lbits, wbits;
        !            98:
        !            99:     numb = size * 8 - nail;
        !           100:
        !           101:     /* whole bytes to process */
        !           102:     wbytes = numb / 8;
        !           103:
        !           104:     /* partial byte to process */
        !           105:     wbits = numb % 8;
        !           106:     wbitsmask = (CNST_LIMB(1) << wbits) - 1;
        !           107:
        !           108:     /* offset to get to the next word after processing wbytes and wbits */
        !           109:     woffset = (numb + 7) / 8;
        !           110:     woffset = (endian >= 0 ? woffset : -woffset)
        !           111:       + (order < 0 ? size : - (mp_size_t) size);
        !           112:
        !           113:     /* least significant byte */
        !           114:     dp = (unsigned char *) data
        !           115:       + (order >= 0 ? (count-1)*size : 0) + (endian >= 0 ? size-1 : 0);
        !           116:
        !           117: #define ACCUMULATE(N)                                   \
        !           118:     do {                                                \
        !           119:       ASSERT (lbits < GMP_NUMB_BITS);                   \
        !           120:       ASSERT (limb <= (CNST_LIMB(1) << lbits) - 1);     \
        !           121:                                                         \
        !           122:       limb |= (mp_limb_t) byte << lbits;                \
        !           123:       lbits += (N);                                     \
        !           124:       if (lbits >= GMP_NUMB_BITS)                       \
        !           125:         {                                               \
        !           126:           *zp++ = limb & GMP_NUMB_MASK;                 \
        !           127:           lbits -= GMP_NUMB_BITS;                       \
        !           128:           ASSERT (lbits < (N));                         \
        !           129:           limb = byte >> ((N) - lbits);                 \
        !           130:         }                                               \
        !           131:     } while (0)
        !           132:
        !           133:     limb = 0;
        !           134:     lbits = 0;
        !           135:     for (i = 0; i < count; i++)
        !           136:       {
        !           137:         for (j = 0; j < wbytes; j++)
        !           138:           {
        !           139:             byte = *dp;
        !           140:             dp -= endian;
        !           141:             ACCUMULATE (8);
        !           142:           }
        !           143:         if (wbits != 0)
        !           144:           {
        !           145:             byte = *dp & wbitsmask;
        !           146:             dp -= endian;
        !           147:             ACCUMULATE (wbits);
        !           148:           }
        !           149:         dp += woffset;
        !           150:       }
        !           151:
        !           152:     if (lbits != 0)
        !           153:       {
        !           154:         ASSERT (lbits <= GMP_NUMB_BITS);
        !           155:         ASSERT_LIMB (limb);
        !           156:         *zp++ = limb;
        !           157:       }
        !           158:
        !           159:     ASSERT (zp == PTR(z) + zsize);
        !           160:
        !           161:     /* low byte of word after most significant */
        !           162:     ASSERT (dp == (unsigned char *) data
        !           163:             + (order < 0 ? count*size : - (mp_size_t) size)
        !           164:             + (endian >= 0 ? (mp_size_t) size - 1 : 0));
        !           165:
        !           166:   }
        !           167:
        !           168:  done:
        !           169:   zp = PTR(z);
        !           170:   MPN_NORMALIZE (zp, zsize);
        !           171:   SIZ(z) = zsize;
        !           172: }

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