From e15c7eab0bb6acca8192e6f50bced0be00493402 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 25 Oct 2023 14:14:15 -0700 Subject: [PATCH] base32: new function isubase32; also, tune. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * lib/base32.c (BASE32_INLINE): Define. (base32_to_int): Rename from b32 and make it extern. All uses changed. (uchar_in_range): Remove. All uses removed. (isbase32, base32_decode_ctx_init): Move to lib/base32.h and make inline. * lib/base32.h: Ignore -Wtype-limits, so that we needn’t worry about uchar_in_range. (BASE32_INLINE): Define, and use _GL_INLINE_HEADER_BEGIN. (isubase32): New function, useful as it as a different signature. (isbase32): Define in terms of isubase32. * modules/base32 (Depends-on): Add extern-inline. --- ChangeLog | 13 +++++++++++++ lib/base32.c | 52 ++++++++++++++------------------------------------ lib/base32.h | 51 ++++++++++++++++++++++++++++++++++++++++++------- modules/base32 | 1 + 4 files changed, 72 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7f3c293de..fed7803763 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2023-10-25 Paul Eggert + base32: new function isubase32; also, tune. + * lib/base32.c (BASE32_INLINE): Define. + (base32_to_int): Rename from b32 and make it extern. All uses changed. + (uchar_in_range): Remove. All uses removed. + (isbase32, base32_decode_ctx_init): + Move to lib/base32.h and make inline. + * lib/base32.h: Ignore -Wtype-limits, so that we needn’t + worry about uchar_in_range. + (BASE32_INLINE): Define, and use _GL_INLINE_HEADER_BEGIN. + (isubase32): New function, useful as it as a different signature. + (isbase32): Define in terms of isubase32. + * modules/base32 (Depends-on): Add extern-inline. + base64: new function isubase64; also, tune. * lib/base64.c (BASE64_INLINE): Define. (base64_to_int): Rename from b64 and make it extern. All uses changed. diff --git a/lib/base32.c b/lib/base32.c index 50f9d4201a..c1882c13a3 100644 --- a/lib/base32.c +++ b/lib/base32.c @@ -40,6 +40,7 @@ #include /* Get prototype. */ +#define BASE64_INLINE _GL_EXTERN_INLINE #include "base32.h" /* Get imalloc. */ @@ -47,9 +48,6 @@ #include -/* Get UCHAR_MAX. */ -#include - #include /* Convert 'char' to 'unsigned char' without casting. */ @@ -205,7 +203,7 @@ base32_encode_alloc (const char *in, idx_t inlen, char **out) : (_) == '7' ? 31 \ : -1) -static const signed char b32[0x100] = { +signed char const base32_to_int[256] = { B32 (0), B32 (1), B32 (2), B32 (3), B32 (4), B32 (5), B32 (6), B32 (7), B32 (8), B32 (9), B32 (10), B32 (11), @@ -272,28 +270,6 @@ static const signed char b32[0x100] = { B32 (252), B32 (253), B32 (254), B32 (255) }; -#if UCHAR_MAX == 255 -# define uchar_in_range(c) true -#else -# define uchar_in_range(c) ((c) <= 255) -#endif - -/* Return true if CH is a character from the Base32 alphabet, and - false otherwise. Note that '=' is padding and not considered to be - part of the alphabet. */ -bool -isbase32 (char ch) -{ - return uchar_in_range (to_uchar (ch)) && 0 <= b32[to_uchar (ch)]; -} - -/* Initialize decode-context buffer, CTX. */ -void -base32_decode_ctx_init (struct base32_decode_context *ctx) -{ - ctx->i = 0; -} - /* If CTX->i is 0 or 8, there are eight or more bytes in [*IN..IN_END), and none of those eight is a newline, then return *IN. Otherwise, copy up to 4 - CTX->i non-newline bytes from that range into CTX->buf, starting at @@ -368,8 +344,8 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[0])] << 3) - | (b32[to_uchar (in[1])] >> 2)); + *out++ = ((base32_to_int[to_uchar (in[0])] << 3) + | (base32_to_int[to_uchar (in[1])] >> 2)); --*outleft; } @@ -386,9 +362,9 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[1])] << 6) - | (b32[to_uchar (in[2])] << 1) - | (b32[to_uchar (in[3])] >> 4)); + *out++ = ((base32_to_int[to_uchar (in[1])] << 6) + | (base32_to_int[to_uchar (in[2])] << 1) + | (base32_to_int[to_uchar (in[3])] >> 4)); --*outleft; } @@ -404,8 +380,8 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[3])] << 4) - | (b32[to_uchar (in[4])] >> 1)); + *out++ = ((base32_to_int[to_uchar (in[3])] << 4) + | (base32_to_int[to_uchar (in[4])] >> 1)); --*outleft; } @@ -421,9 +397,9 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[4])] << 7) - | (b32[to_uchar (in[5])] << 2) - | (b32[to_uchar (in[6])] >> 3)); + *out++ = ((base32_to_int[to_uchar (in[4])] << 7) + | (base32_to_int[to_uchar (in[5])] << 2) + | (base32_to_int[to_uchar (in[6])] >> 3)); --*outleft; } @@ -434,8 +410,8 @@ decode_8 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b32[to_uchar (in[6])] << 5) - | (b32[to_uchar (in[7])])); + *out++ = ((base32_to_int[to_uchar (in[6])] << 5) + | (base32_to_int[to_uchar (in[7])])); --*outleft; } } diff --git a/lib/base32.h b/lib/base32.h index 2e784d95c8..4f633bb290 100644 --- a/lib/base32.h +++ b/lib/base32.h @@ -16,19 +16,33 @@ along with this program. If not, see . */ #ifndef BASE32_H -# define BASE32_H +#define BASE32_H -/* This file uses _GL_ATTRIBUTE_CONST. */ +/* This file uses _GL_INLINE_HEADER_BEGIN. */ #if !_GL_CONFIG_H_INCLUDED #error "Please include config.h first." #endif -/* Get idx_t. */ -# include +/* Get idx_t. */ +#include + +/* Pacify GCC in isubase32. */ +#if defined __GNUC__ && 4 < __GNUC__ + (3 <= __GNUC_MINOR__) +# pragma GCC diagnostic ignored "-Wtype-limits" +#endif + +_GL_INLINE_HEADER_BEGIN +#ifndef BASE32_INLINE +# define BASE32_INLINE _GL_INLINE +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* This uses that the expression (n+(k-1))/k means the smallest integer >= n/k, i.e., the ceiling of n/k. */ -# define BASE32_LENGTH(inlen) ((((inlen) + 4) / 5) * 8) +#define BASE32_LENGTH(inlen) ((((inlen) + 4) / 5) * 8) struct base32_decode_context { @@ -36,14 +50,31 @@ struct base32_decode_context char buf[8]; }; -extern bool isbase32 (char ch) _GL_ATTRIBUTE_CONST; +extern signed char const base32_to_int[256]; + +BASE32_INLINE bool +isubase32 (unsigned char ch) +{ + return ch < sizeof base32_to_int && 0 <= base32_to_int[ch]; +} + +BASE32_INLINE bool +isbase32 (char ch) +{ + return isubase32 (ch); +} extern void base32_encode (const char *restrict in, idx_t inlen, char *restrict out, idx_t outlen); extern idx_t base32_encode_alloc (const char *in, idx_t inlen, char **out); -extern void base32_decode_ctx_init (struct base32_decode_context *ctx); +/* Initialize decode-context buffer, CTX. */ +BASE32_INLINE void +base32_decode_ctx_init (struct base32_decode_context *ctx) +{ + ctx->i = 0; +} extern bool base32_decode_ctx (struct base32_decode_context *ctx, const char *restrict in, idx_t inlen, @@ -59,4 +90,10 @@ extern bool base32_decode_alloc_ctx (struct base32_decode_context *ctx, #define base32_decode_alloc(in, inlen, out, outlen) \ base32_decode_alloc_ctx (NULL, in, inlen, out, outlen) +#ifdef __cplusplus +} +#endif + +_GL_INLINE_HEADER_END + #endif /* BASE32_H */ diff --git a/modules/base32 b/modules/base32 index 93c180b09d..85cbeeb8a8 100644 --- a/modules/base32 +++ b/modules/base32 @@ -7,6 +7,7 @@ lib/base32.c m4/base32.m4 Depends-on: +extern-inline ialloc stdbool memchr -- 2.39.5