bug-gnulib
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]