[project @ 2005-07-11 18:10:10 by jmb]

Cache previous iconv conversion descriptor

svn path=/import/netsurf/; revision=1792
This commit is contained in:
John Mark Bell 2005-07-11 18:10:10 +00:00
parent cfcc08137d
commit 46bc8ca154
3 changed files with 49 additions and 12 deletions

View File

@ -23,6 +23,7 @@
#endif #endif
#include "netsurf/utils/log.h" #include "netsurf/utils/log.h"
#include "netsurf/utils/url.h" #include "netsurf/utils/url.h"
#include "netsurf/utils/utf8.h"
#include "netsurf/utils/utils.h" #include "netsurf/utils/utils.h"
bool netsurf_quit = false; bool netsurf_quit = false;
@ -73,6 +74,7 @@ void netsurf_init(int argc, char** argv)
"machine <%s>", utsname.sysname, "machine <%s>", utsname.sysname,
utsname.nodename, utsname.release, utsname.nodename, utsname.release,
utsname.version, utsname.machine)); utsname.version, utsname.machine));
lib_init(); lib_init();
url_init(); url_init();
gui_init(argc, argv); gui_init(argc, argv);
@ -103,6 +105,7 @@ void netsurf_exit(void)
gui_quit(); gui_quit();
content_quit(); content_quit();
fetch_quit(); fetch_quit();
utf8_finalise();
} }

View File

@ -198,6 +198,26 @@ size_t utf8_next(const char *s, size_t l, size_t o)
return 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 * Convert a UTF8 string into the named encoding
@ -262,6 +282,14 @@ utf8_convert_ret utf8_convert(const char *string, size_t len,
in = (char *)string; in = (char *)string;
/* 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); cd = iconv_open(to, from);
if (cd == (iconv_t)-1) { if (cd == (iconv_t)-1) {
if (errno == EINVAL) if (errno == EINVAL)
@ -270,6 +298,15 @@ utf8_convert_ret utf8_convert(const char *string, size_t len,
return UTF8_CONVERT_NOMEM; 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); slen = len ? len : strlen(string);
/* Worst case = ACSII -> UCS4, so allocate an output buffer /* Worst case = ACSII -> UCS4, so allocate an output buffer
* 4 times larger than the input buffer, and add 4 bytes at * 4 times larger than the input buffer, and add 4 bytes at
@ -278,15 +315,12 @@ utf8_convert_ret utf8_convert(const char *string, size_t len,
rlen = slen * 4 + 4; rlen = slen * 4 + 4;
temp = out = malloc(rlen); temp = out = malloc(rlen);
if (!out) { if (!out)
iconv_close(cd);
return UTF8_CONVERT_NOMEM; return UTF8_CONVERT_NOMEM;
}
/* perform conversion */ /* perform conversion */
if (iconv(cd, &in, &slen, &out, &rlen) == (size_t)-1) { if (iconv(cd, &in, &slen, &out, &rlen) == (size_t)-1) {
free(temp); free(temp);
iconv_close(cd);
/** \todo handle the various cases properly /** \todo handle the various cases properly
* There are 3 possible error cases: * There are 3 possible error cases:
* a) Insufficiently large output buffer * a) Insufficiently large output buffer
@ -295,8 +329,6 @@ utf8_convert_ret utf8_convert(const char *string, size_t len,
return UTF8_CONVERT_NOMEM; return UTF8_CONVERT_NOMEM;
} }
iconv_close(cd);
*(result) = realloc(temp, out - temp + 4); *(result) = realloc(temp, out - temp + 4);
if (!(*result)) { if (!(*result)) {
free(temp); free(temp);

View File

@ -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, utf8_convert_ret utf8_from_enc(const char *string, const char *encname,
size_t len, char **result); size_t len, char **result);
void utf8_finalise(void);
#endif #endif