mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-23 04:26:50 +03:00
[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:
parent
cfcc08137d
commit
46bc8ca154
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
56
utils/utf8.c
56
utils/utf8.c
@ -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,12 +282,29 @@ utf8_convert_ret utf8_convert(const char *string, size_t len,
|
|||||||
|
|
||||||
in = (char *)string;
|
in = (char *)string;
|
||||||
|
|
||||||
cd = iconv_open(to, from);
|
/* we cache the last used conversion descriptor,
|
||||||
if (cd == (iconv_t)-1) {
|
* so check if we're trying to use it here */
|
||||||
if (errno == EINVAL)
|
if (strncasecmp(last_cd.from, from, 32) == 0 &&
|
||||||
return UTF8_CONVERT_BADENC;
|
strncasecmp(last_cd.to, to, 32) == 0) {
|
||||||
/* default to no memory */
|
cd = last_cd.cd;
|
||||||
return UTF8_CONVERT_NOMEM;
|
}
|
||||||
|
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);
|
slen = len ? len : strlen(string);
|
||||||
@ -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);
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user