From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=45304 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OG624-0005ke-Qs for qemu-devel@nongnu.org; Sun, 23 May 2010 03:55:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OG622-0003uz-Pd for qemu-devel@nongnu.org; Sun, 23 May 2010 03:55:36 -0400 Received: from fmmailgate03.web.de ([217.72.192.234]:43942) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OG622-0003uq-9V for qemu-devel@nongnu.org; Sun, 23 May 2010 03:55:34 -0400 Message-ID: <4BF8DF6D.20409@web.de> Date: Sun, 23 May 2010 09:55:25 +0200 From: Jan Kiszka MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH v2 08/15] Add base64 encoder/decoder References: In-Reply-To: Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enig17710524D7CFA9096B8D7A38" Sender: jan.kiszka@web.de List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Blue Swirl Cc: Anthony Liguori , Juan Quintela , Jan Kiszka , qemu-devel@nongnu.org, Markus Armbruster , Avi Kivity , Luiz Capitulino This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig17710524D7CFA9096B8D7A38 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Blue Swirl wrote: > On Sat, May 22, 2010 at 8:18 AM, Jan Kiszka wrote: >> From: Jan Kiszka >> >> Will be used by QBuffer. >> >> Signed-off-by: Jan Kiszka >> --- >> 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 =3D qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o >> qobject-obj-y +=3D qjson.o json-lexer.o json-streamer.o json-parser.o= >> -qobject-obj-y +=3D qerror.o >> +qobject-obj-y +=3D 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 >> + * >> + * 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" >=20 > Why not ? Oops, no intention. >=20 >> +#include "base64.h" >> + >> +static const char base[] =3D >> + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= "; >> + >> +static void encode3to4(const char *src, char *dest) >> +{ >> + uint32_t b32 =3D 0; >> + int i, j =3D 18; >> + >> + for (i =3D 0; i < 3; i++) { >> + b32 <<=3D 8; >> + b32 |=3D src[i]; >> + } >> + for (i =3D 0; i < 4; i++) { >> + dest[i] =3D base[(b32 >> j) & 0x3F]; >> + j -=3D 6; >> + } >> +} >> + >> +static void encode2to4(const char *src, char *dest) >> +{ >> + dest[0] =3D base[(src[0] >> 2) & 0x3F]; >> + dest[1] =3D base[((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)]= ; >> + dest[2] =3D base[(src[1] & 0x0F) << 2]; >> + dest[3] =3D '=3D'; >> +} >> + >> +static void encode1to4(const char *src, char *dest) >> +{ >> + dest[0] =3D base[(src[0] >> 2) & 0x3F]; >> + dest[1] =3D base[(src[0] & 0x03) << 4]; >> + dest[2] =3D '=3D'; >> + dest[3] =3D '=3D'; >> +} >> + >> +/* >> + * 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 >=3D 3) { >> + encode3to4(src, dest); >> + src +=3D 3; >> + dest +=3D 4; >> + srclen -=3D 3; >> + } >> + switch (srclen) { >> + case 2: >> + encode2to4(src, dest); >> + dest +=3D 4; >> + break; >> + case 1: >> + encode1to4(src, dest); >> + dest +=3D 4; >> + break; >> + case 0: >> + break; >> + } >> + dest[0] =3D 0; >> +} >> + >> +static int32_t codetovalue(char c) >> +{ >> + if (c >=3D 'A' && c <=3D 'Z') { >> + return c - 'A'; >> + } else if (c >=3D 'a' && c <=3D 'z') { >> + return c - 'a' + 26; >> + } else if (c >=3D '0' && c <=3D '9') { >> + return c - '0' + 52; >> + } else if (c =3D=3D '+') { >> + return 62; >> + } else if ( c =3D=3D '/') { >> + return 63; >> + } else { >> + return -1; >> + } >> +} >> + >> +static int decode4to3 (const char *src, char *dest) >> +{ >> + uint32_t b32 =3D 0; >> + int32_t bits; >> + int i; >> + >> + for (i =3D 0; i < 4; i++) { >> + bits =3D codetovalue(src[i]); >> + if (bits < 0) { >> + return bits; >> + } >> + b32 <<=3D 6; >> + b32 |=3D bits; >> + } >> + dest[0] =3D (b32 >> 16) & 0xFF; >> + dest[1] =3D (b32 >> 8) & 0xFF; >> + dest[2] =3D b32 & 0xFF; >> + >> + return 0; >> +} >> + >> +static int decode3to2(const char *src, char *dest) >> +{ >> + uint32_t b32 =3D 0; >> + int32_t bits; >> + >> + bits =3D codetovalue(src[0]); >> + if (bits < 0) { >> + return bits; >> + } >> + b32 =3D (uint32_t)bits; >> + b32 <<=3D 6; >> + >> + bits =3D codetovalue(src[1]); >> + if (bits < 0) { >> + return bits; >> + } >> + b32 |=3D (uint32_t)bits; >> + b32 <<=3D 4; >> + >> + bits =3D codetovalue(src[2]); >> + if (bits < 0) { >> + return bits; >> + } >> + b32 |=3D ((uint32_t)bits) >> 2; >> + >> + dest[0] =3D (b32 >> 8) & 0xFF; >> + dest[1] =3D b32 & 0xFF; >> + >> + return 0; >> +} >> + >> +static int decode2to1(const char *src, char *dest) >> +{ >> + uint32_t b32; >> + int32_t bits; >> + >> + bits =3D codetovalue(src[0]); >> + if (bits < 0) { >> + return bits; >> + } >> + b32 =3D (uint32_t)bits << 2; >> + >> + bits =3D codetovalue(src[1]); >> + if (bits < 0) { >> + return bits; >> + } >> + b32 |=3D ((uint32_t)bits) >> 4; >> + >> + dest[0] =3D 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 mu= st 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) >=20 > I think dest should be char *, like all the functions where dest is pas= sed 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 *. >=20 >> +{ >> + int ret; >> + >> + while (srclen >=3D 4) { >> + ret =3D decode4to3(src, dest); >> + if (ret < 0) { >> + return ret; >> + } >> + src +=3D 4; >> + dest +=3D 3; >> + srclen -=3D 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 >> + * >> + * 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 >=20 > Maybe instead, it's only for size_t? Makes sense. >=20 >> + >> +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 --------------enig17710524D7CFA9096B8D7A38 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iEYEARECAAYFAkv433MACgkQitSsb3rl5xRURQCgkRfjeVV6fh4JyuQb9cVYcZiX KGcAoINVTU0qC0Kr4l22T7LLswpawMrB =0m7Z -----END PGP SIGNATURE----- --------------enig17710524D7CFA9096B8D7A38--