[Top][All Lists]
[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
>
>
>
[Qemu-devel] [PATCH v2 04/15] qdev: Convert device and bus lists to QTAILQ, Jan Kiszka, 2010/05/22
[Qemu-devel] [PATCH v2 05/15] qdev: Allow device specification by qtree path for device_del, Jan Kiszka, 2010/05/22
[Qemu-devel] [PATCH v2 07/15] monitor: Add completion for qdev paths, Jan Kiszka, 2010/05/22
[Qemu-devel] [PATCH v2 11/15] monitor: return length of printed string via monitor_[v]printf, Jan Kiszka, 2010/05/22
[Qemu-devel] [PATCH v2 09/15] QMP: Reserve namespace for complex object classes, Jan Kiszka, 2010/05/22
[Qemu-devel] [PATCH v2 10/15] Add QBuffer, Jan Kiszka, 2010/05/22
[Qemu-devel] [PATCH v2 15/15] QMP: Add support for buffer class to qmp python helper, Jan Kiszka, 2010/05/22