/*
 * Copyright (C) 1999-2001, 2005, 2012, 2016 Free Software Foundation, Inc.
 * This file is part of the GNU LIBICONV Library.
 *
 * The GNU LIBICONV Library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * The GNU LIBICONV Library is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
 * If not, see <https://www.gnu.org/licenses/>.
 */

/*
 * ISO-IR-165
 */

/*
 * ISO-IR-165 is an extension of GB 2312, consisting of:
 * 1. GB 6345.1-86 corrections:
 *    Two corrections to GB 2312, at 0x2367 and 0x6F71.
 * 2. GB 6345.1-86 additions:
 *    - 6 new full-width pinyin characters in row 0x28.
 *    - ISO646-CN in row 0x2A.
 *    - 32 half-width pinyin characters in row 0x2B.
 * 3. GB 8565.2-88 additions:
 *    - 50 characters in row 0x2D.
 *    - 92 characters in row 0x2E.
 *    - 93 characters in row 0x2F.
 *    - 470 characters in rows 0x7A-0x7E.
 * 4. ISO-IR-165 additions:
 *    - 22 characters in row 0x26.
 *    - 94 characters in row 0x2C.
 *    - 44 new characters in row 0x2D.
 *    - 1 new character in row 0x2F.
 *
 * The conversion table was created from the following sources:
 * Ad 1. The 0x2367 correction is already integrated in the unicode.org
 *       GB2312.TXT table. The 0x6F71 mapping is the same in the unicode.org
 *       GB2312.TXT and UNIHAN.TXT table and in Koichi Yasuoka's Uni2GB table,
 *       so we assume it's correct.
 * The unicode.org UNIHAN.TXT table about GB 8565 is not usable: it has
 * extraneous code points at rows 0x28, 0x2C, 0x2D. Note also that it does
 * not list the 69 non-hanzi in row 0x2F. Moreover, it has the characters
 * 0x2F7A-0x2F7D shifted down by one to 0x2F79-0x2F7C.
 * Therefore we take the GB8565 and ISO-IR-165 data from Koichi Yasuoka's
 * Uni2GB table.
 * Ad 1. Yasuoka maps 0x2367 to U+0261 (small script g) and 0x2840 to U+FF47
 *       (full-width small normal g). While coherent with ISO-IR's 165.pdf,
 *       this disagrees with Ken Lunde's book: He says that ISO-IR-165
 *       includes the GB6345 correction, i.e. maps 0x2367 to U+FF47 or U+0067
 *       and _not_ to U+0261 (small script g).
 *       To overcome the confusion, we just map both 0x2367 and 0x2840 to
 *       U+FF47.
 * Ad 2. Row 0x28: Add a mapping from 0x283F to U+01F9.
 *       Row 0x2A: Mapping is well-known, also present in Koichi Yasuoka's
 *                 table.
 *       Row 0x2B: Typed in by hand from appendix E in Ken Lunde's book.
 *       When converting from Unicode to ISO-IR-165, prefer the half-width
 *       range 0x2B{21..40} to the full-width range 0x28{21..40}.
 * Ad 3. Rows 0x2D, 0x2E: Both Koichi Yasuoka's Uni2GB table and the UNIHAN.TXT
 *                 data for GB 8565 agree here.
 *       Row 0x2F: Taken from Koichi Yasuoka's Uni2GB table.
 *       Rows 0x7A-0x7E: Koichi Yasuoka's Uni2GB table and the UNIHAN.TXT
 *                 data for GB 8565 agree here mostly. Differences:
 *                 0x7C38 -> U+6F26 or U+527A ? We choose U+6F26.
 *                 0x7C5A -> U+7A40 or U+6996 ? We choose U+6996.
 * Ad 4. Row 0x26: Mapping unknown.
 *       Rows 0x2C, 0x2D: Both Koichi Yasuoka's Uni2GB table and the UNIHAN.TXT
 *                 data for GB 8565 (!) agree here.
 *       Row 0x2F: Taken from Koichi Yasuoka's Uni2GB table.
 */

#include "isoir165ext.h"

static int
isoir165_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
{
  int ret;

  /* Map full-width pinyin (row 0x28) like half-width pinyin (row 0x2B). */
  if (s[0] == 0x28) {
    if (n >= 2) {
      unsigned char c2 = s[1];
      if (c2 >= 0x21 && c2 <= 0x40) {
        unsigned char buf[2];
        buf[0] = 0x2b;
        buf[1] = c2;
        ret = isoir165ext_mbtowc(conv,pwc,buf,2);
        if (ret != RET_ILSEQ)
          return ret;
      }
    }
  }
  /* Try the GB2312 -> Unicode table. */
  ret = gb2312_mbtowc(conv,pwc,s,n);
  if (ret != RET_ILSEQ)
    return ret;
  /* Row 0x2A is GB_1988-80. */
  if (s[0] == 0x2a) {
    if (n >= 2) {
      unsigned char c2 = s[1];
      if (c2 >= 0x21 && c2 < 0x7f) {
        ret = iso646_cn_mbtowc(conv,pwc,s+1,1);
        if (ret != 1) abort();
        return 2;
      }
      return RET_ILSEQ;
    }
    return RET_TOOFEW(0);
  }
  /* Try the ISO-IR-165 extensions -> Unicode table. */
  ret = isoir165ext_mbtowc(conv,pwc,s,n);
  return ret;
}

static int
isoir165_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, size_t n)
{
  unsigned char buf[2];
  int ret;

  /* Try the Unicode -> GB2312 table. */
  ret = gb2312_wctomb(conv,buf,wc,2);
  if (ret != RET_ILUNI) {
    if (ret != 2) abort();
    if (!(buf[0] == 0x28 && buf[1] >= 0x21 && buf[1] <= 0x40)) {
      if (n >= 2) {
        r[0] = buf[0];
        r[1] = buf[1];
        return 2;
      }
      return RET_TOOSMALL;
    }
  }
  /* Row 0x2A is GB_1988-80. */
  ret = iso646_cn_wctomb(conv,buf,wc,1);
  if (ret != RET_ILUNI) {
    if (ret != 1) abort();
    if (buf[0] >= 0x21 && buf[0] < 0x7f) {
      if (n >= 2) {
        r[0] = 0x2a;
        r[1] = buf[0];
        return 2;
      }
      return RET_TOOSMALL;
    }
  }
  /* Try the Unicode -> ISO-IR-165 extensions table. */
  ret = isoir165ext_wctomb(conv,r,wc,n);
  return ret;
}
