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>