summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2005-07-11 18:10:10 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2005-07-11 18:10:10 +0000
commit46bc8ca1541d80b272e2ef0cbb499a4cb1bea659 (patch)
tree2d537ca9433defd576dfdf7a662b9e4ed729ca55 /utils
parentcfcc08137d844a35899bdaea3aa77052a7a4b11d (diff)
downloadnetsurf-46bc8ca1541d80b272e2ef0cbb499a4cb1bea659.tar.gz
netsurf-46bc8ca1541d80b272e2ef0cbb499a4cb1bea659.tar.bz2
[project @ 2005-07-11 18:10:10 by jmb]
Cache previous iconv conversion descriptor svn path=/import/netsurf/; revision=1792
Diffstat (limited to 'utils')
-rw-r--r--utils/utf8.c56
-rw-r--r--utils/utf8.h2
2 files changed, 46 insertions, 12 deletions
diff --git a/utils/utf8.c b/utils/utf8.c
index 801fca1a3..6c06c76f5 100644
--- a/utils/utf8.c
+++ b/utils/utf8.c
@@ -198,6 +198,26 @@ size_t utf8_next(const char *s, size_t l, size_t o)
return o;
}
+/* Cache of previous iconv conversion descriptor used by utf8_convert */
+static struct {
+ char from[32]; /**< Encoding name to convert from */
+ char to[32]; /**< Encoding name to convert to */
+ iconv_t cd; /**< Iconv conversion descriptor */
+} last_cd;
+
+/**
+ * Finalise the UTF-8 library
+ */
+void utf8_finalise(void)
+{
+ if (last_cd.cd != 0)
+ iconv_close(last_cd.cd);
+
+ /* paranoia follows */
+ last_cd.from[0] = '\0';
+ last_cd.to[0] = '\0';
+ last_cd.cd = 0;
+}
/**
* Convert a UTF8 string into the named encoding
@@ -262,12 +282,29 @@ utf8_convert_ret utf8_convert(const char *string, size_t len,
in = (char *)string;
- cd = iconv_open(to, from);
- if (cd == (iconv_t)-1) {
- if (errno == EINVAL)
- return UTF8_CONVERT_BADENC;
- /* default to no memory */
- return UTF8_CONVERT_NOMEM;
+ /* we cache the last used conversion descriptor,
+ * so check if we're trying to use it here */
+ if (strncasecmp(last_cd.from, from, 32) == 0 &&
+ strncasecmp(last_cd.to, to, 32) == 0) {
+ cd = last_cd.cd;
+ }
+ else {
+ /* no match, so create a new cd */
+ cd = iconv_open(to, from);
+ if (cd == (iconv_t)-1) {
+ if (errno == EINVAL)
+ return UTF8_CONVERT_BADENC;
+ /* default to no memory */
+ return UTF8_CONVERT_NOMEM;
+ }
+
+ /* close the last cd - we don't care if this fails */
+ iconv_close(last_cd.cd);
+
+ /* and copy the to/from/cd data into last_cd */
+ strncpy(last_cd.from, from, 32);
+ strncpy(last_cd.to, to, 32);
+ last_cd.cd = cd;
}
slen = len ? len : strlen(string);
@@ -278,15 +315,12 @@ utf8_convert_ret utf8_convert(const char *string, size_t len,
rlen = slen * 4 + 4;
temp = out = malloc(rlen);
- if (!out) {
- iconv_close(cd);
+ if (!out)
return UTF8_CONVERT_NOMEM;
- }
/* perform conversion */
if (iconv(cd, &in, &slen, &out, &rlen) == (size_t)-1) {
free(temp);
- iconv_close(cd);
/** \todo handle the various cases properly
* There are 3 possible error cases:
* a) Insufficiently large output buffer
@@ -295,8 +329,6 @@ utf8_convert_ret utf8_convert(const char *string, size_t len,
return UTF8_CONVERT_NOMEM;
}
- iconv_close(cd);
-
*(result) = realloc(temp, out - temp + 4);
if (!(*result)) {
free(temp);
diff --git a/utils/utf8.h b/utils/utf8.h
index a1d98685d..a77af29d0 100644
--- a/utils/utf8.h
+++ b/utils/utf8.h
@@ -31,4 +31,6 @@ utf8_convert_ret utf8_to_enc(const char *string, const char *encname,
utf8_convert_ret utf8_from_enc(const char *string, const char *encname,
size_t len, char **result);
+void utf8_finalise(void);
+
#endif