More changes. Still embryonic.
[u/mdw/catacomb] / mp-mem.c
1 /* -*-c-*-
2 *
3 * $Id: mp-mem.c,v 1.2 1999/12/10 23:19:02 mdw Exp $
4 *
5 * Memory management for multiprecision numbers
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
10 /*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30 /*----- Revision history --------------------------------------------------*
31 *
32 * $Log: mp-mem.c,v $
33 * Revision 1.2 1999/12/10 23:19:02 mdw
34 * Improve error-checking.
35 *
36 * Revision 1.1 1999/11/17 18:02:16 mdw
37 * New multiprecision integer arithmetic suite.
38 *
39 */
40
41 /*----- Header files ------------------------------------------------------*/
42
43 #include "mp.h"
44
45 /*----- Main code ---------------------------------------------------------*/
46
47 /* --- @mp_create@ --- *
48 *
49 * Arguments: @size_t sz@ = size of vector required
50 *
51 * Returns: Pointer to pristine new MP structure with enough memory
52 * bolted onto it.
53 *
54 * Use: Creates a new multiprecision integer, initially zero. The
55 * integer has a single reference.
56 */
57
58 mp *mp_create(size_t sz)
59 {
60 mp *m = CREATE(mp);
61 m->v = MP_ALLOC(sz);
62 m->vl = m->v + sz;
63 m->sz = sz;
64 m->f = MP_UNDEF;
65 m->ref = 1;
66 return (m);
67 }
68
69 /* --- @mp_build@ --- *
70 *
71 * Arguments: @mp *m@ = pointer to an MP block to fill in
72 * @mpw *v@ = pointer to a word array
73 * @mpw *vl@ = pointer just past end of array
74 *
75 * Returns: ---
76 *
77 * Use: Creates a multiprecision integer representing some smallish
78 * number. You must provide storage for the number and dispose
79 * of it when you've finished with it. The number is marked as
80 * constant while it exists.
81 */
82
83 void mp_build(mp *m, mpw *v, mpw *vl)
84 {
85 m->v = v;
86 m->vl = vl;
87 m->sz = vl - v;
88 m->f = MP_CONST;
89 m->ref = 1;
90 }
91
92 /* --- @mp_destroy@ --- *
93 *
94 * Arguments: @mp *m@ = pointer to a multiprecision integer
95 *
96 * Returns: ---
97 *
98 * Use: Destroys a multiprecision integer. The reference count isn't
99 * checked. Don't use this function if you don't know what
100 * you're doing: use @mp_drop@ instead.
101 */
102
103 void mp_destroy(mp *m)
104 {
105 assert(((void)"Destroying a free integer", !(m->f & MP_DESTROYED)));
106 assert(((void)"Attempted to destroy a constant", !(m->f & MP_CONST)));
107 if (m->f & MP_BURN)
108 memset(m->v, 0, MPWS(m->sz));
109 MP_FREE(m->v);
110 m->f |= MP_DESTROYED;
111 DESTROY(m);
112 }
113
114 /* --- @mp_copy@ --- *
115 *
116 * Arguments: @mp *m@ = pointer to a multiprecision integer
117 *
118 * Returns: A copy of the given multiprecision integer.
119 *
120 * Use: Copies the given integer. In fact you just get another
121 * reference to the same old one again.
122 */
123
124 mp *mp_copy(mp *m) { return MP_COPY(m); }
125
126 /* --- @mp_drop@ --- *
127 *
128 * Arguments: @mp *m@ = pointer to a multiprecision integer
129 *
130 * Returns: ---
131 *
132 * Use: Drops a reference to an integer which isn't wanted any more.
133 * If there are no more references, the integer is destroyed.
134 */
135
136 void mp_drop(mp *m) { MP_DROP(m); }
137
138 /* --- @mp_split@ --- *
139 *
140 * Arguments: @mp *m@ = pointer to a multiprecision integer
141 *
142 * Returns: A reference to the same integer, possibly with a different
143 * address.
144 *
145 * Use: Splits off a modifiable version of the integer referred to.
146 */
147
148 mp *mp_split(mp *m) { MP_SPLIT(m); return (m); }
149
150 /* --- @mp_resize@ --- *
151 *
152 * Arguments: @mp *m@ = pointer to a multiprecision integer
153 * @size_t sz@ = new size
154 *
155 * Returns: ---
156 *
157 * Use: Resizes the vector containing the integer's digits. The new
158 * size must be at least as large as the current integer's
159 * length. This isn't really intended for client use.
160 */
161
162 void mp_resize(mp *m, size_t sz) { MP_RESIZE(m, sz); }
163
164 /* --- @mp_ensure@ --- *
165 *
166 * Arguments: @mp *m@ = pointer to a multiprecision integer
167 * @size_t sz@ = required size
168 *
169 * Returns: ---
170 *
171 * Use: Ensures that the integer has enough space for @sz@ digits.
172 * The value is not changed.
173 */
174
175 void mp_ensure(mp *m, size_t sz) { MP_ENSURE(m, sz); }
176
177 /* --- @mp_modify@ --- *
178 *
179 * Arguments: @mp *m@ = pointer to a multiprecision integer
180 * @size_t sz@ = size required
181 *
182 * Returns: Pointer to the integer (possibly different).
183 *
184 * Use: Prepares an integer to be overwritten. It's split off from
185 * other references to the same integer, and sufficient space is
186 * allocated.
187 */
188
189 mp *mp_modify(mp *m, size_t sz) { MP_MODIFY(m, sz); return (m); }
190
191 /*----- That's all, folks -------------------------------------------------*/