Subversion Repositories planix.SVN

Rev

Rev 22 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 22 Rev 26
Line 1... Line 1...
1
#include "os.h"
1
#include "os.h"
2
#include <mp.h>
2
#include <mp.h>
3
#include <libsec.h>
-
 
4
#include "dat.h"
3
#include "dat.h"
5
 
4
 
-
 
5
	
-
 
6
#define between(x,min,max)	(((min-1-x) & (x-max-1))>>8)
-
 
7
 
6
static int
8
static int
7
to64(mpint *b, char *buf, int len)
9
enc16chr(int o)
8
{
10
{
9
	uchar *p;
11
	int c;
-
 
12
 
-
 
13
	c  = between(o,  0,  9) & ('0'+o);
-
 
14
	c |= between(o, 10, 15) & ('A'+(o-10));
10
	int n, rv;
15
	return c;
-
 
16
}
11
 
17
 
12
	p = nil;
-
 
13
	n = mptobe(b, nil, 0, &p);
-
 
14
	if(n < 0)
-
 
15
		return -1;
-
 
16
	rv = enc64(buf, len, p, n);
-
 
17
	free(p);
-
 
18
	return rv;
-
 
19
}
-
 
20
 
18
 
21
static int
19
static int
22
to32(mpint *b, char *buf, int len)
20
toencx(mpint *b, char *buf, int len, int (*enc)(char*, int, uchar*, int))
23
{
21
{
24
	uchar *p;
22
	uchar *p;
25
	int n, rv;
23
	int n, rv;
26
 
24
 
27
	// leave room for a multiple of 5 buffer size
-
 
28
	n = b->top*Dbytes + 5;
25
	p = nil;
29
	p = malloc(n);
26
	n = mptobe(b, nil, 0, &p);
30
	if(p == nil)
27
	if(n < 0)
31
		return -1;
28
		return -1;
32
	n = mptobe(b, p, n, nil);
-
 
33
	if(n < 0)
-
 
34
		return -1;
-
 
35
 
-
 
36
	// round up buffer size, enc32 only accepts a multiple of 5
-
 
37
	if(n%5)
-
 
38
		n += 5 - (n%5);
-
 
39
	rv = enc32(buf, len, p, n);
29
	rv = (*enc)(buf, len, p, n);
40
	free(p);
30
	free(p);
41
	return rv;
31
	return rv;
42
}
32
}
43
 
-
 
44
static char set16[] = "0123456789ABCDEF";
-
 
45
 
33
 
