svn commit: r205742 - user/des/svnsup/src/libsvnsup
Dag-Erling Smorgrav
des at FreeBSD.org
Sat Mar 27 16:44:52 UTC 2010
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;
More information about the svn-src-user
mailing list