14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * _codecs_kr.c: Codecs collection for Korean encodings
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Written by Hye-Shik Chang <perky@FreeBSD.org>
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "cjkcodecs.h"
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "mappings_kr.h"
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * EUC-KR codec
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define EUCKR_JAMO_FIRSTBYTE    0xA4
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define EUCKR_JAMO_FILLER       0xD4
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char u2cgk_choseong[19] = {
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xa9, 0xb1, 0xb2,
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xbc, 0xbd, 0xbe
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char u2cgk_jungseong[21] = {
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xcf, 0xd0, 0xd1, 0xd2, 0xd3
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char u2cgk_jongseong[28] = {
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xd4, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xba,
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xbb, 0xbc, 0xbd, 0xbe
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmENCODER(euc_kr)
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (inleft > 0) {
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_UNICODE c = IN1;
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        DBCHAR code;
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c < 0x80) {
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            WRITE1((unsigned char)c)
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(1, 1)
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue;
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        UCS4INVALID(c)
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        REQUIRE_OUTBUF(2)
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TRYMAP_ENC(cp949, code, c);
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else return 1;
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if ((code & 0x8000) == 0) {
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* KS X 1001 coded character */
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT1((code >> 8) | 0x80)
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT2((code & 0xFF) | 0x80)
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(1, 2)
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else {          /* Mapping is found in CP949 extension,
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                 * but we encode it in KS X 1001:1998 Annex 3,
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                 * make-up sequence for EUC-KR. */
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            REQUIRE_OUTBUF(8)
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* syllable composition precedence */
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT1(EUCKR_JAMO_FIRSTBYTE)
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT2(EUCKR_JAMO_FILLER)
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* All codepoints in CP949 extension are in unicode
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             * Hangul Syllable area. */
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            assert(0xac00 <= c && c <= 0xd7a3);
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c -= 0xac00;
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT3(EUCKR_JAMO_FIRSTBYTE)
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT4(u2cgk_choseong[c / 588])
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT_OUT(4)
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT1(EUCKR_JAMO_FIRSTBYTE)
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT2(u2cgk_jungseong[(c / 28) % 21])
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT3(EUCKR_JAMO_FIRSTBYTE)
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT4(u2cgk_jongseong[c % 28])
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(1, 4)
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define NONE    127
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char cgk2u_choseong[] = { /* [A1, BE] */
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       0,    1, NONE,    2, NONE, NONE,    3,    4,
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       5, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       6,    7,    8, NONE,    9,   10,   11,   12,
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      13,   14,   15,   16,   17,   18
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char cgk2u_jongseong[] = { /* [A1, BE] */
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       1,    2,    3,    4,    5,    6,    7, NONE,
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       8,    9,   10,   11,   12,   13,   14,   15,
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      16,   17, NONE,   18,   19,   20,   21,   22,
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE,   23,   24,   25,   26,   27
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmDECODER(euc_kr)
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (inleft > 0) {
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned char c = IN1;
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        REQUIRE_OUTBUF(1)
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c < 0x80) {
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT1(c)
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(1, 1)
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue;
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        REQUIRE_INBUF(2)
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c == EUCKR_JAMO_FIRSTBYTE &&
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            IN2 == EUCKR_JAMO_FILLER) {
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* KS X 1001:1998 Annex 3 make-up sequence */
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            DBCHAR cho, jung, jong;
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            REQUIRE_INBUF(8)
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if ((*inbuf)[2] != EUCKR_JAMO_FIRSTBYTE ||
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (*inbuf)[4] != EUCKR_JAMO_FIRSTBYTE ||
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (*inbuf)[6] != EUCKR_JAMO_FIRSTBYTE)
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 8;
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c = (*inbuf)[3];
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (0xa1 <= c && c <= 0xbe)
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                cho = cgk2u_choseong[c - 0xa1];
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                cho = NONE;
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c = (*inbuf)[5];
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            jung = (0xbf <= c && c <= 0xd3) ? c - 0xbf : NONE;
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c = (*inbuf)[7];
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (c == EUCKR_JAMO_FILLER)
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                jong = 0;
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (0xa1 <= c && c <= 0xbe)
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                jong = cgk2u_jongseong[c - 0xa1];
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                jong = NONE;
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (cho == NONE || jung == NONE || jong == NONE)
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 8;
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT1(0xac00 + cho*588 + jung*28 + jong);
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(8, 1)
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else TRYMAP_DEC(ksx1001, **outbuf, c ^ 0x80, IN2 ^ 0x80) {
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(2, 1)
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 2;
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#undef NONE
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * CP949 codec
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmENCODER(cp949)
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (inleft > 0) {
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_UNICODE c = IN1;
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        DBCHAR code;
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c < 0x80) {
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            WRITE1((unsigned char)c)
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(1, 1)
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue;
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        UCS4INVALID(c)
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        REQUIRE_OUTBUF(2)
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TRYMAP_ENC(cp949, code, c);
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else return 1;
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        OUT1((code >> 8) | 0x80)
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (code & 0x8000)
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT2(code & 0xFF) /* MSB set: CP949 */
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT2((code & 0xFF) | 0x80) /* MSB unset: ks x 1001 */
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        NEXT(1, 2)
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmDECODER(cp949)
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (inleft > 0) {
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned char c = IN1;
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        REQUIRE_OUTBUF(1)
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c < 0x80) {
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT1(c)
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(1, 1)
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue;
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        REQUIRE_INBUF(2)
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TRYMAP_DEC(ksx1001, **outbuf, c ^ 0x80, IN2 ^ 0x80);
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else TRYMAP_DEC(cp949ext, **outbuf, c, IN2);
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else return 2;
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        NEXT(2, 1)
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * JOHAB codec
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char u2johabidx_choseong[32] = {
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x10, 0x11, 0x12, 0x13, 0x14,
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char u2johabidx_jungseong[32] = {
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      0x03, 0x04, 0x05, 0x06, 0x07,
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                0x1a, 0x1b, 0x1c, 0x1d,
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char u2johabidx_jongseong[32] = {
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm          0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x10, 0x11,       0x13, 0x14, 0x15, 0x16, 0x17,
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const DBCHAR u2johabjamo[] = {
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            0x8841, 0x8c41, 0x8444, 0x9041, 0x8446, 0x8447, 0x9441,
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x9841, 0x9c41, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f,
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x8450, 0xa041, 0xa441, 0xa841, 0x8454, 0xac41, 0xb041, 0xb441,
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0xb841, 0xbc41, 0xc041, 0xc441, 0xc841, 0xcc41, 0xd041, 0x8461,
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x8481, 0x84a1, 0x84c1, 0x84e1, 0x8541, 0x8561, 0x8581, 0x85a1,
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x85c1, 0x85e1, 0x8641, 0x8661, 0x8681, 0x86a1, 0x86c1, 0x86e1,
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x8741, 0x8761, 0x8781, 0x87a1,
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmENCODER(johab)
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (inleft > 0) {
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_UNICODE c = IN1;
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        DBCHAR code;
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c < 0x80) {
2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            WRITE1((unsigned char)c)
2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(1, 1)
2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue;
2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        UCS4INVALID(c)
2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        REQUIRE_OUTBUF(2)
2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c >= 0xac00 && c <= 0xd7a3) {
2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c -= 0xac00;
2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            code = 0x8000 |
2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (u2johabidx_choseong[c / 588] << 10) |
2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (u2johabidx_jungseong[(c / 28) % 21] << 5) |
2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                u2johabidx_jongseong[c % 28];
2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (c >= 0x3131 && c <= 0x3163)
2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            code = u2johabjamo[c - 0x3131];
2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else TRYMAP_ENC(cp949, code, c) {
2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            unsigned char c1, c2, t2;
2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            unsigned short t1;
2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            assert((code & 0x8000) == 0);
2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c1 = code >> 8;
2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c2 = code & 0xff;
2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (((c1 >= 0x21 && c1 <= 0x2c) ||
2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (c1 >= 0x4a && c1 <= 0x7d)) &&
2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (c2 >= 0x21 && c2 <= 0x7e)) {
2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                t1 = (c1 < 0x4a ? (c1 - 0x21 + 0x1b2) :
2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          (c1 - 0x21 + 0x197));
2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                t2 = ((t1 & 1) ? 0x5e : 0) + (c2 - 0x21);
2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                OUT1(t1 >> 1)
2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                OUT2(t2 < 0x4e ? t2 + 0x31 : t2 + 0x43)
2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                NEXT(1, 2)
2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                continue;
2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 1;
2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 1;
2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        OUT1(code >> 8)
3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        OUT2(code & 0xff)
3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        NEXT(1, 2)
3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define FILL 0xfd
3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define NONE 0xff
3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char johabidx_choseong[32] = {
3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x0e, 0x0f, 0x10, 0x11, 0x12, NONE, NONE, NONE,
3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char johabidx_jungseong[32] = {
3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04,
3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, 0x11, 0x12, 0x13, 0x14, NONE, NONE,
3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char johabidx_jongseong[32] = {
3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, FILL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x0f, 0x10, NONE, 0x11, 0x12, 0x13, 0x14, 0x15,
3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, NONE, NONE,
3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char johabjamo_choseong[32] = {
3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, FILL, 0x31, 0x32, 0x34, 0x37, 0x38, 0x39,
3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x41, 0x42, 0x43, 0x45, 0x46, 0x47, 0x48, 0x49,
3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE, NONE,
3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char johabjamo_jungseong[32] = {
3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, FILL, 0x4f, 0x50, 0x51, 0x52, 0x53,
3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, NONE, 0x60, 0x61, 0x62, 0x63, NONE, NONE,
3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const unsigned char johabjamo_jongseong[32] = {
3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NONE, FILL, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x37, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x40, 0x41, NONE, 0x42, 0x44, 0x45, 0x46, 0x47,
3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0x48, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE,
3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmDECODER(johab)
3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (inleft > 0) {
3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned char    c = IN1, c2;
3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        REQUIRE_OUTBUF(1)
3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c < 0x80) {
3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            OUT1(c)
3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(1, 1)
3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue;
3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        REQUIRE_INBUF(2)
3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        c2 = IN2;
3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c < 0xd8) {
3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* johab hangul */
3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            unsigned char c_cho, c_jung, c_jong;
3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            unsigned char i_cho, i_jung, i_jong;
3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c_cho = (c >> 2) & 0x1f;
3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c_jung = ((c << 3) | c2 >> 5) & 0x1f;
3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            c_jong = c2 & 0x1f;
3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            i_cho = johabidx_choseong[c_cho];
3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            i_jung = johabidx_jungseong[c_jung];
3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            i_jong = johabidx_jongseong[c_jong];
3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (i_cho == NONE || i_jung == NONE || i_jong == NONE)
3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 2;
3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* we don't use U+1100 hangul jamo yet. */
3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (i_cho == FILL) {
3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (i_jung == FILL) {
3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if (i_jong == FILL)
3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        OUT1(0x3000)
3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    else
3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        OUT1(0x3100 |
3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          johabjamo_jongseong[c_jong])
3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else {
3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if (i_jong == FILL)
3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        OUT1(0x3100 |
3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          johabjamo_jungseong[c_jung])
3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    else
3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        return 2;
3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            } else {
3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (i_jung == FILL) {
3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if (i_jong == FILL)
3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        OUT1(0x3100 |
4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          johabjamo_choseong[c_cho])
4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    else
4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        return 2;
4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else
4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    OUT1(0xac00 +
4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         i_cho * 588 +
4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         i_jung * 28 +
4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         (i_jong == FILL ? 0 : i_jong))
4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            NEXT(2, 1)
4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else {
4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* KS X 1001 except hangul jamos and syllables */
4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (c == 0xdf || c > 0xf9 ||
4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                c2 < 0x31 || (c2 >= 0x80 && c2 < 0x91) ||
4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (c2 & 0x7f) == 0x7f ||
4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (c == 0xda && (c2 >= 0xa1 && c2 <= 0xd3)))
4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 2;
4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else {
4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                unsigned char t1, t2;
4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                t1 = (c < 0xe0 ? 2 * (c - 0xd9) :
4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         2 * c - 0x197);
4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                t2 = (c2 < 0x91 ? c2 - 0x31 : c2 - 0x43);
4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                t1 = t1 + (t2 < 0x5e ? 0 : 1) + 0x21;
4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                t2 = (t2 < 0x5e ? t2 : t2 - 0x5e) + 0x21;
4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                TRYMAP_DEC(ksx1001, **outbuf, t1, t2);
4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else return 2;
4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                NEXT(2, 1)
4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#undef NONE
4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#undef FILL
4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBEGIN_MAPPINGS_LIST
4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  MAPPING_DECONLY(ksx1001)
4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  MAPPING_ENCONLY(cp949)
4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  MAPPING_DECONLY(cp949ext)
4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEND_MAPPINGS_LIST
4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBEGIN_CODECS_LIST
4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  CODEC_STATELESS(euc_kr)
4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  CODEC_STATELESS(cp949)
4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  CODEC_STATELESS(johab)
4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEND_CODECS_LIST
4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmI_AM_A_MODULE_FOR(kr)
453