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

Annotation of OpenXM_contrib/gmp/mpz/export.c, Revision 1.1.1.1

1.1       ohara       1: /* mpz_export -- create word data from mpz.
                      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: #include "longlong.h"
                     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: #define MPN_SIZEINBASE_2EXP(result, ptr, size, base2exp)                \
                     41:   do {                                                                  \
                     42:     int            __cnt;                                               \
                     43:     unsigned long  __totbits;                                           \
                     44:     ASSERT ((size) > 0);                                                \
                     45:     ASSERT ((ptr)[(size)-1] != 0);                                      \
                     46:     count_leading_zeros (__cnt, (ptr)[(size)-1]);                       \
                     47:     __totbits = (size) * GMP_NUMB_BITS - (__cnt - GMP_NAIL_BITS);       \
                     48:     (result) = (__totbits + (base2exp)-1) / (base2exp);                 \
                     49:   } while (0)
                     50:
                     51:
                     52: void *
                     53: mpz_export (void *data, size_t *countp, int order,
                     54:             size_t size, int endian, size_t nail, mpz_srcptr z)
                     55: {
                     56:   mp_size_t      zsize;
                     57:   mp_srcptr      zp;
                     58:   size_t         count;
                     59:   unsigned long  numb;
                     60:   unsigned       align;
                     61:
                     62:   ASSERT (order == 1 || order == -1);
                     63:   ASSERT (endian == 1 || endian == 0 || endian == -1);
                     64:   ASSERT (nail <= 8*size);
                     65:   ASSERT (8*size-nail > 0);
                     66:
                     67:   zsize = SIZ(z);
                     68:   if (zsize == 0)
                     69:     {
                     70:       *countp = 0;
                     71:       return data;
                     72:     }
                     73:
                     74:   zsize = ABS (zsize);
                     75:   zp = PTR(z);
                     76:   numb = 8*size - nail;
                     77:   MPN_SIZEINBASE_2EXP (count, zp, zsize, numb);
                     78:   *countp = count;
                     79:
                     80:   if (data == NULL)
                     81:     data = (*__gmp_allocate_func) (count*size);
                     82:
                     83:   if (endian == 0)
                     84:     endian = HOST_ENDIAN;
                     85:
                     86:   align = ((char *) data - (char *) NULL) % sizeof (mp_limb_t);
                     87:
                     88:   if (nail == GMP_NAIL_BITS)
                     89:     {
                     90:       if (size == sizeof (mp_limb_t) && align == 0)
                     91:         {
                     92:           if (order == -1 && endian == HOST_ENDIAN)
                     93:             {
                     94:               MPN_COPY ((mp_ptr) data, zp, (mp_size_t) count);
                     95:               return data;
                     96:             }
                     97:           if (order == 1 && endian == HOST_ENDIAN)
                     98:             {
                     99:               MPN_REVERSE ((mp_ptr) data, zp, (mp_size_t) count);
                    100:               return data;
                    101:             }
                    102:
                    103:           if (order == -1 && endian == -HOST_ENDIAN)
                    104:             {
                    105:               MPN_BSWAP ((mp_ptr) data, zp, (mp_size_t) count);
                    106:               return data;
                    107:             }
                    108:           if (order == 1 && endian == -HOST_ENDIAN)
                    109:             {
                    110:               MPN_BSWAP_REVERSE ((mp_ptr) data, zp, (mp_size_t) count);
                    111:               return data;
                    112:             }
                    113:         }
                    114:     }
                    115:
                    116:   {
                    117:     mp_limb_t      limb, wbitsmask;
                    118:     size_t         i, numb;
                    119:     mp_size_t      j, wbytes, woffset;
                    120:     unsigned char  *dp;
                    121:     int            lbits, wbits;
                    122:     mp_srcptr      zend;
                    123:
                    124:     numb = size * 8 - nail;
                    125:
                    126:     /* whole bytes per word */
                    127:     wbytes = numb / 8;
                    128:
                    129:     /* possible partial byte */
                    130:     wbits = numb % 8;
                    131:     wbitsmask = (CNST_LIMB(1) << wbits) - 1;
                    132:
                    133:     /* offset to get to the next word */
                    134:     woffset = (endian >= 0 ? size : - (mp_size_t) size)
                    135:       + (order < 0 ? size : - (mp_size_t) size);
                    136:
                    137:     /* least significant byte */
                    138:     dp = (unsigned char *) data
                    139:       + (order >= 0 ? (count-1)*size : 0) + (endian >= 0 ? size-1 : 0);
                    140:
                    141: #define EXTRACT(N, MASK)                                \
                    142:     do {                                                \
                    143:       if (lbits >= (N))                                 \
                    144:         {                                               \
                    145:           *dp = limb MASK;                              \
                    146:           limb >>= (N);                                 \
                    147:           lbits -= (N);                                 \
                    148:         }                                               \
                    149:       else                                              \
                    150:         {                                               \
                    151:           mp_limb_t  newlimb;                           \
                    152:           newlimb = (zp == zend ? 0 : *zp++);           \
                    153:           *dp = (limb | (newlimb << lbits)) MASK;       \
                    154:           limb = newlimb >> ((N)-lbits);                \
                    155:           lbits += GMP_NUMB_BITS - (N);                 \
                    156:         }                                               \
                    157:     } while (0)
                    158:
                    159:     zend = zp + zsize;
                    160:     lbits = 0;
                    161:     limb = 0;
                    162:     for (i = 0; i < count; i++)
                    163:       {
                    164:         for (j = 0; j < wbytes; j++)
                    165:           {
                    166:             EXTRACT (8, + 0);
                    167:             dp -= endian;
                    168:           }
                    169:         if (wbits != 0)
                    170:           {
                    171:             EXTRACT (wbits, & wbitsmask);
                    172:             dp -= endian;
                    173:             j++;
                    174:           }
                    175:         for ( ; j < size; j++)
                    176:           {
                    177:             *dp = '\0';
                    178:             dp -= endian;
                    179:           }
                    180:         dp += woffset;
                    181:       }
                    182:
                    183:     ASSERT (zp == PTR(z) + ABSIZ(z));
                    184:
                    185:     /* low byte of word after most significant */
                    186:     ASSERT (dp == (unsigned char *) data
                    187:             + (order < 0 ? count*size : - (mp_size_t) size)
                    188:             + (endian >= 0 ? (mp_size_t) size - 1 : 0));
                    189:   }
                    190:   return data;
                    191: }

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