回精華區
作者itoc, 信區: itoc
標題[功能] 簡體支援 (2) -- 繁體/簡體中文轉換程式
時間04/12/17
作者: itoc (站上人數:802) 看板: plan
標題: [功能] 簡體支援 (2)
時間: 2004/12/17 Fri 18:06:00                           Updated: 2004/12/17

: maple.p

/* visio.c */
+ uschar *b52gb(char *str);
+ uschar *gb2b5(char *str);
void prints(char *fmt, ...);

: 以下這一段加在 visio.c:outs() 前面

/* ----------------------------------------------------- */
/* 繁體/簡體轉換程式                                     */
/* ----------------------------------------------------- */

#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;     /* 每個漢字 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, len)
  char *src;                    /* source char buffer pointer */
  char *dst;                    /* destination char buffer pointer */
  void (*dbcvrt) ();            /* 漢字 2-byte conversion funcntion */
  int len;
{
  char *end, *p;

  conv_init();

  p = dst;
  end = src + len;
  while (src < end)
  {
    if (*src & 0x80)            /* hi-bit on 表示是漢字 */
    {
      dbcvrt(src, p);
      src += 2;                 /* 一次轉二碼 */
      p += 2;
    }
    else
    {
      *p = *src;
      src++;
      p++;
    }
  }
  dst[len] = '\0';

  return dst;
}


unsigned char *
b52gb(str)
  char *str;
{
  static unsigned char *dst = NULL;
  int size;

  size = strlen(str);
  if (size < 2)         /* 漢字長度至少要 2 */
    return str;

  dst = !dst ? (unsigned char *) malloc(size + 1) :
               (unsigned char *) realloc(dst, size + 1);

  hzconvert(str, dst, b2g, size);

  return dst;
}


unsigned char *
gb2b5(str)
  char *str;
{
  static unsigned char *dst = NULL;
  int size;

  size = strlen(str);
  if (size < 2)         /* 漢字長度至少要 2 */
    return str;

  dst = !dst ? (unsigned char *) malloc(size + 1) :
               (unsigned char *) realloc(dst, size + 1);

  hzconvert(str, dst, g2b, size);

  return dst;
}

--
□ 本文章由 itocitoc.Dorm11.NCTU.edu.tw 發表
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