]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libc/port/u64.c
libregexp: improve the transition to next available thread, instruction, and generation
[plan9front.git] / sys / src / libc / port / u64.c
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
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
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 }