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