From: Paul Eggert Date: Wed, 25 Oct 2023 21:00:40 +0000 (-0700) Subject: base64: new function isubase64; also, tune. X-Git-Tag: v1.0~683 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=48d0d5e95f0ae115f8b7097efbeda73e453091fc;p=gnulib.git 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. (uchar_in_range): Remove. All uses removed. (isbase64, base64_decode_ctx_init): Move to lib/base64.h and make inline. * lib/base64.h: Ignore -Wtype-limits, so that we needn’t worry about uchar_in_range. (BASE64_INLINE): Define, and use _GL_INLINE_HEADER_BEGIN. (isubase64): New function, useful as it as a different signature. (isbase64): Define in terms of isubase64. * modules/base64 (Depends-on): Add extern-inline. --- diff --git a/ChangeLog b/ChangeLog index 67ab92d10a..e7f3c293de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2023-10-25 Paul Eggert + + 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. + (uchar_in_range): Remove. All uses removed. + (isbase64, base64_decode_ctx_init): + Move to lib/base64.h and make inline. + * lib/base64.h: Ignore -Wtype-limits, so that we needn’t + worry about uchar_in_range. + (BASE64_INLINE): Define, and use _GL_INLINE_HEADER_BEGIN. + (isubase64): New function, useful as it as a different signature. + (isbase64): Define in terms of isubase64. + * modules/base64 (Depends-on): Add extern-inline. + 2023-10-24 Paul Eggert tests/unistr/u16-chr-tests: pacify -Wcast-align diff --git a/lib/base64.c b/lib/base64.c index 95b669aac7..59a2135bf1 100644 --- a/lib/base64.c +++ b/lib/base64.c @@ -42,6 +42,7 @@ #include /* Get prototype. */ +#define BASE64_INLINE _GL_EXTERN_INLINE #include "base64.h" /* Get imalloc. */ @@ -49,9 +50,6 @@ #include -/* Get UCHAR_MAX. */ -#include - #include /* Convert 'char' to 'unsigned char' without casting. */ @@ -242,7 +240,7 @@ base64_encode_alloc (const char *in, idx_t inlen, char **out) : (_) == '/' ? 63 \ : -1) -static const signed char b64[0x100] = { +signed char const base64_to_int[256] = { B64 (0), B64 (1), B64 (2), B64 (3), B64 (4), B64 (5), B64 (6), B64 (7), B64 (8), B64 (9), B64 (10), B64 (11), @@ -309,28 +307,6 @@ static const signed char b64[0x100] = { B64 (252), B64 (253), B64 (254), B64 (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 Base64 alphabet, and - false otherwise. Note that '=' is padding and not considered to be - part of the alphabet. */ -bool -isbase64 (char ch) -{ - return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)]; -} - -/* Initialize decode-context buffer, CTX. */ -void -base64_decode_ctx_init (struct base64_decode_context *ctx) -{ - ctx->i = 0; -} - /* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and none of those four is a newline, then return *IN. Otherwise, copy up to 4 - CTX->i non-newline bytes from that range into CTX->buf, starting at @@ -405,8 +381,8 @@ decode_4 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = ((b64[to_uchar (in[0])] << 2) - | (b64[to_uchar (in[1])] >> 4)); + *out++ = ((base64_to_int[to_uchar (in[0])] << 2) + | (base64_to_int[to_uchar (in[1])] >> 4)); --*outleft; } @@ -428,8 +404,8 @@ decode_4 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0) - | (b64[to_uchar (in[2])] >> 2)); + *out++ = (((base64_to_int[to_uchar (in[1])] << 4) & 0xf0) + | (base64_to_int[to_uchar (in[2])] >> 2)); --*outleft; } @@ -448,8 +424,8 @@ decode_4 (char const *restrict in, idx_t inlen, if (*outleft) { - *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0) - | b64[to_uchar (in[3])]); + *out++ = (((base64_to_int[to_uchar (in[2])] << 6) & 0xc0) + | base64_to_int[to_uchar (in[3])]); --*outleft; } } diff --git a/lib/base64.h b/lib/base64.h index b5cb2ea5cb..133d2d1356 100644 --- a/lib/base64.h +++ b/lib/base64.h @@ -16,23 +16,33 @@ along with this program. If not, see . */ #ifndef BASE64_H -# define BASE64_H +#define BASE64_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 +#include -# ifdef __cplusplus +/* Pacify GCC in isubase64. */ +#if defined __GNUC__ && 4 < __GNUC__ + (3 <= __GNUC_MINOR__) +# pragma GCC diagnostic ignored "-Wtype-limits" +#endif + +_GL_INLINE_HEADER_BEGIN +#ifndef BASE64_INLINE +# define BASE64_INLINE _GL_INLINE +#endif + +#ifdef __cplusplus extern "C" { -# endif +#endif /* This uses that the expression (n+(k-1))/k means the smallest integer >= n/k, i.e., the ceiling of n/k. */ -# define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4) +#define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4) struct base64_decode_context { @@ -40,14 +50,31 @@ struct base64_decode_context char buf[4]; }; -extern bool isbase64 (char ch) _GL_ATTRIBUTE_CONST; +extern signed char const base64_to_int[256]; + +BASE64_INLINE bool +isubase64 (unsigned char ch) +{ + return ch < sizeof base64_to_int && 0 <= base64_to_int[ch]; +} + +BASE64_INLINE bool +isbase64 (char ch) +{ + return isubase64 (ch); +} extern void base64_encode (const char *restrict in, idx_t inlen, char *restrict out, idx_t outlen); extern idx_t base64_encode_alloc (const char *in, idx_t inlen, char **out); -extern void base64_decode_ctx_init (struct base64_decode_context *ctx); +/* Initialize decode-context buffer, CTX. */ +BASE64_INLINE void +base64_decode_ctx_init (struct base64_decode_context *ctx) +{ + ctx->i = 0; +} extern bool base64_decode_ctx (struct base64_decode_context *ctx, const char *restrict in, idx_t inlen, @@ -63,8 +90,10 @@ extern bool base64_decode_alloc_ctx (struct base64_decode_context *ctx, #define base64_decode_alloc(in, inlen, out, outlen) \ base64_decode_alloc_ctx (NULL, in, inlen, out, outlen) -# ifdef __cplusplus +#ifdef __cplusplus } -# endif +#endif + +_GL_INLINE_HEADER_END #endif /* BASE64_H */ diff --git a/modules/base64 b/modules/base64 index 278e52fc8b..8956c44af8 100644 --- a/modules/base64 +++ b/modules/base64 @@ -7,6 +7,7 @@ lib/base64.c m4/base64.m4 Depends-on: +extern-inline ialloc stdbool memchr