[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/2] base64: new function isubase64; also, tune.
From: |
Paul Eggert |
Subject: |
[PATCH 1/2] base64: new function isubase64; also, tune. |
Date: |
Wed, 25 Oct 2023 14:18:10 -0700 |
* 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.
---
ChangeLog | 15 +++++++++++++++
lib/base64.c | 40 ++++++++--------------------------------
lib/base64.h | 49 +++++++++++++++++++++++++++++++++++++++----------
modules/base64 | 1 +
4 files changed, 63 insertions(+), 42 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 67ab92d10a..e7f3c293de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2023-10-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ 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 <eggert@cs.ucla.edu>
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 <config.h>
/* Get prototype. */
+#define BASE64_INLINE _GL_EXTERN_INLINE
#include "base64.h"
/* Get imalloc. */
@@ -49,9 +50,6 @@
#include <intprops.h>
-/* Get UCHAR_MAX. */
-#include <limits.h>
-
#include <string.h>
/* 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 <https://www.gnu.org/licenses/>. */
#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 <idx.h>
+#include <idx.h>
-# 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
--
2.41.0
- [PATCH 1/2] base64: new function isubase64; also, tune.,
Paul Eggert <=