qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 08/15] Add base64 encoder/decoder


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH v2 08/15] Add base64 encoder/decoder
Date: Sat, 22 May 2010 13:59:21 +0000

On Sat, May 22, 2010 at 8:18 AM, Jan Kiszka <address@hidden> wrote:
> From: Jan Kiszka <address@hidden>
>
> Will be used by QBuffer.
>
> Signed-off-by: Jan Kiszka <address@hidden>
> ---
>  Makefile.objs |    2 +-
>  base64.c      |  202 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  base64.h      |   18 +++++
>  3 files changed, 221 insertions(+), 1 deletions(-)
>  create mode 100644 base64.c
>  create mode 100644 base64.h
>
> diff --git a/Makefile.objs b/Makefile.objs
> index acbaf22..2c603b2 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -2,7 +2,7 @@
>  # QObject
>  qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
>  qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
> -qobject-obj-y += qerror.o
> +qobject-obj-y += qerror.o base64.o
>
>  #######################################################################
>  # block-obj-y is code used by both qemu system emulation and qemu-img
> diff --git a/base64.c b/base64.c
> new file mode 100644
> index 0000000..543e8c6
> --- /dev/null
> +++ b/base64.c
> @@ -0,0 +1,202 @@
> +/*
> + * Base64 encoder/decoder conforming to RFC 4648
> + * (based on Mozilla's nsprpub/lib/libc/src/base64.c)
> + *
> + * Copyright (C) 2010 Siemens AG
> + *
> + * Authors:
> + *  Jan Kiszka <address@hidden>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or 
> later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#include "inttypes.h"

Why not <inttypes.h>?

> +#include "base64.h"
> +
> +static const char base[] =
> +    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
> +
> +static void encode3to4(const char *src, char *dest)
> +{
> +    uint32_t b32 = 0;
> +    int i, j = 18;
> +
> +    for (i = 0; i < 3; i++) {
> +        b32 <<= 8;
> +        b32 |= src[i];
> +    }
> +    for (i = 0; i < 4; i++) {
> +        dest[i] = base[(b32 >> j) & 0x3F];
> +        j -= 6;
> +    }
> +}
> +
> +static void encode2to4(const char *src, char *dest)
> +{
> +    dest[0] = base[(src[0] >> 2) & 0x3F];
> +    dest[1] = base[((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)];
> +    dest[2] = base[(src[1] & 0x0F) << 2];
> +    dest[3] = '=';
> +}
> +
> +static void encode1to4(const char *src, char *dest)
> +{
> +    dest[0] = base[(src[0] >> 2) & 0x3F];
> +    dest[1] = base[(src[0] & 0x03) << 4];
> +    dest[2] = '=';
> +    dest[3] = '=';
> +}
> +
> +/*
> + * Encode data in 'src' of length 'srclen' to a base64 string, saving the
> + * null-terminated result in 'dest'. The size of the destition buffer must be
> + * at least ((srclen + 2) / 3) * 4 + 1.
> + */
> +void base64_encode(const void *src, size_t srclen, char *dest)
> +{
> +    while (srclen >= 3) {
> +        encode3to4(src, dest);
> +        src += 3;
> +        dest += 4;
> +        srclen -= 3;
> +    }
> +    switch (srclen) {
> +    case 2:
> +        encode2to4(src, dest);
> +        dest += 4;
> +        break;
> +    case 1:
> +        encode1to4(src, dest);
> +        dest += 4;
> +        break;
> +    case 0:
> +        break;
> +    }
> +    dest[0] = 0;
> +}
> +
> +static int32_t codetovalue(char c)
> +{
> +    if (c >= 'A' && c <= 'Z') {
> +        return c - 'A';
> +    } else if (c >= 'a' && c <= 'z') {
> +        return c - 'a' + 26;
> +    } else if (c >= '0' && c <= '9') {
> +        return c - '0' + 52;
> +    } else if (c == '+') {
> +        return 62;
> +    } else if ( c == '/') {
> +        return 63;
> +    } else {
> +        return -1;
> +    }
> +}
> +
> +static int decode4to3 (const char *src, char *dest)
> +{
> +    uint32_t b32 = 0;
> +    int32_t bits;
> +    int i;
> +
> +    for (i = 0; i < 4; i++) {
> +        bits = codetovalue(src[i]);
> +        if (bits < 0) {
> +            return bits;
> +        }
> +        b32 <<= 6;
> +        b32 |= bits;
> +    }
> +    dest[0] = (b32 >> 16) & 0xFF;
> +    dest[1] = (b32 >> 8) & 0xFF;
> +    dest[2] = b32 & 0xFF;
> +
> +    return 0;
> +}
> +
> +static int decode3to2(const char *src, char *dest)
> +{
> +    uint32_t b32 = 0;
> +    int32_t bits;
> +
> +    bits = codetovalue(src[0]);
> +    if (bits < 0) {
> +        return bits;
> +    }
> +    b32 = (uint32_t)bits;
> +    b32 <<= 6;
> +
> +    bits = codetovalue(src[1]);
> +    if (bits < 0) {
> +        return bits;
> +    }
> +    b32 |= (uint32_t)bits;
> +    b32 <<= 4;
> +
> +    bits = codetovalue(src[2]);
> +    if (bits < 0) {
> +        return bits;
> +    }
> +    b32 |= ((uint32_t)bits) >> 2;
> +
> +    dest[0] = (b32 >> 8) & 0xFF;
> +    dest[1] = b32 & 0xFF;
> +
> +    return 0;
> +}
> +
> +static int decode2to1(const char *src, char *dest)
> +{
> +    uint32_t b32;
> +    int32_t bits;
> +
> +    bits = codetovalue(src[0]);
> +    if (bits < 0) {
> +        return bits;
> +    }
> +    b32 = (uint32_t)bits << 2;
> +
> +    bits = codetovalue(src[1]);
> +    if (bits < 0) {
> +        return bits;
> +    }
> +    b32 |= ((uint32_t)bits) >> 4;
> +
> +    dest[0] = b32;
> +
> +    return 0;
> +}
> +
> +/*
> + * Convert string 'src' of length 'srclen' from base64 to binary form,
> + * saving the result in 'dest'. The size of the destination buffer must be at
> + * least srclen * 3 / 4.
> + *
> + * Returns 0 on success, -1 on conversion error.
> + */
> +int base64_decode(const char *src, size_t srclen, void *dest)

