diff options
Diffstat (limited to 'src/modules/raop/base64.c')
| -rw-r--r-- | src/modules/raop/base64.c | 126 | 
1 files changed, 126 insertions, 0 deletions
diff --git a/src/modules/raop/base64.c b/src/modules/raop/base64.c new file mode 100644 index 00000000..8918def8 --- /dev/null +++ b/src/modules/raop/base64.c @@ -0,0 +1,126 @@ +/*** +  This file is part of PulseAudio. + +  Copyright 2008 Colin Guthrie + +  PulseAudio is free software; you can redistribute it and/or modify +  it under the terms of the GNU Lesser General Public License as published +  by the Free Software Foundation; either version 2 of the License, +  or (at your option) any later version. + +  PulseAudio is distributed in the hope that it will be useful, but +  WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +  General Public License for more details. + +  You should have received a copy of the GNU Lesser General Public License +  along with PulseAudio; if not, write to the Free Software +  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +  USA. +***/ + +/* +  This file was originally inspired by a file developed by +    Kungliga Tekniska H�gskolan +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> + +#include <pulse/xmalloc.h> + +#include "base64.h" + +static const char base64_chars[] = +    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static int pos(char c) +{ +    if (c >= 'A' && c <= 'Z') return c - 'A' + 0; +    if (c >= 'a' && c <= 'z') return c - 'a' + 26; +    if (c >= '0' && c <= '9') return c - '0' + 52; +    if (c == '+') return 62; +    if (c == '/') return 63; +} + +int pa_base64_encode(const void *data, int size, char **str) +{ +    char *s, *p; +    int i; +    int c; +    const unsigned char *q; + +    p = s = pa_xnew(char, size * 4 / 3 + 4); +    q = (const unsigned char *) data; +    i = 0; +    for (i = 0; i < size;) { +        c = q[i++]; +        c *= 256; +        if (i < size) +            c += q[i]; +        i++; +        c *= 256; +        if (i < size) +            c += q[i]; +        i++; +        p[0] = base64_chars[(c & 0x00fc0000) >> 18]; +        p[1] = base64_chars[(c & 0x0003f000) >> 12]; +        p[2] = base64_chars[(c & 0x00000fc0) >> 6]; +        p[3] = base64_chars[(c & 0x0000003f) >> 0]; +        if (i > size) +            p[3] = '='; +        if (i > size + 1) +            p[2] = '='; +        p += 4; +    } +    *p = 0; +    *str = s; +    return strlen(s); +} + +#define DECODE_ERROR 0xffffffff + +static unsigned int token_decode(const char *token) +{ +    int i; +    unsigned int val = 0; +    int marker = 0; +    if (strlen(token) < 4) +        return DECODE_ERROR; +    for (i = 0; i < 4; i++) { +        val *= 64; +        if (token[i] == '=') +            marker++; +        else if (marker > 0) +            return DECODE_ERROR; +        else +            val += pos(token[i]); +    } +    if (marker > 2) +        return DECODE_ERROR; +    return (marker << 24) | val; +} + +int pa_base64_decode(const char *str, void *data) +{ +    const char *p; +    unsigned char *q; + +    q = data; +    for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) { +        unsigned int val = token_decode(p); +        unsigned int marker = (val >> 24) & 0xff; +        if (val == DECODE_ERROR) +            return -1; +        *q++ = (val >> 16) & 0xff; +        if (marker < 2) +            *q++ = (val >> 8) & 0xff; +        if (marker < 1) +            *q++ = val & 0xff; +    } +    return q - (unsigned char *) data; +}  | 
