diff options
Diffstat (limited to 'innbbsd/convcode.c')
-rw-r--r-- | innbbsd/convcode.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/innbbsd/convcode.c b/innbbsd/convcode.c new file mode 100644 index 0000000..55ac2c4 --- /dev/null +++ b/innbbsd/convcode.c @@ -0,0 +1,169 @@ +/* ----------------------------------------------------- */ +/* ²�c��~�r�ഫ */ +/* ----------------------------------------------------- */ +/* create : / / */ +/* update : 03/05/16 */ +/* author : kcn@cic.tsinghua.edu.cn */ +/* modify : itoc.bbs@bbs.tnfsh.tn.edu.tw */ +/* ----------------------------------------------------- */ + + +#include <stdio.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> + + +#define BtoG_count 13973 +#define GtoB_count 7614 + +#define BtoG_bad1 0xa1 +#define BtoG_bad2 0xf5 +#define GtoB_bad1 0xa1 +#define GtoB_bad2 0xbc + + +static unsigned char *BtoG = NULL; +static unsigned char *GtoB = NULL; + + +static void +conv_init() +{ + int fd, size, BGsize, GBsize; + struct stat st; + + if (BtoG != NULL) + return; + + BGsize = BtoG_count << 1; /* �C�Ӻ~�r 2-byte */ + GBsize = GtoB_count << 1; + BtoG = (unsigned char *) malloc(BGsize + GBsize); + GtoB = BtoG + BGsize; + + if ((fd = open("etc/b2g_table", O_RDONLY)) >= 0) + { + fstat(fd, &st); + size = BGsize <= st.st_size ? BGsize : st.st_size; + read(fd, BtoG, size); + close(fd); + } + if ((fd = open("etc/g2b_table", O_RDONLY)) >= 0) + { + fstat(fd, &st); + size = GBsize <= st.st_size ? GBsize : st.st_size; + read(fd, GtoB, size); + close(fd); + } +} + + +#define c1 (unsigned char)(src[0]) +#define c2 (unsigned char)(src[1]) + + +static void +b2g(src, dst) + unsigned char *src, *dst; +{ + int i; + + if ((c1 >= 0xa1) && (c1 <= 0xf9)) + { + if ((c2 >= 0x40) && (c2 <= 0x7e)) + { + i = ((c1 - 0xa1) * 157 + (c2 - 0x40)) * 2; + dst[0] = BtoG[i++]; + dst[1] = BtoG[i]; + return; + } + else if ((c2 >= 0xa1) && (c2 <= 0xfe)) + { + i = ((c1 - 0xa1) * 157 + (c2 - 0xa1) + 63) * 2; + dst[0] = BtoG[i++]; + dst[1] = BtoG[i]; + return; + } + } + dst[0] = BtoG_bad1; + dst[1] = BtoG_bad2; +} + + +static void +g2b(src, dst) + unsigned char *src, *dst; +{ + int i; + + if ((c2 >= 0xa1) && (c2 <= 0xfe)) + { + if ((c1 >= 0xa1) && (c1 <= 0xa9)) + { + i = ((c1 - 0xa1) * 94 + (c2 - 0xa1)) * 2; + dst[0] = GtoB[i++]; + dst[1] = GtoB[i]; + return; + } + else if ((c1 >= 0xb0) && (c1 <= 0xf7)) + { + i = ((c1 - 0xb0 + 9) * 94 + (c2 - 0xa1)) * 2; + dst[0] = GtoB[i++]; + dst[1] = GtoB[i]; + return; + } + } + dst[0] = GtoB_bad1; + dst[1] = GtoB_bad2; +} + + +static char * +hzconvert(src, dst, dbcvrt) + char *src; /* source char buffer pointer */ + char *dst; /* destination char buffer pointer */ + void (*dbcvrt) (); /* �~�r 2-byte conversion funcntion */ +{ + int len; + char *end, *p; + + conv_init(); + + p = dst; + len = strlen(src); + end = src + len; + while (src < end) + { + if (*src & 0x80) /* hi-bit on ���ܬO�~�r */ + { + dbcvrt(src, p); + src += 2; /* �@����G�X */ + p += 2; + } + else + { + /* *p = *src; */ /* ���ݭn�A�]���b b52gb()�Bgb2b5() �����θ� src == dst */ + src++; + p++; + } + } + /* dst[len] = '\0'; */ /* ���ݭn�A�]���b b52gb()�Bgb2b5() �����θ� src == dst */ + + return dst; +} + + +void +b52gb(str) + char *str; +{ + hzconvert(str, str, b2g); +} + + +void +gb2b5(str) + char *str; +{ + hzconvert(str, str, g2b); +} |