New multiprecision integer arithmetic suite.
[u/mdw/catacomb] / mp-mem.c
diff --git a/mp-mem.c b/mp-mem.c
new file mode 100644 (file)
index 0000000..2f75365
--- /dev/null
+++ b/mp-mem.c
@@ -0,0 +1,187 @@
+/* -*-c-*-
+ *
+ * $Id: mp-mem.c,v 1.1 1999/11/17 18:02:16 mdw Exp $
+ *
+ * Memory management for multiprecision numbers
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ * 
+ * Catacomb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: mp-mem.c,v $
+ * Revision 1.1  1999/11/17 18:02:16  mdw
+ * New multiprecision integer arithmetic suite.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include "mp.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @mp_create@ --- *
+ *
+ * Arguments:  @size_t sz@ = size of vector required
+ *
+ * Returns:    Pointer to pristine new MP structure with enough memory
+ *             bolted onto it.
+ *
+ * Use:                Creates a new multiprecision integer, initially zero.  The
+ *             integer has a single reference.
+ */
+
+mp *mp_create(size_t sz)
+{
+  mp *m = CREATE(mp);
+  m->v = MP_ALLOC(sz);
+  m->vl = m->v + sz;
+  m->sz = sz;
+  m->f = MP_UNDEF;
+  m->ref = 1;
+  return (m);
+}
+
+/* --- @mp_build@ --- *
+ *
+ * Arguments:  @mp *m@ = pointer to an MP block to fill in
+ *             @mpw *v@ = pointer to a word array
+ *             @mpw *vl@ = pointer just past end of array
+ *
+ * Returns:    ---
+ *
+ * Use:                Creates a multiprecision integer representing some smallish
+ *             number.  You must provide storage for the number and dispose
+ *             of it when you've finished with it.  The number is marked as
+ *             constant while it exists.
+ */
+
+void mp_build(mp *m, mpw *v, mpw *vl)
+{
+  m->v = v;
+  m->vl = vl;
+  m->sz = vl - v;
+  m->f = MP_CONST;
+  m->ref = 1;
+}
+
+/* --- @mp_destroy@ --- *
+ *
+ * Arguments:  @mp *m@ = pointer to a multiprecision integer
+ *
+ * Returns:    ---
+ *
+ * Use:                Destroys a multiprecision integer. The reference count isn't
+ *             checked.  Don't use this function if you don't know what
+ *             you're doing: use @mp_drop@ instead.
+ */
+
+void mp_destroy(mp *m)
+{
+  if (m->f & MP_CONST)
+    return;
+  if (m->f & MP_BURN)
+    memset(m->v, 0, MPWS(m->sz));
+  MP_FREE(m->v);
+  DESTROY(m);
+}
+
+/* --- @mp_copy@ --- *
+ *
+ * Arguments:  @mp *m@ = pointer to a multiprecision integer
+ *
+ * Returns:    A copy of the given multiprecision integer.
+ *
+ * Use:                Copies the given integer.  In fact you just get another
+ *             reference to the same old one again.
+ */
+
+mp *mp_copy(mp *m) { return MP_COPY(m); }
+
+/* --- @mp_drop@ --- *
+ *
+ * Arguments:  @mp *m@ = pointer to a multiprecision integer
+ *
+ * Returns:    ---
+ *
+ * Use:                Drops a reference to an integer which isn't wanted any more.
+ *             If there are no more references, the integer is destroyed.
+ */
+
+void mp_drop(mp *m) { MP_DROP(m); }
+
+/* --- @mp_split@ --- *
+ *
+ * Arguments:  @mp *m@ = pointer to a multiprecision integer
+ *
+ * Returns:    A reference to the same integer, possibly with a different
+ *             address.
+ *
+ * Use:                Splits off a modifiable version of the integer referred to.
+ */
+
+mp *mp_split(mp *m) { MP_SPLIT(m); return (m); }
+
+/* --- @mp_resize@ --- *
+ *
+ * Arguments:  @mp *m@ = pointer to a multiprecision integer
+ *             @size_t sz@ = new size
+ *
+ * Returns:    ---
+ *
+ * Use:                Resizes the vector containing the integer's digits.  The new
+ *             size must be at least as large as the current integer's
+ *             length.  This isn't really intended for client use.
+ */
+
+void mp_resize(mp *m, size_t sz) { MP_RESIZE(m, sz); }
+
+/* --- @mp_ensure@ --- *
+ *
+ * Arguments:  @mp *m@ = pointer to a multiprecision integer
+ *             @size_t sz@ = required size
+ *
+ * Returns:    ---
+ *
+ * Use:                Ensures that the integer has enough space for @sz@ digits.
+ *             The value is not changed.
+ */
+
+void mp_ensure(mp *m, size_t sz) { MP_ENSURE(m, sz); }
+
+/* --- @mp_modify@ --- *
+ *
+ * Arguments:  @mp *m@ = pointer to a multiprecision integer
+ *             @size_t sz@ = size required
+ *
+ * Returns:    Pointer to the integer (possibly different).
+ *
+ * Use:                Prepares an integer to be overwritten.  It's split off from
+ *             other references to the same integer, and sufficient space is
+ *             allocated.
+ */
+
+mp *mp_modify(mp *m, size_t sz) { MP_MODIFY(m, sz); return (m); }
+
+/*----- That's all, folks -------------------------------------------------*/