184 lines
3.3 KiB
C
184 lines
3.3 KiB
C
/*
|
|
* Copyright (c) 2003 Bob Deblier
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
|
|
/*!\file mpnumber.c
|
|
* \brief Multi-precision numbers.
|
|
* \author Bob Deblier <bob.deblier@pandora.be>
|
|
* \ingroup MP_m
|
|
*/
|
|
|
|
#include "system.h"
|
|
#include "mpnumber.h"
|
|
#include "mp.h"
|
|
#include "debug.h"
|
|
|
|
void mpnzero(mpnumber* n)
|
|
{
|
|
n->size = 0;
|
|
n->data = (mpw*) 0;
|
|
}
|
|
|
|
/*@-compdef @*/ /* n->data not initialized */
|
|
void mpnsize(mpnumber* n, size_t size)
|
|
{
|
|
if (size)
|
|
{
|
|
if (n->data)
|
|
{
|
|
if (n->size != size)
|
|
n->data = (mpw*) realloc(n->data, size * sizeof(*n->data));
|
|
}
|
|
else
|
|
n->data = (mpw*) malloc(size * sizeof(*n->data));
|
|
|
|
if (n->data)
|
|
n->size = size;
|
|
else
|
|
{
|
|
n->size = 0;
|
|
n->data = (mpw*) 0;
|
|
}
|
|
|
|
}
|
|
else if (n->data)
|
|
{
|
|
free(n->data);
|
|
n->data = (mpw*) 0;
|
|
n->size = 0;
|
|
}
|
|
}
|
|
/*@=compdef @*/
|
|
|
|
void mpninit(mpnumber* n, size_t size, const mpw* data)
|
|
{
|
|
n->size = size;
|
|
if (n->data)
|
|
{
|
|
free(n->data);
|
|
n->data = (mpw*) 0;
|
|
}
|
|
n->data = (mpw*) malloc(size * sizeof(*n->data));
|
|
|
|
if (n->data != (mpw*) 0 && data != (mpw*) 0)
|
|
mpcopy(size, n->data, data);
|
|
}
|
|
|
|
void mpnfree(mpnumber* n)
|
|
{
|
|
if (n->data)
|
|
{
|
|
free(n->data);
|
|
n->data = (mpw*) 0;
|
|
}
|
|
n->size = 0;
|
|
}
|
|
|
|
void mpncopy(mpnumber* n, const mpnumber* copy)
|
|
{
|
|
mpnset(n, copy->size, copy->data);
|
|
}
|
|
|
|
void mpnwipe(mpnumber* n)
|
|
{
|
|
if (n->data)
|
|
mpzero(n->size, n->data);
|
|
}
|
|
|
|
void mpnset(mpnumber* n, size_t size, const mpw* data)
|
|
{
|
|
if (size)
|
|
{
|
|
if (n->data)
|
|
{
|
|
if (n->size != size)
|
|
n->data = (mpw*) realloc(n->data, size * sizeof(*n->data));
|
|
}
|
|
else
|
|
n->data = (mpw*) malloc(size * sizeof(*n->data));
|
|
|
|
if (n->data != (mpw*) 0 && data != (mpw*) 0)
|
|
{
|
|
n->size = size;
|
|
/*@-nullpass@*/ /* data is notnull */
|
|
mpcopy(n->size, n->data, data);
|
|
/*@=nullpass@*/
|
|
}
|
|
else
|
|
{
|
|
n->size = 0;
|
|
n->data = (mpw*) 0;
|
|
}
|
|
}
|
|
else if (n->data)
|
|
{
|
|
free(n->data);
|
|
n->data = (mpw*) 0;
|
|
n->size = 0;
|
|
}
|
|
}
|
|
|
|
void mpnsetw(mpnumber* n, mpw val)
|
|
{
|
|
if (n->data)
|
|
{
|
|
if (n->size != 1)
|
|
n->data = (mpw*) realloc(n->data, 1 * sizeof(*n->data));
|
|
}
|
|
else
|
|
n->data = (mpw*) malloc(1 * sizeof(*n->data));
|
|
|
|
if (n->data)
|
|
{
|
|
n->size = 1;
|
|
n->data[0] = val;
|
|
}
|
|
else
|
|
{
|
|
n->size = 0;
|
|
n->data = (mpw*) 0;
|
|
}
|
|
}
|
|
|
|
/*@-usedef @*/ /* n->data may be NULL */
|
|
void mpnsethex(mpnumber* n, const char* hex)
|
|
{
|
|
register size_t len = strlen(hex);
|
|
register size_t size = MP_NIBBLES_TO_WORDS(len + MP_WNIBBLES - 1);
|
|
|
|
if (n->data)
|
|
{
|
|
if (n->size != size)
|
|
n->data = (mpw*) realloc(n->data, size * sizeof(*n->data));
|
|
}
|
|
else
|
|
n->data = (mpw*) malloc(size * sizeof(*n->data));
|
|
|
|
if (n->data)
|
|
{
|
|
n->size = size;
|
|
|
|
(void) hs2ip(n->data, size, hex, len);
|
|
}
|
|
else {
|
|
n->size = 0;
|
|
n->data = (mpw*)0;
|
|
}
|
|
}
|
|
/*@=usedef @*/
|