implement fp_toradix_n()

It is not implemened yet, just added to the headerfile. Therefore I don't
think it is a ABI breakage if I change maxlen from int to unsigned int.

The function releases fp_toradix() for the work which in turn now calls
fp_toradix_n() with a largest possible maxlen parameter.

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
This commit is contained in:
Sebastian Andrzej Siewior 2015-01-28 19:11:36 +01:00 committed by Steffen Jaeckel
parent 8aba8446f2
commit f734a43b05
2 changed files with 65 additions and 21 deletions

View File

@ -1,59 +1,103 @@
/* TomsFastMath, a fast ISO C bignum library.
*
*
* This project is meant to fill in where LibTomMath
* falls short. That is speed ;-)
*
* This project is public domain and free for all purposes.
*
*
* Tom St Denis, tomstdenis@gmail.com
*/
#include <tfm.h>
int fp_toradix(fp_int *a, char *str, int radix)
/**
* a: pointer to fp_int representing the input number
* str: output buffer
* radix: number of character to use for encoding of the number
* maxlen: maximum number of the buffer that can be used
*
* The radix value can be in the range 2 to 64. This function converts number
* a into a string str. This function writes at most size bytes (including the
* terminating null byte to str. It behaves like snprintf(3) in regard to this.
*
* Return: If invalid parameter are detected a negative value is returned. On
* success the function returns the number of bytes that would be written if
* the function had enough space. Thus a return value of maxlen or more means
* that the function was not able store all characters and the output is
* incomplete.
*/
int fp_toradix_n(fp_int *a, char *str, int radix, unsigned int maxlen)
{
int digs;
fp_int t;
fp_digit d;
char *_s = str;
unsigned int wrote;
/* check range of the radix */
if (radix < 2 || radix > 64) {
return FP_VAL;
if (radix < 2 || radix > 64)
return -1;
/* quick check for zero */
if (fp_iszero(a) == 1) {
if (maxlen >= 2)
*str++ = '0';
if (maxlen >= 1)
*str = '\0';
return 1;
}
/* quick out if its zero */
if (fp_iszero(a) == 1) {
*str++ = '0';
*str = '\0';
return FP_OKAY;
}
wrote = 0;
fp_init_copy(&t, a);
/* if it is negative output a - */
if (t.sign == FP_NEG) {
++_s;
*str++ = '-';
wrote++;
if (wrote < maxlen)
*str++ = '-';
t.sign = FP_ZPOS;
}
digs = 0;
while (fp_iszero (&t) == FP_NO) {
fp_div_d (&t, (fp_digit) radix, &t, &d);
*str++ = fp_s_rmap[d];
wrote++;
if (wrote < maxlen)
*str++ = fp_s_rmap[d];
++digs;
}
/* reverse the digits of the string. In this case _s points
* to the first digit [exluding the sign] of the number]
*/
fp_reverse ((unsigned char *)_s, digs);
if (wrote < maxlen)
fp_reverse ((unsigned char *)_s, digs);
/* append a NULL so the string is properly terminated */
*str = '\0';
return FP_OKAY;
/* append a NULL so the string is properly terminated */
if (maxlen >= 1)
*str = '\0';
return wrote;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
/**
* a: pointer to fp_int representing the input number
* str: output buffer
* radix: number of character to use for encoding of the number
*
* The radix value can be in the range 2 to 64. This function converts number
* a into a string str. Please don't use this function because a too small
* chosen str buffer would lead to an overflow which can not be detected.
* Please use fp_toradix_n() instead.
*
* Return: FP_VAL on error, FP_OKAY on success.
*/
int fp_toradix(fp_int *a, char *str, int radix)
{
int ret;
ret = fp_toradix_n(a, str, radix, UINT_MAX);
if (ret < 0)
return FP_VAL;
return FP_OKAY;
}

View File

@ -465,7 +465,7 @@ int fp_read_radix(fp_int *a, char *str, int radix);
int fp_radix_size(fp_int *a, int radix, int *size);
int fp_toradix(fp_int *a, char *str, int radix);
int fp_toradix_n(fp_int * a, char *str, int radix, int maxlen);
int fp_toradix_n(fp_int * a, char *str, int radix, unsigned int maxlen);
/* VARIOUS LOW LEVEL STUFFS */