* 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-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
#include <config.h>
/* Get prototype. */
+#define BASE64_INLINE _GL_EXTERN_INLINE
#include "base64.h"
/* Get imalloc. */
#include <intprops.h>
-/* Get UCHAR_MAX. */
-#include <limits.h>
-
#include <string.h>
/* Convert 'char' to 'unsigned char' without casting. */
: (_) == '/' ? 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),
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
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;
}
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;
}
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;
}
}
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
{
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,
#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 */
m4/base64.m4
Depends-on:
+extern-inline
ialloc
stdbool
memchr