summaryrefslogtreecommitdiff
path: root/sys/src/libc
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2021-07-03 20:03:17 +0000
committerOri Bernstein <ori@eigenstate.org>2021-07-03 20:03:17 +0000
commite934530ee4512f033952e4efa80a80058607b741 (patch)
tree2bde95220e1d5e26000286a7f04b93431d8121c8 /sys/src/libc
parentc848ca62673689df20e7fef74d1d5180f37fcea6 (diff)
libc: add encode(2) variants for custom alphabets
There are a number of alphabets in common use for base32 and base64 encoding, such as url-safe encodings. This adds support for passing a function to encode into arbitary alphabets.
Diffstat (limited to 'sys/src/libc')
-rw-r--r--sys/src/libc/port/u32.c50
-rw-r--r--sys/src/libc/port/u64.c36
2 files changed, 55 insertions, 31 deletions
diff --git a/sys/src/libc/port/u32.c b/sys/src/libc/port/u32.c
index 9ad9eb781..a7abdc012 100644
--- a/sys/src/libc/port/u32.c
+++ b/sys/src/libc/port/u32.c
@@ -25,7 +25,7 @@ dec32chr(int c)
}
int
-dec32(uchar *dest, int ndest, char *src, int nsrc)
+dec32x(uchar *dest, int ndest, char *src, int nsrc, int (*chr)(int))
{
uchar *start;
int i, j, u[8];
@@ -35,7 +35,7 @@ dec32(uchar *dest, int ndest, char *src, int nsrc)
start = dest;
while(nsrc>=8){
for(i=0; i<8; i++){
- j = dec32chr(src[i]);
+ j = chr(src[i]);
if(j < 0)
j = 0;
u[i] = j;
@@ -52,7 +52,7 @@ dec32(uchar *dest, int ndest, char *src, int nsrc)
if(nsrc == 1 || nsrc == 3 || nsrc == 6)
return -1;
for(i=0; i<nsrc; i++){
- j = dec32chr(src[i]);
+ j = chr(src[i]);
if(j < 0)
j = 0;
u[i] = j;
@@ -73,7 +73,7 @@ out:
}
int
-enc32(char *dest, int ndest, uchar *src, int nsrc)
+enc32x(char *dest, int ndest, uchar *src, int nsrc, int (*chr)(int))
{
char *start;
int j;
@@ -83,50 +83,62 @@ enc32(char *dest, int ndest, uchar *src, int nsrc)
start = dest;
while(nsrc>=5){
j = (0x1f & (src[0]>>3));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x1c & (src[0]<<2)) | (0x03 & (src[1]>>6));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x1f & (src[1]>>1));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x10 & (src[1]<<4)) | (0x0f & (src[2]>>4));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x1e & (src[2]<<1)) | (0x01 & (src[3]>>7));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x1f & (src[3]>>2));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x18 & (src[3]<<3)) | (0x07 & (src[4]>>5));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x1f & (src[4]));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
src += 5;
nsrc -= 5;
}
if(nsrc){
j = (0x1f & (src[0]>>3));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x1c & (src[0]<<2));
if(nsrc == 1)
goto out;
j |= (0x03 & (src[1]>>6));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x1f & (src[1]>>1));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x10 & (src[1]<<4));
if(nsrc == 2)
goto out;
j |= (0x0f & (src[2]>>4));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x1e & (src[2]<<1));
if(nsrc == 3)
goto out;
j |= (0x01 & (src[3]>>7));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x1f & (src[3]>>2));
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
j = (0x18 & (src[3]<<3));
out:
- *dest++ = enc32chr(j);
+ *dest++ = chr(j);
}
*dest = 0;
return dest-start;
}
+
+int
+enc32(char *dest, int ndest, uchar *src, int nsrc)
+{
+ return enc32x(dest, ndest, src, nsrc, enc32chr);
+}
+
+int
+dec32(uchar *dest, int ndest, char *src, int nsrc)
+{
+ return dec32x(dest, ndest, src, nsrc, dec32chr);
+}
diff --git a/sys/src/libc/port/u64.c b/sys/src/libc/port/u64.c
index 44f716fbe..5be0142b8 100644
--- a/sys/src/libc/port/u64.c
+++ b/sys/src/libc/port/u64.c
@@ -30,7 +30,7 @@ dec64chr(int c)
}
int
-dec64(uchar *out, int lim, char *in, int n)
+dec64x(uchar *out, int lim, char *in, int n, int (*chr)(int))
{
ulong b24;
uchar *start = out;
@@ -40,7 +40,7 @@ dec64(uchar *out, int lim, char *in, int n)
b24 = 0;
i = 0;
while(n-- > 0){
- c = dec64chr(*in++);
+ c = chr(*in++);
if(c < 0)
continue;
switch(i){
@@ -84,7 +84,7 @@ exhausted:
}
int
-enc64(char *out, int lim, uchar *in, int n)
+enc64x(char *out, int lim, uchar *in, int n, int (*chr)(int))
{
int i;
ulong b24;
@@ -97,10 +97,10 @@ enc64(char *out, int lim, uchar *in, int n)
b24 |= *in++;
if(out + 4 >= e)
goto exhausted;
- *out++ = enc64chr(b24>>18);
- *out++ = enc64chr((b24>>12)&0x3f);
- *out++ = enc64chr((b24>>6)&0x3f);
- *out++ = enc64chr(b24&0x3f);
+ *out++ = chr(b24>>18);
+ *out++ = chr((b24>>12)&0x3f);
+ *out++ = chr((b24>>6)&0x3f);
+ *out++ = chr(b24&0x3f);
}
switch(n%3){
@@ -109,17 +109,17 @@ enc64(char *out, int lim, uchar *in, int n)
b24 |= *in<<8;
if(out + 4 >= e)
goto exhausted;
- *out++ = enc64chr(b24>>18);
- *out++ = enc64chr((b24>>12)&0x3f);
- *out++ = enc64chr((b24>>6)&0x3f);
+ *out++ = chr(b24>>18);
+ *out++ = chr((b24>>12)&0x3f);
+ *out++ = chr((b24>>6)&0x3f);
*out++ = '=';
break;
case 1:
b24 = *in<<16;
if(out + 4 >= e)
goto exhausted;
- *out++ = enc64chr(b24>>18);
- *out++ = enc64chr((b24>>12)&0x3f);
+ *out++ = chr(b24>>18);
+ *out++ = chr((b24>>12)&0x3f);
*out++ = '=';
*out++ = '=';
break;
@@ -128,3 +128,15 @@ exhausted:
*out = 0;
return out - start;
}
+
+int
+enc64(char *out, int lim, uchar *in, int n)
+{
+ return enc64x(out, lim, in, n, enc64chr);
+}
+
+int
+dec64(uchar *out, int lim, char *in, int n)
+{
+ return dec64x(out, lim, in, n, dec64chr);
+}