From f734a43b0539bc7d955c40b328a7183e8f19b8ae Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 28 Jan 2015 19:11:36 +0100 Subject: [PATCH] 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 --- src/bin/fp_toradix.c | 84 +++++++++++++++++++++++++++++++++----------- src/headers/tfm.h | 2 +- 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/bin/fp_toradix.c b/src/bin/fp_toradix.c index 6ca2e0d..fb623c5 100644 --- a/src/bin/fp_toradix.c +++ b/src/bin/fp_toradix.c @@ -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 -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; +} diff --git a/src/headers/tfm.h b/src/headers/tfm.h index ac6c9e6..1019b6a 100644 --- a/src/headers/tfm.h +++ b/src/headers/tfm.h @@ -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 */