回精華區
作者PaulLiu.bbs@processor.tfcis.org (GrandPaul) 看板: plan
標題Re: [問題] 關於 RFC 2045 / RFC 2047
時間XEON (Tue, 01 Apr 2003 19:22:16 +0800 (CST)) Updated: 2005/08/29
※ -------------- lib 的部分 -------------- ※

: libiconv

  裝 libiconv
  若是 FreeBSD,在 /usr/ports/converters/libiconv

: lib/dao.p

/* str_decode.c */
char *mm_getencode(unsigned char *str, char *code);
void mm_getcharset(const char *str, char *charset, int size);
int mmdecode(unsigned char *src, int encode, unsigned char *dst);
void str_decode(unsigned char *str);
+ void str_conv(unsigned char *fromcode, unsigned char *tocode,
+   char *str, int len);

: lib/Makefile 若是 FreeBSD 要改這個

CC      = gcc
RANLIB  = ranlib
CPROTO  = cproto -E"gcc -pipe -E" -I../include # -s -v
! CFLAGS  = .... -I../include -I/usr/local/include

: lib/str_decode.c 在最後加入這一整段

/* 這個函式會將一個字串 (src) 從 charset=fromcode 轉成 charset=tocode,
   srclen 是 src 的長度, dst 是輸出的buffer, dstlen 則指定了
   dst 的大小, 最後會補 '\0', 所以要留一個byte給'\0'.
   如果遇到 src 中有非字集的字, 或是 src 中有未完整的 byte,
   都會砍掉.
*/

#include <errno.h>
#include <iconv.h>

static int
str_iconv(fromcode, tocode, src, srclen, dst, dstlen)
  const char *fromcode; /* charset of source string */
  const char *tocode;   /* charset of destination string */
  char *src;            /* source string */
  int srclen;           /* source string length */
  char *dst;            /* destination string */
  int dstlen;           /* destination string length */
{
  iconv_t iconv_descriptor;
  int dstlen_old;
  extern int errno;

  dstlen--;                     /* keep space for '\0' */

  /* Open a descriptor for iconv */
  iconv_descriptor = iconv_open(tocode, fromcode);

  if (iconv_descriptor == ((iconv_t) (-1)))     /* if open fail */
  {
    strncpy(dst, src, dstlen);
    return dstlen;
  }

  dstlen_old = dstlen;

  /* Start translation */
  while (srclen > 0 && dstlen > 0)
  {
    if (iconv(iconv_descriptor, (void *) &src, &srclen, &dst, &dstlen))
    {
      switch (errno)
      {
      case EILSEQ:  /* invalid multibyte happened */
      case EINVAL:  /* incomplete multibyte happened */
        /* delete that byte */
        *dst = *src;
        src++;
        srclen--;
        dst++;
        dstlen--;
        break;

      case E2BIG:   /* dst no rooms */
        /* break out the while loop */
        srclen = 0;
        break;
      }
    }
  }
  *dst = '\0';

  /* close descriptor of iconv */
  iconv_close(iconv_descriptor);

  return (dstlen_old - dstlen);
}


void
str_conv(fromcode, tocode, str, len)
  unsigned char *fromcode;
  unsigned char *tocode;
  char *str;        /* 欲 convert 的字串 (未必要 end with '\0') */
  int len;          /* 字串 str 的長度 */
{
  char *ptr;

  if (len <= 0)
    return;

  if (!str_cmp(fromcode, tocode))    /* 相同 charset 就不轉了 */
    return;

  ptr = (char *) malloc(len);
  strncpy(ptr, str, len);
  str_iconv(fromcode, tocode, ptr, len, str, len);
  free(ptr);
}

--
    ╭─ Origin ─╗ O processor.tfcis.org  ~ κλμ ─┤
    ├   Author   ╡ cnal.csie.nctu.edu.tw                    
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