aboutsummaryrefslogtreecommitdiffstats
path: root/src/base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base64.c')
-rw-r--r--src/base64.c94
1 files changed, 51 insertions, 43 deletions
diff --git a/src/base64.c b/src/base64.c
index 763c2d2e..6f292d02 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -32,7 +32,7 @@
@see <a href="http://tools.ietf.org/html/rfc3548#section-3">RFC3548 S3</a>.
*/
static const uint8_t b64_map[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
Base64 decoding table.
@@ -42,27 +42,28 @@ static const uint8_t b64_map[] =
A '$' is a placeholder for characters not in the base64 alphabet.
*/
static const char b64_unmap[] =
- "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$m$$$ncdefghijkl$$$$$$"
- "$/0123456789:;<=>?@ABCDEFGH$$$$$$IJKLMNOPQRSTUVWXYZ[\\]^_`ab$$$$"
- "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"
- "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$";
+ "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$m$$$ncdefghijkl$$$$$$"
+ "$/0123456789:;<=>?@ABCDEFGH$$$$$$IJKLMNOPQRSTUVWXYZ[\\]^_`ab$$$$"
+ "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"
+ "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$";
/** Encode 3 raw bytes to 4 base64 characters. */
static inline void
encode_chunk(uint8_t out[4], const uint8_t in[3], size_t n_in)
{
- out[0] = b64_map[in[0] >> 2];
- out[1] = b64_map[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
- out[2] = ((n_in > 1)
- ? (b64_map[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)])
- : (uint8_t)'=');
- out[3] = ((n_in > 2) ? b64_map[in[2] & 0x3F] : (uint8_t)'=');
+ out[0] = b64_map[in[0] >> 2];
+ out[1] = b64_map[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
+
+ out[2] = (n_in > 1) ? (b64_map[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)])
+ : (uint8_t)'=';
+
+ out[3] = ((n_in > 2) ? b64_map[in[2] & 0x3F] : (uint8_t)'=');
}
size_t
serd_base64_get_length(const size_t size, const bool wrap_lines)
{
- return (size + 2) / 3 * 4 + (wrap_lines * ((size - 1) / 57));
+ return (size + 2) / 3 * 4 + (wrap_lines * ((size - 1) / 57));
}
bool
@@ -71,54 +72,61 @@ serd_base64_encode(uint8_t* const str,
const size_t size,
const bool wrap_lines)
{
- bool has_newline = false;
- for (size_t i = 0, j = 0; i < size; i += 3, j += 4) {
- uint8_t in[4] = { 0, 0, 0, 0 };
- size_t n_in = MIN(3, size - i);
- memcpy(in, (const uint8_t*)buf + i, n_in);
+ bool has_newline = false;
+
+ for (size_t i = 0, j = 0; i < size; i += 3, j += 4) {
+ uint8_t in[4] = {0, 0, 0, 0};
+ size_t n_in = MIN(3, size - i);
+ memcpy(in, (const uint8_t*)buf + i, n_in);
- if (wrap_lines && i > 0 && (i % 57) == 0) {
- str[j++] = '\n';
- has_newline = true;
- }
+ if (wrap_lines && i > 0 && (i % 57) == 0) {
+ str[j++] = '\n';
+ has_newline = true;
+ }
- encode_chunk(str + j, in, n_in);
- }
+ encode_chunk(str + j, in, n_in);
+ }
- return has_newline;
+ return has_newline;
}
static inline uint8_t
unmap(const uint8_t in)
{
- return (uint8_t)(b64_unmap[in] - 47);
+ return (uint8_t)(b64_unmap[in] - 47);
}
/** Decode 4 base64 characters to 3 raw bytes. */
static inline size_t
decode_chunk(const uint8_t in[4], uint8_t out[3])
{
- out[0] = (uint8_t)(((unmap(in[0]) << 2)) | unmap(in[1]) >> 4);
- out[1] = (uint8_t)(((unmap(in[1]) << 4) & 0xF0) | unmap(in[2]) >> 2);
- out[2] = (uint8_t)(((unmap(in[2]) << 6) & 0xC0) | unmap(in[3]));
- return 1 + (in[2] != '=') + ((in[2] != '=') && (in[3] != '='));
+ out[0] = (uint8_t)(((unmap(in[0]) << 2)) | unmap(in[1]) >> 4);
+ out[1] = (uint8_t)(((unmap(in[1]) << 4) & 0xF0) | unmap(in[2]) >> 2);
+ out[2] = (uint8_t)(((unmap(in[2]) << 6) & 0xC0) | unmap(in[3]));
+ return 1 + (in[2] != '=') + ((in[2] != '=') && (in[3] != '='));
}
void*
serd_base64_decode(const uint8_t* str, size_t len, size_t* size)
{
- void* buf = malloc((len * 3) / 4 + 2);
- *size = 0;
- for (size_t i = 0, j = 0; i < len; j += 3) {
- uint8_t in[] = "====";
- size_t n_in = 0;
- for (; i < len && n_in < 4; ++n_in) {
- for (; i < len && !is_base64(str[i]); ++i) {} // Skip junk
- in[n_in] = str[i++];
- }
- if (n_in > 1) {
- *size += decode_chunk(in, (uint8_t*)buf + j);
- }
- }
- return buf;
+ void* buf = malloc((len * 3) / 4 + 2);
+
+ *size = 0;
+ for (size_t i = 0, j = 0; i < len; j += 3) {
+ uint8_t in[] = "====";
+ size_t n_in = 0;
+ for (; i < len && n_in < 4; ++n_in) {
+ for (; i < len && !is_base64(str[i]); ++i) {
+ // Skip junk
+ }
+
+ in[n_in] = str[i++];
+ }
+
+ if (n_in > 1) {
+ *size += decode_chunk(in, (uint8_t*)buf + j);
+ }
+ }
+
+ return buf;
}