isoir165.h
Upload User: yingmei828
Upload Date: 2007-01-01
Package Size: 1646k
Code Size: 5k
Development Platform:

Unix_Linux

  1. /*
  2.  * ISO-IR-165
  3.  */
  4. /*
  5.  * ISO-IR-165 is an extension of GB 2312, consisting of:
  6.  * 1. GB 6345.1-86 corrections:
  7.  *    Two corrections to GB 2312, at 0x2367 and 0x6F71.
  8.  * 2. GB 6345.1-86 additions:
  9.  *    - 6 new full-width pinyin characters in row 0x28.
  10.  *    - ISO646-CN in row 0x2A.
  11.  *    - 32 half-width pinyin characters in row 0x2B.
  12.  * 3. GB 8565.2-88 additions:
  13.  *    - 50 characters in row 0x2D.
  14.  *    - 92 characters in row 0x2E.
  15.  *    - 93 characters in row 0x2F.
  16.  *    - 470 characters in rows 0x7A-0x7E.
  17.  * 4. ISO-IR-165 additions:
  18.  *    - 22 characters in row 0x26.
  19.  *    - 94 characters in row 0x2C.
  20.  *    - 44 new characters in row 0x2D.
  21.  *    - 1 new character in row 0x2F.
  22.  *
  23.  * The conversion table was created from the following sources:
  24.  * Ad 1. The 0x2367 correction is already integrated in the unicode.org
  25.  *       GB2312.TXT table. The 0x6F71 mapping is the same in the unicode.org
  26.  *       GB2312.TXT and UNIHAN.TXT table and in Koichi Yasuoka's Uni2GB table,
  27.  *       so we assume it's correct.
  28.  * The unicode.org UNIHAN.TXT table about GB 8565 is not usable: it has
  29.  * extraneous code points at rows 0x28, 0x2C, 0x2D. Note also that it does
  30.  * not list the 69 non-hanzi in row 0x2F. Moreover, it has the characters
  31.  * 0x2F7A-0x2F7D shifted down by one to 0x2F79-0x2F7C.
  32.  * Therefore we take the GB8565 and ISO-IR-165 data from Koichi Yasuoka's
  33.  * Uni2GB table.
  34.  * Ad 1. Yasuoka maps 0x2367 to U+0261 (small script g) and 0x2840 to U+FF47
  35.  *       (full-width small normal g). While coherent with ISO-IR's 165.pdf,
  36.  *       this disagrees with Ken Lunde's book: He says that ISO-IR-165
  37.  *       includes the GB6345 correction, i.e. maps 0x2367 to U+FF47 or U+0067
  38.  *       and _not_ to U+0261 (small script g).
  39.  *       To overcome the confusion, we just map both 0x2367 and 0x2840 to
  40.  *       U+FF47.
  41.  * Ad 2. Row 0x28: Add a mapping from 0x283F to U+01F9.
  42.  *       Row 0x2A: Mapping is well-known, also present in Koichi Yasuoka's
  43.  *                 table.
  44.  *       Row 0x2B: Typed in by hand from appendix E in Ken Lunde's book.
  45.  *       When converting from Unicode to ISO-IR-165, prefer the half-width
  46.  *       range 0x2B{21..40} to the full-width range 0x28{21..40}.
  47.  * Ad 3. Rows 0x2D, 0x2E: Both Koichi Yasuoka's Uni2GB table and the UNIHAN.TXT
  48.  *                 data for GB 8565 agree here.
  49.  *       Row 0x2F: Taken from Koichi Yasuoka's Uni2GB table.
  50.  *       Rows 0x7A-0x7E: Koichi Yasuoka's Uni2GB table and the UNIHAN.TXT
  51.  *                 data for GB 8565 agree here mostly. Differences:
  52.  *                 0x7C38 -> U+6F26 or U+527A ? We choose U+6F26.
  53.  *                 0x7C5A -> U+7A40 or U+6996 ? We choose U+6996.
  54.  * Ad 4. Row 0x26: Mapping unknown.
  55.  *       Rows 0x2C, 0x2D: Both Koichi Yasuoka's Uni2GB table and the UNIHAN.TXT
  56.  *                 data for GB 8565 (!) agree here.
  57.  *       Row 0x2F: Taken from Koichi Yasuoka's Uni2GB table.
  58.  */
  59. #include "isoir165ext.h"
  60. static int
  61. isoir165_mbtowc (conv_t conv, wchar_t *pwc, const unsigned char *s, int n)
  62. {
  63.   int ret;
  64.   /* Map full-width pinyin (row 0x28) like half-width pinyin (row 0x2B). */
  65.   if (s[0] == 0x28) {
  66.     if (n >= 2) {
  67.       unsigned char c2 = s[1];
  68.       if (c2 >= 0x21 && c2 <= 0x40) {
  69.         unsigned char buf[2];
  70.         buf[0] = 0x2b;
  71.         buf[1] = c2;
  72.         ret = isoir165ext_mbtowc(conv,pwc,buf,2);
  73.         if (ret != RET_ILSEQ)
  74.           return ret;
  75.       }
  76.     }
  77.   }
  78.   /* Try the GB2312 -> Unicode table. */
  79.   ret = gb2312_mbtowc(conv,pwc,s,n);
  80.   if (ret != RET_ILSEQ)
  81.     return ret;
  82.   /* Row 0x2A is GB_1988-80. */
  83.   if (s[0] == 0x2a) {
  84.     if (n >= 2) {
  85.       unsigned char c2 = s[1];
  86.       if (c2 >= 0x21 && c2 < 0x7f) {
  87.         int ret = iso646_cn_mbtowc(conv,pwc,s+1,1);
  88.         if (ret != 1) abort();
  89.         return 2;
  90.       }
  91.       return RET_ILSEQ;
  92.     }
  93.     return RET_TOOFEW(0);
  94.   }
  95.   /* Try the ISO-IR-165 extensions -> Unicode table. */
  96.   ret = isoir165ext_mbtowc(conv,pwc,s,n);
  97.   return ret;
  98. }
  99. static int
  100. isoir165_wctomb (conv_t conv, unsigned char *r, wchar_t wc, int n)
  101. {
  102.   unsigned char buf[1];
  103.   int ret;
  104.   /* Try the Unicode -> GB2312 table table. */
  105.   ret = gb2312_wctomb(conv,r,wc,n);
  106.   if (ret != RET_ILSEQ) {
  107.     if (ret != 2) abort();
  108.     if (!(r[0] == 0x28 && r[1] >= 0x21 && r[1] <= 0x40))
  109.       return ret;
  110.   }
  111.   /* Row 0x2A is GB_1988-80. */
  112.   ret = iso646_cn_wctomb(conv,buf,wc,1);
  113.   if (ret != RET_ILSEQ) {
  114.     if (ret != 1) abort();
  115.     if (buf[0] >= 0x21 && buf[0] < 0x7f) {
  116.       if (n >= 2) {
  117.         r[0] = 0x2a;
  118.         r[1] = buf[0];
  119.         return 2;
  120.       }
  121.       return RET_TOOSMALL;
  122.     }
  123.   }
  124.   /* Try the Unicode -> ISO-IR-165 extensions table. */
  125.   ret = isoir165ext_wctomb(conv,r,wc,n);
  126.   return ret;
  127. }