diff --git a/src/lib-charset/Makefile.am b/src/lib-charset/Makefile.am index cb711909a4..3b16b47a91 100644 --- a/src/lib-charset/Makefile.am +++ b/src/lib-charset/Makefile.am @@ -11,7 +11,8 @@ libcharset_la_SOURCES = \ charset-utf8-only.c headers = \ - charset-utf8.h + charset-utf8.h \ + charset-utf8-private.h pkginc_libdir=$(pkgincludedir) pkginc_lib_HEADERS = $(headers) diff --git a/src/lib-charset/charset-iconv.c b/src/lib-charset/charset-iconv.c index 091f85e7be..3cf015a58a 100644 --- a/src/lib-charset/charset-iconv.c +++ b/src/lib-charset/charset-iconv.c @@ -2,8 +2,7 @@ #include "lib.h" #include "buffer.h" -#include "unichar.h" -#include "charset-utf8.h" +#include "charset-utf8-private.h" #ifdef HAVE_ICONV @@ -15,8 +14,9 @@ struct charset_translation { normalizer_func_t *normalizer; }; -int charset_to_utf8_begin(const char *charset, normalizer_func_t *normalizer, - struct charset_translation **t_r) +static int +iconv_charset_to_utf8_begin(const char *charset, normalizer_func_t *normalizer, + struct charset_translation **t_r) { struct charset_translation *t; iconv_t cd; @@ -38,18 +38,14 @@ int charset_to_utf8_begin(const char *charset, normalizer_func_t *normalizer, return 0; } -void charset_to_utf8_end(struct charset_translation **_t) +static void iconv_charset_to_utf8_end(struct charset_translation *t) { - struct charset_translation *t = *_t; - - *_t = NULL; - if (t->cd != (iconv_t)-1) iconv_close(t->cd); i_free(t); } -void charset_to_utf8_reset(struct charset_translation *t) +static void iconv_charset_to_utf8_reset(struct charset_translation *t) { if (t->cd != (iconv_t)-1) (void)iconv(t->cd, NULL, NULL, NULL, NULL); @@ -103,9 +99,10 @@ charset_to_utf8_try(struct charset_translation *t, return ret; } -enum charset_result -charset_to_utf8(struct charset_translation *t, - const unsigned char *src, size_t *src_size, buffer_t *dest) +static enum charset_result +iconv_charset_to_utf8(struct charset_translation *t, + const unsigned char *src, size_t *src_size, + buffer_t *dest) { enum charset_result result; size_t pos, size; @@ -140,4 +137,11 @@ charset_to_utf8(struct charset_translation *t, return result; } +const struct charset_utf8_vfuncs charset_iconv = { + .to_utf8_begin = iconv_charset_to_utf8_begin, + .to_utf8_end = iconv_charset_to_utf8_end, + .to_utf8_reset = iconv_charset_to_utf8_reset, + .to_utf8 = iconv_charset_to_utf8, +}; + #endif diff --git a/src/lib-charset/charset-utf8-only.c b/src/lib-charset/charset-utf8-only.c index 1b2d940d9f..d95cfe9d45 100644 --- a/src/lib-charset/charset-utf8-only.c +++ b/src/lib-charset/charset-utf8-only.c @@ -1,7 +1,7 @@ /* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */ #include "lib.h" -#include "charset-utf8.h" +#include "charset-utf8-private.h" #ifndef HAVE_ICONV @@ -9,8 +9,10 @@ struct charset_translation { normalizer_func_t *normalizer; }; -int charset_to_utf8_begin(const char *charset, normalizer_func_t *normalizer, - struct charset_translation **t_r) +static int +utf8only_charset_to_utf8_begin(const char *charset, + normalizer_func_t *normalizer, + struct charset_translation **t_r) { struct charset_translation *t; @@ -25,23 +27,29 @@ int charset_to_utf8_begin(const char *charset, normalizer_func_t *normalizer, return 0; } -void charset_to_utf8_end(struct charset_translation **_t) +static void utf8only_charset_to_utf8_end(struct charset_translation *t) { - struct charset_translation *t = *_t; - - *_t = NULL; i_free(t); } -void charset_to_utf8_reset(struct charset_translation *t ATTR_UNUSED) +static void +utf8only_charset_to_utf8_reset(struct charset_translation *t ATTR_UNUSED) { } -enum charset_result -charset_to_utf8(struct charset_translation *t, - const unsigned char *src, size_t *src_size, buffer_t *dest) +static enum charset_result +utf8only_charset_to_utf8(struct charset_translation *t, + const unsigned char *src, size_t *src_size, + buffer_t *dest) { return charset_utf8_to_utf8(t->normalizer, src, src_size, dest); } +const struct charset_utf8_vfuncs charset_utf8only = { + .to_utf8_begin = utf8only_charset_to_utf8_begin, + .to_utf8_end = utf8only_charset_to_utf8_end, + .to_utf8_reset = utf8only_charset_to_utf8_reset, + .to_utf8 = utf8only_charset_to_utf8, +}; + #endif diff --git a/src/lib-charset/charset-utf8-private.h b/src/lib-charset/charset-utf8-private.h new file mode 100644 index 0000000000..0f5064b6c1 --- /dev/null +++ b/src/lib-charset/charset-utf8-private.h @@ -0,0 +1,21 @@ +#ifndef CHARSET_UTF8_PRIVATE_H +#define CHARSET_UTF8_PRIVATE_H + +#include "unichar.h" +#include "charset-utf8.h" + +struct charset_utf8_vfuncs { + int (*to_utf8_begin)(const char *charset, normalizer_func_t *normalizer, + struct charset_translation **t_r); + void (*to_utf8_end)(struct charset_translation *t); + void (*to_utf8_reset)(struct charset_translation *t); + + enum charset_result (*to_utf8)(struct charset_translation *t, + const unsigned char *src, + size_t *src_size, buffer_t *dest); +}; + +extern const struct charset_utf8_vfuncs charset_utf8only; +extern const struct charset_utf8_vfuncs charset_iconv; + +#endif diff --git a/src/lib-charset/charset-utf8.c b/src/lib-charset/charset-utf8.c index 8a25eddcd5..22038e5592 100644 --- a/src/lib-charset/charset-utf8.c +++ b/src/lib-charset/charset-utf8.c @@ -3,11 +3,16 @@ #include "lib.h" #include "buffer.h" #include "str.h" -#include "unichar.h" -#include "charset-utf8.h" +#include "charset-utf8-private.h" #include +#ifdef HAVE_ICONV +const struct charset_utf8_vfuncs *charset_utf8_vfuncs = &charset_iconv; +#else +const struct charset_utf8_vfuncs *charset_utf8_vfuncs = &charset_utf8only; +#endif + bool charset_is_utf8(const char *charset) { return strcasecmp(charset, "us-ascii") == 0 || @@ -66,3 +71,29 @@ charset_utf8_to_utf8(normalizer_func_t *normalizer, } return res; } + +int charset_to_utf8_begin(const char *charset, normalizer_func_t *normalizer, + struct charset_translation **t_r) +{ + return charset_utf8_vfuncs->to_utf8_begin(charset, normalizer, t_r); +} + +void charset_to_utf8_end(struct charset_translation **_t) +{ + struct charset_translation *t = *_t; + + *_t = NULL; + charset_utf8_vfuncs->to_utf8_end(t); +} + +void charset_to_utf8_reset(struct charset_translation *t) +{ + charset_utf8_vfuncs->to_utf8_reset(t); +} + +enum charset_result +charset_to_utf8(struct charset_translation *t, + const unsigned char *src, size_t *src_size, buffer_t *dest) +{ + return charset_utf8_vfuncs->to_utf8(t, src, src_size, dest); +}