From cd636cf42dad21bdd474fd413d0aec4457670110 Mon Sep 17 00:00:00 2001 From: Julien BLACHE Date: Fri, 1 May 2009 20:56:22 +0200 Subject: [PATCH] Add base64 decoding routine --- src/misc.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/misc.h | 3 ++ 2 files changed, 97 insertions(+) diff --git a/src/misc.c b/src/misc.c index 87f6dbaf..f6b204bb 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,6 +1,9 @@ /* * Copyright (C) 2009 Julien BLACHE * + * Pieces of code adapted from mt-daapd: + * Copyright (C) 2003-2007 Ron Pedde (ron@pedde.com) + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -110,3 +113,94 @@ djb_hash(void *data, size_t len) return hash; } + + +static unsigned char b64_decode_table[256]; + +char * +b64_decode(const char *b64) +{ + char *str; + const unsigned char *iptr; + unsigned char *optr; + unsigned char c; + int len; + int i; + + if (b64_decode_table[0] == 0) + { + memset(b64_decode_table, 0xff, sizeof(b64_decode_table)); + + /* Base64 encoding: A-Za-z0-9+/ */ + for (i = 0; i < 26; i++) + { + b64_decode_table['A' + i] = i; + b64_decode_table['a' + i] = i + 26; + } + + for (i = 0; i < 10; i++) + b64_decode_table['0' + i] = i + 52; + + b64_decode_table['+'] = 62; + b64_decode_table['/'] = 63; + + /* Stop on '=' */ + b64_decode_table['='] = 100; /* > 63 */ + } + + len = strlen(b64); + + str = (char *)malloc(len); + if (!str) + return NULL; + + memset(str, 0, len); + + iptr = (const unsigned char *)b64; + optr = (unsigned char *)str; + i = 0; + + while (len) + { + if (*iptr == '=') + break; + + c = b64_decode_table[*iptr]; + if (c > 63) + { + iptr++; + len--; + continue; + } + + switch (i) + { + case 0: + optr[0] = c << 2; + break; + case 1: + optr[0] |= c >> 4; + optr[1] = c << 4; + break; + case 2: + optr[1] |= c >> 2; + optr[2] = c << 6; + break; + case 3: + optr[2] |= c; + break; + } + + i++; + if (i == 4) + { + optr += 3; + i = 0; + } + + len--; + iptr++; + } + + return str; +} diff --git a/src/misc.h b/src/misc.h index 4f4f2748..61a25c44 100644 --- a/src/misc.h +++ b/src/misc.h @@ -13,4 +13,7 @@ safe_atol(const char *str, long *val); uint32_t djb_hash(void *data, size_t len); +char * +b64_decode(const char *b64); + #endif /* !__MISC_H__ */