Mercurial > libpst
diff src/vbuf.c @ 151:cda7c812ec01
track character set individually for each mapi element
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sun, 08 Mar 2009 14:35:26 -0700 |
parents | 2189a6b8134e |
children | ab384fed78c5 |
line wrap: on
line diff
--- a/src/vbuf.c Thu Mar 05 08:23:32 2009 -0800 +++ b/src/vbuf.c Sun Mar 08 14:35:26 2009 -0700 @@ -43,16 +43,18 @@ static int unicode_up = 0; static iconv_t i16to8; static const char *target_charset = NULL; -static int target_open = 0; -static iconv_t i8totarget; +static int target_open_from = 0; +static int target_open_to = 0; +static iconv_t i8totarget = (iconv_t)-1; +static iconv_t target2i8 = (iconv_t)-1; void unicode_init() { if (unicode_up) unicode_close(); - i16to8 = iconv_open("UTF-8", "UTF-16LE"); + i16to8 = iconv_open("utf-8", "utf-16le"); if (i16to8 == (iconv_t)-1) { - fprintf(stderr, "Couldn't open iconv descriptor for UTF-16LE to UTF-8.\n"); + WARN(("Couldn't open iconv descriptor for utf-16le to utf-8.\n")); exit(1); } unicode_up = 1; @@ -62,12 +64,12 @@ void unicode_close() { iconv_close(i16to8); - if (target_open) { - iconv_close(i8totarget); - free((char *)target_charset); - target_charset = NULL; - target_open = 0; - } + if (target_open_from) iconv_close(i8totarget); + if (target_open_to) iconv_close(target2i8); + if (target_charset) free((char *)target_charset); + target_charset = NULL; + target_open_from = 0; + target_open_to = 0; unicode_up = 0; } @@ -125,39 +127,47 @@ } -size_t vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset) +static void open_targets(const char* charset); +static void open_targets(const char* charset) +{ + if (!target_charset || strcasecmp(target_charset, charset)) { + if (target_open_from) iconv_close(i8totarget); + if (target_open_to) iconv_close(target2i8); + if (target_charset) free((char *)target_charset); + target_charset = strdup(charset); + target_open_from = 1; + target_open_to = 1; + i8totarget = iconv_open(target_charset, "utf-8"); + if (i8totarget == (iconv_t)-1) { + target_open_from = 0; + WARN(("Couldn't open iconv descriptor for utf-8 to %s.\n", target_charset)); + } + target2i8 = iconv_open("utf-8", target_charset); + if (target2i8 == (iconv_t)-1) { + target_open_to = 0; + WARN(("Couldn't open iconv descriptor for %s to utf-8.\n", target_charset)); + } + } +} + + +static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion); +static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion) { size_t inbytesleft = iblen; size_t icresult = (size_t)-1; size_t outbytesleft = 0; char *outbuf = NULL; - if (!target_charset || strcasecmp(target_charset, charset)) { - if (target_open) { - iconv_close(i8totarget); - free((char *)target_charset); - } - target_charset = strdup(charset); - target_open = 1; - i8totarget = iconv_open(target_charset, "UTF-8"); - if (i8totarget == (iconv_t)-1) { - target_open = 0; - fprintf(stderr, "Couldn't open iconv descriptor for UTF-8 to %s.\n", target_charset); - return (size_t)-1; - } - } - - if (!target_open) return (size_t)-1; // previous failure to open the target - - if (2 > dest->blen) vbresize(dest, 2); + vbresize(dest, 2*iblen); dest->dlen = 0; do { outbytesleft = dest->blen - dest->dlen; outbuf = dest->b + dest->dlen; - icresult = iconv(i8totarget, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); + icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); dest->dlen = outbuf - dest->b; - vbgrow(dest, 20); + if (inbytesleft) vbgrow(dest, 2*inbytesleft); } while ((size_t)-1 == icresult && E2BIG == errno); if (icresult == (size_t)-1) { @@ -169,6 +179,22 @@ } +size_t vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset) +{ + open_targets(charset); + if (!target_open_from) return (size_t)-1; // failure to open the target + return sbcs_conversion(dest, inbuf, iblen, i8totarget); +} + + +size_t vb_8bit2utf8(vbuf *dest, const char *inbuf, int iblen, const char* charset) +{ + open_targets(charset); + if (!target_open_to) return (size_t)-1; // failure to open the target + return sbcs_conversion(dest, inbuf, iblen, target2i8); +} + + vbuf *vballoc(size_t len) { struct varbuf *result = malloc(sizeof(struct varbuf)); @@ -226,20 +252,6 @@ } -//void vbdump( vbuf *vb ) // TODO: to stdout? Yuck -//{ -// printf("vb dump-------------\n"); -// printf("dlen: %d\n", vb->dlen ); -// printf("blen: %d\n", vb->blen ); -// printf("b - buf: %d\n", vb->b - vb->buf ); -// printf("buf:\n"); -// hexdump( vb->buf, 0, vb->blen, 1 ); -// printf("b:\n"); -// hexdump( vb->b, 0, vb->dlen, 1 ); -// printf("^^^^^^^^^^^^^^^^^^^^\n"); -//} - - void vbgrow(struct varbuf *vb, size_t len) // out: vbavail(vb) >= len, data are preserved { if (0 == len)