11cb0ef41Sopenharmony_cifunction dec2char(n) {
21cb0ef41Sopenharmony_ci    // converts a decimal number to a Unicode character
31cb0ef41Sopenharmony_ci    // n: the dec codepoint value to be converted
41cb0ef41Sopenharmony_ci    if (n <= 0xffff) {
51cb0ef41Sopenharmony_ci        out = String.fromCharCode(n);
61cb0ef41Sopenharmony_ci    } else if (n <= 0x10ffff) {
71cb0ef41Sopenharmony_ci        n -= 0x10000;
81cb0ef41Sopenharmony_ci        out =
91cb0ef41Sopenharmony_ci            String.fromCharCode(0xd800 | (n >> 10)) +
101cb0ef41Sopenharmony_ci            String.fromCharCode(0xdc00 | (n & 0x3ff));
111cb0ef41Sopenharmony_ci    } else out = "dec2char error: Code point out of range: " + n;
121cb0ef41Sopenharmony_ci    return out;
131cb0ef41Sopenharmony_ci}
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cifunction getIndexPtr(cp, index) {
161cb0ef41Sopenharmony_ci    for (p = 0; p < index.length; p++) {
171cb0ef41Sopenharmony_ci        if (index[p] == cp) {
181cb0ef41Sopenharmony_ci            return p;
191cb0ef41Sopenharmony_ci        }
201cb0ef41Sopenharmony_ci    }
211cb0ef41Sopenharmony_ci    return null;
221cb0ef41Sopenharmony_ci}
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_cifunction iso2022jpDecoder(stream) {
251cb0ef41Sopenharmony_ci    stream = stream.replace(/%/g, " ");
261cb0ef41Sopenharmony_ci    stream = stream.replace(/[\s]+/g, " ").trim();
271cb0ef41Sopenharmony_ci    var bytes = stream.split(" ");
281cb0ef41Sopenharmony_ci    for (var i = 0; i < bytes.length; i++) bytes[i] = parseInt(bytes[i], 16);
291cb0ef41Sopenharmony_ci    var endofstream = 2000000;
301cb0ef41Sopenharmony_ci    //bytes.push(endofstream)
311cb0ef41Sopenharmony_ci    var out = "";
321cb0ef41Sopenharmony_ci    var decState = "ascii";
331cb0ef41Sopenharmony_ci    var outState = "ascii";
341cb0ef41Sopenharmony_ci    var isoLead = 0x00;
351cb0ef41Sopenharmony_ci    var outFlag = false;
361cb0ef41Sopenharmony_ci    var cp, ptr, lead;
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci    var finished = false;
391cb0ef41Sopenharmony_ci    while (!finished) {
401cb0ef41Sopenharmony_ci        if (bytes.length == 0) byte = endofstream;
411cb0ef41Sopenharmony_ci        else var byte = bytes.shift();
421cb0ef41Sopenharmony_ci        //byte = bytes.shift()
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci        switch (decState) {
451cb0ef41Sopenharmony_ci            case "ascii":
461cb0ef41Sopenharmony_ci                if (byte == 0x1b) {
471cb0ef41Sopenharmony_ci                    decState = "escStart";
481cb0ef41Sopenharmony_ci                    continue;
491cb0ef41Sopenharmony_ci                } else if (
501cb0ef41Sopenharmony_ci                    byte >= 0x00 &&
511cb0ef41Sopenharmony_ci                    byte <= 0x7f &&
521cb0ef41Sopenharmony_ci                    byte !== 0x0e &&
531cb0ef41Sopenharmony_ci                    byte !== 0x0f &&
541cb0ef41Sopenharmony_ci                    byte !== 0x1b
551cb0ef41Sopenharmony_ci                ) {
561cb0ef41Sopenharmony_ci                    outFlag = false;
571cb0ef41Sopenharmony_ci                    out += dec2char(byte);
581cb0ef41Sopenharmony_ci                    continue;
591cb0ef41Sopenharmony_ci                } else if (byte == endofstream) {
601cb0ef41Sopenharmony_ci                    finished = true;
611cb0ef41Sopenharmony_ci                    continue;
621cb0ef41Sopenharmony_ci                } else {
631cb0ef41Sopenharmony_ci                    outFlag = false;
641cb0ef41Sopenharmony_ci                    out += "�";
651cb0ef41Sopenharmony_ci                    continue;
661cb0ef41Sopenharmony_ci                }
671cb0ef41Sopenharmony_ci                break;
681cb0ef41Sopenharmony_ci            case "roman":
691cb0ef41Sopenharmony_ci                if (byte == 0x1b) {
701cb0ef41Sopenharmony_ci                    decState = "escStart";
711cb0ef41Sopenharmony_ci                    continue;
721cb0ef41Sopenharmony_ci                } else if (byte == 0x5c) {
731cb0ef41Sopenharmony_ci                    outFlag = false;
741cb0ef41Sopenharmony_ci                    out += dec2char(0xa5);
751cb0ef41Sopenharmony_ci                    continue;
761cb0ef41Sopenharmony_ci                } else if (byte == 0x7e) {
771cb0ef41Sopenharmony_ci                    outFlag = false;
781cb0ef41Sopenharmony_ci                    out += dec2char(0x203e);
791cb0ef41Sopenharmony_ci                    continue;
801cb0ef41Sopenharmony_ci                } else if (
811cb0ef41Sopenharmony_ci                    byte >= 0x00 &&
821cb0ef41Sopenharmony_ci                    byte <= 0x7f &&
831cb0ef41Sopenharmony_ci                    byte !== 0x0e &&
841cb0ef41Sopenharmony_ci                    byte !== 0x0f &&
851cb0ef41Sopenharmony_ci                    byte !== 0x1b &&
861cb0ef41Sopenharmony_ci                    byte !== 0x5c &&
871cb0ef41Sopenharmony_ci                    byte !== 0x7e
881cb0ef41Sopenharmony_ci                ) {
891cb0ef41Sopenharmony_ci                    outFlag = false;
901cb0ef41Sopenharmony_ci                    out += dec2char(byte);
911cb0ef41Sopenharmony_ci                    continue;
921cb0ef41Sopenharmony_ci                } else if (byte == endofstream) {
931cb0ef41Sopenharmony_ci                    finished = true;
941cb0ef41Sopenharmony_ci                    continue;
951cb0ef41Sopenharmony_ci                } else {
961cb0ef41Sopenharmony_ci                    outFlag = false;
971cb0ef41Sopenharmony_ci                    out += "�";
981cb0ef41Sopenharmony_ci                    continue;
991cb0ef41Sopenharmony_ci                }
1001cb0ef41Sopenharmony_ci                break;
1011cb0ef41Sopenharmony_ci            case "katakana":
1021cb0ef41Sopenharmony_ci                if (byte == 0x1b) {
1031cb0ef41Sopenharmony_ci                    decState = "escStart";
1041cb0ef41Sopenharmony_ci                    continue;
1051cb0ef41Sopenharmony_ci                } else if (byte >= 0x21 && byte <= 0x5f) {
1061cb0ef41Sopenharmony_ci                    outFlag = false;
1071cb0ef41Sopenharmony_ci                    out += dec2char(0xff61 + byte - 0x21);
1081cb0ef41Sopenharmony_ci                    continue;
1091cb0ef41Sopenharmony_ci                } else if (byte == endofstream) {
1101cb0ef41Sopenharmony_ci                    finished = true;
1111cb0ef41Sopenharmony_ci                    continue;
1121cb0ef41Sopenharmony_ci                } else {
1131cb0ef41Sopenharmony_ci                    outFlag = false;
1141cb0ef41Sopenharmony_ci                    out += "�";
1151cb0ef41Sopenharmony_ci                    continue;
1161cb0ef41Sopenharmony_ci                }
1171cb0ef41Sopenharmony_ci                break;
1181cb0ef41Sopenharmony_ci            case "leadbyte":
1191cb0ef41Sopenharmony_ci                if (byte == 0x1b) {
1201cb0ef41Sopenharmony_ci                    decState = "escStart";
1211cb0ef41Sopenharmony_ci                    continue;
1221cb0ef41Sopenharmony_ci                } else if (byte >= 0x21 && byte <= 0x7e) {
1231cb0ef41Sopenharmony_ci                    outFlag = false;
1241cb0ef41Sopenharmony_ci                    isoLead = byte;
1251cb0ef41Sopenharmony_ci                    decState = "trailbyte";
1261cb0ef41Sopenharmony_ci                    continue;
1271cb0ef41Sopenharmony_ci                } else if (byte == endofstream) {
1281cb0ef41Sopenharmony_ci                    finished = true;
1291cb0ef41Sopenharmony_ci                    continue;
1301cb0ef41Sopenharmony_ci                } else {
1311cb0ef41Sopenharmony_ci                    outFlag = false;
1321cb0ef41Sopenharmony_ci                    out += "�";
1331cb0ef41Sopenharmony_ci                    continue;
1341cb0ef41Sopenharmony_ci                }
1351cb0ef41Sopenharmony_ci                break;
1361cb0ef41Sopenharmony_ci            case "trailbyte":
1371cb0ef41Sopenharmony_ci                if (byte == 0x1b) {
1381cb0ef41Sopenharmony_ci                    decState = "escStart";
1391cb0ef41Sopenharmony_ci                    out += "�";
1401cb0ef41Sopenharmony_ci                    continue;
1411cb0ef41Sopenharmony_ci                } else if (byte >= 0x21 && byte <= 0x7e) {
1421cb0ef41Sopenharmony_ci                    decState = "leadbyte";
1431cb0ef41Sopenharmony_ci                    ptr = (isoLead - 0x21) * 94 + byte - 0x21;
1441cb0ef41Sopenharmony_ci                    cp = jis0208[ptr];
1451cb0ef41Sopenharmony_ci                    if (cp == null) {
1461cb0ef41Sopenharmony_ci                        out += "�";
1471cb0ef41Sopenharmony_ci                        continue;
1481cb0ef41Sopenharmony_ci                    }
1491cb0ef41Sopenharmony_ci                    out += dec2char(cp);
1501cb0ef41Sopenharmony_ci                    continue;
1511cb0ef41Sopenharmony_ci                } else if (byte == endofstream) {
1521cb0ef41Sopenharmony_ci                    decState = "leadbyte";
1531cb0ef41Sopenharmony_ci                    bytes.unshift(byte);
1541cb0ef41Sopenharmony_ci                    out += "�";
1551cb0ef41Sopenharmony_ci                    continue;
1561cb0ef41Sopenharmony_ci                } else {
1571cb0ef41Sopenharmony_ci                    decState = "leadbyte";
1581cb0ef41Sopenharmony_ci                    out += "�";
1591cb0ef41Sopenharmony_ci                    continue;
1601cb0ef41Sopenharmony_ci                }
1611cb0ef41Sopenharmony_ci                break;
1621cb0ef41Sopenharmony_ci            case "escStart":
1631cb0ef41Sopenharmony_ci                if (byte == 0x24 || byte == 0x28) {
1641cb0ef41Sopenharmony_ci                    isoLead = byte;
1651cb0ef41Sopenharmony_ci                    decState = "escape";
1661cb0ef41Sopenharmony_ci                    continue;
1671cb0ef41Sopenharmony_ci                } else {
1681cb0ef41Sopenharmony_ci                    bytes.unshift(byte);
1691cb0ef41Sopenharmony_ci                    outFlag = false;
1701cb0ef41Sopenharmony_ci                    decState = outState;
1711cb0ef41Sopenharmony_ci                    out += "�";
1721cb0ef41Sopenharmony_ci                    continue;
1731cb0ef41Sopenharmony_ci                }
1741cb0ef41Sopenharmony_ci                break;
1751cb0ef41Sopenharmony_ci            case "escape":
1761cb0ef41Sopenharmony_ci                lead = isoLead;
1771cb0ef41Sopenharmony_ci                isoLead = 0x00;
1781cb0ef41Sopenharmony_ci                var state = null;
1791cb0ef41Sopenharmony_ci                if (lead == 0x28 && byte == 0x42) state = "ascii";
1801cb0ef41Sopenharmony_ci                if (lead == 0x28 && byte == 0x4a) state = "roman";
1811cb0ef41Sopenharmony_ci                if (lead == 0x28 && byte == 0x49) state = "katakana";
1821cb0ef41Sopenharmony_ci                if (lead == 0x24 && (byte == 0x40 || byte == 0x42))
1831cb0ef41Sopenharmony_ci                    state = "leadbyte";
1841cb0ef41Sopenharmony_ci                if (state != null) {
1851cb0ef41Sopenharmony_ci                    decState = state;
1861cb0ef41Sopenharmony_ci                    outState = state;
1871cb0ef41Sopenharmony_ci                    var outputflag = false;
1881cb0ef41Sopenharmony_ci                    outputflag = outFlag;
1891cb0ef41Sopenharmony_ci                    outFlag = true;
1901cb0ef41Sopenharmony_ci                    if (outputflag == false) continue;
1911cb0ef41Sopenharmony_ci                    else {
1921cb0ef41Sopenharmony_ci                        out += "�";
1931cb0ef41Sopenharmony_ci                        continue;
1941cb0ef41Sopenharmony_ci                    }
1951cb0ef41Sopenharmony_ci                }
1961cb0ef41Sopenharmony_ci                // Prepend the sequence (lead, byte) to the stream
1971cb0ef41Sopenharmony_ci                bytes.unshift(lead, byte);
1981cb0ef41Sopenharmony_ci                outFlag = false;
1991cb0ef41Sopenharmony_ci                decState = outState;
2001cb0ef41Sopenharmony_ci                out += "�";
2011cb0ef41Sopenharmony_ci                continue;
2021cb0ef41Sopenharmony_ci                break;
2031cb0ef41Sopenharmony_ci        }
2041cb0ef41Sopenharmony_ci    }
2051cb0ef41Sopenharmony_ci    return out;
2061cb0ef41Sopenharmony_ci}
207