comparison src/lib-charset/charset-iconv.c @ 568:f2aa58c2afd0 HEAD

SEARCH CHARSET support. Currently we do it through iconv() and only ASCII characters are compared case-insensitively.
author Timo Sirainen <tss@iki.fi>
date Sun, 03 Nov 2002 10:39:43 +0200
parents
children e524da896d92
comparison
equal deleted inserted replaced
567:a59f68334ad6 568:f2aa58c2afd0
1 /* Copyright (C) 2002 Timo Sirainen */
2
3 #include "lib.h"
4
5 #ifdef HAVE_ICONV_H
6
7 #include <iconv.h>
8
9 const char *charset_to_ucase_utf8(const unsigned char *data, size_t *size,
10 const char *charset, int *unknown_charset)
11 {
12 iconv_t cd;
13 char *inbuf, *outbuf, *outpos;
14 size_t inleft, outleft, outsize, pos;
15
16 if (charset == NULL || strcasecmp(charset, "us-ascii") == 0)
17 return str_ucase(t_strdup_noconst(data));
18
19 cd = iconv_open("UTF8", charset);
20 if (cd == (iconv_t)-1) {
21 if (unknown_charset != NULL)
22 *unknown_charset = TRUE;
23 return NULL;
24 }
25
26 if (unknown_charset != NULL)
27 *unknown_charset = FALSE;
28
29 inbuf = (char *) data;
30 inleft = *size;
31
32 outsize = outleft = *size * 2;
33 outbuf = outpos = t_buffer_get(outsize + 1);
34
35 while (iconv(cd, &inbuf, &inleft, &outpos, &outleft) == (size_t)-1) {
36 if (errno != E2BIG) {
37 /* invalid data */
38 iconv_close(cd);
39 return NULL;
40 }
41
42 /* output buffer too small, grow it */
43 pos = outsize - outleft;
44 outsize *= 2;
45 outleft = outsize - pos;
46
47 outbuf = t_buffer_reget(outbuf, outsize + 1);
48 outpos = outbuf + pos;
49 }
50
51 *size = (size_t) (outpos - outbuf);
52 *outpos++ = '\0';
53 t_buffer_alloc(*size + 1);
54
55 /* FIXME: this works only for ASCII */
56 str_ucase(outbuf);
57
58 iconv_close(cd);
59 return outbuf;
60 }
61
62 #endif