From: Jan Kiszka <jan.kiszka@web.de>
To: Blue Swirl <blauwirbel@gmail.com>
Cc: Anthony Liguori <aliguori@us.ibm.com>,
Juan Quintela <quintela@redhat.com>,
Jan Kiszka <jan.kiszka@siemens.com>,
qemu-devel@nongnu.org, Markus Armbruster <armbru@redhat.com>,
Avi Kivity <avi@redhat.com>,
Luiz Capitulino <lcapitulino@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v2 08/15] Add base64 encoder/decoder
Date: Sun, 23 May 2010 09:55:25 +0200 [thread overview]
Message-ID: <4BF8DF6D.20409@web.de> (raw)
In-Reply-To: <AANLkTil9OcJ7oomdYMK-kA3z4lqPLS_MXplCO3rV03Yr@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 7503 bytes --]
Blue Swirl wrote:
> On Sat, May 22, 2010 at 8:18 AM, Jan Kiszka <jan.kiszka@web.de> wrote:
>> From: Jan Kiszka <jan.kiszka@siemens.com>
>>
>> Will be used by QBuffer.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>> 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 <jan.kiszka@siemens.com>
>> + *
>> + * 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>?
Oops, no intention.
>
>> +#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.
The output may but need not be a string, it's binary data. And to avoid
needless warnings about signedness mismatches if unsigned char or
uint8_t buffers are passed, I chose void *.
>
>> +{
>> + 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 <jan.kiszka@siemens.com>
>> + *
>> + * 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?
Makes sense.
>
>> +
>> +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
>>
>>
>>
Thanks,
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]
next prev parent reply other threads:[~2010-05-23 7:55 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-22 8:17 [Qemu-devel] [PATCH v2 00/15] Basic device state visualization Jan Kiszka
2010-05-22 8:17 ` [Qemu-devel] [PATCH v2 01/15] Add dependency of JSON unit tests on config-host.h Jan Kiszka
2010-05-22 8:17 ` [Qemu-devel] [PATCH v2 02/15] qdev: Fix scanning across single-bus devices Jan Kiszka
2010-05-29 7:38 ` Markus Armbruster
2010-05-29 7:56 ` Jan Kiszka
2010-05-31 9:45 ` Gerd Hoffmann
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 03/15] qdev: Allow device addressing via 'driver.instance' Jan Kiszka
2010-05-29 7:50 ` Markus Armbruster
2010-05-29 8:09 ` Jan Kiszka
2010-05-31 8:43 ` Markus Armbruster
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 04/15] qdev: Convert device and bus lists to QTAILQ Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 05/15] qdev: Allow device specification by qtree path for device_del Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 06/15] qdev: Push QMP mode checks into qbus_list_bus/dev Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 07/15] monitor: Add completion for qdev paths Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 08/15] Add base64 encoder/decoder Jan Kiszka
2010-05-22 13:59 ` Blue Swirl
2010-05-23 7:55 ` Jan Kiszka [this message]
2010-05-23 8:48 ` Avi Kivity
2010-05-23 10:04 ` Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 09/15] QMP: Reserve namespace for complex object classes Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 10/15] Add QBuffer Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 11/15] monitor: return length of printed string via monitor_[v]printf Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 12/15] monitor: Add basic device state visualization Jan Kiszka
2010-05-22 18:55 ` [Qemu-devel] " Avi Kivity
2010-05-23 7:57 ` Jan Kiszka
2010-05-23 8:44 ` Avi Kivity
2010-05-23 10:03 ` Jan Kiszka
2010-05-23 10:42 ` Avi Kivity
2010-05-29 8:00 ` Markus Armbruster
2010-05-29 8:14 ` Jan Kiszka
2010-05-30 8:26 ` Avi Kivity
2010-05-30 12:36 ` Jan Kiszka
2010-05-31 8:46 ` Markus Armbruster
2010-05-31 8:58 ` Jan Kiszka
2010-05-31 11:07 ` Markus Armbruster
2010-05-31 11:11 ` Jan Kiszka
2010-05-24 12:51 ` Luiz Capitulino
2010-05-24 20:22 ` Anthony Liguori
2010-05-24 20:22 ` Anthony Liguori
2010-05-24 20:35 ` Jan Kiszka
2010-05-24 21:49 ` Anthony Liguori
2010-05-24 22:12 ` Jan Kiszka
2010-05-24 22:27 ` Anthony Liguori
2010-05-25 7:23 ` Avi Kivity
2010-05-25 13:03 ` Anthony Liguori
2010-05-25 13:19 ` Avi Kivity
2010-05-25 13:31 ` Anthony Liguori
2010-05-25 13:41 ` Avi Kivity
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 13/15] QMP: Teach basic capability negotiation to python example Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 14/15] QMP: Fix python helper /wrt long return strings Jan Kiszka
2010-05-22 8:18 ` [Qemu-devel] [PATCH v2 15/15] QMP: Add support for buffer class to qmp python helper Jan Kiszka
2010-05-22 14:05 ` [Qemu-devel] [PATCH v2 00/15] Basic device state visualization Blue Swirl
2010-05-23 7:55 ` Jan Kiszka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4BF8DF6D.20409@web.de \
--to=jan.kiszka@web.de \
--cc=aliguori@us.ibm.com \
--cc=armbru@redhat.com \
--cc=avi@redhat.com \
--cc=blauwirbel@gmail.com \
--cc=jan.kiszka@siemens.com \
--cc=lcapitulino@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.