xref: /plan9/sys/src/cmd/unix/drawterm/libc/u64.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier 
4*8ccd4a63SDavid du Colombier enum {
5*8ccd4a63SDavid du Colombier 	INVAL=	255
6*8ccd4a63SDavid du Colombier };
7*8ccd4a63SDavid du Colombier 
8*8ccd4a63SDavid du Colombier static uchar t64d[256] = {
9*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
10*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
11*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,   62,INVAL,INVAL,INVAL,   63,
12*8ccd4a63SDavid du Colombier       52,   53,   54,   55,   56,   57,   58,   59,   60,   61,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
13*8ccd4a63SDavid du Colombier    INVAL,    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
14*8ccd4a63SDavid du Colombier       15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,INVAL,INVAL,INVAL,INVAL,INVAL,
15*8ccd4a63SDavid du Colombier    INVAL,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
16*8ccd4a63SDavid du Colombier       41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,INVAL,INVAL,INVAL,INVAL,INVAL,
17*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
18*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
19*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
20*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
21*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
22*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
23*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
24*8ccd4a63SDavid du Colombier    INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL
25*8ccd4a63SDavid du Colombier };
26*8ccd4a63SDavid du Colombier static char t64e[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
27*8ccd4a63SDavid du Colombier 
28*8ccd4a63SDavid du Colombier int
dec64(uchar * out,int lim,char * in,int n)29*8ccd4a63SDavid du Colombier dec64(uchar *out, int lim, char *in, int n)
30*8ccd4a63SDavid du Colombier {
31*8ccd4a63SDavid du Colombier 	ulong b24;
32*8ccd4a63SDavid du Colombier 	uchar *start = out;
33*8ccd4a63SDavid du Colombier 	uchar *e = out + lim;
34*8ccd4a63SDavid du Colombier 	int i, c;
35*8ccd4a63SDavid du Colombier 
36*8ccd4a63SDavid du Colombier 	b24 = 0;
37*8ccd4a63SDavid du Colombier 	i = 0;
38*8ccd4a63SDavid du Colombier 	while(n-- > 0){
39*8ccd4a63SDavid du Colombier 
40*8ccd4a63SDavid du Colombier 		c = t64d[*(uchar*)in++];
41*8ccd4a63SDavid du Colombier 		if(c == INVAL)
42*8ccd4a63SDavid du Colombier 			continue;
43*8ccd4a63SDavid du Colombier 		switch(i){
44*8ccd4a63SDavid du Colombier 		case 0:
45*8ccd4a63SDavid du Colombier 			b24 = c<<18;
46*8ccd4a63SDavid du Colombier 			break;
47*8ccd4a63SDavid du Colombier 		case 1:
48*8ccd4a63SDavid du Colombier 			b24 |= c<<12;
49*8ccd4a63SDavid du Colombier 			break;
50*8ccd4a63SDavid du Colombier 		case 2:
51*8ccd4a63SDavid du Colombier 			b24 |= c<<6;
52*8ccd4a63SDavid du Colombier 			break;
53*8ccd4a63SDavid du Colombier 		case 3:
54*8ccd4a63SDavid du Colombier 			if(out + 3 > e)
55*8ccd4a63SDavid du Colombier 				goto exhausted;
56*8ccd4a63SDavid du Colombier 
57*8ccd4a63SDavid du Colombier 			b24 |= c;
58*8ccd4a63SDavid du Colombier 			*out++ = b24>>16;
59*8ccd4a63SDavid du Colombier 			*out++ = b24>>8;
60*8ccd4a63SDavid du Colombier 			*out++ = b24;
61*8ccd4a63SDavid du Colombier 			i = -1;
62*8ccd4a63SDavid du Colombier 			break;
63*8ccd4a63SDavid du Colombier 		}
64*8ccd4a63SDavid du Colombier 		i++;
65*8ccd4a63SDavid du Colombier 	}
66*8ccd4a63SDavid du Colombier 	switch(i){
67*8ccd4a63SDavid du Colombier 	case 2:
68*8ccd4a63SDavid du Colombier 		if(out + 1 > e)
69*8ccd4a63SDavid du Colombier 			goto exhausted;
70*8ccd4a63SDavid du Colombier 		*out++ = b24>>16;
71*8ccd4a63SDavid du Colombier 		break;
72*8ccd4a63SDavid du Colombier 	case 3:
73*8ccd4a63SDavid du Colombier 		if(out + 2 > e)
74*8ccd4a63SDavid du Colombier 			goto exhausted;
75*8ccd4a63SDavid du Colombier 		*out++ = b24>>16;
76*8ccd4a63SDavid du Colombier 		*out++ = b24>>8;
77*8ccd4a63SDavid du Colombier 		break;
78*8ccd4a63SDavid du Colombier 	}
79*8ccd4a63SDavid du Colombier exhausted:
80*8ccd4a63SDavid du Colombier 	return out - start;
81*8ccd4a63SDavid du Colombier }
82*8ccd4a63SDavid du Colombier 
83*8ccd4a63SDavid du Colombier int
enc64(char * out,int lim,uchar * in,int n)84*8ccd4a63SDavid du Colombier enc64(char *out, int lim, uchar *in, int n)
85*8ccd4a63SDavid du Colombier {
86*8ccd4a63SDavid du Colombier 	int i;
87*8ccd4a63SDavid du Colombier 	ulong b24;
88*8ccd4a63SDavid du Colombier 	char *start = out;
89*8ccd4a63SDavid du Colombier 	char *e = out + lim;
90*8ccd4a63SDavid du Colombier 
91*8ccd4a63SDavid du Colombier 	for(i = n/3; i > 0; i--){
92*8ccd4a63SDavid du Colombier 		b24 = (*in++)<<16;
93*8ccd4a63SDavid du Colombier 		b24 |= (*in++)<<8;
94*8ccd4a63SDavid du Colombier 		b24 |= *in++;
95*8ccd4a63SDavid du Colombier 		if(out + 4 >= e)
96*8ccd4a63SDavid du Colombier 			goto exhausted;
97*8ccd4a63SDavid du Colombier 		*out++ = t64e[(b24>>18)];
98*8ccd4a63SDavid du Colombier 		*out++ = t64e[(b24>>12)&0x3f];
99*8ccd4a63SDavid du Colombier 		*out++ = t64e[(b24>>6)&0x3f];
100*8ccd4a63SDavid du Colombier 		*out++ = t64e[(b24)&0x3f];
101*8ccd4a63SDavid du Colombier 	}
102*8ccd4a63SDavid du Colombier 
103*8ccd4a63SDavid du Colombier 	switch(n%3){
104*8ccd4a63SDavid du Colombier 	case 2:
105*8ccd4a63SDavid du Colombier 		b24 = (*in++)<<16;
106*8ccd4a63SDavid du Colombier 		b24 |= (*in)<<8;
107*8ccd4a63SDavid du Colombier 		if(out + 4 >= e)
108*8ccd4a63SDavid du Colombier 			goto exhausted;
109*8ccd4a63SDavid du Colombier 		*out++ = t64e[(b24>>18)];
110*8ccd4a63SDavid du Colombier 		*out++ = t64e[(b24>>12)&0x3f];
111*8ccd4a63SDavid du Colombier 		*out++ = t64e[(b24>>6)&0x3f];
112*8ccd4a63SDavid du Colombier 		*out++ = '=';
113*8ccd4a63SDavid du Colombier 		break;
114*8ccd4a63SDavid du Colombier 	case 1:
115*8ccd4a63SDavid du Colombier 		b24 = (*in)<<16;
116*8ccd4a63SDavid du Colombier 		if(out + 4 >= e)
117*8ccd4a63SDavid du Colombier 			goto exhausted;
118*8ccd4a63SDavid du Colombier 		*out++ = t64e[(b24>>18)];
119*8ccd4a63SDavid du Colombier 		*out++ = t64e[(b24>>12)&0x3f];
120*8ccd4a63SDavid du Colombier 		*out++ = '=';
121*8ccd4a63SDavid du Colombier 		*out++ = '=';
122*8ccd4a63SDavid du Colombier 		break;
123*8ccd4a63SDavid du Colombier 	}
124*8ccd4a63SDavid du Colombier exhausted:
125*8ccd4a63SDavid du Colombier 	*out = 0;
126*8ccd4a63SDavid du Colombier 	return out - start;
127*8ccd4a63SDavid du Colombier }
128