Blame


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 "dat.h"
4 b3f61791 2004-03-21 devnull
5 b3f61791 2004-03-21 devnull static int
6 b3f61791 2004-03-21 devnull to64(mpint *b, char *buf, int len)
7 b3f61791 2004-03-21 devnull {
8 b3f61791 2004-03-21 devnull uchar *p;
9 b3f61791 2004-03-21 devnull int n, rv;
10 b3f61791 2004-03-21 devnull
11 b3f61791 2004-03-21 devnull p = nil;
12 b3f61791 2004-03-21 devnull n = mptobe(b, nil, 0, &p);
13 b3f61791 2004-03-21 devnull if(n < 0)
14 b3f61791 2004-03-21 devnull return -1;
15 b3f61791 2004-03-21 devnull rv = enc64(buf, len, p, n);
16 b3f61791 2004-03-21 devnull free(p);
17 b3f61791 2004-03-21 devnull return rv;
18 b3f61791 2004-03-21 devnull }
19 b3f61791 2004-03-21 devnull
20 b3f61791 2004-03-21 devnull static int
21 b3f61791 2004-03-21 devnull to32(mpint *b, char *buf, int len)
22 b3f61791 2004-03-21 devnull {
23 b3f61791 2004-03-21 devnull uchar *p;
24 b3f61791 2004-03-21 devnull int n, rv;
25 b3f61791 2004-03-21 devnull
26 b3f61791 2004-03-21 devnull // leave room for a multiple of 5 buffer size
27 b3f61791 2004-03-21 devnull n = b->top*Dbytes + 5;
28 b3f61791 2004-03-21 devnull p = malloc(n);
29 b3f61791 2004-03-21 devnull if(p == nil)
30 b3f61791 2004-03-21 devnull return -1;
31 b3f61791 2004-03-21 devnull n = mptobe(b, p, n, nil);
32 b3f61791 2004-03-21 devnull if(n < 0)
33 b3f61791 2004-03-21 devnull return -1;
34 b3f61791 2004-03-21 devnull
35 b3f61791 2004-03-21 devnull // round up buffer size, enc32 only accepts a multiple of 5
36 b3f61791 2004-03-21 devnull if(n%5)
37 b3f61791 2004-03-21 devnull n += 5 - (n%5);
38 b3f61791 2004-03-21 devnull rv = enc32(buf, len, p, n);
39 b3f61791 2004-03-21 devnull free(p);
40 b3f61791 2004-03-21 devnull return rv;
41 b3f61791 2004-03-21 devnull }
42 b3f61791 2004-03-21 devnull
43 b3f61791 2004-03-21 devnull static char set16[] = "0123456789ABCDEF";
44 b3f61791 2004-03-21 devnull
45 b3f61791 2004-03-21 devnull static int
46 b3f61791 2004-03-21 devnull to16(mpint *b, char *buf, int len)
47 b3f61791 2004-03-21 devnull {
48 b3f61791 2004-03-21 devnull mpdigit *p, x;
49 b3f61791 2004-03-21 devnull int i, j;
50 b3f61791 2004-03-21 devnull char *out, *eout;
51 b3f61791 2004-03-21 devnull
52 b3f61791 2004-03-21 devnull if(len < 1)
53 b3f61791 2004-03-21 devnull return -1;
54 b3f61791 2004-03-21 devnull
55 b3f61791 2004-03-21 devnull out = buf;
56 b3f61791 2004-03-21 devnull eout = buf+len;
57 b3f61791 2004-03-21 devnull for(p = &b->p[b->top-1]; p >= b->p; p--){
58 b3f61791 2004-03-21 devnull x = *p;
59 b3f61791 2004-03-21 devnull for(i = Dbits-4; i >= 0; i -= 4){
60 b3f61791 2004-03-21 devnull j = 0xf & (x>>i);
61 b3f61791 2004-03-21 devnull if(j != 0 || out != buf){
62 b3f61791 2004-03-21 devnull if(out >= eout)
63 b3f61791 2004-03-21 devnull return -1;
64 b3f61791 2004-03-21 devnull *out++ = set16[j];
65 b3f61791 2004-03-21 devnull }
66 b3f61791 2004-03-21 devnull }
67 b3f61791 2004-03-21 devnull }
68 b3f61791 2004-03-21 devnull if(out == buf)
69 b3f61791 2004-03-21 devnull *out++ = '0';
70 b3f61791 2004-03-21 devnull if(out >= eout)
71 b3f61791 2004-03-21 devnull return -1;
72 b3f61791 2004-03-21 devnull *out = 0;
73 b3f61791 2004-03-21 devnull return 0;
74 b3f61791 2004-03-21 devnull }
75 b3f61791 2004-03-21 devnull
76 b3f61791 2004-03-21 devnull static char*
77 b3f61791 2004-03-21 devnull modbillion(int rem, ulong r, char *out, char *buf)
78 b3f61791 2004-03-21 devnull {
79 b3f61791 2004-03-21 devnull ulong rr;
80 b3f61791 2004-03-21 devnull int i;
81 b3f61791 2004-03-21 devnull
82 b3f61791 2004-03-21 devnull for(i = 0; i < 9; i++){
83 b3f61791 2004-03-21 devnull rr = r%10;
84 b3f61791 2004-03-21 devnull r /= 10;
85 b3f61791 2004-03-21 devnull if(out <= buf)
86 b3f61791 2004-03-21 devnull return nil;
87 b3f61791 2004-03-21 devnull *--out = '0' + rr;
88 b3f61791 2004-03-21 devnull if(rem == 0 && r == 0)
89 b3f61791 2004-03-21 devnull break;
90 b3f61791 2004-03-21 devnull }
91 b3f61791 2004-03-21 devnull return out;
92 b3f61791 2004-03-21 devnull }
93 b3f61791 2004-03-21 devnull
94 b3f61791 2004-03-21 devnull static int
95 b3f61791 2004-03-21 devnull to10(mpint *b, char *buf, int len)
96 b3f61791 2004-03-21 devnull {
97 b3f61791 2004-03-21 devnull mpint *d, *r, *billion;
98 b3f61791 2004-03-21 devnull char *out;
99 b3f61791 2004-03-21 devnull
100 b3f61791 2004-03-21 devnull if(len < 1)
101 b3f61791 2004-03-21 devnull return -1;
102 b3f61791 2004-03-21 devnull
103 b3f61791 2004-03-21 devnull d = mpcopy(b);
104 b3f61791 2004-03-21 devnull r = mpnew(0);
105 b3f61791 2004-03-21 devnull billion = uitomp(1000000000, nil);
106 b3f61791 2004-03-21 devnull out = buf+len;
107 b3f61791 2004-03-21 devnull *--out = 0;
108 b3f61791 2004-03-21 devnull do {
109 b3f61791 2004-03-21 devnull mpdiv(d, billion, d, r);
110 b3f61791 2004-03-21 devnull out = modbillion(d->top, r->p[0], out, buf);
111 b3f61791 2004-03-21 devnull if(out == nil)
112 b3f61791 2004-03-21 devnull break;
113 b3f61791 2004-03-21 devnull } while(d->top != 0);
114 b3f61791 2004-03-21 devnull mpfree(d);
115 b3f61791 2004-03-21 devnull mpfree(r);
116 b3f61791 2004-03-21 devnull mpfree(billion);
117 b3f61791 2004-03-21 devnull
118 b3f61791 2004-03-21 devnull if(out == nil)
119 b3f61791 2004-03-21 devnull return -1;
120 b3f61791 2004-03-21 devnull len -= out-buf;
121 b3f61791 2004-03-21 devnull if(out != buf)
122 b3f61791 2004-03-21 devnull memmove(buf, out, len);
123 b3f61791 2004-03-21 devnull return 0;
124 b3f61791 2004-03-21 devnull }
125 b3f61791 2004-03-21 devnull
126 b3f61791 2004-03-21 devnull int
127 b3f61791 2004-03-21 devnull mpfmt(Fmt *fmt)
128 b3f61791 2004-03-21 devnull {
129 b3f61791 2004-03-21 devnull mpint *b;
130 b3f61791 2004-03-21 devnull char *p;
131 b3f61791 2004-03-21 devnull
132 b3f61791 2004-03-21 devnull b = va_arg(fmt->args, mpint*);
133 b3f61791 2004-03-21 devnull if(b == nil)
134 b3f61791 2004-03-21 devnull return fmtstrcpy(fmt, "*");
135 b3f61791 2004-03-21 devnull
136 b3f61791 2004-03-21 devnull p = mptoa(b, fmt->prec, nil, 0);
137 b3f61791 2004-03-21 devnull fmt->flags &= ~FmtPrec;
138 b3f61791 2004-03-21 devnull
139 b3f61791 2004-03-21 devnull if(p == nil)
140 b3f61791 2004-03-21 devnull return fmtstrcpy(fmt, "*");
141 b3f61791 2004-03-21 devnull else{
142 b3f61791 2004-03-21 devnull fmtstrcpy(fmt, p);
143 b3f61791 2004-03-21 devnull free(p);
144 b3f61791 2004-03-21 devnull return 0;
145 b3f61791 2004-03-21 devnull }
146 b3f61791 2004-03-21 devnull }
147 b3f61791 2004-03-21 devnull
148 b3f61791 2004-03-21 devnull char*
149 b3f61791 2004-03-21 devnull mptoa(mpint *b, int base, char *buf, int len)
150 b3f61791 2004-03-21 devnull {
151 b3f61791 2004-03-21 devnull char *out;
152 b3f61791 2004-03-21 devnull int rv, alloced;
153 b3f61791 2004-03-21 devnull
154 b3f61791 2004-03-21 devnull alloced = 0;
155 b3f61791 2004-03-21 devnull if(buf == nil){
156 b3f61791 2004-03-21 devnull len = ((b->top+1)*Dbits+2)/3 + 1;
157 b3f61791 2004-03-21 devnull buf = malloc(len);
158 b3f61791 2004-03-21 devnull if(buf == nil)
159 b3f61791 2004-03-21 devnull return nil;
160 b3f61791 2004-03-21 devnull alloced = 1;
161 b3f61791 2004-03-21 devnull }
162 b3f61791 2004-03-21 devnull
163 b3f61791 2004-03-21 devnull if(len < 2)
164 b3f61791 2004-03-21 devnull return nil;
165 b3f61791 2004-03-21 devnull
166 b3f61791 2004-03-21 devnull out = buf;
167 b3f61791 2004-03-21 devnull if(b->sign < 0){
168 b3f61791 2004-03-21 devnull *out++ = '-';
169 b3f61791 2004-03-21 devnull len--;
170 b3f61791 2004-03-21 devnull }
171 b3f61791 2004-03-21 devnull switch(base){
172 b3f61791 2004-03-21 devnull case 64:
173 b3f61791 2004-03-21 devnull rv = to64(b, out, len);
174 b3f61791 2004-03-21 devnull break;
175 b3f61791 2004-03-21 devnull case 32:
176 b3f61791 2004-03-21 devnull rv = to32(b, out, len);
177 b3f61791 2004-03-21 devnull break;
178 b3f61791 2004-03-21 devnull default:
179 b3f61791 2004-03-21 devnull case 16:
180 b3f61791 2004-03-21 devnull rv = to16(b, out, len);
181 b3f61791 2004-03-21 devnull break;
182 b3f61791 2004-03-21 devnull case 10:
183 b3f61791 2004-03-21 devnull rv = to10(b, out, len);
184 b3f61791 2004-03-21 devnull break;
185 b3f61791 2004-03-21 devnull }
186 b3f61791 2004-03-21 devnull if(rv < 0){
187 b3f61791 2004-03-21 devnull if(alloced)
188 b3f61791 2004-03-21 devnull free(buf);
189 b3f61791 2004-03-21 devnull return nil;
190 b3f61791 2004-03-21 devnull }
191 b3f61791 2004-03-21 devnull return buf;
192 b3f61791 2004-03-21 devnull }