I think dest should be char *, like all the functions where dest is passed to.

> +{
> +    int ret;
> +
> +    while (srclen >= 4) {
> +        ret = decode4to3(src, dest);
> +        if (ret < 0) {
> +            return ret;
> +        }
> +        src += 4;
> +        dest += 3;
> +        srclen -= 4;
> +    }
> +
> +    switch (srclen) {
> +    case 3:
> +        return decode3to2(src, dest);
> +    case 2:
> +        return decode2to1(src, dest);
> +    case 1:
> +        return -1;
> +    default: /* 0 */
> +        return 0;
> +    }
> +}
> diff --git a/base64.h b/base64.h
> new file mode 100644
> index 0000000..9a0e03a
> --- /dev/null
> +++ b/base64.h
> @@ -0,0 +1,18 @@
> +/*
> + * Base64 encoder/decoder conforming to RFC 4648
> + * (based on Mozilla's nsprpub/lib/libc/src/base64.c)
> + *
> + * Copyright (C) 2010 Siemens AG
> + *
> + * Authors:
> + *  Jan Kiszka <address@hidden>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or 
> later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#include <unistd.h>

Maybe <stddef.h> instead, it's only for size_t?

> +
> +void base64_encode(const void *src, size_t srclen, char *dest);
> +int base64_decode(const char *src, size_t srclen, void *dest);
> --
> 1.6.0.2
>
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]