out_str.c revision 1.1.1.1
1/* mpz_out_str(stream, base, integer) -- Output to STREAM the multi prec. 2 integer INTEGER in base BASE. 3 4Copyright 1991, 1993, 1994, 1996, 2001, 2005 Free Software Foundation, Inc. 5 6This file is part of the GNU MP Library. 7 8The GNU MP Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MP Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ 20 21#include <stdio.h> 22#include "gmp.h" 23#include "gmp-impl.h" 24 25size_t 26mpz_out_str (FILE *stream, int base, mpz_srcptr x) 27{ 28 mp_ptr xp; 29 mp_size_t x_size = x->_mp_size; 30 unsigned char *str; 31 size_t str_size; 32 size_t i; 33 size_t written; 34 char *num_to_text; 35 TMP_DECL; 36 37 if (stream == 0) 38 stream = stdout; 39 40 if (base >= 0) 41 { 42 num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz"; 43 if (base == 0) 44 base = 10; 45 else if (base > 36) 46 { 47 num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 48 if (base > 62) 49 return 0; 50 } 51 } 52 else 53 { 54 base = -base; 55 num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 56 } 57 58 if (x_size == 0) 59 { 60 fputc ('0', stream); 61 return ferror (stream) ? 0 : 1; 62 } 63 64 written = 0; 65 66 if (x_size < 0) 67 { 68 fputc ('-', stream); 69 x_size = -x_size; 70 written = 1; 71 } 72 73 TMP_MARK; 74 str_size = ((size_t) (x_size * GMP_LIMB_BITS 75 * mp_bases[base].chars_per_bit_exactly)) + 3; 76 str = (unsigned char *) TMP_ALLOC (str_size); 77 78 /* Move the number to convert into temporary space, since mpn_get_str 79 clobbers its argument + needs one extra high limb.... */ 80 xp = TMP_ALLOC_LIMBS (x_size + 1); 81 MPN_COPY (xp, x->_mp_d, x_size); 82 83 str_size = mpn_get_str (str, base, xp, x_size); 84 85 /* mpn_get_str might make some leading zeros. Skip them. */ 86 while (*str == 0) 87 { 88 str_size--; 89 str++; 90 } 91 92 /* Translate to printable chars. */ 93 for (i = 0; i < str_size; i++) 94 str[i] = num_to_text[str[i]]; 95 str[str_size] = 0; 96 97 { 98 size_t fwret; 99 fwret = fwrite ((char *) str, 1, str_size, stream); 100 written += fwret; 101 } 102 103 TMP_FREE; 104 return ferror (stream) ? 0 : written; 105} 106