1*8ccd4a63SDavid du Colombier #include "os.h"
2*8ccd4a63SDavid du Colombier #include <mp.h>
3*8ccd4a63SDavid du Colombier #include <libsec.h>
4*8ccd4a63SDavid du Colombier #include "dat.h"
5*8ccd4a63SDavid du Colombier
6*8ccd4a63SDavid du Colombier static struct {
7*8ccd4a63SDavid du Colombier int inited;
8*8ccd4a63SDavid du Colombier
9*8ccd4a63SDavid du Colombier uchar t64[256];
10*8ccd4a63SDavid du Colombier uchar t32[256];
11*8ccd4a63SDavid du Colombier uchar t16[256];
12*8ccd4a63SDavid du Colombier uchar t10[256];
13*8ccd4a63SDavid du Colombier } tab;
14*8ccd4a63SDavid du Colombier
15*8ccd4a63SDavid du Colombier enum {
16*8ccd4a63SDavid du Colombier INVAL= 255
17*8ccd4a63SDavid du Colombier };
18*8ccd4a63SDavid du Colombier
19*8ccd4a63SDavid du Colombier static char set64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
20*8ccd4a63SDavid du Colombier static char set32[] = "23456789abcdefghijkmnpqrstuvwxyz";
21*8ccd4a63SDavid du Colombier static char set16[] = "0123456789ABCDEF0123456789abcdef";
22*8ccd4a63SDavid du Colombier static char set10[] = "0123456789";
23*8ccd4a63SDavid du Colombier
24*8ccd4a63SDavid du Colombier static void
init(void)25*8ccd4a63SDavid du Colombier init(void)
26*8ccd4a63SDavid du Colombier {
27*8ccd4a63SDavid du Colombier char *p;
28*8ccd4a63SDavid du Colombier
29*8ccd4a63SDavid du Colombier memset(tab.t64, INVAL, sizeof(tab.t64));
30*8ccd4a63SDavid du Colombier memset(tab.t32, INVAL, sizeof(tab.t32));
31*8ccd4a63SDavid du Colombier memset(tab.t16, INVAL, sizeof(tab.t16));
32*8ccd4a63SDavid du Colombier memset(tab.t10, INVAL, sizeof(tab.t10));
33*8ccd4a63SDavid du Colombier
34*8ccd4a63SDavid du Colombier for(p = set64; *p; p++)
35*8ccd4a63SDavid du Colombier tab.t64[(uchar)*p] = p-set64;
36*8ccd4a63SDavid du Colombier for(p = set32; *p; p++)
37*8ccd4a63SDavid du Colombier tab.t32[(uchar)*p] = p-set32;
38*8ccd4a63SDavid du Colombier for(p = set16; *p; p++)
39*8ccd4a63SDavid du Colombier tab.t16[(uchar)*p] = (p-set16)%16;
40*8ccd4a63SDavid du Colombier for(p = set10; *p; p++)
41*8ccd4a63SDavid du Colombier tab.t10[(uchar)*p] = (p-set10);
42*8ccd4a63SDavid du Colombier
43*8ccd4a63SDavid du Colombier tab.inited = 1;
44*8ccd4a63SDavid du Colombier }
45*8ccd4a63SDavid du Colombier
46*8ccd4a63SDavid du Colombier static char*
from16(char * a,mpint * b)47*8ccd4a63SDavid du Colombier from16(char *a, mpint *b)
48*8ccd4a63SDavid du Colombier {
49*8ccd4a63SDavid du Colombier char *p, *next;
50*8ccd4a63SDavid du Colombier int i;
51*8ccd4a63SDavid du Colombier mpdigit x;
52*8ccd4a63SDavid du Colombier
53*8ccd4a63SDavid du Colombier b->top = 0;
54*8ccd4a63SDavid du Colombier for(p = a; *p; p++)
55*8ccd4a63SDavid du Colombier if(tab.t16[(uchar)*p] == INVAL)
56*8ccd4a63SDavid du Colombier break;
57*8ccd4a63SDavid du Colombier mpbits(b, (p-a)*4);
58*8ccd4a63SDavid du Colombier b->top = 0;
59*8ccd4a63SDavid du Colombier next = p;
60*8ccd4a63SDavid du Colombier while(p > a){
61*8ccd4a63SDavid du Colombier x = 0;
62*8ccd4a63SDavid du Colombier for(i = 0; i < Dbits; i += 4){
63*8ccd4a63SDavid du Colombier if(p <= a)
64*8ccd4a63SDavid du Colombier break;
65*8ccd4a63SDavid du Colombier x |= tab.t16[(uchar)*--p]<<i;
66*8ccd4a63SDavid du Colombier }
67*8ccd4a63SDavid du Colombier b->p[b->top++] = x;
68*8ccd4a63SDavid du Colombier }
69*8ccd4a63SDavid du Colombier return next;
70*8ccd4a63SDavid du Colombier }
71*8ccd4a63SDavid du Colombier
72*8ccd4a63SDavid du Colombier static ulong mppow10[] = {
73*8ccd4a63SDavid du Colombier 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
74*8ccd4a63SDavid du Colombier };
75*8ccd4a63SDavid du Colombier
76*8ccd4a63SDavid du Colombier static char*
from10(char * a,mpint * b)77*8ccd4a63SDavid du Colombier from10(char *a, mpint *b)
78*8ccd4a63SDavid du Colombier {
79*8ccd4a63SDavid du Colombier ulong x, y;
80*8ccd4a63SDavid du Colombier mpint *pow, *r;
81*8ccd4a63SDavid du Colombier int i;
82*8ccd4a63SDavid du Colombier
83*8ccd4a63SDavid du Colombier pow = mpnew(0);
84*8ccd4a63SDavid du Colombier r = mpnew(0);
85*8ccd4a63SDavid du Colombier
86*8ccd4a63SDavid du Colombier b->top = 0;
87*8ccd4a63SDavid du Colombier for(;;){
88*8ccd4a63SDavid du Colombier // do a billion at a time in native arithmetic
89*8ccd4a63SDavid du Colombier x = 0;
90*8ccd4a63SDavid du Colombier for(i = 0; i < 9; i++){
91*8ccd4a63SDavid du Colombier y = tab.t10[(uchar)*a];
92*8ccd4a63SDavid du Colombier if(y == INVAL)
93*8ccd4a63SDavid du Colombier break;
94*8ccd4a63SDavid du Colombier a++;
95*8ccd4a63SDavid du Colombier x *= 10;
96*8ccd4a63SDavid du Colombier x += y;
97*8ccd4a63SDavid du Colombier }
98*8ccd4a63SDavid du Colombier if(i == 0)
99*8ccd4a63SDavid du Colombier break;
100*8ccd4a63SDavid du Colombier
101*8ccd4a63SDavid du Colombier // accumulate into mpint
102*8ccd4a63SDavid du Colombier uitomp(mppow10[i], pow);
103*8ccd4a63SDavid du Colombier uitomp(x, r);
104*8ccd4a63SDavid du Colombier mpmul(b, pow, b);
105*8ccd4a63SDavid du Colombier mpadd(b, r, b);
106*8ccd4a63SDavid du Colombier if(i != 9)
107*8ccd4a63SDavid du Colombier break;
108*8ccd4a63SDavid du Colombier }
109*8ccd4a63SDavid du Colombier mpfree(pow);
110*8ccd4a63SDavid du Colombier mpfree(r);
111*8ccd4a63SDavid du Colombier return a;
112*8ccd4a63SDavid du Colombier }
113*8ccd4a63SDavid du Colombier
114*8ccd4a63SDavid du Colombier static char*
from64(char * a,mpint * b)115*8ccd4a63SDavid du Colombier from64(char *a, mpint *b)
116*8ccd4a63SDavid du Colombier {
117*8ccd4a63SDavid du Colombier char *buf = a;
118*8ccd4a63SDavid du Colombier uchar *p;
119*8ccd4a63SDavid du Colombier int n, m;
120*8ccd4a63SDavid du Colombier
121*8ccd4a63SDavid du Colombier for(; tab.t64[(uchar)*a] != INVAL; a++)
122*8ccd4a63SDavid du Colombier ;
123*8ccd4a63SDavid du Colombier n = a-buf;
124*8ccd4a63SDavid du Colombier mpbits(b, n*6);
125*8ccd4a63SDavid du Colombier p = malloc(n);
126*8ccd4a63SDavid du Colombier if(p == nil)
127*8ccd4a63SDavid du Colombier return a;
128*8ccd4a63SDavid du Colombier m = dec64(p, n, buf, n);
129*8ccd4a63SDavid du Colombier betomp(p, m, b);
130*8ccd4a63SDavid du Colombier free(p);
131*8ccd4a63SDavid du Colombier return a;
132*8ccd4a63SDavid du Colombier }
133*8ccd4a63SDavid du Colombier
134*8ccd4a63SDavid du Colombier static char*
from32(char * a,mpint * b)135*8ccd4a63SDavid du Colombier from32(char *a, mpint *b)
136*8ccd4a63SDavid du Colombier {
137*8ccd4a63SDavid du Colombier char *buf = a;
138*8ccd4a63SDavid du Colombier uchar *p;
139*8ccd4a63SDavid du Colombier int n, m;
140*8ccd4a63SDavid du Colombier
141*8ccd4a63SDavid du Colombier for(; tab.t64[(uchar)*a] != INVAL; a++)
142*8ccd4a63SDavid du Colombier ;
143*8ccd4a63SDavid du Colombier n = a-buf;
144*8ccd4a63SDavid du Colombier mpbits(b, n*5);
145*8ccd4a63SDavid du Colombier p = malloc(n);
146*8ccd4a63SDavid du Colombier if(p == nil)
147*8ccd4a63SDavid du Colombier return a;
148*8ccd4a63SDavid du Colombier m = dec32(p, n, buf, n);
149*8ccd4a63SDavid du Colombier betomp(p, m, b);
150*8ccd4a63SDavid du Colombier free(p);
151*8ccd4a63SDavid du Colombier return a;
152*8ccd4a63SDavid du Colombier }
153*8ccd4a63SDavid du Colombier
154*8ccd4a63SDavid du Colombier mpint*
strtomp(char * a,char ** pp,int base,mpint * b)155*8ccd4a63SDavid du Colombier strtomp(char *a, char **pp, int base, mpint *b)
156*8ccd4a63SDavid du Colombier {
157*8ccd4a63SDavid du Colombier int sign;
158*8ccd4a63SDavid du Colombier char *e;
159*8ccd4a63SDavid du Colombier
160*8ccd4a63SDavid du Colombier if(b == nil)
161*8ccd4a63SDavid du Colombier b = mpnew(0);
162*8ccd4a63SDavid du Colombier
163*8ccd4a63SDavid du Colombier if(tab.inited == 0)
164*8ccd4a63SDavid du Colombier init();
165*8ccd4a63SDavid du Colombier
166*8ccd4a63SDavid du Colombier while(*a==' ' || *a=='\t')
167*8ccd4a63SDavid du Colombier a++;
168*8ccd4a63SDavid du Colombier
169*8ccd4a63SDavid du Colombier sign = 1;
170*8ccd4a63SDavid du Colombier for(;; a++){
171*8ccd4a63SDavid du Colombier switch(*a){
172*8ccd4a63SDavid du Colombier case '-':
173*8ccd4a63SDavid du Colombier sign *= -1;
174*8ccd4a63SDavid du Colombier continue;
175*8ccd4a63SDavid du Colombier }
176*8ccd4a63SDavid du Colombier break;
177*8ccd4a63SDavid du Colombier }
178*8ccd4a63SDavid du Colombier
179*8ccd4a63SDavid du Colombier switch(base){
180*8ccd4a63SDavid du Colombier case 10:
181*8ccd4a63SDavid du Colombier e = from10(a, b);
182*8ccd4a63SDavid du Colombier break;
183*8ccd4a63SDavid du Colombier default:
184*8ccd4a63SDavid du Colombier case 16:
185*8ccd4a63SDavid du Colombier e = from16(a, b);
186*8ccd4a63SDavid du Colombier break;
187*8ccd4a63SDavid du Colombier case 32:
188*8ccd4a63SDavid du Colombier e = from32(a, b);
189*8ccd4a63SDavid du Colombier break;
190*8ccd4a63SDavid du Colombier case 64:
191*8ccd4a63SDavid du Colombier e = from64(a, b);
192*8ccd4a63SDavid du Colombier break;
193*8ccd4a63SDavid du Colombier }
194*8ccd4a63SDavid du Colombier
195*8ccd4a63SDavid du Colombier // if no characters parsed, there wasn't a number to convert
196*8ccd4a63SDavid du Colombier if(e == a)
197*8ccd4a63SDavid du Colombier return nil;
198*8ccd4a63SDavid du Colombier
199*8ccd4a63SDavid du Colombier mpnorm(b);
200*8ccd4a63SDavid du Colombier b->sign = sign;
201*8ccd4a63SDavid du Colombier if(pp != nil)
202*8ccd4a63SDavid du Colombier *pp = e;
203*8ccd4a63SDavid du Colombier
204*8ccd4a63SDavid du Colombier return b;
205*8ccd4a63SDavid du Colombier }
206