Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Mar 2010 16:44:52 +0000 (UTC)
From:      Dag-Erling Smorgrav <des@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r205742 - user/des/svnsup/src/libsvnsup
Message-ID:  <201003271644.o2RGiqVP041397@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: des
Date: Sat Mar 27 16:44:52 2010
New Revision: 205742
URL: http://svn.freebsd.org/changeset/base/205742

Log:
  Implement memory-to-memory base64 encoding and decoding.
  Use size_t instead of int for lengths.

Modified:
  user/des/svnsup/src/libsvnsup/svnsup.h
  user/des/svnsup/src/libsvnsup/svnsup_base64.c
  user/des/svnsup/src/libsvnsup/svnsup_string.c

Modified: user/des/svnsup/src/libsvnsup/svnsup.h
==============================================================================
--- user/des/svnsup/src/libsvnsup/svnsup.h	Sat Mar 27 16:42:53 2010	(r205741)
+++ user/des/svnsup/src/libsvnsup/svnsup.h	Sat Mar 27 16:44:52 2010	(r205742)
@@ -74,15 +74,18 @@ char *svnsup_string_encode(const char *)
 char *svnsup_buf_encode(const char *, size_t);
 
 #ifdef FOPEN_MAX /* defined by stdio.h, cf. IEEE 1003.1 */
-int svnsup_string_fencode(FILE *, const char *);
-int svnsup_buf_fencode(FILE *, const char *, size_t);
+size_t svnsup_string_fencode(FILE *, const char *);
+size_t svnsup_buf_fencode(FILE *, const char *, size_t);
 #endif
 
 /*
  * svnsup_base64.c
  */
+size_t svnsup_base64_encode(char *, const unsigned char *, size_t);
+size_t svnsup_base64_decode(unsigned char *, const char *, size_t);
 #ifdef FOPEN_MAX /* defined by stdio.h, cf. IEEE 1003.1 */
-int svnsup_base64_fencode(FILE *, const unsigned char *, size_t);
+size_t svnsup_base64_fencode(FILE *, const unsigned char *, size_t);
+/* no fdecode yet */
 #endif
 
 #endif

Modified: user/des/svnsup/src/libsvnsup/svnsup_base64.c
==============================================================================
--- user/des/svnsup/src/libsvnsup/svnsup_base64.c	Sat Mar 27 16:42:53 2010	(r205741)
+++ user/des/svnsup/src/libsvnsup/svnsup_base64.c	Sat Mar 27 16:44:52 2010	(r205742)
@@ -33,32 +33,103 @@
 
 #include <sys/types.h>
 
+#include <assert.h>
 #include <stdio.h>
 
 #include "svnsup.h"
 
