[v5,3/4] iconv: make utf-7.c able to use variants
Commit Message
Add infrastructure in utf-7.c to handle variants. The approach comes from
iso646.c
The variant is defined at gconv_init time and is passed as a
supplementary variable.
Signed-off-by: Max Gautier <mg@max.gautier.name>
---
iconvdata/utf-7.c | 230 ++++++++++++++++++++++++++++++++++------------
1 file changed, 170 insertions(+), 60 deletions(-)
Comments
On 20/03/2022 13:42, Max Gautier via Libc-alpha wrote:
> Add infrastructure in utf-7.c to handle variants. The approach comes from
> iso646.c
> The variant is defined at gconv_init time and is passed as a
> supplementary variable.
>
> Signed-off-by: Max Gautier <mg@max.gautier.name>
Patch looks ok, although it should be refactor to add 'enum variant' argument
on isdirect and isxdirect instead of relying on previous patch (to keep the
patch consistent).
> ---
> iconvdata/utf-7.c | 230 ++++++++++++++++++++++++++++++++++------------
> 1 file changed, 170 insertions(+), 60 deletions(-)
>
> diff --git a/iconvdata/utf-7.c b/iconvdata/utf-7.c
> index 15f3669ac8..b639d8ff3e 100644
> --- a/iconvdata/utf-7.c
> +++ b/iconvdata/utf-7.c
> @@ -29,6 +29,24 @@
> #include <stdlib.h>
>
>
> +enum variant
> +{
> + UTF7,
> +};
> +
> +/* Must be in the same order as enum variant above. */
> +static const char names[] =
> + "UTF-7//\0"
> + "\0";
> +
> +static uint32_t
> +shift_character (enum variant const var)
> +{
> + if (var == UTF7)
> + return '+';
> + else
> + abort ();
> +}
>
> static bool
> between (uint32_t const ch,
> @@ -38,23 +56,27 @@ between (uint32_t const ch,
> }
>
> /* The set of "direct characters":
> + FOR UTF-7
> A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr
> */
>
> static bool
> isdirect (uint32_t ch, enum variant var)
> {
> - return (between (ch, 'A', 'Z')
> - || between (ch, 'a', 'z')
> - || between (ch, '0', '9')
> - || ch == '\'' || ch == '(' || ch == ')'
> - || between (ch, ',', '/')
> - || ch == ':' || ch == '?'
> - || ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
> + if (var == UTF7)
> + return (between (ch, 'A', 'Z')
> + || between (ch, 'a', 'z')
> + || between (ch, '0', '9')
> + || ch == '\'' || ch == '(' || ch == ')'
> + || between (ch, ',', '/')
> + || ch == ':' || ch == '?'
> + || ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
> + abort ();
> }
>
>
> /* The set of "direct and optional direct characters":
> + (UTF-7 only)
> A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr
> ! " # $ % & * ; < = > @ [ ] ^ _ ` { | }
> */
> @@ -62,10 +84,15 @@ isdirect (uint32_t ch, enum variant var)
> static bool
> isxdirect (uint32_t ch, enum variant var)
> {
> - return (ch == '\t'
> - || ch == '\n'
> - || ch == '\r'
> - || (between (ch, ' ', '}') && ch != '+' && ch != '\\'));
> + if (isdirect (ch, var))
> + return true;
> + if (var != UTF7)
> + return false;
> + return between (ch, '!', '&')
> + || ch == '*'
> + || between (ch, ';', '@')
> + || (between (ch, '[', '`') && ch != '\\')
> + || between (ch, '{', '}');
> }
>
>
> @@ -85,7 +112,7 @@ needs_explicit_shift (uint32_t ch)
>
> /* Converts a value in the range 0..63 to a base64 encoded char. */
> static unsigned char
> -base64 (unsigned int i)
> +base64 (unsigned int i, enum variant var)
> {
> if (i < 26)
> return i + 'A';
> @@ -95,7 +122,7 @@ base64 (unsigned int i)
> return i - 52 + '0';
> else if (i == 62)
> return '+';
> - else if (i == 63)
> + else if (i == 63 && var == UTF7)
> return '/';
> else
> abort ();
> @@ -103,9 +130,8 @@ base64 (unsigned int i)
>
>
> /* Definitions used in the body of the `gconv' function. */
> -#define CHARSET_NAME "UTF-7//"
> -#define DEFINE_INIT 1
> -#define DEFINE_FINI 1
> +#define DEFINE_INIT 0
> +#define DEFINE_FINI 0
> #define FROM_LOOP from_utf7_loop
> #define TO_LOOP to_utf7_loop
> #define MIN_NEEDED_FROM 1
> @@ -113,11 +139,27 @@ base64 (unsigned int i)
> #define MIN_NEEDED_TO 4
> #define MAX_NEEDED_TO 4
> #define ONE_DIRECTION 0
> +#define FROM_DIRECTION (dir == from_utf7)
> #define PREPARE_LOOP \
> mbstate_t saved_state; \
> - mbstate_t *statep = data->__statep;
> -#define EXTRA_LOOP_ARGS , statep
> + mbstate_t *statep = data->__statep; \
> + enum direction dir = ((struct utf7_data *) step->__data)->dir; \
> + enum direction var = ((struct utf7_data *) step->__data)->var;
> +#define EXTRA_LOOP_ARGS , statep, var
> +
>
> +enum direction
> +{
> + illegal_dir,
> + from_utf7,
> + to_utf7
> +};
> +
> +struct utf7_data
> +{
> + enum direction dir;
> + enum variant var;
> +};
>
> /* Since we might have to reset input pointer we must be able to save
> and restore the state. */
> @@ -127,6 +169,70 @@ base64 (unsigned int i)
> else \
> *statep = saved_state
>
> +int
> +gconv_init (struct __gconv_step *step)
> +{
> + /* Determine which direction. */
> + struct utf7_data *new_data;
> + enum direction dir = illegal_dir;
> +
> + enum variant var = 0;
> + for (const char *name = names; *name != '\0';
> + name = __rawmemchr (name, '\0') + 1)
> + {
> + if (__strcasecmp (step->__from_name, name) == 0)
> + {
> + dir = from_utf7;
> + break;
> + }
> + else if (__strcasecmp (step->__to_name, name) == 0)
> + {
> + dir = to_utf7;
> + break;
> + }
> + ++var;
> + }
> +
> + if (__glibc_likely (dir != illegal_dir))
> + {
> + new_data = malloc (sizeof (*new_data));
> + if (new_data == NULL)
> + return __GCONV_NOMEM;
> +
> + new_data->dir = dir;
> + new_data->var = var;
> + step->__data = new_data;
> +
> + if (dir == from_utf7)
> + {
> + step->__min_needed_from = MIN_NEEDED_FROM;
> + step->__max_needed_from = MAX_NEEDED_FROM;
> + step->__min_needed_to = MIN_NEEDED_TO;
> + step->__max_needed_to = MAX_NEEDED_TO;
> + }
> + else
> + {
> + step->__min_needed_from = MIN_NEEDED_TO;
> + step->__max_needed_from = MAX_NEEDED_TO;
> + step->__min_needed_to = MIN_NEEDED_FROM;
> + step->__max_needed_to = MAX_NEEDED_FROM;
> + }
> + }
> + else
> + return __GCONV_NOCONV;
> +
> + step->__stateful = 1;
> +
> + return __GCONV_OK;
> +}
> +
> +void
> +gconv_end (struct __gconv_step *data)
> +{
> + free (data->__data);
> +}
> +
> +
>
> /* First define the conversion function from UTF-7 to UCS4.
> The state is structured as follows:
> @@ -154,13 +260,13 @@ base64 (unsigned int i)
> if ((statep->__count >> 3) == 0) \
> { \
> /* base64 encoding inactive. */ \
> - if (isxdirect (ch)) \
> + if (isxdirect (ch, var)) \
> { \
> inptr++; \
> put32 (outptr, ch); \
> outptr += 4; \
> } \
> - else if (__glibc_likely (ch == '+')) \
> + else if (__glibc_likely (ch == shift_character (var))) \
> { \
> if (__glibc_unlikely (inptr + 2 > inend)) \
> { \
> @@ -285,7 +391,7 @@ base64 (unsigned int i)
> } \
> }
> #define LOOP_NEED_FLAGS
> -#define EXTRA_LOOP_DECLS , mbstate_t *statep
> +#define EXTRA_LOOP_DECLS , mbstate_t *statep, enum variant var
> #include <iconv/loop.c>
>
>
> @@ -316,7 +422,7 @@ base64 (unsigned int i)
> if ((statep->__count & 0x18) == 0) \
> { \
> /* base64 encoding inactive */ \
> - if (isdirect (ch)) \
> + if (isdirect (ch, var)) \
> { \
> *outptr++ = (unsigned char) ch; \
> } \
> @@ -324,7 +430,7 @@ base64 (unsigned int i)
> { \
> size_t count; \
> \
> - if (ch == '+') \
> + if (ch == shift_character (var)) \
> count = 2; \
> else if (ch < 0x10000) \
> count = 3; \
> @@ -339,13 +445,13 @@ base64 (unsigned int i)
> break; \
> } \
> \
> - *outptr++ = '+'; \
> - if (ch == '+') \
> + *outptr++ = shift_character (var); \
> + if (ch == shift_character (var)) \
> *outptr++ = '-'; \
> else if (ch < 0x10000) \
> { \
> - *outptr++ = base64 (ch >> 10); \
> - *outptr++ = base64 ((ch >> 4) & 0x3f); \
> + *outptr++ = base64 (ch >> 10, var); \
> + *outptr++ = base64 ((ch >> 4) & 0x3f, var); \
> statep->__count = ((ch & 15) << 5) | (3 << 3); \
> } \
> else if (ch < 0x110000) \
> @@ -354,11 +460,11 @@ base64 (unsigned int i)
> uint32_t ch2 = 0xdc00 + ((ch - 0x10000) & 0x3ff); \
> \
> ch = (ch1 << 16) | ch2; \
> - *outptr++ = base64 (ch >> 26); \
> - *outptr++ = base64 ((ch >> 20) & 0x3f); \
> - *outptr++ = base64 ((ch >> 14) & 0x3f); \
> - *outptr++ = base64 ((ch >> 8) & 0x3f); \
> - *outptr++ = base64 ((ch >> 2) & 0x3f); \
> + *outptr++ = base64 (ch >> 26, var); \
> + *outptr++ = base64 ((ch >> 20) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 14) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 8) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 2) & 0x3f, var); \
> statep->__count = ((ch & 3) << 7) | (2 << 3); \
> } \
> else \
> @@ -368,7 +474,7 @@ base64 (unsigned int i)
> else \
> { \
> /* base64 encoding active */ \
> - if (isdirect (ch)) \
> + if (isdirect (ch, var)) \
> { \
> /* deactivate base64 encoding */ \
> size_t count; \
> @@ -382,7 +488,7 @@ base64 (unsigned int i)
> } \
> \
> if ((statep->__count & 0x18) >= 0x10) \
> - *outptr++ = base64 ((statep->__count >> 3) & ~3); \
> + *outptr++ = base64 ((statep->__count >> 3) & ~3, var); \
> if (needs_explicit_shift (ch)) \
> *outptr++ = '-'; \
> *outptr++ = (unsigned char) ch; \
> @@ -410,22 +516,24 @@ base64 (unsigned int i)
> switch ((statep->__count >> 3) & 3) \
> { \
> case 1: \
> - *outptr++ = base64 (ch >> 10); \
> - *outptr++ = base64 ((ch >> 4) & 0x3f); \
> + *outptr++ = base64 (ch >> 10, var); \
> + *outptr++ = base64 ((ch >> 4) & 0x3f, var); \
> statep->__count = ((ch & 15) << 5) | (3 << 3); \
> break; \
> case 2: \
> *outptr++ = \
> - base64 (((statep->__count >> 3) & ~3) | (ch >> 12)); \
> - *outptr++ = base64 ((ch >> 6) & 0x3f); \
> - *outptr++ = base64 (ch & 0x3f); \
> + base64 (((statep->__count >> 3) & ~3) | (ch >> 12), \
> + var); \
> + *outptr++ = base64 ((ch >> 6) & 0x3f, var); \
> + *outptr++ = base64 (ch & 0x3f, var); \
> statep->__count = (1 << 3); \
> break; \
> case 3: \
> *outptr++ = \
> - base64 (((statep->__count >> 3) & ~3) | (ch >> 14)); \
> - *outptr++ = base64 ((ch >> 8) & 0x3f); \
> - *outptr++ = base64 ((ch >> 2) & 0x3f); \
> + base64 (((statep->__count >> 3) & ~3) | (ch >> 14), \
> + var); \
> + *outptr++ = base64 ((ch >> 8) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 2) & 0x3f, var); \
> statep->__count = ((ch & 3) << 7) | (2 << 3); \
> break; \
> default: \
> @@ -441,30 +549,32 @@ base64 (unsigned int i)
> switch ((statep->__count >> 3) & 3) \
> { \
> case 1: \
> - *outptr++ = base64 (ch >> 26); \
> - *outptr++ = base64 ((ch >> 20) & 0x3f); \
> - *outptr++ = base64 ((ch >> 14) & 0x3f); \
> - *outptr++ = base64 ((ch >> 8) & 0x3f); \
> - *outptr++ = base64 ((ch >> 2) & 0x3f); \
> + *outptr++ = base64 (ch >> 26, var); \
> + *outptr++ = base64 ((ch >> 20) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 14) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 8) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 2) & 0x3f, var); \
> statep->__count = ((ch & 3) << 7) | (2 << 3); \
> break; \
> case 2: \
> *outptr++ = \
> - base64 (((statep->__count >> 3) & ~3) | (ch >> 28)); \
> - *outptr++ = base64 ((ch >> 22) & 0x3f); \
> - *outptr++ = base64 ((ch >> 16) & 0x3f); \
> - *outptr++ = base64 ((ch >> 10) & 0x3f); \
> - *outptr++ = base64 ((ch >> 4) & 0x3f); \
> + base64 (((statep->__count >> 3) & ~3) | (ch >> 28), \
> + var); \
> + *outptr++ = base64 ((ch >> 22) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 16) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 10) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 4) & 0x3f, var); \
> statep->__count = ((ch & 15) << 5) | (3 << 3); \
> break; \
> case 3: \
> *outptr++ = \
> - base64 (((statep->__count >> 3) & ~3) | (ch >> 30)); \
> - *outptr++ = base64 ((ch >> 24) & 0x3f); \
> - *outptr++ = base64 ((ch >> 18) & 0x3f); \
> - *outptr++ = base64 ((ch >> 12) & 0x3f); \
> - *outptr++ = base64 ((ch >> 6) & 0x3f); \
> - *outptr++ = base64 (ch & 0x3f); \
> + base64 (((statep->__count >> 3) & ~3) | (ch >> 30), \
> + var); \
> + *outptr++ = base64 ((ch >> 24) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 18) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 12) & 0x3f, var); \
> + *outptr++ = base64 ((ch >> 6) & 0x3f, var); \
> + *outptr++ = base64 (ch & 0x3f, var); \
> statep->__count = (1 << 3); \
> break; \
> default: \
> @@ -480,7 +590,7 @@ base64 (unsigned int i)
> inptr += 4; \
> }
> #define LOOP_NEED_FLAGS
> -#define EXTRA_LOOP_DECLS , mbstate_t *statep
> +#define EXTRA_LOOP_DECLS , mbstate_t *statep, enum variant var
> #include <iconv/loop.c>
>
>
> @@ -510,7 +620,7 @@ base64 (unsigned int i)
> { \
> /* Write out the shift sequence. */ \
> if ((state & 0x18) >= 0x10) \
> - *outbuf++ = base64 ((state >> 3) & ~3); \
> + *outbuf++ = base64 ((state >> 3) & ~3, var); \
> *outbuf++ = '-'; \
> \
> data->__statep->__count = 0; \
@@ -29,6 +29,24 @@
#include <stdlib.h>
+enum variant
+{
+ UTF7,
+};
+
+/* Must be in the same order as enum variant above. */
+static const char names[] =
+ "UTF-7//\0"
+ "\0";
+
+static uint32_t
+shift_character (enum variant const var)
+{
+ if (var == UTF7)
+ return '+';
+ else
+ abort ();
+}
static bool
between (uint32_t const ch,
@@ -38,23 +56,27 @@ between (uint32_t const ch,
}
/* The set of "direct characters":
+ FOR UTF-7
A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr
*/
static bool
isdirect (uint32_t ch, enum variant var)
{
- return (between (ch, 'A', 'Z')
- || between (ch, 'a', 'z')
- || between (ch, '0', '9')
- || ch == '\'' || ch == '(' || ch == ')'
- || between (ch, ',', '/')
- || ch == ':' || ch == '?'
- || ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
+ if (var == UTF7)
+ return (between (ch, 'A', 'Z')
+ || between (ch, 'a', 'z')
+ || between (ch, '0', '9')
+ || ch == '\'' || ch == '(' || ch == ')'
+ || between (ch, ',', '/')
+ || ch == ':' || ch == '?'
+ || ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
+ abort ();
}
/* The set of "direct and optional direct characters":
+ (UTF-7 only)
A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr
! " # $ % & * ; < = > @ [ ] ^ _ ` { | }
*/
@@ -62,10 +84,15 @@ isdirect (uint32_t ch, enum variant var)
static bool
isxdirect (uint32_t ch, enum variant var)
{
- return (ch == '\t'
- || ch == '\n'
- || ch == '\r'
- || (between (ch, ' ', '}') && ch != '+' && ch != '\\'));
+ if (isdirect (ch, var))
+ return true;
+ if (var != UTF7)
+ return false;
+ return between (ch, '!', '&')
+ || ch == '*'
+ || between (ch, ';', '@')
+ || (between (ch, '[', '`') && ch != '\\')
+ || between (ch, '{', '}');
}
@@ -85,7 +112,7 @@ needs_explicit_shift (uint32_t ch)
/* Converts a value in the range 0..63 to a base64 encoded char. */
static unsigned char
-base64 (unsigned int i)
+base64 (unsigned int i, enum variant var)
{
if (i < 26)
return i + 'A';
@@ -95,7 +122,7 @@ base64 (unsigned int i)
return i - 52 + '0';
else if (i == 62)
return '+';
- else if (i == 63)
+ else if (i == 63 && var == UTF7)
return '/';
else
abort ();
@@ -103,9 +130,8 @@ base64 (unsigned int i)
/* Definitions used in the body of the `gconv' function. */
-#define CHARSET_NAME "UTF-7//"
-#define DEFINE_INIT 1
-#define DEFINE_FINI 1
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
#define FROM_LOOP from_utf7_loop
#define TO_LOOP to_utf7_loop
#define MIN_NEEDED_FROM 1
@@ -113,11 +139,27 @@ base64 (unsigned int i)
#define MIN_NEEDED_TO 4
#define MAX_NEEDED_TO 4
#define ONE_DIRECTION 0
+#define FROM_DIRECTION (dir == from_utf7)
#define PREPARE_LOOP \
mbstate_t saved_state; \
- mbstate_t *statep = data->__statep;
-#define EXTRA_LOOP_ARGS , statep
+ mbstate_t *statep = data->__statep; \
+ enum direction dir = ((struct utf7_data *) step->__data)->dir; \
+ enum direction var = ((struct utf7_data *) step->__data)->var;
+#define EXTRA_LOOP_ARGS , statep, var
+
+enum direction
+{
+ illegal_dir,
+ from_utf7,
+ to_utf7
+};
+
+struct utf7_data
+{
+ enum direction dir;
+ enum variant var;
+};
/* Since we might have to reset input pointer we must be able to save
and restore the state. */
@@ -127,6 +169,70 @@ base64 (unsigned int i)
else \
*statep = saved_state
+int
+gconv_init (struct __gconv_step *step)
+{
+ /* Determine which direction. */
+ struct utf7_data *new_data;
+ enum direction dir = illegal_dir;
+
+ enum variant var = 0;
+ for (const char *name = names; *name != '\0';
+ name = __rawmemchr (name, '\0') + 1)
+ {
+ if (__strcasecmp (step->__from_name, name) == 0)
+ {
+ dir = from_utf7;
+ break;
+ }
+ else if (__strcasecmp (step->__to_name, name) == 0)
+ {
+ dir = to_utf7;
+ break;
+ }
+ ++var;
+ }
+
+ if (__glibc_likely (dir != illegal_dir))
+ {
+ new_data = malloc (sizeof (*new_data));
+ if (new_data == NULL)
+ return __GCONV_NOMEM;
+
+ new_data->dir = dir;
+ new_data->var = var;
+ step->__data = new_data;
+
+ if (dir == from_utf7)
+ {
+ step->__min_needed_from = MIN_NEEDED_FROM;
+ step->__max_needed_from = MAX_NEEDED_FROM;
+ step->__min_needed_to = MIN_NEEDED_TO;
+ step->__max_needed_to = MAX_NEEDED_TO;
+ }
+ else
+ {
+ step->__min_needed_from = MIN_NEEDED_TO;
+ step->__max_needed_from = MAX_NEEDED_TO;
+ step->__min_needed_to = MIN_NEEDED_FROM;
+ step->__max_needed_to = MAX_NEEDED_FROM;
+ }
+ }
+ else
+ return __GCONV_NOCONV;
+
+ step->__stateful = 1;
+
+ return __GCONV_OK;
+}
+
+void
+gconv_end (struct __gconv_step *data)
+{
+ free (data->__data);
+}
+
+
/* First define the conversion function from UTF-7 to UCS4.
The state is structured as follows:
@@ -154,13 +260,13 @@ base64 (unsigned int i)
if ((statep->__count >> 3) == 0) \
{ \
/* base64 encoding inactive. */ \
- if (isxdirect (ch)) \
+ if (isxdirect (ch, var)) \
{ \
inptr++; \
put32 (outptr, ch); \
outptr += 4; \
} \
- else if (__glibc_likely (ch == '+')) \
+ else if (__glibc_likely (ch == shift_character (var))) \
{ \
if (__glibc_unlikely (inptr + 2 > inend)) \
{ \
@@ -285,7 +391,7 @@ base64 (unsigned int i)
} \
}
#define LOOP_NEED_FLAGS
-#define EXTRA_LOOP_DECLS , mbstate_t *statep
+#define EXTRA_LOOP_DECLS , mbstate_t *statep, enum variant var
#include <iconv/loop.c>
@@ -316,7 +422,7 @@ base64 (unsigned int i)
if ((statep->__count & 0x18) == 0) \
{ \
/* base64 encoding inactive */ \
- if (isdirect (ch)) \
+ if (isdirect (ch, var)) \
{ \
*outptr++ = (unsigned char) ch; \
} \
@@ -324,7 +430,7 @@ base64 (unsigned int i)
{ \
size_t count; \
\
- if (ch == '+') \
+ if (ch == shift_character (var)) \
count = 2; \
else if (ch < 0x10000) \
count = 3; \
@@ -339,13 +445,13 @@ base64 (unsigned int i)
break; \
} \
\
- *outptr++ = '+'; \
- if (ch == '+') \
+ *outptr++ = shift_character (var); \
+ if (ch == shift_character (var)) \
*outptr++ = '-'; \
else if (ch < 0x10000) \
{ \
- *outptr++ = base64 (ch >> 10); \
- *outptr++ = base64 ((ch >> 4) & 0x3f); \
+ *outptr++ = base64 (ch >> 10, var); \
+ *outptr++ = base64 ((ch >> 4) & 0x3f, var); \
statep->__count = ((ch & 15) << 5) | (3 << 3); \
} \
else if (ch < 0x110000) \
@@ -354,11 +460,11 @@ base64 (unsigned int i)
uint32_t ch2 = 0xdc00 + ((ch - 0x10000) & 0x3ff); \
\
ch = (ch1 << 16) | ch2; \
- *outptr++ = base64 (ch >> 26); \
- *outptr++ = base64 ((ch >> 20) & 0x3f); \
- *outptr++ = base64 ((ch >> 14) & 0x3f); \
- *outptr++ = base64 ((ch >> 8) & 0x3f); \
- *outptr++ = base64 ((ch >> 2) & 0x3f); \
+ *outptr++ = base64 (ch >> 26, var); \
+ *outptr++ = base64 ((ch >> 20) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 14) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 8) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 2) & 0x3f, var); \
statep->__count = ((ch & 3) << 7) | (2 << 3); \
} \
else \
@@ -368,7 +474,7 @@ base64 (unsigned int i)
else \
{ \
/* base64 encoding active */ \
- if (isdirect (ch)) \
+ if (isdirect (ch, var)) \
{ \
/* deactivate base64 encoding */ \
size_t count; \
@@ -382,7 +488,7 @@ base64 (unsigned int i)
} \
\
if ((statep->__count & 0x18) >= 0x10) \
- *outptr++ = base64 ((statep->__count >> 3) & ~3); \
+ *outptr++ = base64 ((statep->__count >> 3) & ~3, var); \
if (needs_explicit_shift (ch)) \
*outptr++ = '-'; \
*outptr++ = (unsigned char) ch; \
@@ -410,22 +516,24 @@ base64 (unsigned int i)
switch ((statep->__count >> 3) & 3) \
{ \
case 1: \
- *outptr++ = base64 (ch >> 10); \
- *outptr++ = base64 ((ch >> 4) & 0x3f); \
+ *outptr++ = base64 (ch >> 10, var); \
+ *outptr++ = base64 ((ch >> 4) & 0x3f, var); \
statep->__count = ((ch & 15) << 5) | (3 << 3); \
break; \
case 2: \
*outptr++ = \
- base64 (((statep->__count >> 3) & ~3) | (ch >> 12)); \
- *outptr++ = base64 ((ch >> 6) & 0x3f); \
- *outptr++ = base64 (ch & 0x3f); \
+ base64 (((statep->__count >> 3) & ~3) | (ch >> 12), \
+ var); \
+ *outptr++ = base64 ((ch >> 6) & 0x3f, var); \
+ *outptr++ = base64 (ch & 0x3f, var); \
statep->__count = (1 << 3); \
break; \
case 3: \
*outptr++ = \
- base64 (((statep->__count >> 3) & ~3) | (ch >> 14)); \
- *outptr++ = base64 ((ch >> 8) & 0x3f); \
- *outptr++ = base64 ((ch >> 2) & 0x3f); \
+ base64 (((statep->__count >> 3) & ~3) | (ch >> 14), \
+ var); \
+ *outptr++ = base64 ((ch >> 8) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 2) & 0x3f, var); \
statep->__count = ((ch & 3) << 7) | (2 << 3); \
break; \
default: \
@@ -441,30 +549,32 @@ base64 (unsigned int i)
switch ((statep->__count >> 3) & 3) \
{ \
case 1: \
- *outptr++ = base64 (ch >> 26); \
- *outptr++ = base64 ((ch >> 20) & 0x3f); \
- *outptr++ = base64 ((ch >> 14) & 0x3f); \
- *outptr++ = base64 ((ch >> 8) & 0x3f); \
- *outptr++ = base64 ((ch >> 2) & 0x3f); \
+ *outptr++ = base64 (ch >> 26, var); \
+ *outptr++ = base64 ((ch >> 20) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 14) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 8) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 2) & 0x3f, var); \
statep->__count = ((ch & 3) << 7) | (2 << 3); \
break; \
case 2: \
*outptr++ = \
- base64 (((statep->__count >> 3) & ~3) | (ch >> 28)); \
- *outptr++ = base64 ((ch >> 22) & 0x3f); \
- *outptr++ = base64 ((ch >> 16) & 0x3f); \
- *outptr++ = base64 ((ch >> 10) & 0x3f); \
- *outptr++ = base64 ((ch >> 4) & 0x3f); \
+ base64 (((statep->__count >> 3) & ~3) | (ch >> 28), \
+ var); \
+ *outptr++ = base64 ((ch >> 22) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 16) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 10) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 4) & 0x3f, var); \
statep->__count = ((ch & 15) << 5) | (3 << 3); \
break; \
case 3: \
*outptr++ = \
- base64 (((statep->__count >> 3) & ~3) | (ch >> 30)); \
- *outptr++ = base64 ((ch >> 24) & 0x3f); \
- *outptr++ = base64 ((ch >> 18) & 0x3f); \
- *outptr++ = base64 ((ch >> 12) & 0x3f); \
- *outptr++ = base64 ((ch >> 6) & 0x3f); \
- *outptr++ = base64 (ch & 0x3f); \
+ base64 (((statep->__count >> 3) & ~3) | (ch >> 30), \
+ var); \
+ *outptr++ = base64 ((ch >> 24) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 18) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 12) & 0x3f, var); \
+ *outptr++ = base64 ((ch >> 6) & 0x3f, var); \
+ *outptr++ = base64 (ch & 0x3f, var); \
statep->__count = (1 << 3); \
break; \
default: \
@@ -480,7 +590,7 @@ base64 (unsigned int i)
inptr += 4; \
}
#define LOOP_NEED_FLAGS
-#define EXTRA_LOOP_DECLS , mbstate_t *statep
+#define EXTRA_LOOP_DECLS , mbstate_t *statep, enum variant var
#include <iconv/loop.c>
@@ -510,7 +620,7 @@ base64 (unsigned int i)
{ \
/* Write out the shift sequence. */ \
if ((state & 0x18) >= 0x10) \
- *outbuf++ = base64 ((state >> 3) & ~3); \
+ *outbuf++ = base64 ((state >> 3) & ~3, var); \
*outbuf++ = '-'; \
\
data->__statep->__count = 0; \