function dec2char(n) { // converts a decimal number to a Unicode character // n: the dec codepoint value to be converted if (n <= 0xffff) { out = String.fromCharCode(n); } else if (n <= 0x10ffff) { n -= 0x10000; out = String.fromCharCode(0xd800 | (n >> 10)) + String.fromCharCode(0xdc00 | (n & 0x3ff)); } else out = "dec2char error: Code point out of range: " + n; return out; } function getIndexPtr(cp, index) { for (p = 0; p < index.length; p++) { if (index[p] == cp) { return p; } } return null; } function iso2022jpDecoder(stream) { stream = stream.replace(/%/g, " "); stream = stream.replace(/[\s]+/g, " ").trim(); var bytes = stream.split(" "); for (var i = 0; i < bytes.length; i++) bytes[i] = parseInt(bytes[i], 16); var endofstream = 2000000; //bytes.push(endofstream) var out = ""; var decState = "ascii"; var outState = "ascii"; var isoLead = 0x00; var outFlag = false; var cp, ptr, lead; var finished = false; while (!finished) { if (bytes.length == 0) byte = endofstream; else var byte = bytes.shift(); //byte = bytes.shift() switch (decState) { case "ascii": if (byte == 0x1b) { decState = "escStart"; continue; } else if ( byte >= 0x00 && byte <= 0x7f && byte !== 0x0e && byte !== 0x0f && byte !== 0x1b ) { outFlag = false; out += dec2char(byte); continue; } else if (byte == endofstream) { finished = true; continue; } else { outFlag = false; out += "�"; continue; } break; case "roman": if (byte == 0x1b) { decState = "escStart"; continue; } else if (byte == 0x5c) { outFlag = false; out += dec2char(0xa5); continue; } else if (byte == 0x7e) { outFlag = false; out += dec2char(0x203e); continue; } else if ( byte >= 0x00 && byte <= 0x7f && byte !== 0x0e && byte !== 0x0f && byte !== 0x1b && byte !== 0x5c && byte !== 0x7e ) { outFlag = false; out += dec2char(byte); continue; } else if (byte == endofstream) { finished = true; continue; } else { outFlag = false; out += "�"; continue; } break; case "katakana": if (byte == 0x1b) { decState = "escStart"; continue; } else if (byte >= 0x21 && byte <= 0x5f) { outFlag = false; out += dec2char(0xff61 + byte - 0x21); continue; } else if (byte == endofstream) { finished = true; continue; } else { outFlag = false; out += "�"; continue; } break; case "leadbyte": if (byte == 0x1b) { decState = "escStart"; continue; } else if (byte >= 0x21 && byte <= 0x7e) { outFlag = false; isoLead = byte; decState = "trailbyte"; continue; } else if (byte == endofstream) { finished = true; continue; } else { outFlag = false; out += "�"; continue; } break; case "trailbyte": if (byte == 0x1b) { decState = "escStart"; out += "�"; continue; } else if (byte >= 0x21 && byte <= 0x7e) { decState = "leadbyte"; ptr = (isoLead - 0x21) * 94 + byte - 0x21; cp = jis0208[ptr]; if (cp == null) { out += "�"; continue; } out += dec2char(cp); continue; } else if (byte == endofstream) { decState = "leadbyte"; bytes.unshift(byte); out += "�"; continue; } else { decState = "leadbyte"; out += "�"; continue; } break; case "escStart": if (byte == 0x24 || byte == 0x28) { isoLead = byte; decState = "escape"; continue; } else { bytes.unshift(byte); outFlag = false; decState = outState; out += "�"; continue; } break; case "escape": lead = isoLead; isoLead = 0x00; var state = null; if (lead == 0x28 && byte == 0x42) state = "ascii"; if (lead == 0x28 && byte == 0x4a) state = "roman"; if (lead == 0x28 && byte == 0x49) state = "katakana"; if (lead == 0x24 && (byte == 0x40 || byte == 0x42)) state = "leadbyte"; if (state != null) { decState = state; outState = state; var outputflag = false; outputflag = outFlag; outFlag = true; if (outputflag == false) continue; else { out += "�"; continue; } } // Prepend the sequence (lead, byte) to the stream bytes.unshift(lead, byte); outFlag = false; decState = outState; out += "�"; continue; break; } } return out; }