X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/mp-mem.c diff --git a/mp-mem.c b/mp-mem.c deleted file mode 100644 index fcb6c4d..0000000 --- a/mp-mem.c +++ /dev/null @@ -1,336 +0,0 @@ -/* -*-c-*- - * - * $Id: mp-mem.c,v 1.8 2004/04/08 16:17:32 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. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include - - -#include "mp.h" - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @mp_new@ --- * - * - * Arguments: @size_t sz@ = size of vector required - * @unsigned f@ = flags to set - * - * Returns: Pointer to a new MP structure. - * - * Use: Allocates a new multiprecision integer. The data space is - * allocated from either the standard global or secret arena, - * depending on the initial flags requested. - */ - -mp *mp_new(size_t sz, unsigned f) -{ - mp *m = CREATE(mp); - m->a = (f & MP_BURN) ? MPARENA_SECURE : MPARENA_GLOBAL; - m->v = mpalloc(m->a, sz); - m->vl = m->v + sz; - m->sz = sz; - m->f = f & ~(MP_CONST | MP_DESTROYED); - m->ref = 1; - return (m); -} - -/* --- @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 = mpalloc(MPARENA_GLOBAL, sz); - m->vl = m->v + sz; - m->sz = sz; - m->a = MPARENA_GLOBAL; - m->f = MP_UNDEF; - m->ref = 1; - return (m); -} - -/* --- @mp_createsecure@ --- * - * - * 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 with indeterminate - * contents. The integer has a single reference. The integer's - * data space is allocated from the secure arena. Its burn flag - * is set. - */ - -mp *mp_createsecure(size_t sz) -{ - mp *m = CREATE(mp); - m->v = mpalloc(MPARENA_SECURE, sz); - m->vl = m->v + sz; - m->sz = sz; - m->a = MPARENA_SECURE; - m->f = MP_UNDEF | MP_BURN; - 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->a = MPARENA_GLOBAL; - 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) -{ - assert(((void)"Destroying a free integer", !(m->f & MP_DESTROYED))); - assert(((void)"Attempted to destroy a constant", !(m->f & MP_CONST))); - if (m->f & MP_BURN) - memset(m->v, 0, MPWS(m->sz)); - mpfree(m->a, m->v); - m->f |= MP_DESTROYED; - 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) { if (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: Changes an integer's size. The length and value are not - * changed. It is an error to - */ - -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 length - * - * Returns: --- - * - * Use: Changes an integer's length. If there is not enough space - * allocated for the new length then the size is increased. It - */ - -void mp_ensure(mp *m, size_t sz) { MP_ENSURE(m, sz); } - -/* --- @mp_dest@ --- * - * - * Arguments: @mp *m@ = a suggested destination integer - * @size_t sz@ = size required for result, in digits - * @unsigned f@ = various flags - * - * Returns: A pointer to an appropriate destination. - * - * Use: Converts a suggested destination into a real destination with - * the required properties. If the real destination is @d@, - * then the following properties will hold: - * - * * @d@ will have exactly one reference. - * - * * If @m@ is not @MP_NEW@, then the contents of @m@ will not - * change, unless @f@ has the @MP_UNDEF@ flag set. - * - * * If @m@ is not @MP_NEW@, then he reference count of @m@ on - * entry is equal to the sum of the counts of @d@ and @m@ on - * exit. - * - * * The size of @d@ will be at least @sz@. - * - * * If @f@ has the @MP_BURN@ flag set, then @d@ will be - * allocated from @MPARENA_SECURE@. - * - * Understanding this function is crucial to using Catacomb's - * multiprecision integer library effectively. - */ - -mp *mp_dest(mp *m, size_t sz, unsigned f) -{ - /* --- If no destination, make one --- */ - - if (m == MP_NEWSEC) - m = mp_new(sz, f | MP_UNDEF | MP_BURN); - else if (m == MP_NEW) - m = mp_new(sz, f | MP_UNDEF); - else { - size_t len = MP_LEN(m); - unsigned undef = (m->f | f) & MP_UNDEF; - - /* --- If the value must be preserved, the block can't shrink --- */ - - if (!undef && sz < len) - sz = len; - - /* --- Otherwise check whether the destination is suitable --- */ - - if (m->ref > 1 || (m->f & MP_CONST) || - sz > m->sz || ((f & ~m->f) & MP_BURN)) { - - /* --- No -- allocate a new buffer --- * - * - * The buffer must be secure if (a) the caller requested a secure - * buffer, or (b) the old buffer is secure and I'm not allowed to - * discard the old contents. - */ - - mparena *a; - mpw *v; - - if ((f & MP_BURN) || (!undef && (m->f & MP_BURN))) - a = MPARENA_SECURE; - else - a = MPARENA_GLOBAL; - v = mpalloc(a, sz); - - /* --- Copy the data over --- */ - - if (!undef) { - memcpy(v, m->v, MPWS(len)); - if (sz - len > 0) - memset(v + len, 0, MPWS(sz - len)); - } - - /* --- If @m@ has other references, make a new node --- * - * - * Otherwise dispose of the old buffer. - */ - - if (!(m->f & MP_CONST) && m->ref == 1) { - if (m->f & MP_BURN) - memset(m->v, 0, MPWS(m->sz)); - mpfree(m->a, m->v); - } else { - mp *mm = CREATE(mp); - mm->ref = 1; - mm->f = m->f; - m->ref--; - m = mm; - } - - /* --- Fix up the node --- */ - - m->v = v; - m->vl = v + sz; - m->sz = sz; - m->f = ((m->f & ~(MP_CONST | MP_BURN)) | - (f & (MP_BURN | MP_UNDEF))); - m->a = a; - } - - /* --- If the number is growing in its buffer, fix it up --- */ - - else if (sz > len) { - if (!undef) - memset(m->vl, 0, MPWS(sz - len)); - m->vl = m->v + sz; - } - } - - /* --- Done --- */ - - return (m); -} - -/*----- That's all, folks -------------------------------------------------*/