aboutsummaryrefslogtreecommitdiffstats
path: root/etc.c
diff options
context:
space:
mode:
Diffstat (limited to 'etc.c')
-rw-r--r--etc.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/etc.c b/etc.c
index 801b098..4e662e4 100644
--- a/etc.c
+++ b/etc.c
@@ -2004,3 +2004,63 @@ void (*mySignal(int signal_number, void (*action) (int))) (int) {
return (signal(signal_number, action));
#endif
}
+
+static char Base64Table[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+char *
+base64_encode(const unsigned char *src, size_t len)
+{
+ unsigned char *w, *at;
+ const unsigned char *in, *endw;
+ int j;
+ size_t k;
+
+ k = len;
+ if (k % 3)
+ k += 3 - (k % 3);
+ k = k / 3 * 4;
+
+ if (k + 1 < len)
+ return NULL;
+
+ w = GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(k + 1);
+ w[k] = 0;
+
+ at = w;
+ in = src;
+
+ endw = src + len - 2;
+
+ while (in < endw) {
+ j = *in++;
+ j = j << 8 | *in++;
+ j = j << 8 | *in++;
+
+ *at++ = Base64Table[(j >> 18) & 0x3f];
+ *at++ = Base64Table[(j >> 12) & 0x3f];
+ *at++ = Base64Table[(j >> 6) & 0x3f];
+ *at++ = Base64Table[j & 0x3f];
+ }
+
+ if (in - src - len) {
+ if (in - src - len == 1) {
+ j = *in++;
+ j = j << 8;
+ j = j << 8;
+ *at++ = Base64Table[(j >> 18) & 0x3f];
+ *at++ = Base64Table[(j >> 12) & 0x3f];
+ *at++ = '=';
+ *at++ = '=';
+ } else {
+ j = *in++;
+ j = j << 8 | *in++;
+ j = j << 8;
+ *at++ = Base64Table[(j >> 18) & 0x3f];
+ *at++ = Base64Table[(j >> 12) & 0x3f];
+ *at++ = Base64Table[(j >> 6) & 0x3f];
+ *at++ = '=';
+ }
+ }
+ return (char *)w;
+}