Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b

Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/base64/b64.c b/src/base64/b64.c
new file mode 100644
index 0000000..a235875
--- /dev/null
+++ b/src/base64/b64.c
@@ -0,0 +1,156 @@
+/**
+ * @file b64.c  Base64 encoding/decoding functions
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re_types.h>
+#include <re_fmt.h>
+#include <re_base64.h>
+
+
+static const char b64_table[65] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	"abcdefghijklmnopqrstuvwxyz"
+	"0123456789+/";
+
+
+/**
+ * Base-64 encode a buffer
+ *
+ * @param in   Input buffer
+ * @param ilen Length of input buffer
+ * @param out  Output buffer
+ * @param olen Size of output buffer, actual written on return
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int base64_encode(const uint8_t *in, size_t ilen, char *out, size_t *olen)
+{
+	const uint8_t *in_end = in + ilen;
+	const char *o = out;
+
+	if (!in || !out || !olen)
+		return EINVAL;
+
+	if (*olen < 4 * ((ilen+2)/3))
+		return EOVERFLOW;
+
+	for (; in < in_end; ) {
+		uint32_t v;
+		int pad = 0;
+
+		v  = *in++ << 16;
+		if (in < in_end) {
+			v |= *in++ << 8;
+		}
+		else {
+			++pad;
+		}
+		if (in < in_end) {
+			v |= *in++ << 0;
+		}
+		else {
+			++pad;
+		}
+
+		*out++ = b64_table[v>>18 & 0x3f];
+		*out++ = b64_table[v>>12 & 0x3f];
+		*out++ = (pad >= 2) ? '=' : b64_table[v>>6  & 0x3f];
+		*out++ = (pad >= 1) ? '=' : b64_table[v>>0  & 0x3f];
+	}
+
+	*olen = out - o;
+
+	return 0;
+}
+
+
+int base64_print(struct re_printf *pf, const uint8_t *ptr, size_t len)
+{
+	char buf[256];
+
+	if (!pf || !ptr)
+		return EINVAL;
+
+	while (len > 0) {
+		size_t l, sz = sizeof(buf);
+		int err;
+
+		l = min(len, 3 * (sizeof(buf)/4));
+
+		err = base64_encode(ptr, l, buf, &sz);
+		if (err)
+			return err;
+
+		err = pf->vph(buf, sz, pf->arg);
+		if (err)
+			return err;
+
+		ptr += l;
+		len -= l;
+	}
+
+	return 0;
+}
+
+
+/* convert char -> 6-bit value */
+static inline uint32_t b64val(char c)
+{
+	if ('A' <= c && c <= 'Z')
+		return c - 'A' + 0;
+	else if ('a' <= c && c <= 'z')
+		return c - 'a' + 26;
+	else if ('0' <= c && c <= '9')
+		return c - '0' + 52;
+	else if ('+' == c)
+		return 62;
+	else if ('/' == c)
+		return 63;
+	else if ('=' == c)
+		return 1<<24; /* special trick */
+	else
+		return 0;
+}
+
+
+/**
+ * Decode a Base-64 encoded string
+ *
+ * @param in   Input buffer
+ * @param ilen Length of input buffer
+ * @param out  Output buffer
+ * @param olen Size of output buffer, actual written on return
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int base64_decode(const char *in, size_t ilen, uint8_t *out, size_t *olen)
+{
+	const char *in_end = in + ilen;
+	const uint8_t *o = out;
+
+	if (!in || !out || !olen)
+		return EINVAL;
+
+	if (*olen < 3 * (ilen/4))
+		return EOVERFLOW;
+
+	for (;in+3 < in_end; ) {
+		uint32_t v;
+
+		v  = b64val(*in++) << 18;
+		v |= b64val(*in++) << 12;
+		v |= b64val(*in++) << 6;
+		v |= b64val(*in++) << 0;
+
+		*out++ = v>>16;
+		if (!(v & (1<<30)))
+			*out++ = (v>>8) & 0xff;
+		if (!(v & (1<<24)))
+			*out++ = (v>>0) & 0xff;
+	}
+
+	*olen = out - o;
+
+	return 0;
+}
diff --git a/src/base64/mod.mk b/src/base64/mod.mk
new file mode 100644
index 0000000..fddc2ee
--- /dev/null
+++ b/src/base64/mod.mk
@@ -0,0 +1,7 @@
+#
+# mod.mk
+#
+# Copyright (C) 2010 Creytiv.com
+#
+
+SRCS	+= base64/b64.c