/* stores a bignum as a ASCII string in a base 10 */
static mp_digit my_divide_by = 1;
static int digits_at_a_time = 0;
static const char s_10map[] = "0123456789";
static void init_mp_tobase10(void) {
if( digits_at_a_time ) return;
while(1) {
mp_digit test = my_divide_by * 10;
if( test >= MP_DIGIT_MAX ) break;
if( test < my_divide_by ) break; /* test for overflow, too */
++digits_at_a_time;
my_divide_by = test;
}
}
int
mp_tobase10 (mp_int * a, char *str)
{
int res, digit, digs;
mp_int t;
mp_digit d, prev;
char *_s = str;
/* quick out if its zero */
if (mp_iszero(a) == 1) {
*str++ = '0';
*str = '\0';
return MP_OKAY;
}
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
return res;
}
if (t.sign == MP_NEG) {
++_s;
*str++ = '-';
t.sign = MP_ZPOS;
}
init_mp_tobase10();
digs = 0;
if ((res = mp_div_d (&t, my_divide_by, &t, &prev)) != MP_OKAY) {
mp_clear (&t);
return res;
}
while (mp_iszero (&t) == 0) {
if ((res = mp_div_d (&t, my_divide_by, &t, &d)) != MP_OKAY) {
mp_clear (&t);
return res;
}
for( digit = digits_at_a_time-1; digit > 0; --digit ) {
*(str++) = s_10map[ prev % 10 ];
prev = prev / 10;
}
*(str++) = s_10map[ prev ];
prev = d;
digs += digits_at_a_time;
}
while( prev != 0 ) {
*(str++) = s_10map[ prev % 10 ];
prev = prev / 10;
digs++;
}
bn_reverse ((unsigned char *)_s, digs);
mp_clear (&t);
return MP_OKAY;
}