46
static int
34
static int
47
to16(mpint *b, char *buf, int len)
35
topow2(mpint *b, char *buf, int len, int s)
48
{
36
{
49
	mpdigit *p, x;
37
	mpdigit *p, x;
50
	int i, j;
38
	int i, j, sn;
51
	char *out, *eout;
39
	char *out, *eout;
52
 
40
 
53
	if(len < 1)
41
	if(len < 1)
54
		return -1;
42
		return -1;
55
 
43
 
-
 
44
	sn = 1<<s;
56
	out = buf;
45
	out = buf;
57
	eout = buf+len;
46
	eout = buf+len;
58
	for(p = &b->p[b->top-1]; p >= b->p; p--){
47
	for(p = &b->p[b->top-1]; p >= b->p; p--){
59
		x = *p;
48
		x = *p;
60
		for(i = Dbits-4; i >= 0; i -= 4){
49
		for(i = Dbits-s; i >= 0; i -= s){
61
			j = 0xf & (x>>i);
50
			j = x >> i & sn - 1;
62
			if(j != 0 || out != buf){
51
			if(j != 0 || out != buf){
63
				if(out >= eout)
52
				if(out >= eout)
64
					return -1;
53
					return -1;
65
				*out++ = set16[j];
54
				*out++ = enc16chr(j);
66
			}
55
			}
67
		}
56
		}
68
	}
57
	}
69
	if(out == buf)
58
	if(out == buf)
70
		*out++ = '0';
59
		*out++ = '0';
Line 94... Line 83...
94
 
83
 
95
static int
84
static int
96
to10(mpint *b, char *buf, int len)
85
to10(mpint *b, char *buf, int len)
97
{
86
{
98
	mpint *d, *r, *billion;
87
	mpint *d, *r, *billion;
99
	char *out;
88
	char *out;
100
 
89
 
101
	if(len < 1)
90
	if(len < 1)
102
		return -1;
91
		return -1;
103
 
92
 
104
	d = mpcopy(b);
93
	d = mpcopy(b);
-
 
94
	d->flags &= ~MPtimesafe;
-
 
95
	mpnorm(d);
105
	r = mpnew(0);
96
	r = mpnew(0);
106
	billion = uitomp(1000000000, nil);
97
	billion = uitomp(1000000000, nil);
107
	out = buf+len;
98
	out = buf+len;
108
	*--out = 0;
99
	*--out = 0;
109
	do {
100
	do {
Line 116... Line 107...
116
	mpfree(r);
107
	mpfree(r);
117
	mpfree(billion);
108
	mpfree(billion);
118
 
109
 
119
	if(out == nil)
110
	if(out == nil)
120
		return -1;
111
		return -1;
-
 
112
	len -= out-buf;
-
 
113
	if(out != buf)
-
 
114
		memmove(buf, out, len);
-
 
115
	return 0;
-
 
116
}
-
 
117
 
-
 
118
static int
-
 
119
to8(mpint *b, char *buf, int len)
-
 
120
{
-
 
121
	mpdigit x, y;
-
 
122
	char *out;
-
 
123
	int i, j;
-
 
124
 
-
 
125
	if(len < 2)
-
 
126
		return -1;
-
 
127
 
-
 
128
	out = buf+len;
-
 
129
	*--out = 0;
-
 
130
 
-
 
131
	i = j = 0;
-
 
132
	x = y = 0;
-
 
133
	while(j < b->top){
-
 
134
		y = b->p[j++];
-
 
135
		if(i > 0)
-
 
136
			x |= y << i;
-
 
137
		else
-
 
138
			x = y;
-
 
139
		i += Dbits;
-
 
140
		while(i >= 3){
-
 
141
Digout:			i -= 3;
-
 
142
			if(out > buf)
-
 
143
				out--;
-
 
144
			else if(x != 0)
-
 
145
				return -1;
-
 
146
			*out = '0' + (x & 7);
-
 
147
			x = y >> Dbits-i;
-
 
148
		}
-
 
149
	}
-
 
150
	if(i > 0)
-
 
151
		goto Digout;
-
 
152
 
-
 
153
	while(*out == '0') out++;
-
 
154
	if(*out == '\0')
-
 
155
		*--out = '0';
-
 
156
 
121
	len -= out-buf;
157
	len -= out-buf;
122
	if(out != buf)
158
	if(out != buf)
123
		memmove(buf, out, len);
159
		memmove(buf, out, len);
124
	return 0;
160
	return 0;
125
}
161
}
126
 
162
 
127
int
163
int
128
mpfmt(Fmt *fmt)
164
mpfmt(Fmt *fmt)
129
{
165
{
130
	mpint *b;
166
	mpint *b;
131
	char *p;
167
	char *x, *p;
-
 
168
	int base;
132
 
169
 
133
	b = va_arg(fmt->args, mpint*);
170
	b = va_arg(fmt->args, mpint*);
134
	if(b == nil)
171
	if(b == nil)
135
		return fmtstrcpy(fmt, "*");
172
		return fmtstrcpy(fmt, "*");
136
	
-
 
137
	p = mptoa(b, fmt->prec, nil, 0);
-
 
138
	fmt->flags &= ~FmtPrec;
-
 
139
 
173
 
-
 
174
	base = fmt->prec;
-
 
175
	if(base == 0)
-
 
176
		base = 16;	/* default */
-
 
177
	fmt->flags &= ~FmtPrec;
-
 
178
	p = mptoa(b, base, nil, 0);
140
	if(p == nil)
179
	if(p == nil)
141
		return fmtstrcpy(fmt, "*");
180
		return fmtstrcpy(fmt, "*");
142
	else{
181
	else{
-
 
182
		if((fmt->flags & FmtSharp) != 0){
-
 
183
			switch(base){
-
 
184
			case 16:
-
 
185
				x = "0x";
-
 
186
				break;
-
 
187
			case 8:
-
 
188
				x = "0";
-
 
189
				break;
-
 
190
			case 2:
-
 
191
				x = "0b";
-
 
192
				break;
-
 
193
			default:
-
 
194
				x = "";
-
 
195
			}
-
 
196
			if(*p == '-')
-
 
197
				fmtprint(fmt, "-%s%s", x, p + 1);
-
 
198
			else
-
 
199
				fmtprint(fmt, "%s%s", x, p);
-
 
200
		}
-
 
201
		else
143
		fmtstrcpy(fmt, p);
202
			fmtstrcpy(fmt, p);
144
		free(p);
203
		free(p);
145
		return 0;
204
		return 0;
146
	}
205
	}
147
}
206
}
148
 
207
 
149
char*
208
char*
150
mptoa(mpint *b, int base, char *buf, int len)
209
mptoa(mpint *b, int base, char *buf, int len)
151
{
210
{
152
	char *out;
211
	char *out;
153
	int rv, alloced;
212
	int rv, alloced;
154
 
213
 
-
 
214
	if(base == 0)
-
 
215
		base = 16;	/* default */
155
	alloced = 0;
216
	alloced = 0;
156
	if(buf == nil){
217
	if(buf == nil){
-
 
218
		/* rv <= logâ‚‚(base) */
-
 
219
		for(rv=1; (base >> rv) > 1; rv++)
-
 
220
			;
157
		len = ((b->top+1)*Dbits+2)/3 + 1;
221
		len = 10 + (b->top*Dbits / rv);
158
		buf = malloc(len);
222
		buf = malloc(len);
159
		if(buf == nil)
223
		if(buf == nil)
160
			return nil;
224
			return nil;
161
		alloced = 1;
225
		alloced = 1;
162
	}
226
	}
163
 
227
 
164
	if(len < 2)
228
	if(len < 2)
165
		return nil;
229
		return nil;
166
 
230
 
167
	out = buf;
231
	out = buf;
168
	if(b->sign < 0){
232
	if(b->sign < 0){
169
		*out++ = '-';
233
		*out++ = '-';
170
		len--;
234
		len--;
171
	}
235
	}
172
	switch(base){
236
	switch(base){
173
	case 64:
237
	case 64:
174
		rv = to64(b, out, len);
238
		rv = toencx(b, out, len, enc64);
175
		break;
239
		break;
176
	case 32:
240
	case 32:
177
		rv = to32(b, out, len);
241
		rv = toencx(b, out, len, enc32);
178
		break;
242
		break;
179
	default:
-
 
180
	case 16:
243
	case 16:
181
		rv = to16(b, out, len);
244
		rv = topow2(b, out, len, 4);
182
		break;
245
		break;
183
	case 10:
246
	case 10:
184
		rv = to10(b, out, len);
247
		rv = to10(b, out, len);
185
		break;
248
		break;
-
 
249
	case 8:
-
 
250
		rv = to8(b, out, len);
-
 
251
		break;
-
 
252
	case 4:
-
 
253
		rv = topow2(b, out, len, 2);
-
 
254
		break;
-
 
255
	case 2:
-
 
256
		rv = topow2(b, out, len, 1);
-
 
257
		break;
-
 
258
	default:
-
 
259
		abort();
-
 
260
		return nil;
186
	}
261
	}
187
	if(rv < 0){
262
	if(rv < 0){
188
		if(alloced)
263
		if(alloced)
189
			free(buf);
264
			free(buf);
190
		return nil;
265
		return nil;