1 b3f61791 2004-03-21 devnull #include "os.h"
2 b3f61791 2004-03-21 devnull #include <mp.h>
3 b3f61791 2004-03-21 devnull #include <libsec.h>
4 b3f61791 2004-03-21 devnull #include "dat.h"
6 b3f61791 2004-03-21 devnull static int
7 b3f61791 2004-03-21 devnull to64(mpint *b, char *buf, int len)
10 b3f61791 2004-03-21 devnull int n, rv;
13 b3f61791 2004-03-21 devnull n = mptobe(b, nil, 0, &p);
14 b3f61791 2004-03-21 devnull if(n < 0)
15 b3f61791 2004-03-21 devnull return -1;
16 b3f61791 2004-03-21 devnull rv = enc64(buf, len, p, n);
18 b3f61791 2004-03-21 devnull return rv;
21 b3f61791 2004-03-21 devnull static int
22 b3f61791 2004-03-21 devnull to32(mpint *b, char *buf, int len)
24 b3f61791 2004-03-21 devnull uchar *p;
25 b3f61791 2004-03-21 devnull int n, rv;
27 b3f61791 2004-03-21 devnull // leave room for a multiple of 5 buffer size
28 b3f61791 2004-03-21 devnull n = b->top*Dbytes + 5;
29 b3f61791 2004-03-21 devnull p = malloc(n);
30 b3f61791 2004-03-21 devnull if(p == nil)
31 b3f61791 2004-03-21 devnull return -1;
32 b3f61791 2004-03-21 devnull n = mptobe(b, p, n, nil);
33 b3f61791 2004-03-21 devnull if(n < 0)
34 b3f61791 2004-03-21 devnull return -1;
36 b3f61791 2004-03-21 devnull // round up buffer size, enc32 only accepts a multiple of 5
38 b3f61791 2004-03-21 devnull n += 5 - (n%5);
39 b3f61791 2004-03-21 devnull rv = enc32(buf, len, p, n);
41 b3f61791 2004-03-21 devnull return rv;
44 b3f61791 2004-03-21 devnull static char set16[] = "0123456789ABCDEF";
46 b3f61791 2004-03-21 devnull static int
47 b3f61791 2004-03-21 devnull to16(mpint *b, char *buf, int len)
49 b3f61791 2004-03-21 devnull mpdigit *p, x;
50 b3f61791 2004-03-21 devnull int i, j;
51 b3f61791 2004-03-21 devnull char *out, *eout;
53 b3f61791 2004-03-21 devnull if(len < 1)
54 b3f61791 2004-03-21 devnull return -1;
56 b3f61791 2004-03-21 devnull out = buf;
57 b3f61791 2004-03-21 devnull eout = buf+len;
58 b3f61791 2004-03-21 devnull for(p = &b->p[b->top-1]; p >= b->p; p--){
60 b3f61791 2004-03-21 devnull for(i = Dbits-4; i >= 0; i -= 4){
61 b3f61791 2004-03-21 devnull j = 0xf & (x>>i);
62 b3f61791 2004-03-21 devnull if(j != 0 || out != buf){
63 b3f61791 2004-03-21 devnull if(out >= eout)
64 b3f61791 2004-03-21 devnull return -1;
65 b3f61791 2004-03-21 devnull *out++ = set16[j];
69 b3f61791 2004-03-21 devnull if(out == buf)
70 b3f61791 2004-03-21 devnull *out++ = '0';
71 b3f61791 2004-03-21 devnull if(out >= eout)
72 b3f61791 2004-03-21 devnull return -1;
73 b3f61791 2004-03-21 devnull *out = 0;
74 b3f61791 2004-03-21 devnull return 0;
77 b3f61791 2004-03-21 devnull static char*
78 b3f61791 2004-03-21 devnull modbillion(int rem, ulong r, char *out, char *buf)
80 b3f61791 2004-03-21 devnull ulong rr;
83 b3f61791 2004-03-21 devnull for(i = 0; i < 9; i++){
84 b3f61791 2004-03-21 devnull rr = r%10;
86 b3f61791 2004-03-21 devnull if(out <= buf)
87 b3f61791 2004-03-21 devnull return nil;
88 b3f61791 2004-03-21 devnull *--out = '0' + rr;
89 b3f61791 2004-03-21 devnull if(rem == 0 && r == 0)
92 b3f61791 2004-03-21 devnull return out;
95 b3f61791 2004-03-21 devnull static int
96 b3f61791 2004-03-21 devnull to10(mpint *b, char *buf, int len)
98 b3f61791 2004-03-21 devnull mpint *d, *r, *billion;
99 b3f61791 2004-03-21 devnull char *out;
101 b3f61791 2004-03-21 devnull if(len < 1)
102 b3f61791 2004-03-21 devnull return -1;
104 b3f61791 2004-03-21 devnull d = mpcopy(b);
105 b3f61791 2004-03-21 devnull r = mpnew(0);
106 b3f61791 2004-03-21 devnull billion = uitomp(1000000000, nil);
107 b3f61791 2004-03-21 devnull out = buf+len;
108 b3f61791 2004-03-21 devnull *--out = 0;
110 b3f61791 2004-03-21 devnull mpdiv(d, billion, d, r);
111 b3f61791 2004-03-21 devnull out = modbillion(d->top, r->p[0], out, buf);
112 b3f61791 2004-03-21 devnull if(out == nil)
114 b3f61791 2004-03-21 devnull } while(d->top != 0);
115 b3f61791 2004-03-21 devnull mpfree(d);
116 b3f61791 2004-03-21 devnull mpfree(r);
117 b3f61791 2004-03-21 devnull mpfree(billion);
119 b3f61791 2004-03-21 devnull if(out == nil)
120 b3f61791 2004-03-21 devnull return -1;
121 b3f61791 2004-03-21 devnull len -= out-buf;
122 b3f61791 2004-03-21 devnull if(out != buf)
123 b3f61791 2004-03-21 devnull memmove(buf, out, len);
124 b3f61791 2004-03-21 devnull return 0;
128 b3f61791 2004-03-21 devnull mpfmt(Fmt *fmt)
130 b3f61791 2004-03-21 devnull mpint *b;
131 b3f61791 2004-03-21 devnull char *p;
133 b3f61791 2004-03-21 devnull b = va_arg(fmt->args, mpint*);
134 b3f61791 2004-03-21 devnull if(b == nil)
135 b3f61791 2004-03-21 devnull return fmtstrcpy(fmt, "*");
137 b3f61791 2004-03-21 devnull p = mptoa(b, fmt->prec, nil, 0);
138 b3f61791 2004-03-21 devnull fmt->flags &= ~FmtPrec;
140 b3f61791 2004-03-21 devnull if(p == nil)
141 b3f61791 2004-03-21 devnull return fmtstrcpy(fmt, "*");
143 b3f61791 2004-03-21 devnull fmtstrcpy(fmt, p);
144 b3f61791 2004-03-21 devnull free(p);
145 b3f61791 2004-03-21 devnull return 0;
150 b3f61791 2004-03-21 devnull mptoa(mpint *b, int base, char *buf, int len)
152 b3f61791 2004-03-21 devnull char *out;
153 b3f61791 2004-03-21 devnull int rv, alloced;
155 b3f61791 2004-03-21 devnull alloced = 0;
156 b3f61791 2004-03-21 devnull if(buf == nil){
157 b3f61791 2004-03-21 devnull len = ((b->top+1)*Dbits+2)/3 + 1;
158 b3f61791 2004-03-21 devnull buf = malloc(len);
159 b3f61791 2004-03-21 devnull if(buf == nil)
160 b3f61791 2004-03-21 devnull return nil;
161 b3f61791 2004-03-21 devnull alloced = 1;
164 b3f61791 2004-03-21 devnull if(len < 2)
165 b3f61791 2004-03-21 devnull return nil;
167 b3f61791 2004-03-21 devnull out = buf;
168 b3f61791 2004-03-21 devnull if(b->sign < 0){
169 b3f61791 2004-03-21 devnull *out++ = '-';
172 b3f61791 2004-03-21 devnull switch(base){
173 b3f61791 2004-03-21 devnull case 64:
174 b3f61791 2004-03-21 devnull rv = to64(b, out, len);
176 b3f61791 2004-03-21 devnull case 32:
177 b3f61791 2004-03-21 devnull rv = to32(b, out, len);
179 b3f61791 2004-03-21 devnull default:
180 b3f61791 2004-03-21 devnull case 16:
181 b3f61791 2004-03-21 devnull rv = to16(b, out, len);
183 b3f61791 2004-03-21 devnull case 10:
184 b3f61791 2004-03-21 devnull rv = to10(b, out, len);
187 b3f61791 2004-03-21 devnull if(rv < 0){
188 b3f61791 2004-03-21 devnull if(alloced)
189 b3f61791 2004-03-21 devnull free(buf);
190 b3f61791 2004-03-21 devnull return nil;
192 b3f61791 2004-03-21 devnull return buf;