diff options
Diffstat (limited to 'console/convert.c')
-rw-r--r-- | console/convert.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/console/convert.c b/console/convert.c new file mode 100644 index 00000000..e5d0f07b --- /dev/null +++ b/console/convert.c @@ -0,0 +1,123 @@ +/* $Id$ */ +#include "bbs.h" + +#ifdef CONVERT + +extern unsigned char *gb2big(unsigned char *, int *, int); +extern unsigned char *big2gb(unsigned char *, int *, int); +extern unsigned char *utf8_uni(unsigned char *, int *, int); +extern unsigned char *uni_utf8(unsigned char *, int *, int); +extern unsigned char *uni2big(unsigned char *, int *, int); +extern unsigned char *big2uni(unsigned char *, int *, int); + +static ssize_t +gb_input(void *buf, ssize_t icount) +{ + /* is sizeof(ssize_t) == sizeof(int)? not sure */ + int ic = (int) icount; + gb2big((unsigned char *)buf, &ic, 0); + return (ssize_t)ic; +} + +static ssize_t +gb_read(int fd, void *buf, size_t count) +{ + ssize_t icount = read(fd, buf, count); + if (icount > 0) + icount = gb_input(buf, icount); + return icount; +} + +static ssize_t +gb_write(int fd, void *buf, size_t count) +{ + int icount = (int)count; + big2gb((unsigned char *)buf, &icount, 0); + if(icount > 0) + return write(fd, buf, (size_t)icount); + else + return count; /* fake */ +} + +static ssize_t +utf8_input (void *buf, ssize_t icount) +{ + /* is sizeof(ssize_t) == sizeof(int)? not sure */ + int ic = (int) icount; + utf8_uni(buf, &ic, 0); + uni2big(buf, &ic, 0); + return (ssize_t)ic; +} + +static ssize_t +utf8_read(int fd, void *buf, size_t count) +{ + ssize_t icount = read(fd, buf, count); + if (icount > 0) + icount = utf8_input(buf, icount); + return icount; +} + +static ssize_t +utf8_write(int fd, void *buf, size_t count) +{ + int icount = (int)count; + static unsigned char *mybuf = NULL; + static int cmybuf = 0; + + /* utf8 output is a special case because + * we need larger buffer which can be + * tripple or more in size. + * Current implementation uses 128 for each block. + */ + + if(cmybuf < count * 4) { + cmybuf = (count*4+0x80) & (~0x7f) ; + mybuf = (unsigned char*) realloc (mybuf, cmybuf); + } + memcpy(mybuf, buf, count); + big2uni(mybuf, &icount, 0); + uni_utf8(mybuf, &icount, 0); + if(icount > 0) + return write(fd, mybuf, (size_t)icount); + else + return count; /* fake */ +} + +static ssize_t +norm_input(void *buf, ssize_t icount) +{ + return icount; +} + +/* global function pointers */ +read_write_type write_type = (read_write_type)write; +read_write_type read_type = read; +convert_type input_type = norm_input; + +// enable this in case some day we want to detect +// current type. but right now disable for less memory cost +// int bbs_convert_type = CONV_NORMAL; + +void set_converting_type(int which) +{ + if (which == CONV_NORMAL) { + read_type = read; + write_type = (read_write_type)write; + /* for speed up, NULL is better.. */ + input_type = NULL; /* norm_input; */ + } + else if (which == CONV_GB) { + read_type = gb_read; + write_type = gb_write; + input_type = gb_input; + } + else if (which == CONV_UTF8) { + read_type = utf8_read; + write_type = utf8_write; + input_type = utf8_input; + } + // bbs_convert_type = which; +} + +#endif |