summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/encoding/legacy-mb-japanese/shift_jis/sjis-decoder.js
blob: 48e08b3fbf7c304570551dbf20c255b60d88aec9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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 sjisDecoder(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 out = "";
	var lead, byte, leadoffset, offset, ptr, cp;
	var sjisLead = 0x00;
	var endofstream = 2000000;
	var finished = false;

	while (!finished) {
		if (bytes.length == 0) byte = endofstream;
		else byte = bytes.shift();

		if (byte == endofstream && sjisLead != 0x00) {
			sjisLead = 0x00;
			out += "�";
			continue;
		}
		if (byte == endofstream && sjisLead == 0x00) {
			finished = true;
			continue;
		}
		if (sjisLead != 0x00) {
			lead = sjisLead;
			ptr = null;
			sjisLead = 0x00;
			if (byte < 0x7f) offset = 0x40;
			else offset = 0x41;
			if (lead < 0xa0) leadoffset = 0x81;
			else leadoffset = 0xc1;
			if ((byte >= 0x40 && byte <= 0x7e) || (byte >= 0x80 && byte <= 0xfc))
				ptr = (lead - leadoffset) * 188 + byte - offset;
			if (ptr != null && ptr >= 8836 && ptr <= 10715) {
				out += dec2char(0xe000 + ptr - 8836);
				continue;
			}
			if (ptr == null) cp = null;
			else cp = jis0208[ptr];
			if (cp == null && byte >= 0x00 && byte <= 0x7f) {
				bytes.unshift(byte);
			}
			if (cp == null) {
				out += "�";
				continue;
			}
			out += dec2char(cp);
			continue;
		}
		if ((byte >= 0x00 && byte <= 0x7f) || byte == 0x80) {
			out += dec2char(byte);
			continue;
		}
		if (byte >= 0xa1 && byte <= 0xdf) {
			out += dec2char(0xff61 + byte - 0xa1);
			continue;
		}
		if ((byte >= 0x81 && byte <= 0x9f) || (byte >= 0xe0 && byte <= 0xfc)) {
			sjisLead = byte;
			continue;
		}
		out += "�";
	}
	return out;
}