[vlc-commits] strings: clean up base64 encoding
Rémi Denis-Courmont
git at videolan.org
Thu Mar 28 16:51:48 CET 2019
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Mar 28 17:16:35 2019 +0200| [8d3c52593e2c5e07e6c821d03160cd2ab4c35fa2] | committer: Rémi Denis-Courmont
strings: clean up base64 encoding
Document, split main loop from tail handling, add missing qualifiers.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8d3c52593e2c5e07e6c821d03160cd2ab4c35fa2
---
include/vlc_strings.h | 25 ++++++++++++++--
src/text/strings.c | 83 ++++++++++++++++++++++++++-------------------------
2 files changed, 65 insertions(+), 43 deletions(-)
diff --git a/include/vlc_strings.h b/include/vlc_strings.h
index 5d6e5d50ff..fb33f18723 100644
--- a/include/vlc_strings.h
+++ b/include/vlc_strings.h
@@ -116,8 +116,29 @@ VLC_API void vlc_xml_decode(char *st);
*/
VLC_API char *vlc_xml_encode(const char *str) VLC_MALLOC;
-VLC_API char * vlc_b64_encode_binary( const uint8_t *, size_t );
-VLC_API char * vlc_b64_encode( const char * );
+/**
+ * Base64 encoding.
+ *
+ * Encodes a buffer into base64 as a (nul-terminated) string.
+ *
+ * \param base start address of buffer to encode
+ * \param length length in bytes of buffer to encode
+ * \return a heap-allocated nul-terminated string
+ * (or NULL on allocation error).
+ */
+VLC_API char *vlc_b64_encode_binary(const void *base, size_t length)
+VLC_USED VLC_MALLOC;
+
+/**
+ * Base64 encoding (string).
+ *
+ * Encodes a nul-terminated string into Base64.
+ *
+ * \param str nul-terminated string to encode
+ * \return a heap-allocated nul-terminated string
+ * (or NULL on allocation error).
+ */
+VLC_API char *vlc_b64_encode(const char *str) VLC_USED VLC_MALLOC;
VLC_API size_t vlc_b64_decode_binary_to_buffer( uint8_t *p_dst, size_t i_dst_max, const char *psz_src );
VLC_API size_t vlc_b64_decode_binary( uint8_t **pp_dst, const char *psz_src );
diff --git a/src/text/strings.c b/src/text/strings.c
index 6fc57d5d92..6987daed0e 100644
--- a/src/text/strings.c
+++ b/src/text/strings.c
@@ -347,58 +347,59 @@ char *vlc_xml_encode (const char *str)
}
/* Base64 encoding */
-char *vlc_b64_encode_binary( const uint8_t *src, size_t i_src )
+char *vlc_b64_encode_binary(const void *src, size_t length)
{
static const char b64[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ const unsigned char *in = src;
+ char *dst = malloc((((length + 2) / 3) * 4) + 1);
+ char *out = dst;
- char *ret = malloc( ( i_src + 4 ) * 4 / 3 );
- char *dst = ret;
-
- if( dst == NULL )
+ if (unlikely(dst == NULL))
return NULL;
- while( i_src > 0 )
- {
- /* pops (up to) 3 bytes of input, push 4 bytes */
- uint32_t v;
-
- /* 1/3 -> 1/4 */
- v = ((unsigned)*src++) << 24;
- *dst++ = b64[v >> 26];
- v = v << 6;
-
- /* 2/3 -> 2/4 */
- if( i_src >= 2 )
- v |= *src++ << 22;
- *dst++ = b64[v >> 26];
- v = v << 6;
-
- /* 3/3 -> 3/4 */
- if( i_src >= 3 )
- v |= *src++ << 20; // 3/3
- *dst++ = ( i_src >= 2 ) ? b64[v >> 26] : '='; // 3/4
- v = v << 6;
-
- /* -> 4/4 */
- *dst++ = ( i_src >= 3 ) ? b64[v >> 26] : '='; // 4/4
-
- if( i_src <= 3 )
- break;
- i_src -= 3;
+ while (length >= 3) { /* pops (up to) 3 bytes of input, push 4 bytes */
+ uint_fast32_t v = (in[0] << 16) | (in[1] << 8) | in[2];
+
+ *(out++) = b64[(v >> 18)];
+ *(out++) = b64[(v >> 12) & 0x3f];
+ *(out++) = b64[(v >> 6) & 0x3f];
+ *(out++) = b64[(v >> 0) & 0x3f];
+ in += 3;
+ length -= 3;
}
- *dst = '\0';
+ switch (length) {
+ case 2: {
+ uint_fast16_t v = (in[0] << 8) | in[1];
+
+ *(out++) = b64[(v >> 10)];
+ *(out++) = b64[(v >> 4) & 0x3f];
+ *(out++) = b64[(v << 2) & 0x3f];
+ *(out++) = '=';
+ break;
+ }
+
+ case 1: {
+ uint_fast8_t v = in[0];
+
+ *(out++) = b64[(v >> 2)];
+ *(out++) = b64[(v << 4) & 0x3f];
+ *(out++) = '=';
+ *(out++) = '=';
+ break;
+ }
+ }
- return ret;
+ *out = '\0';
+ return dst;
}
-char *vlc_b64_encode( const char *src )
+char *vlc_b64_encode(const char *src)
{
- if( src )
- return vlc_b64_encode_binary( (const uint8_t*)src, strlen(src) );
- else
- return vlc_b64_encode_binary( (const uint8_t*)"", 0 );
+ if (src == NULL)
+ src = "";
+ return vlc_b64_encode_binary(src, strlen(src));
}
/* Base64 decoding */
More information about the vlc-commits
mailing list