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

@ -9,51 +9,95 @@
*/ */
#include <tfm.h> #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; int digs;
fp_int t; fp_int t;
fp_digit d; fp_digit d;
char *_s = str; char *_s = str;
unsigned int wrote;
/* check range of the radix */ /* check range of the radix */
if (radix < 2 || radix > 64) { if (radix < 2 || radix > 64)
return FP_VAL; 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 */ wrote = 0;
if (fp_iszero(a) == 1) {
*str++ = '0';
*str = '\0';
return FP_OKAY;
}
fp_init_copy(&t, a); fp_init_copy(&t, a);
/* if it is negative output a - */ /* if it is negative output a - */
if (t.sign == FP_NEG) { if (t.sign == FP_NEG) {
++_s; ++_s;
*str++ = '-'; wrote++;
if (wrote < maxlen)
*str++ = '-';
t.sign = FP_ZPOS; t.sign = FP_ZPOS;
} }
digs = 0; digs = 0;
while (fp_iszero (&t) == FP_NO) { while (fp_iszero (&t) == FP_NO) {
fp_div_d (&t, (fp_digit) radix, &t, &d); fp_div_d (&t, (fp_digit) radix, &t, &d);
*str++ = fp_s_rmap[d]; wrote++;
if (wrote < maxlen)
*str++ = fp_s_rmap[d];
++digs; ++digs;
} }
/* reverse the digits of the string. In this case _s points /* reverse the digits of the string. In this case _s points
* to the first digit [exluding the sign] of the number] * 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 */ /* append a NULL so the string is properly terminated */
*str = '\0'; if (maxlen >= 1)
return FP_OKAY; *str = '\0';
return wrote;
} }
/* $Source$ */ /**
/* $Revision$ */ * a: pointer to fp_int representing the input number
/* $Date$ */ * 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_radix_size(fp_int *a, int radix, int *size);
int fp_toradix(fp_int *a, char *str, int radix); 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 */ /* VARIOUS LOW LEVEL STUFFS */