-static const char b64t[65] =
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "abcdefghijklmnopqrstuvwxyz"
-    "0123456789"
-    "+/"
-    "=";
+static const char b64enc[64] = {
+	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+	'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+	'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+	'w', 'x', 'y', 'z', '0', '1', '2', '3',
+	'4', '5', '6', '7', '8', '9', '+', '/',
+};
+
+static const char b64dec[256] = {
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+	-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+	15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+	-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+	41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+/*
+ * Compute the amount of space required to base64-encode a specified
+ * amount of data.
+ */
+size_t
+svnsup_base64_encode_length(size_t size)
+{
+
+	return (((size + 2) / 3) * 4);
+}
 
-int
-svnsup_base64_fencode(FILE *f, const unsigned char *buf, size_t size)
+/*
+ * Encode a buffer into another.  Assumes that str points to a buffer of
+ * sufficient length.
+ */
+size_t
+svnsup_base64_encode(char *b64, const unsigned char *data, size_t size)
 {
-	int count = 0;
+	size_t count = 0;
+
+	while (size > 3) {
+		*b64++ = b64enc[data[0] >> 2];
+		*b64++ = b64enc[(data[0] << 4 | data[1] >> 4) & 0x3f];
+		*b64++ = b64enc[(data[1] << 2 | data[2] >> 6) & 0x3f];
+		*b64++ = b64enc[data[2] & 0x3f];
+		count += 4;
+		data += 3;
+		size -= 3;
+	}
+	if (size > 0) {
+		*b64++ = b64enc[data[0] >> 2];
+		if (size > 1) {
+			*b64++ = b64enc[(data[0] << 4 | data[1] >> 4) & 0x3f];
+			*b64++ = b64enc[(data[1] << 2) & 0x3f];
+		} else {
+			*b64++ = b64enc[(data[0] << 4) & 0x3f];
+			*b64++ = '=';
+		}
+		*b64++ = '=';
+		count += 4;
+	}
+	return (count);
+}
+
+/*
+ * Encode a buffer and write the result to a file
+ */
+size_t
+svnsup_base64_fencode(FILE *f, const unsigned char *data, size_t size)
+{
+	size_t count = 0;
 #if 0
 	int width = 0;
 #endif
 
 	while (size >= 3) {
-		putc(b64t[buf[0] >> 2], f);
-		putc(b64t[(buf[0] << 4 | buf[1] >> 4) & 0x3f], f);
-		putc(b64t[(buf[1] << 2 | buf[2] >> 6) & 0x3f], f);
-		putc(b64t[buf[2] & 0x3f], f);
+		putc(b64enc[data[0] >> 2], f);
+		putc(b64enc[(data[0] << 4 | data[1] >> 4) & 0x3f], f);
+		putc(b64enc[(data[1] << 2 | data[2] >> 6) & 0x3f], f);
+		putc(b64enc[data[2] & 0x3f], f);
 		count += 4;
-		buf += 3;
+		data += 3;
 		size -= 3;
 #if 0
 		if ((width += 3) == 64 && size > 0) {
@@ -69,12 +140,12 @@ svnsup_base64_fencode(FILE *f, const uns
 #endif
 	}
 	if (size > 0) {
-		putc(b64t[buf[0] >> 2], f);
+		putc(b64enc[data[0] >> 2], f);
 		if (size > 1) {
-			putc(b64t[(buf[0] << 4 | buf[1] >> 4) & 0x3f], f);
-			putc(b64t[(buf[1] << 2) & 0x3f], f);
+			putc(b64enc[(data[0] << 4 | data[1] >> 4) & 0x3f], f);
+			putc(b64enc[(data[1] << 2) & 0x3f], f);
 		} else {
-			putc(b64t[(buf[0] << 4) & 0x3f], f);
+			putc(b64enc[(data[0] << 4) & 0x3f], f);
 			putc('=', f);
 		}
 		putc('=', f);
@@ -82,3 +153,46 @@ svnsup_base64_fencode(FILE *f, const uns
 	}
 	return (count);
 }
+
+/*
+ * Compute the amount of space required to decode a base64-encoded string
+ * of the specified length.  Note that this number may be a little high
+ * due to padding.
+ */
+size_t
+svnsup_base64_decode_length(size_t size)
+{
+
+	return ((size + 3 / 4) * 3);
+}
+
+/*
+ * Decode a bas64-encoded string into a buffer.
+ */
+size_t
+svnsup_base64_decode(unsigned char *data, const char *b64, size_t len)
+{
+	size_t count = 0;
+
+	assert(len % 4 == 0);
+	while (len > 0) {
+		assert(b64dec[(int)b64[0]] != -1);
+		assert(b64dec[(int)b64[1]] != -1);
+		assert(b64dec[(int)b64[2]] != -1 || b64[2] == '=');
+		assert(b64dec[(int)b64[3]] != -1 || b64[3] == '=');
+
+		*data = b64dec[(int)b64[0]] << 2 | b64dec[(int)b64[1]] >> 4;
+		++count, ++data;
+		if (b64[2] != '=') {
+			*data = b64dec[(int)b64[1]] << 4 | b64dec[(int)b64[2]] >> 2;
+			++count, ++data;
+		}
+		if (b64[3] != '=') {
+			*data = b64dec[(int)b64[2]] << 6 | b64dec[(int)b64[3]];
+			++count, ++data;
+		}
+		b64 += 4;
+		len -= 4;
+	}
+	return (count);
+}

Modified: user/des/svnsup/src/libsvnsup/svnsup_string.c
==============================================================================
--- user/des/svnsup/src/libsvnsup/svnsup_string.c	Sat Mar 27 16:42:53 2010	(r205741)
+++ user/des/svnsup/src/libsvnsup/svnsup_string.c	Sat Mar 27 16:44:52 2010	(r205742)
@@ -90,14 +90,14 @@ svnsup_buf_encode(const char *buf, size_
 	return (NULL);
 }
 
-int
+size_t
 svnsup_string_fencode(FILE *f, const char *str)
 {
 
 	return (svnsup_buf_fencode(f, str, strlen(str)));
 }
 
-int
+size_t
 svnsup_buf_fencode(FILE *f, const char *buf, size_t size)
 {
 	int len;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003271644.o2RGiqVP041397>