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>