diff options
Diffstat (limited to 'mbbsd/convert.c')
-rw-r--r-- | mbbsd/convert.c | 119 |
1 files changed, 118 insertions, 1 deletions
diff --git a/mbbsd/convert.c b/mbbsd/convert.c index 141548d1..6ced7d2a 100644 --- a/mbbsd/convert.c +++ b/mbbsd/convert.c @@ -4,9 +4,11 @@ * The following code is copied and modified from "autoconvert" with GPL. */ -#ifdef GB_CONVERT +#ifdef CONVERT #include "convert.h" +#include "iconv.h" + char *hzconvert(char *, int *, char *, void (*dbcvrt)()); @@ -15,6 +17,8 @@ extern const unsigned char GtoB[], BtoG[]; #define c1 (unsigned char)(s[0]) #define c2 (unsigned char)(s[1]) +/* Convert: Big5 <-> GB */ + static void g2b(char *s) { unsigned int i; @@ -74,4 +78,117 @@ unsigned char *big2gb(unsigned char *s, int plen) unsigned char c = 0; return hzconvert(s, &plen, &c, b2g); } + +int gb_converting_read(int fd, void *buf, size_t count) +{ + int len = read(fd, buf, count); + if (len >= 0) + gb2big(buf, len); + return len; +} + +int gb_converting_write(int fd, void *buf, size_t count) +{ + big2gb(buf, count); + return write(fd, buf, count); +} + +/* Convert: Big5 <-> Unicode */ + +/**************************/ +static iconv_t big2ucs, ucs2big; + +int ucs_converting_init(void) +{ + big2ucs = iconv_open("utf8", "big5"); + ucs2big = iconv_open("big5", "utf8"); + return (big2ucs < 0 || ucs2big < 0); +} + +int str_iconv(iconv_t desc, char *src, int srclen) +{ + int iconv_ret; + /* Start translation */ + while (srclen > 0) { + iconv_ret = iconv(desc, (const char* *)&src, &srclen, &src, &srclen); + // deslen - 1 ?? iconv_ret = iconv(desc, (const char* *)&src, &srclen, &src, &srclen); + if (iconv_ret != 0) { + switch(errno) { + case EILSEQ: + /* forward that byte */ + src++; srclen--; + break; + /* incomplete multibyte happened */ + case EINVAL: + /* forward that byte (maybe wrong)*/ + src++; srclen--; + break; + /* des no rooms */ + case E2BIG: + /* break out the while loop */ + srclen = 0; + break; + } + } + } + *src= '\0'; + return srclen; +} + +//int str_iconv(iconv_t desc, char *src, int srclen) +//{ +// deslen--; /* keep space for '\0' */ +// deslen_old = deslen; +// +// /* Start translation */ +// while (srclen > 0 && deslen > 0) { +// iconv_ret = iconv(desc, (const char* *)&src, &srclen, &des, &deslen); +// if (iconv_ret != 0) { +// switch(errno) { +// case EILSEQ: +// /* forward that byte */ +// *des = *src; +// src++; srclen--; +// des++; deslen--; +// break; +// /* incomplete multibyte happened */ +// case EINVAL: +// /* forward that byte (maybe wrong)*/ +// *des = *src; +// src++; srclen--; +// des++; deslen--; +// break; +// /* des no rooms */ +// case E2BIG: +// /* break out the while loop */ +// srclen = 0; +// break; +// } +// } +// } +// *des = '\0'; +// return deslen_old - deslen; +//} + +int ucs_converting_read(int fd, void *buf, size_t count) +{ + int len; + if ((len = read(fd, buf, count)) < 0) + str_iconv(ucs2big, buf, count); + return len; +} + +int ucs_converting_write(int fd, void *buf, size_t count) +{ + str_iconv(big2ucs, buf, count); + return write(fd, buf, count); +} + +/* we don't need it since one cannot use it after stop mbbsd +void ucs_finish_converting(void) +{ + iconv_close(big2ucs); + iconv_close(ucs2big); +} +*/ #endif |