@loaders.gl/polyfills 4.2.0-alpha.3 → 4.2.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/buffer/btoa.node.js +5 -3
- package/dist/buffer/to-array-buffer.node.js +6 -6
- package/dist/crypto/node-hash.js +41 -45
- package/dist/fetch/decode-data-uri.js +56 -41
- package/dist/fetch/fetch-polyfill.d.ts +1 -1
- package/dist/fetch/fetch-polyfill.d.ts.map +1 -1
- package/dist/fetch/fetch-polyfill.js +118 -103
- package/dist/fetch/headers-polyfill.js +90 -89
- package/dist/fetch/response-polyfill.d.ts +1 -1
- package/dist/fetch/response-polyfill.d.ts.map +1 -1
- package/dist/fetch/response-polyfill.js +65 -57
- package/dist/fetch/utils/decode-data-uri.node.js +56 -41
- package/dist/file/blob-stream-controller.js +54 -38
- package/dist/file/blob-stream.d.ts +1 -1
- package/dist/file/blob-stream.d.ts.map +1 -1
- package/dist/file/blob-stream.js +29 -15
- package/dist/file/blob.d.ts +1 -1
- package/dist/file/blob.d.ts.map +1 -1
- package/dist/file/blob.js +146 -109
- package/dist/file/file-reader.js +22 -50
- package/dist/file/file.js +30 -15
- package/dist/file/install-blob-polyfills.js +6 -5
- package/dist/file/install-file-polyfills.js +11 -8
- package/dist/file/readable-stream.js +5 -2
- package/dist/filesystems/fetch-node.js +78 -68
- package/dist/filesystems/node-file.js +119 -87
- package/dist/filesystems/node-filesystem.d.ts +1 -1
- package/dist/filesystems/node-filesystem.d.ts.map +1 -1
- package/dist/filesystems/node-filesystem.js +39 -35
- package/dist/filesystems/stream-utils.node.js +88 -55
- package/dist/images/encode-image-node.js +25 -12
- package/dist/images/encode-image.node.js +25 -12
- package/dist/images/parse-image-node.js +30 -23
- package/dist/images/parse-image.node.js +30 -23
- package/dist/index.browser.js +8 -3
- package/dist/index.cjs +13 -65091
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +45 -15
- package/dist/libs/encoding-indexes-asian.js +6 -7
- package/dist/load-library/require-utils.node.js +70 -44
- package/dist/streams/make-node-stream.js +48 -46
- package/dist/text-encoder/encoding-indexes.js +31 -28
- package/dist/text-encoder/text-encoder.js +2604 -1033
- package/dist/utils/assert.js +3 -4
- package/dist/utils/is-browser.js +7 -2
- package/package.json +10 -8
- package/dist/buffer/btoa.node.js.map +0 -1
- package/dist/buffer/to-array-buffer.node.js.map +0 -1
- package/dist/crypto/node-hash.js.map +0 -1
- package/dist/dist.dev.js +0 -45
- package/dist/fetch/decode-data-uri.js.map +0 -1
- package/dist/fetch/fetch-polyfill.js.map +0 -1
- package/dist/fetch/headers-polyfill.js.map +0 -1
- package/dist/fetch/response-polyfill.js.map +0 -1
- package/dist/fetch/utils/decode-data-uri.node.js.map +0 -1
- package/dist/file/blob-stream-controller.js.map +0 -1
- package/dist/file/blob-stream.js.map +0 -1
- package/dist/file/blob.js.map +0 -1
- package/dist/file/file-reader.js.map +0 -1
- package/dist/file/file.js.map +0 -1
- package/dist/file/install-blob-polyfills.js.map +0 -1
- package/dist/file/install-file-polyfills.js.map +0 -1
- package/dist/file/readable-stream.js.map +0 -1
- package/dist/filesystems/fetch-node.js.map +0 -1
- package/dist/filesystems/node-file.js.map +0 -1
- package/dist/filesystems/node-filesystem.js.map +0 -1
- package/dist/filesystems/stream-utils.node.js.map +0 -1
- package/dist/images/encode-image-node.js.map +0 -1
- package/dist/images/encode-image.node.js.map +0 -1
- package/dist/images/parse-image-node.js.map +0 -1
- package/dist/images/parse-image.node.js.map +0 -1
- package/dist/index.browser.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/load-library/require-utils.node.js.map +0 -1
- package/dist/streams/make-node-stream.js.map +0 -1
- package/dist/text-encoder/encoding-indexes.js.map +0 -1
- package/dist/text-encoder/text-encoder.js.map +0 -1
- package/dist/utils/assert.js.map +0 -1
- package/dist/utils/is-browser.js.map +0 -1
|
@@ -1,1206 +1,2777 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
// Copied from https://github.com/inexorabletash/text-encoding/blob/b4e5bc26e26e51f56e3daa9f13138c79f49d3c34/lib/encoding.js
|
|
4
|
+
// This is free and unencumbered software released into the public domain.
|
|
5
|
+
// See LICENSE.md for more information.
|
|
1
6
|
import indexes from "./encoding-indexes.js";
|
|
7
|
+
// Note: Aaian character indices add half a megabyte to bundle. Ignore, since we really only want the built-in UTF8...
|
|
8
|
+
// import indexes from './encoding-indexes-asian.js';
|
|
2
9
|
globalThis['encoding-indexes'] = indexes || {};
|
|
10
|
+
//
|
|
11
|
+
// Utilities
|
|
12
|
+
//
|
|
13
|
+
/**
|
|
14
|
+
* @param {number} a The number to test.
|
|
15
|
+
* @param {number} min The minimum value in the range, inclusive.
|
|
16
|
+
* @param {number} max The maximum value in the range, inclusive.
|
|
17
|
+
* @return {boolean} True if a >= min and a <= max.
|
|
18
|
+
*/
|
|
3
19
|
function inRange(a, min, max) {
|
|
4
|
-
|
|
20
|
+
return min <= a && a <= max;
|
|
5
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* @param {!Array.<*>} array The array to check.
|
|
24
|
+
* @param {*} item The item to look for in the array.
|
|
25
|
+
* @return {boolean} True if the item appears in the array.
|
|
26
|
+
*/
|
|
6
27
|
function includes(array, item) {
|
|
7
|
-
|
|
28
|
+
return array.indexOf(item) !== -1;
|
|
8
29
|
}
|
|
9
30
|
var floor = Math.floor;
|
|
31
|
+
/**
|
|
32
|
+
* @param {*} o
|
|
33
|
+
* @return {Object}
|
|
34
|
+
*/
|
|
10
35
|
function ToDictionary(o) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
36
|
+
if (o === undefined)
|
|
37
|
+
return {};
|
|
38
|
+
if (o === Object(o))
|
|
39
|
+
return o;
|
|
40
|
+
throw TypeError('Could not convert argument to dictionary');
|
|
14
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* @param {string} string Input string of UTF-16 code units.
|
|
44
|
+
* @return {!Array.<number>} Code points.
|
|
45
|
+
*/
|
|
15
46
|
function stringToCodePoints(string) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
// https://heycam.github.io/webidl/#dfn-obtain-unicode
|
|
48
|
+
// 1. Let S be the DOMString value.
|
|
49
|
+
var s = String(string);
|
|
50
|
+
// 2. Let n be the length of S.
|
|
51
|
+
var n = s.length;
|
|
52
|
+
// 3. Initialize i to 0.
|
|
53
|
+
var i = 0;
|
|
54
|
+
// 4. Initialize U to be an empty sequence of Unicode characters.
|
|
55
|
+
var u = [];
|
|
56
|
+
// 5. While i < n:
|
|
57
|
+
while (i < n) {
|
|
58
|
+
// 1. Let c be the code unit in S at index i.
|
|
59
|
+
var c = s.charCodeAt(i);
|
|
60
|
+
// 2. Depending on the value of c:
|
|
61
|
+
// c < 0xD800 or c > 0xDFFF
|
|
62
|
+
if (c < 0xd800 || c > 0xdfff) {
|
|
63
|
+
// Append to U the Unicode character with code point c.
|
|
64
|
+
u.push(c);
|
|
65
|
+
}
|
|
66
|
+
// 0xDC00 ≤ c ≤ 0xDFFF
|
|
67
|
+
else if (0xdc00 <= c && c <= 0xdfff) {
|
|
68
|
+
// Append to U a U+FFFD REPLACEMENT CHARACTER.
|
|
69
|
+
u.push(0xfffd);
|
|
70
|
+
}
|
|
71
|
+
// 0xD800 ≤ c ≤ 0xDBFF
|
|
72
|
+
else if (0xd800 <= c && c <= 0xdbff) {
|
|
73
|
+
// 1. If i = n−1, then append to U a U+FFFD REPLACEMENT
|
|
74
|
+
// CHARACTER.
|
|
75
|
+
if (i === n - 1) {
|
|
76
|
+
u.push(0xfffd);
|
|
77
|
+
}
|
|
78
|
+
// 2. Otherwise, i < n−1:
|
|
79
|
+
else {
|
|
80
|
+
// 1. Let d be the code unit in S at index i+1.
|
|
81
|
+
var d = s.charCodeAt(i + 1);
|
|
82
|
+
// 2. If 0xDC00 ≤ d ≤ 0xDFFF, then:
|
|
83
|
+
if (0xdc00 <= d && d <= 0xdfff) {
|
|
84
|
+
// 1. Let a be c & 0x3FF.
|
|
85
|
+
var a = c & 0x3ff;
|
|
86
|
+
// 2. Let b be d & 0x3FF.
|
|
87
|
+
var b = d & 0x3ff;
|
|
88
|
+
// 3. Append to U the Unicode character with code point
|
|
89
|
+
// 2^16+2^10*a+b.
|
|
90
|
+
u.push(0x10000 + (a << 10) + b);
|
|
91
|
+
// 4. Set i to i+1.
|
|
92
|
+
i += 1;
|
|
93
|
+
}
|
|
94
|
+
// 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a
|
|
95
|
+
// U+FFFD REPLACEMENT CHARACTER.
|
|
96
|
+
else {
|
|
97
|
+
u.push(0xfffd);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// 3. Set i to i+1.
|
|
102
|
+
i += 1;
|
|
40
103
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return u;
|
|
104
|
+
// 6. Return U.
|
|
105
|
+
return u;
|
|
44
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* @param {!Array.<number>} code_points Array of code points.
|
|
109
|
+
* @return {string} string String of UTF-16 code units.
|
|
110
|
+
*/
|
|
45
111
|
function codePointsToString(code_points) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
112
|
+
var s = '';
|
|
113
|
+
for (var i = 0; i < code_points.length; ++i) {
|
|
114
|
+
var cp = code_points[i];
|
|
115
|
+
if (cp <= 0xffff) {
|
|
116
|
+
s += String.fromCharCode(cp);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
cp -= 0x10000;
|
|
120
|
+
s += String.fromCharCode((cp >> 10) + 0xd800, (cp & 0x3ff) + 0xdc00);
|
|
121
|
+
}
|
|
54
122
|
}
|
|
55
|
-
|
|
56
|
-
return s;
|
|
123
|
+
return s;
|
|
57
124
|
}
|
|
125
|
+
//
|
|
126
|
+
// Implementation of Encoding specification
|
|
127
|
+
// https://encoding.spec.whatwg.org/
|
|
128
|
+
//
|
|
129
|
+
//
|
|
130
|
+
// 4. Terminology
|
|
131
|
+
//
|
|
132
|
+
/**
|
|
133
|
+
* An ASCII byte is a byte in the range 0x00 to 0x7F, inclusive.
|
|
134
|
+
* @param {number} a The number to test.
|
|
135
|
+
* @return {boolean} True if a is in the range 0x00 to 0x7F, inclusive.
|
|
136
|
+
*/
|
|
58
137
|
function isASCIIByte(a) {
|
|
59
|
-
|
|
138
|
+
return 0x00 <= a && a <= 0x7f;
|
|
60
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* An ASCII code point is a code point in the range U+0000 to
|
|
142
|
+
* U+007F, inclusive.
|
|
143
|
+
*/
|
|
61
144
|
var isASCIICodePoint = isASCIIByte;
|
|
62
|
-
|
|
145
|
+
/**
|
|
146
|
+
* End-of-stream is a special token that signifies no more tokens
|
|
147
|
+
* are in the stream.
|
|
148
|
+
* @const
|
|
149
|
+
*/ var end_of_stream = -1;
|
|
150
|
+
/**
|
|
151
|
+
* A stream represents an ordered sequence of tokens.
|
|
152
|
+
*
|
|
153
|
+
* @constructor
|
|
154
|
+
* @param {!(Array.<number>|Uint8Array)} tokens Array of tokens that provide
|
|
155
|
+
* the stream.
|
|
156
|
+
*/
|
|
63
157
|
function Stream(tokens) {
|
|
64
|
-
|
|
65
|
-
|
|
158
|
+
/** @type {!Array.<number>} */
|
|
159
|
+
this.tokens = [].slice.call(tokens);
|
|
160
|
+
// Reversed as push/pop is more efficient than shift/unshift.
|
|
161
|
+
this.tokens.reverse();
|
|
66
162
|
}
|
|
67
163
|
Stream.prototype = {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
164
|
+
/**
|
|
165
|
+
* @return {boolean} True if end-of-stream has been hit.
|
|
166
|
+
*/
|
|
167
|
+
endOfStream: function () {
|
|
168
|
+
return !this.tokens.length;
|
|
169
|
+
},
|
|
170
|
+
/**
|
|
171
|
+
* When a token is read from a stream, the first token in the
|
|
172
|
+
* stream must be returned and subsequently removed, and
|
|
173
|
+
* end-of-stream must be returned otherwise.
|
|
174
|
+
*
|
|
175
|
+
* @return {number} Get the next token from the stream, or
|
|
176
|
+
* end_of_stream.
|
|
177
|
+
*/
|
|
178
|
+
read: function () {
|
|
179
|
+
if (!this.tokens.length)
|
|
180
|
+
return end_of_stream;
|
|
181
|
+
return this.tokens.pop();
|
|
182
|
+
},
|
|
183
|
+
/**
|
|
184
|
+
* When one or more tokens are prepended to a stream, those tokens
|
|
185
|
+
* must be inserted, in given order, before the first token in the
|
|
186
|
+
* stream.
|
|
187
|
+
*
|
|
188
|
+
* @param {(number|!Array.<number>)} token The token(s) to prepend to the
|
|
189
|
+
* stream.
|
|
190
|
+
*/
|
|
191
|
+
prepend: function (token) {
|
|
192
|
+
if (Array.isArray(token)) {
|
|
193
|
+
var tokens = /**@type {!Array.<number>}*/ token;
|
|
194
|
+
while (tokens.length)
|
|
195
|
+
this.tokens.push(tokens.pop());
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
this.tokens.push(token);
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
/**
|
|
202
|
+
* When one or more tokens are pushed to a stream, those tokens
|
|
203
|
+
* must be inserted, in given order, after the last token in the
|
|
204
|
+
* stream.
|
|
205
|
+
*
|
|
206
|
+
* @param {(number|!Array.<number>)} token The tokens(s) to push to the
|
|
207
|
+
* stream.
|
|
208
|
+
*/
|
|
209
|
+
push: function (token) {
|
|
210
|
+
if (Array.isArray(token)) {
|
|
211
|
+
var tokens = /**@type {!Array.<number>}*/ token;
|
|
212
|
+
while (tokens.length)
|
|
213
|
+
this.tokens.unshift(tokens.shift());
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
this.tokens.unshift(token);
|
|
217
|
+
}
|
|
89
218
|
}
|
|
90
|
-
}
|
|
91
219
|
};
|
|
220
|
+
//
|
|
221
|
+
// 5. Encodings
|
|
222
|
+
//
|
|
223
|
+
// 5.1 Encoders and decoders
|
|
224
|
+
/** @const */
|
|
92
225
|
var finished = -1;
|
|
226
|
+
/**
|
|
227
|
+
* @param {boolean} fatal If true, decoding errors raise an exception.
|
|
228
|
+
* @param {number=} opt_code_point Override the standard fallback code point.
|
|
229
|
+
* @return {number} The code point to insert on a decoding error.
|
|
230
|
+
*/
|
|
93
231
|
function decoderError(fatal, opt_code_point) {
|
|
94
|
-
|
|
95
|
-
|
|
232
|
+
if (fatal)
|
|
233
|
+
throw TypeError('Decoder error');
|
|
234
|
+
return opt_code_point || 0xfffd;
|
|
96
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* @param {number} code_point The code point that could not be encoded.
|
|
238
|
+
* @return {number} Always throws, no value is actually returned.
|
|
239
|
+
*/
|
|
97
240
|
function encoderError(code_point) {
|
|
98
|
-
|
|
241
|
+
throw TypeError('The code point ' + code_point + ' could not be encoded.');
|
|
99
242
|
}
|
|
100
|
-
|
|
243
|
+
/** @interface */
|
|
244
|
+
function Decoder() { }
|
|
101
245
|
Decoder.prototype = {
|
|
102
|
-
|
|
246
|
+
/**
|
|
247
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
248
|
+
* @param {number} bite The next byte read from the stream.
|
|
249
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
250
|
+
* decoded, or null if not enough data exists in the input
|
|
251
|
+
* stream to decode a complete code point, or |finished|.
|
|
252
|
+
*/
|
|
253
|
+
handler: function (stream, bite) { }
|
|
103
254
|
};
|
|
104
|
-
|
|
255
|
+
/** @interface */
|
|
256
|
+
function Encoder() { }
|
|
105
257
|
Encoder.prototype = {
|
|
106
|
-
|
|
258
|
+
/**
|
|
259
|
+
* @param {Stream} stream The stream of code points being encoded.
|
|
260
|
+
* @param {number} code_point Next code point read from the stream.
|
|
261
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit, or |finished|.
|
|
262
|
+
*/
|
|
263
|
+
handler: function (stream, code_point) { }
|
|
107
264
|
};
|
|
265
|
+
// 5.2 Names and labels
|
|
266
|
+
// TODO: Define @typedef for Encoding: {name:string,labels:Array.<string>}
|
|
267
|
+
// https://github.com/google/closure-compiler/issues/247
|
|
268
|
+
/**
|
|
269
|
+
* @param {string} label The encoding label.
|
|
270
|
+
* @return {?{name:string,labels:Array.<string>}}
|
|
271
|
+
*/
|
|
108
272
|
function getEncoding(label) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
273
|
+
// 1. Remove any leading and trailing ASCII whitespace from label.
|
|
274
|
+
label = String(label).trim().toLowerCase();
|
|
275
|
+
// 2. If label is an ASCII case-insensitive match for any of the
|
|
276
|
+
// labels listed in the table below, return the corresponding
|
|
277
|
+
// encoding, and failure otherwise.
|
|
278
|
+
if (Object.prototype.hasOwnProperty.call(label_to_encoding, label)) {
|
|
279
|
+
return label_to_encoding[label];
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
114
282
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
283
|
+
/**
|
|
284
|
+
* Encodings table: https://encoding.spec.whatwg.org/encodings.json
|
|
285
|
+
* @const
|
|
286
|
+
* @type {!Array.<{
|
|
287
|
+
* heading: string,
|
|
288
|
+
* encodings: Array.<{name:string,labels:Array.<string>}>
|
|
289
|
+
* }>}
|
|
290
|
+
*/
|
|
291
|
+
var encodings = [
|
|
292
|
+
{
|
|
293
|
+
encodings: [
|
|
294
|
+
{
|
|
295
|
+
labels: ['unicode-1-1-utf-8', 'utf-8', 'utf8'],
|
|
296
|
+
name: 'UTF-8'
|
|
297
|
+
}
|
|
298
|
+
],
|
|
299
|
+
heading: 'The Encoding'
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
encodings: [
|
|
303
|
+
{
|
|
304
|
+
labels: ['866', 'cp866', 'csibm866', 'ibm866'],
|
|
305
|
+
name: 'IBM866'
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
labels: [
|
|
309
|
+
'csisolatin2',
|
|
310
|
+
'iso-8859-2',
|
|
311
|
+
'iso-ir-101',
|
|
312
|
+
'iso8859-2',
|
|
313
|
+
'iso88592',
|
|
314
|
+
'iso_8859-2',
|
|
315
|
+
'iso_8859-2:1987',
|
|
316
|
+
'l2',
|
|
317
|
+
'latin2'
|
|
318
|
+
],
|
|
319
|
+
name: 'ISO-8859-2'
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
labels: [
|
|
323
|
+
'csisolatin3',
|
|
324
|
+
'iso-8859-3',
|
|
325
|
+
'iso-ir-109',
|
|
326
|
+
'iso8859-3',
|
|
327
|
+
'iso88593',
|
|
328
|
+
'iso_8859-3',
|
|
329
|
+
'iso_8859-3:1988',
|
|
330
|
+
'l3',
|
|
331
|
+
'latin3'
|
|
332
|
+
],
|
|
333
|
+
name: 'ISO-8859-3'
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
labels: [
|
|
337
|
+
'csisolatin4',
|
|
338
|
+
'iso-8859-4',
|
|
339
|
+
'iso-ir-110',
|
|
340
|
+
'iso8859-4',
|
|
341
|
+
'iso88594',
|
|
342
|
+
'iso_8859-4',
|
|
343
|
+
'iso_8859-4:1988',
|
|
344
|
+
'l4',
|
|
345
|
+
'latin4'
|
|
346
|
+
],
|
|
347
|
+
name: 'ISO-8859-4'
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
labels: [
|
|
351
|
+
'csisolatincyrillic',
|
|
352
|
+
'cyrillic',
|
|
353
|
+
'iso-8859-5',
|
|
354
|
+
'iso-ir-144',
|
|
355
|
+
'iso8859-5',
|
|
356
|
+
'iso88595',
|
|
357
|
+
'iso_8859-5',
|
|
358
|
+
'iso_8859-5:1988'
|
|
359
|
+
],
|
|
360
|
+
name: 'ISO-8859-5'
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
labels: [
|
|
364
|
+
'arabic',
|
|
365
|
+
'asmo-708',
|
|
366
|
+
'csiso88596e',
|
|
367
|
+
'csiso88596i',
|
|
368
|
+
'csisolatinarabic',
|
|
369
|
+
'ecma-114',
|
|
370
|
+
'iso-8859-6',
|
|
371
|
+
'iso-8859-6-e',
|
|
372
|
+
'iso-8859-6-i',
|
|
373
|
+
'iso-ir-127',
|
|
374
|
+
'iso8859-6',
|
|
375
|
+
'iso88596',
|
|
376
|
+
'iso_8859-6',
|
|
377
|
+
'iso_8859-6:1987'
|
|
378
|
+
],
|
|
379
|
+
name: 'ISO-8859-6'
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
labels: [
|
|
383
|
+
'csisolatingreek',
|
|
384
|
+
'ecma-118',
|
|
385
|
+
'elot_928',
|
|
386
|
+
'greek',
|
|
387
|
+
'greek8',
|
|
388
|
+
'iso-8859-7',
|
|
389
|
+
'iso-ir-126',
|
|
390
|
+
'iso8859-7',
|
|
391
|
+
'iso88597',
|
|
392
|
+
'iso_8859-7',
|
|
393
|
+
'iso_8859-7:1987',
|
|
394
|
+
'sun_eu_greek'
|
|
395
|
+
],
|
|
396
|
+
name: 'ISO-8859-7'
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
labels: [
|
|
400
|
+
'csiso88598e',
|
|
401
|
+
'csisolatinhebrew',
|
|
402
|
+
'hebrew',
|
|
403
|
+
'iso-8859-8',
|
|
404
|
+
'iso-8859-8-e',
|
|
405
|
+
'iso-ir-138',
|
|
406
|
+
'iso8859-8',
|
|
407
|
+
'iso88598',
|
|
408
|
+
'iso_8859-8',
|
|
409
|
+
'iso_8859-8:1988',
|
|
410
|
+
'visual'
|
|
411
|
+
],
|
|
412
|
+
name: 'ISO-8859-8'
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
labels: ['csiso88598i', 'iso-8859-8-i', 'logical'],
|
|
416
|
+
name: 'ISO-8859-8-I'
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
labels: [
|
|
420
|
+
'csisolatin6',
|
|
421
|
+
'iso-8859-10',
|
|
422
|
+
'iso-ir-157',
|
|
423
|
+
'iso8859-10',
|
|
424
|
+
'iso885910',
|
|
425
|
+
'l6',
|
|
426
|
+
'latin6'
|
|
427
|
+
],
|
|
428
|
+
name: 'ISO-8859-10'
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
labels: ['iso-8859-13', 'iso8859-13', 'iso885913'],
|
|
432
|
+
name: 'ISO-8859-13'
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
labels: ['iso-8859-14', 'iso8859-14', 'iso885914'],
|
|
436
|
+
name: 'ISO-8859-14'
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
labels: ['csisolatin9', 'iso-8859-15', 'iso8859-15', 'iso885915', 'iso_8859-15', 'l9'],
|
|
440
|
+
name: 'ISO-8859-15'
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
labels: ['iso-8859-16'],
|
|
444
|
+
name: 'ISO-8859-16'
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
labels: ['cskoi8r', 'koi', 'koi8', 'koi8-r', 'koi8_r'],
|
|
448
|
+
name: 'KOI8-R'
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
labels: ['koi8-ru', 'koi8-u'],
|
|
452
|
+
name: 'KOI8-U'
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
labels: ['csmacintosh', 'mac', 'macintosh', 'x-mac-roman'],
|
|
456
|
+
name: 'macintosh'
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
labels: ['dos-874', 'iso-8859-11', 'iso8859-11', 'iso885911', 'tis-620', 'windows-874'],
|
|
460
|
+
name: 'windows-874'
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
labels: ['cp1250', 'windows-1250', 'x-cp1250'],
|
|
464
|
+
name: 'windows-1250'
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
labels: ['cp1251', 'windows-1251', 'x-cp1251'],
|
|
468
|
+
name: 'windows-1251'
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
labels: [
|
|
472
|
+
'ansi_x3.4-1968',
|
|
473
|
+
'ascii',
|
|
474
|
+
'cp1252',
|
|
475
|
+
'cp819',
|
|
476
|
+
'csisolatin1',
|
|
477
|
+
'ibm819',
|
|
478
|
+
'iso-8859-1',
|
|
479
|
+
'iso-ir-100',
|
|
480
|
+
'iso8859-1',
|
|
481
|
+
'iso88591',
|
|
482
|
+
'iso_8859-1',
|
|
483
|
+
'iso_8859-1:1987',
|
|
484
|
+
'l1',
|
|
485
|
+
'latin1',
|
|
486
|
+
'us-ascii',
|
|
487
|
+
'windows-1252',
|
|
488
|
+
'x-cp1252'
|
|
489
|
+
],
|
|
490
|
+
name: 'windows-1252'
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
labels: ['cp1253', 'windows-1253', 'x-cp1253'],
|
|
494
|
+
name: 'windows-1253'
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
labels: [
|
|
498
|
+
'cp1254',
|
|
499
|
+
'csisolatin5',
|
|
500
|
+
'iso-8859-9',
|
|
501
|
+
'iso-ir-148',
|
|
502
|
+
'iso8859-9',
|
|
503
|
+
'iso88599',
|
|
504
|
+
'iso_8859-9',
|
|
505
|
+
'iso_8859-9:1989',
|
|
506
|
+
'l5',
|
|
507
|
+
'latin5',
|
|
508
|
+
'windows-1254',
|
|
509
|
+
'x-cp1254'
|
|
510
|
+
],
|
|
511
|
+
name: 'windows-1254'
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
labels: ['cp1255', 'windows-1255', 'x-cp1255'],
|
|
515
|
+
name: 'windows-1255'
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
labels: ['cp1256', 'windows-1256', 'x-cp1256'],
|
|
519
|
+
name: 'windows-1256'
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
labels: ['cp1257', 'windows-1257', 'x-cp1257'],
|
|
523
|
+
name: 'windows-1257'
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
labels: ['cp1258', 'windows-1258', 'x-cp1258'],
|
|
527
|
+
name: 'windows-1258'
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
labels: ['x-mac-cyrillic', 'x-mac-ukrainian'],
|
|
531
|
+
name: 'x-mac-cyrillic'
|
|
532
|
+
}
|
|
533
|
+
],
|
|
534
|
+
heading: 'Legacy single-byte encodings'
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
encodings: [
|
|
538
|
+
{
|
|
539
|
+
labels: [
|
|
540
|
+
'chinese',
|
|
541
|
+
'csgb2312',
|
|
542
|
+
'csiso58gb231280',
|
|
543
|
+
'gb2312',
|
|
544
|
+
'gb_2312',
|
|
545
|
+
'gb_2312-80',
|
|
546
|
+
'gbk',
|
|
547
|
+
'iso-ir-58',
|
|
548
|
+
'x-gbk'
|
|
549
|
+
],
|
|
550
|
+
name: 'GBK'
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
labels: ['gb18030'],
|
|
554
|
+
name: 'gb18030'
|
|
555
|
+
}
|
|
556
|
+
],
|
|
557
|
+
heading: 'Legacy multi-byte Chinese (simplified) encodings'
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
encodings: [
|
|
561
|
+
{
|
|
562
|
+
labels: ['big5', 'big5-hkscs', 'cn-big5', 'csbig5', 'x-x-big5'],
|
|
563
|
+
name: 'Big5'
|
|
564
|
+
}
|
|
565
|
+
],
|
|
566
|
+
heading: 'Legacy multi-byte Chinese (traditional) encodings'
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
encodings: [
|
|
570
|
+
{
|
|
571
|
+
labels: ['cseucpkdfmtjapanese', 'euc-jp', 'x-euc-jp'],
|
|
572
|
+
name: 'EUC-JP'
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
labels: ['csiso2022jp', 'iso-2022-jp'],
|
|
576
|
+
name: 'ISO-2022-JP'
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
labels: [
|
|
580
|
+
'csshiftjis',
|
|
581
|
+
'ms932',
|
|
582
|
+
'ms_kanji',
|
|
583
|
+
'shift-jis',
|
|
584
|
+
'shift_jis',
|
|
585
|
+
'sjis',
|
|
586
|
+
'windows-31j',
|
|
587
|
+
'x-sjis'
|
|
588
|
+
],
|
|
589
|
+
name: 'Shift_JIS'
|
|
590
|
+
}
|
|
591
|
+
],
|
|
592
|
+
heading: 'Legacy multi-byte Japanese encodings'
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
encodings: [
|
|
596
|
+
{
|
|
597
|
+
labels: [
|
|
598
|
+
'cseuckr',
|
|
599
|
+
'csksc56011987',
|
|
600
|
+
'euc-kr',
|
|
601
|
+
'iso-ir-149',
|
|
602
|
+
'korean',
|
|
603
|
+
'ks_c_5601-1987',
|
|
604
|
+
'ks_c_5601-1989',
|
|
605
|
+
'ksc5601',
|
|
606
|
+
'ksc_5601',
|
|
607
|
+
'windows-949'
|
|
608
|
+
],
|
|
609
|
+
name: 'EUC-KR'
|
|
610
|
+
}
|
|
611
|
+
],
|
|
612
|
+
heading: 'Legacy multi-byte Korean encodings'
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
encodings: [
|
|
616
|
+
{
|
|
617
|
+
labels: ['csiso2022kr', 'hz-gb-2312', 'iso-2022-cn', 'iso-2022-cn-ext', 'iso-2022-kr'],
|
|
618
|
+
name: 'replacement'
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
labels: ['utf-16be'],
|
|
622
|
+
name: 'UTF-16BE'
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
labels: ['utf-16', 'utf-16le'],
|
|
626
|
+
name: 'UTF-16LE'
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
labels: ['x-user-defined'],
|
|
630
|
+
name: 'x-user-defined'
|
|
631
|
+
}
|
|
632
|
+
],
|
|
633
|
+
heading: 'Legacy miscellaneous encodings'
|
|
634
|
+
}
|
|
635
|
+
];
|
|
636
|
+
// Label to encoding registry.
|
|
637
|
+
/** @type {Object.<string,{name:string,labels:Array.<string>}>} */
|
|
257
638
|
var label_to_encoding = {};
|
|
258
639
|
encodings.forEach(function (category) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
640
|
+
category.encodings.forEach(function (encoding) {
|
|
641
|
+
encoding.labels.forEach(function (label) {
|
|
642
|
+
label_to_encoding[label] = encoding;
|
|
643
|
+
});
|
|
262
644
|
});
|
|
263
|
-
});
|
|
264
645
|
});
|
|
646
|
+
// Registry of of encoder/decoder factories, by encoding name.
|
|
647
|
+
/** @type {Object.<string, function({fatal:boolean}): Encoder>} */
|
|
265
648
|
var encoders = {};
|
|
649
|
+
/** @type {Object.<string, function({fatal:boolean}): Decoder>} */
|
|
266
650
|
var decoders = {};
|
|
651
|
+
//
|
|
652
|
+
// 6. Indexes
|
|
653
|
+
//
|
|
654
|
+
/**
|
|
655
|
+
* @param {number} pointer The |pointer| to search for.
|
|
656
|
+
* @param {(!Array.<?number>|undefined)} index The |index| to search within.
|
|
657
|
+
* @return {?number} The code point corresponding to |pointer| in |index|,
|
|
658
|
+
* or null if |code point| is not in |index|.
|
|
659
|
+
*/
|
|
267
660
|
function indexCodePointFor(pointer, index) {
|
|
268
|
-
|
|
269
|
-
|
|
661
|
+
if (!index)
|
|
662
|
+
return null;
|
|
663
|
+
return index[pointer] || null;
|
|
270
664
|
}
|
|
665
|
+
/**
|
|
666
|
+
* @param {number} code_point The |code point| to search for.
|
|
667
|
+
* @param {!Array.<?number>} index The |index| to search within.
|
|
668
|
+
* @return {?number} The first pointer corresponding to |code point| in
|
|
669
|
+
* |index|, or null if |code point| is not in |index|.
|
|
670
|
+
*/
|
|
271
671
|
function indexPointerFor(code_point, index) {
|
|
272
|
-
|
|
273
|
-
|
|
672
|
+
var pointer = index.indexOf(code_point);
|
|
673
|
+
return pointer === -1 ? null : pointer;
|
|
274
674
|
}
|
|
675
|
+
/**
|
|
676
|
+
* @param {string} name Name of the index.
|
|
677
|
+
* @return {(!Array.<number>|!Array.<Array.<number>>)}
|
|
678
|
+
* */
|
|
275
679
|
function index(name) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
680
|
+
if (!('encoding-indexes' in globalThis)) {
|
|
681
|
+
throw Error('Indexes missing.' + ' Did you forget to include encoding-indexes.js first?');
|
|
682
|
+
}
|
|
683
|
+
return globalThis['encoding-indexes'][name];
|
|
280
684
|
}
|
|
685
|
+
/**
|
|
686
|
+
* @param {number} pointer The |pointer| to search for in the gb18030 index.
|
|
687
|
+
* @return {?number} The code point corresponding to |pointer| in |index|,
|
|
688
|
+
* or null if |code point| is not in the gb18030 index.
|
|
689
|
+
*/
|
|
281
690
|
function indexGB18030RangesCodePointFor(pointer) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
691
|
+
// 1. If pointer is greater than 39419 and less than 189000, or
|
|
692
|
+
// pointer is greater than 1237575, return null.
|
|
693
|
+
if ((pointer > 39419 && pointer < 189000) || pointer > 1237575)
|
|
694
|
+
return null;
|
|
695
|
+
// 2. If pointer is 7457, return code point U+E7C7.
|
|
696
|
+
if (pointer === 7457)
|
|
697
|
+
return 0xe7c7;
|
|
698
|
+
// 3. Let offset be the last pointer in index gb18030 ranges that
|
|
699
|
+
// is equal to or less than pointer and let code point offset be
|
|
700
|
+
// its corresponding code point.
|
|
701
|
+
var offset = 0;
|
|
702
|
+
var code_point_offset = 0;
|
|
703
|
+
var idx = index('gb18030-ranges');
|
|
704
|
+
var i;
|
|
705
|
+
for (i = 0; i < idx.length; ++i) {
|
|
706
|
+
/** @type {!Array.<number>} */
|
|
707
|
+
var entry = idx[i];
|
|
708
|
+
if (entry[0] <= pointer) {
|
|
709
|
+
offset = entry[0];
|
|
710
|
+
code_point_offset = entry[1];
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
break;
|
|
714
|
+
}
|
|
295
715
|
}
|
|
296
|
-
|
|
297
|
-
|
|
716
|
+
// 4. Return a code point whose value is code point offset +
|
|
717
|
+
// pointer − offset.
|
|
718
|
+
return code_point_offset + pointer - offset;
|
|
298
719
|
}
|
|
720
|
+
/**
|
|
721
|
+
* @param {number} code_point The |code point| to locate in the gb18030 index.
|
|
722
|
+
* @return {number} The first pointer corresponding to |code point| in the
|
|
723
|
+
* gb18030 index.
|
|
724
|
+
*/
|
|
299
725
|
function indexGB18030RangesPointerFor(code_point) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
var
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
726
|
+
// 1. If code point is U+E7C7, return pointer 7457.
|
|
727
|
+
if (code_point === 0xe7c7)
|
|
728
|
+
return 7457;
|
|
729
|
+
// 2. Let offset be the last code point in index gb18030 ranges
|
|
730
|
+
// that is equal to or less than code point and let pointer offset
|
|
731
|
+
// be its corresponding pointer.
|
|
732
|
+
var offset = 0;
|
|
733
|
+
var pointer_offset = 0;
|
|
734
|
+
var idx = index('gb18030-ranges');
|
|
735
|
+
var i;
|
|
736
|
+
for (i = 0; i < idx.length; ++i) {
|
|
737
|
+
/** @type {!Array.<number>} */
|
|
738
|
+
var entry = idx[i];
|
|
739
|
+
if (entry[1] <= code_point) {
|
|
740
|
+
offset = entry[1];
|
|
741
|
+
pointer_offset = entry[0];
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
312
746
|
}
|
|
313
|
-
|
|
314
|
-
|
|
747
|
+
// 3. Return a pointer whose value is pointer offset + code point
|
|
748
|
+
// − offset.
|
|
749
|
+
return pointer_offset + code_point - offset;
|
|
315
750
|
}
|
|
751
|
+
/**
|
|
752
|
+
* @param {number} code_point The |code_point| to search for in the Shift_JIS
|
|
753
|
+
* index.
|
|
754
|
+
* @return {?number} The code point corresponding to |pointer| in |index|,
|
|
755
|
+
* or null if |code point| is not in the Shift_JIS index.
|
|
756
|
+
*/
|
|
316
757
|
function indexShiftJISPointerFor(code_point) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
758
|
+
// 1. Let index be index jis0208 excluding all entries whose
|
|
759
|
+
// pointer is in the range 8272 to 8835, inclusive.
|
|
760
|
+
shift_jis_index =
|
|
761
|
+
shift_jis_index ||
|
|
762
|
+
index('jis0208').map(function (code_point, pointer) {
|
|
763
|
+
return inRange(pointer, 8272, 8835) ? null : code_point;
|
|
764
|
+
});
|
|
765
|
+
var index_ = shift_jis_index;
|
|
766
|
+
// 2. Return the index pointer for code point in index.
|
|
767
|
+
return index_.indexOf(code_point);
|
|
322
768
|
}
|
|
323
769
|
var shift_jis_index;
|
|
770
|
+
/**
|
|
771
|
+
* @param {number} code_point The |code_point| to search for in the big5
|
|
772
|
+
* index.
|
|
773
|
+
* @return {?number} The code point corresponding to |pointer| in |index|,
|
|
774
|
+
* or null if |code point| is not in the big5 index.
|
|
775
|
+
*/
|
|
324
776
|
function indexBig5PointerFor(code_point) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
777
|
+
// 1. Let index be index Big5 excluding all entries whose pointer
|
|
778
|
+
big5_index_no_hkscs =
|
|
779
|
+
big5_index_no_hkscs ||
|
|
780
|
+
index('big5').map(function (code_point, pointer) {
|
|
781
|
+
return pointer < (0xa1 - 0x81) * 157 ? null : code_point;
|
|
782
|
+
});
|
|
783
|
+
var index_ = big5_index_no_hkscs;
|
|
784
|
+
// 2. If code point is U+2550, U+255E, U+2561, U+256A, U+5341, or
|
|
785
|
+
// U+5345, return the last pointer corresponding to code point in
|
|
786
|
+
// index.
|
|
787
|
+
if (code_point === 0x2550 ||
|
|
788
|
+
code_point === 0x255e ||
|
|
789
|
+
code_point === 0x2561 ||
|
|
790
|
+
code_point === 0x256a ||
|
|
791
|
+
code_point === 0x5341 ||
|
|
792
|
+
code_point === 0x5345) {
|
|
793
|
+
return index_.lastIndexOf(code_point);
|
|
794
|
+
}
|
|
795
|
+
// 3. Return the index pointer for code point in index.
|
|
796
|
+
return indexPointerFor(code_point, index_);
|
|
333
797
|
}
|
|
334
798
|
var big5_index_no_hkscs;
|
|
335
|
-
|
|
799
|
+
//
|
|
800
|
+
// 8. API
|
|
801
|
+
//
|
|
802
|
+
/** @const */ var DEFAULT_ENCODING = 'utf-8';
|
|
803
|
+
// 8.1 Interface TextDecoder
|
|
804
|
+
/**
|
|
805
|
+
* @constructor
|
|
806
|
+
* @param {string=} label The label of the encoding;
|
|
807
|
+
* defaults to 'utf-8'.
|
|
808
|
+
* @param {Object=} options
|
|
809
|
+
*/
|
|
336
810
|
function TextDecoder(label, options) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
this.
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
811
|
+
// Web IDL conventions
|
|
812
|
+
if (!(this instanceof TextDecoder))
|
|
813
|
+
throw TypeError("Called as a function. Did you forget 'new'?");
|
|
814
|
+
label = label !== undefined ? String(label) : DEFAULT_ENCODING;
|
|
815
|
+
options = ToDictionary(options);
|
|
816
|
+
// A TextDecoder object has an associated encoding, decoder,
|
|
817
|
+
// stream, ignore BOM flag (initially unset), BOM seen flag
|
|
818
|
+
// (initially unset), error mode (initially replacement), and do
|
|
819
|
+
// not flush flag (initially unset).
|
|
820
|
+
/** @private */
|
|
821
|
+
this._encoding = null;
|
|
822
|
+
/** @private @type {?Decoder} */
|
|
823
|
+
this._decoder = null;
|
|
824
|
+
/** @private @type {boolean} */
|
|
825
|
+
this._ignoreBOM = false;
|
|
826
|
+
/** @private @type {boolean} */
|
|
827
|
+
this._BOMseen = false;
|
|
828
|
+
/** @private @type {string} */
|
|
829
|
+
this._error_mode = 'replacement';
|
|
830
|
+
/** @private @type {boolean} */
|
|
831
|
+
this._do_not_flush = false;
|
|
832
|
+
// 1. Let encoding be the result of getting an encoding from
|
|
833
|
+
// label.
|
|
834
|
+
var encoding = getEncoding(label);
|
|
835
|
+
// 2. If encoding is failure or replacement, throw a RangeError.
|
|
836
|
+
if (encoding === null || encoding.name === 'replacement')
|
|
837
|
+
throw RangeError('Unknown encoding: ' + label);
|
|
838
|
+
if (!decoders[encoding.name]) {
|
|
839
|
+
throw Error('Decoder not present.' + ' Did you forget to include encoding-indexes.js first?');
|
|
840
|
+
}
|
|
841
|
+
// 3. Let dec be a new TextDecoder object.
|
|
842
|
+
var dec = this;
|
|
843
|
+
// 4. Set dec's encoding to encoding.
|
|
844
|
+
dec._encoding = encoding;
|
|
845
|
+
// 5. If options's fatal member is true, set dec's error mode to
|
|
846
|
+
// fatal.
|
|
847
|
+
if (Boolean(options['fatal']))
|
|
848
|
+
dec._error_mode = 'fatal';
|
|
849
|
+
// 6. If options's ignoreBOM member is true, set dec's ignore BOM
|
|
850
|
+
// flag.
|
|
851
|
+
if (Boolean(options['ignoreBOM']))
|
|
852
|
+
dec._ignoreBOM = true;
|
|
853
|
+
// For pre-ES5 runtimes:
|
|
854
|
+
if (!Object.defineProperty) {
|
|
855
|
+
this.encoding = dec._encoding.name.toLowerCase();
|
|
856
|
+
this.fatal = dec._error_mode === 'fatal';
|
|
857
|
+
this.ignoreBOM = dec._ignoreBOM;
|
|
858
|
+
}
|
|
859
|
+
// 7. Return dec.
|
|
860
|
+
return dec;
|
|
361
861
|
}
|
|
362
862
|
if (Object.defineProperty) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
863
|
+
// The encoding attribute's getter must return encoding's name.
|
|
864
|
+
Object.defineProperty(TextDecoder.prototype, 'encoding', {
|
|
865
|
+
/** @this {TextDecoder} */
|
|
866
|
+
get: function () {
|
|
867
|
+
return this._encoding.name.toLowerCase();
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
// The fatal attribute's getter must return true if error mode
|
|
871
|
+
// is fatal, and false otherwise.
|
|
872
|
+
Object.defineProperty(TextDecoder.prototype, 'fatal', {
|
|
873
|
+
/** @this {TextDecoder} */
|
|
874
|
+
get: function () {
|
|
875
|
+
return this._error_mode === 'fatal';
|
|
876
|
+
}
|
|
877
|
+
});
|
|
878
|
+
// The ignoreBOM attribute's getter must return true if ignore
|
|
879
|
+
// BOM flag is set, and false otherwise.
|
|
880
|
+
Object.defineProperty(TextDecoder.prototype, 'ignoreBOM', {
|
|
881
|
+
/** @this {TextDecoder} */
|
|
882
|
+
get: function () {
|
|
883
|
+
return this._ignoreBOM;
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* @param {BufferSource=} input The buffer of bytes to decode.
|
|
889
|
+
* @param {Object=} options
|
|
890
|
+
* @return {string} The decoded string.
|
|
891
|
+
*/
|
|
892
|
+
TextDecoder.prototype.decode = function decode(input, options) {
|
|
893
|
+
var bytes;
|
|
894
|
+
if (typeof input === 'object' && input instanceof ArrayBuffer) {
|
|
895
|
+
bytes = new Uint8Array(input);
|
|
366
896
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
897
|
+
else if (typeof input === 'object' &&
|
|
898
|
+
'buffer' in input &&
|
|
899
|
+
input.buffer instanceof ArrayBuffer) {
|
|
900
|
+
bytes = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
|
|
371
901
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
get: function () {
|
|
375
|
-
return this._ignoreBOM;
|
|
902
|
+
else {
|
|
903
|
+
bytes = new Uint8Array(0);
|
|
376
904
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
bytes = new Uint8Array(0);
|
|
387
|
-
}
|
|
388
|
-
options = ToDictionary(options);
|
|
389
|
-
if (!this._do_not_flush) {
|
|
390
|
-
this._decoder = decoders[this._encoding.name]({
|
|
391
|
-
fatal: this._error_mode === 'fatal'
|
|
392
|
-
});
|
|
393
|
-
this._BOMseen = false;
|
|
394
|
-
}
|
|
395
|
-
this._do_not_flush = Boolean(options['stream']);
|
|
396
|
-
var input_stream = new Stream(bytes);
|
|
397
|
-
var output = [];
|
|
398
|
-
var result;
|
|
399
|
-
while (true) {
|
|
400
|
-
var token = input_stream.read();
|
|
401
|
-
if (token === end_of_stream) break;
|
|
402
|
-
result = this._decoder.handler(input_stream, token);
|
|
403
|
-
if (result === finished) break;
|
|
404
|
-
if (result !== null) {
|
|
405
|
-
if (Array.isArray(result)) output.push.apply(output, result);else output.push(result);
|
|
905
|
+
options = ToDictionary(options);
|
|
906
|
+
// 1. If the do not flush flag is unset, set decoder to a new
|
|
907
|
+
// encoding's decoder, set stream to a new stream, and unset the
|
|
908
|
+
// BOM seen flag.
|
|
909
|
+
if (!this._do_not_flush) {
|
|
910
|
+
this._decoder = decoders[this._encoding.name]({
|
|
911
|
+
fatal: this._error_mode === 'fatal'
|
|
912
|
+
});
|
|
913
|
+
this._BOMseen = false;
|
|
406
914
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
stream
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
915
|
+
// 2. If options's stream is true, set the do not flush flag, and
|
|
916
|
+
// unset the do not flush flag otherwise.
|
|
917
|
+
this._do_not_flush = Boolean(options['stream']);
|
|
918
|
+
// 3. If input is given, push a copy of input to stream.
|
|
919
|
+
// TODO: Align with spec algorithm - maintain stream on instance.
|
|
920
|
+
var input_stream = new Stream(bytes);
|
|
921
|
+
// 4. Let output be a new stream.
|
|
922
|
+
var output = [];
|
|
923
|
+
/** @type {?(number|!Array.<number>)} */
|
|
924
|
+
var result;
|
|
925
|
+
// 5. While true:
|
|
926
|
+
while (true) {
|
|
927
|
+
// 1. Let token be the result of reading from stream.
|
|
928
|
+
var token = input_stream.read();
|
|
929
|
+
// 2. If token is end-of-stream and the do not flush flag is
|
|
930
|
+
// set, return output, serialized.
|
|
931
|
+
// TODO: Align with spec algorithm.
|
|
932
|
+
if (token === end_of_stream)
|
|
933
|
+
break;
|
|
934
|
+
// 3. Otherwise, run these subsubsteps:
|
|
935
|
+
// 1. Let result be the result of processing token for decoder,
|
|
936
|
+
// stream, output, and error mode.
|
|
937
|
+
result = this._decoder.handler(input_stream, token);
|
|
938
|
+
// 2. If result is finished, return output, serialized.
|
|
939
|
+
if (result === finished)
|
|
940
|
+
break;
|
|
941
|
+
if (result !== null) {
|
|
942
|
+
if (Array.isArray(result))
|
|
943
|
+
output.push.apply(output, /**@type {!Array.<number>}*/ result);
|
|
944
|
+
else
|
|
945
|
+
output.push(result);
|
|
946
|
+
}
|
|
947
|
+
// 3. Otherwise, if result is error, throw a TypeError.
|
|
948
|
+
// (Thrown in handler)
|
|
949
|
+
// 4. Otherwise, do nothing.
|
|
950
|
+
}
|
|
951
|
+
// TODO: Align with spec algorithm.
|
|
952
|
+
if (!this._do_not_flush) {
|
|
953
|
+
do {
|
|
954
|
+
result = this._decoder.handler(input_stream, input_stream.read());
|
|
955
|
+
if (result === finished)
|
|
956
|
+
break;
|
|
957
|
+
if (result === null)
|
|
958
|
+
continue;
|
|
959
|
+
if (Array.isArray(result))
|
|
960
|
+
output.push.apply(output, /**@type {!Array.<number>}*/ result);
|
|
961
|
+
else
|
|
962
|
+
output.push(result);
|
|
963
|
+
} while (!input_stream.endOfStream());
|
|
964
|
+
this._decoder = null;
|
|
965
|
+
}
|
|
966
|
+
// A TextDecoder object also has an associated serialize stream
|
|
967
|
+
// algorithm...
|
|
968
|
+
/**
|
|
969
|
+
* @param {!Array.<number>} stream
|
|
970
|
+
* @return {string}
|
|
971
|
+
* @this {TextDecoder}
|
|
972
|
+
*/
|
|
973
|
+
function serializeStream(stream) {
|
|
974
|
+
// 1. Let token be the result of reading from stream.
|
|
975
|
+
// (Done in-place on array, rather than as a stream)
|
|
976
|
+
// 2. If encoding is UTF-8, UTF-16BE, or UTF-16LE, and ignore
|
|
977
|
+
// BOM flag and BOM seen flag are unset, run these subsubsteps:
|
|
978
|
+
if (includes(['UTF-8', 'UTF-16LE', 'UTF-16BE'], this._encoding.name) &&
|
|
979
|
+
!this._ignoreBOM &&
|
|
980
|
+
!this._BOMseen) {
|
|
981
|
+
if (stream.length > 0 && stream[0] === 0xfeff) {
|
|
982
|
+
// 1. If token is U+FEFF, set BOM seen flag.
|
|
983
|
+
this._BOMseen = true;
|
|
984
|
+
stream.shift();
|
|
985
|
+
}
|
|
986
|
+
else if (stream.length > 0) {
|
|
987
|
+
// 2. Otherwise, if token is not end-of-stream, set BOM seen
|
|
988
|
+
// flag and append token to stream.
|
|
989
|
+
this._BOMseen = true;
|
|
990
|
+
}
|
|
991
|
+
else {
|
|
992
|
+
// 3. Otherwise, if token is not end-of-stream, append token
|
|
993
|
+
// to output.
|
|
994
|
+
// (no-op)
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
// 4. Otherwise, return output.
|
|
998
|
+
return codePointsToString(stream);
|
|
425
999
|
}
|
|
426
|
-
return
|
|
427
|
-
}
|
|
428
|
-
return serializeStream.call(this, output);
|
|
1000
|
+
return serializeStream.call(this, output);
|
|
429
1001
|
};
|
|
1002
|
+
// 8.2 Interface TextEncoder
|
|
1003
|
+
/**
|
|
1004
|
+
* @constructor
|
|
1005
|
+
* @param {string=} label The label of the encoding. NONSTANDARD.
|
|
1006
|
+
* @param {Object=} options NONSTANDARD.
|
|
1007
|
+
*/
|
|
430
1008
|
function TextEncoder(label, options) {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
1009
|
+
// Web IDL conventions
|
|
1010
|
+
if (!(this instanceof TextEncoder))
|
|
1011
|
+
throw TypeError("Called as a function. Did you forget 'new'?");
|
|
1012
|
+
options = ToDictionary(options);
|
|
1013
|
+
// A TextEncoder object has an associated encoding and encoder.
|
|
1014
|
+
/** @private */
|
|
1015
|
+
this._encoding = null;
|
|
1016
|
+
/** @private @type {?Encoder} */
|
|
1017
|
+
this._encoder = null;
|
|
1018
|
+
// Non-standard
|
|
1019
|
+
/** @private @type {boolean} */
|
|
1020
|
+
this._do_not_flush = false;
|
|
1021
|
+
/** @private @type {string} */
|
|
1022
|
+
this._fatal = Boolean(options['fatal']) ? 'fatal' : 'replacement';
|
|
1023
|
+
// 1. Let enc be a new TextEncoder object.
|
|
1024
|
+
var enc = this;
|
|
1025
|
+
// 2. Set enc's encoding to UTF-8's encoder.
|
|
1026
|
+
if (Boolean(options['NONSTANDARD_allowLegacyEncoding'])) {
|
|
1027
|
+
// NONSTANDARD behavior.
|
|
1028
|
+
label = label !== undefined ? String(label) : DEFAULT_ENCODING;
|
|
1029
|
+
var encoding = getEncoding(label);
|
|
1030
|
+
if (encoding === null || encoding.name === 'replacement')
|
|
1031
|
+
throw RangeError('Unknown encoding: ' + label);
|
|
1032
|
+
if (!encoders[encoding.name]) {
|
|
1033
|
+
throw Error('Encoder not present.' + ' Did you forget to include encoding-indexes.js first?');
|
|
1034
|
+
}
|
|
1035
|
+
enc._encoding = encoding;
|
|
444
1036
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
1037
|
+
else {
|
|
1038
|
+
// Standard behavior.
|
|
1039
|
+
enc._encoding = getEncoding('utf-8');
|
|
1040
|
+
if (label !== undefined && 'console' in globalThis) {
|
|
1041
|
+
console.warn('TextEncoder constructor called with encoding label, ' + 'which is ignored.');
|
|
1042
|
+
}
|
|
450
1043
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
1044
|
+
// For pre-ES5 runtimes:
|
|
1045
|
+
if (!Object.defineProperty)
|
|
1046
|
+
this.encoding = enc._encoding.name.toLowerCase();
|
|
1047
|
+
// 3. Return enc.
|
|
1048
|
+
return enc;
|
|
454
1049
|
}
|
|
455
1050
|
if (Object.defineProperty) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
1051
|
+
// The encoding attribute's getter must return encoding's name.
|
|
1052
|
+
Object.defineProperty(TextEncoder.prototype, 'encoding', {
|
|
1053
|
+
/** @this {TextEncoder} */
|
|
1054
|
+
get: function () {
|
|
1055
|
+
return this._encoding.name.toLowerCase();
|
|
1056
|
+
}
|
|
1057
|
+
});
|
|
461
1058
|
}
|
|
1059
|
+
/**
|
|
1060
|
+
* @param {string=} opt_string The string to encode.
|
|
1061
|
+
* @param {Object=} options
|
|
1062
|
+
* @return {!Uint8Array} Encoded bytes, as a Uint8Array.
|
|
1063
|
+
*/
|
|
462
1064
|
TextEncoder.prototype.encode = function encode(opt_string, options) {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
1065
|
+
opt_string = opt_string === undefined ? '' : String(opt_string);
|
|
1066
|
+
options = ToDictionary(options);
|
|
1067
|
+
// NOTE: This option is nonstandard. None of the encodings
|
|
1068
|
+
// permitted for encoding (i.e. UTF-8, UTF-16) are stateful when
|
|
1069
|
+
// the input is a USVString so streaming is not necessary.
|
|
1070
|
+
if (!this._do_not_flush)
|
|
1071
|
+
this._encoder = encoders[this._encoding.name]({
|
|
1072
|
+
fatal: this._fatal === 'fatal'
|
|
1073
|
+
});
|
|
1074
|
+
this._do_not_flush = Boolean(options['stream']);
|
|
1075
|
+
// 1. Convert input to a stream.
|
|
1076
|
+
var input = new Stream(stringToCodePoints(opt_string));
|
|
1077
|
+
// 2. Let output be a new stream
|
|
1078
|
+
var output = [];
|
|
1079
|
+
/** @type {?(number|!Array.<number>)} */
|
|
1080
|
+
var result;
|
|
1081
|
+
// 3. While true, run these substeps:
|
|
480
1082
|
while (true) {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
1083
|
+
// 1. Let token be the result of reading from input.
|
|
1084
|
+
var token = input.read();
|
|
1085
|
+
if (token === end_of_stream)
|
|
1086
|
+
break;
|
|
1087
|
+
// 2. Let result be the result of processing token for encoder,
|
|
1088
|
+
// input, output.
|
|
1089
|
+
result = this._encoder.handler(input, token);
|
|
1090
|
+
if (result === finished)
|
|
1091
|
+
break;
|
|
1092
|
+
if (Array.isArray(result))
|
|
1093
|
+
output.push.apply(output, /**@type {!Array.<number>}*/ result);
|
|
1094
|
+
else
|
|
1095
|
+
output.push(result);
|
|
484
1096
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
1097
|
+
// TODO: Align with spec algorithm.
|
|
1098
|
+
if (!this._do_not_flush) {
|
|
1099
|
+
while (true) {
|
|
1100
|
+
result = this._encoder.handler(input, input.read());
|
|
1101
|
+
if (result === finished)
|
|
1102
|
+
break;
|
|
1103
|
+
if (Array.isArray(result))
|
|
1104
|
+
output.push.apply(output, /**@type {!Array.<number>}*/ result);
|
|
1105
|
+
else
|
|
1106
|
+
output.push(result);
|
|
1107
|
+
}
|
|
1108
|
+
this._encoder = null;
|
|
1109
|
+
}
|
|
1110
|
+
// 3. If result is finished, convert output into a byte sequence,
|
|
1111
|
+
// and then return a Uint8Array object wrapping an ArrayBuffer
|
|
1112
|
+
// containing output.
|
|
1113
|
+
return new Uint8Array(output);
|
|
488
1114
|
};
|
|
1115
|
+
//
|
|
1116
|
+
// 9. The encoding
|
|
1117
|
+
//
|
|
1118
|
+
// 9.1 utf-8
|
|
1119
|
+
// 9.1.1 utf-8 decoder
|
|
1120
|
+
/**
|
|
1121
|
+
* @constructor
|
|
1122
|
+
* @implements {Decoder}
|
|
1123
|
+
* @param {{fatal: boolean}} options
|
|
1124
|
+
*/
|
|
489
1125
|
function UTF8Decoder(options) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if (bite ===
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
if (bite ===
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
1126
|
+
var fatal = options.fatal;
|
|
1127
|
+
// utf-8's decoder's has an associated utf-8 code point, utf-8
|
|
1128
|
+
// bytes seen, and utf-8 bytes needed (all initially 0), a utf-8
|
|
1129
|
+
// lower boundary (initially 0x80), and a utf-8 upper boundary
|
|
1130
|
+
// (initially 0xBF).
|
|
1131
|
+
var /** @type {number} */ utf8_code_point = 0,
|
|
1132
|
+
/** @type {number} */ utf8_bytes_seen = 0,
|
|
1133
|
+
/** @type {number} */ utf8_bytes_needed = 0,
|
|
1134
|
+
/** @type {number} */ utf8_lower_boundary = 0x80,
|
|
1135
|
+
/** @type {number} */ utf8_upper_boundary = 0xbf;
|
|
1136
|
+
/**
|
|
1137
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
1138
|
+
* @param {number} bite The next byte read from the stream.
|
|
1139
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
1140
|
+
* decoded, or null if not enough data exists in the input
|
|
1141
|
+
* stream to decode a complete code point.
|
|
1142
|
+
*/
|
|
1143
|
+
this.handler = function (stream, bite) {
|
|
1144
|
+
// 1. If byte is end-of-stream and utf-8 bytes needed is not 0,
|
|
1145
|
+
// set utf-8 bytes needed to 0 and return error.
|
|
1146
|
+
if (bite === end_of_stream && utf8_bytes_needed !== 0) {
|
|
1147
|
+
utf8_bytes_needed = 0;
|
|
1148
|
+
return decoderError(fatal);
|
|
1149
|
+
}
|
|
1150
|
+
// 2. If byte is end-of-stream, return finished.
|
|
1151
|
+
if (bite === end_of_stream)
|
|
1152
|
+
return finished;
|
|
1153
|
+
// 3. If utf-8 bytes needed is 0, based on byte:
|
|
1154
|
+
if (utf8_bytes_needed === 0) {
|
|
1155
|
+
// 0x00 to 0x7F
|
|
1156
|
+
if (inRange(bite, 0x00, 0x7f)) {
|
|
1157
|
+
// Return a code point whose value is byte.
|
|
1158
|
+
return bite;
|
|
1159
|
+
}
|
|
1160
|
+
// 0xC2 to 0xDF
|
|
1161
|
+
else if (inRange(bite, 0xc2, 0xdf)) {
|
|
1162
|
+
// 1. Set utf-8 bytes needed to 1.
|
|
1163
|
+
utf8_bytes_needed = 1;
|
|
1164
|
+
// 2. Set UTF-8 code point to byte & 0x1F.
|
|
1165
|
+
utf8_code_point = bite & 0x1f;
|
|
1166
|
+
}
|
|
1167
|
+
// 0xE0 to 0xEF
|
|
1168
|
+
else if (inRange(bite, 0xe0, 0xef)) {
|
|
1169
|
+
// 1. If byte is 0xE0, set utf-8 lower boundary to 0xA0.
|
|
1170
|
+
if (bite === 0xe0)
|
|
1171
|
+
utf8_lower_boundary = 0xa0;
|
|
1172
|
+
// 2. If byte is 0xED, set utf-8 upper boundary to 0x9F.
|
|
1173
|
+
if (bite === 0xed)
|
|
1174
|
+
utf8_upper_boundary = 0x9f;
|
|
1175
|
+
// 3. Set utf-8 bytes needed to 2.
|
|
1176
|
+
utf8_bytes_needed = 2;
|
|
1177
|
+
// 4. Set UTF-8 code point to byte & 0xF.
|
|
1178
|
+
utf8_code_point = bite & 0xf;
|
|
1179
|
+
}
|
|
1180
|
+
// 0xF0 to 0xF4
|
|
1181
|
+
else if (inRange(bite, 0xf0, 0xf4)) {
|
|
1182
|
+
// 1. If byte is 0xF0, set utf-8 lower boundary to 0x90.
|
|
1183
|
+
if (bite === 0xf0)
|
|
1184
|
+
utf8_lower_boundary = 0x90;
|
|
1185
|
+
// 2. If byte is 0xF4, set utf-8 upper boundary to 0x8F.
|
|
1186
|
+
if (bite === 0xf4)
|
|
1187
|
+
utf8_upper_boundary = 0x8f;
|
|
1188
|
+
// 3. Set utf-8 bytes needed to 3.
|
|
1189
|
+
utf8_bytes_needed = 3;
|
|
1190
|
+
// 4. Set UTF-8 code point to byte & 0x7.
|
|
1191
|
+
utf8_code_point = bite & 0x7;
|
|
1192
|
+
}
|
|
1193
|
+
// Otherwise
|
|
1194
|
+
else {
|
|
1195
|
+
// Return error.
|
|
1196
|
+
return decoderError(fatal);
|
|
1197
|
+
}
|
|
1198
|
+
// Return continue.
|
|
1199
|
+
return null;
|
|
1200
|
+
}
|
|
1201
|
+
// 4. If byte is not in the range utf-8 lower boundary to utf-8
|
|
1202
|
+
// upper boundary, inclusive, run these substeps:
|
|
1203
|
+
if (!inRange(bite, utf8_lower_boundary, utf8_upper_boundary)) {
|
|
1204
|
+
// 1. Set utf-8 code point, utf-8 bytes needed, and utf-8
|
|
1205
|
+
// bytes seen to 0, set utf-8 lower boundary to 0x80, and set
|
|
1206
|
+
// utf-8 upper boundary to 0xBF.
|
|
1207
|
+
utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0;
|
|
1208
|
+
utf8_lower_boundary = 0x80;
|
|
1209
|
+
utf8_upper_boundary = 0xbf;
|
|
1210
|
+
// 2. Prepend byte to stream.
|
|
1211
|
+
stream.prepend(bite);
|
|
1212
|
+
// 3. Return error.
|
|
1213
|
+
return decoderError(fatal);
|
|
1214
|
+
}
|
|
1215
|
+
// 5. Set utf-8 lower boundary to 0x80 and utf-8 upper boundary
|
|
1216
|
+
// to 0xBF.
|
|
1217
|
+
utf8_lower_boundary = 0x80;
|
|
1218
|
+
utf8_upper_boundary = 0xbf;
|
|
1219
|
+
// 6. Set UTF-8 code point to (UTF-8 code point << 6) | (byte &
|
|
1220
|
+
// 0x3F)
|
|
1221
|
+
utf8_code_point = (utf8_code_point << 6) | (bite & 0x3f);
|
|
1222
|
+
// 7. Increase utf-8 bytes seen by one.
|
|
1223
|
+
utf8_bytes_seen += 1;
|
|
1224
|
+
// 8. If utf-8 bytes seen is not equal to utf-8 bytes needed,
|
|
1225
|
+
// continue.
|
|
1226
|
+
if (utf8_bytes_seen !== utf8_bytes_needed)
|
|
1227
|
+
return null;
|
|
1228
|
+
// 9. Let code point be utf-8 code point.
|
|
1229
|
+
var code_point = utf8_code_point;
|
|
1230
|
+
// 10. Set utf-8 code point, utf-8 bytes needed, and utf-8 bytes
|
|
1231
|
+
// seen to 0.
|
|
1232
|
+
utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0;
|
|
1233
|
+
// 11. Return a code point whose value is code point.
|
|
1234
|
+
return code_point;
|
|
1235
|
+
};
|
|
539
1236
|
}
|
|
1237
|
+
// 9.1.2 utf-8 encoder
|
|
1238
|
+
/**
|
|
1239
|
+
* @constructor
|
|
1240
|
+
* @implements {Encoder}
|
|
1241
|
+
* @param {{fatal: boolean}} options
|
|
1242
|
+
*/
|
|
540
1243
|
function UTF8Encoder(options) {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
1244
|
+
var fatal = options.fatal;
|
|
1245
|
+
/**
|
|
1246
|
+
* @param {Stream} stream Input stream.
|
|
1247
|
+
* @param {number} code_point Next code point read from the stream.
|
|
1248
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
1249
|
+
*/
|
|
1250
|
+
this.handler = function (stream, code_point) {
|
|
1251
|
+
// 1. If code point is end-of-stream, return finished.
|
|
1252
|
+
if (code_point === end_of_stream)
|
|
1253
|
+
return finished;
|
|
1254
|
+
// 2. If code point is an ASCII code point, return a byte whose
|
|
1255
|
+
// value is code point.
|
|
1256
|
+
if (isASCIICodePoint(code_point))
|
|
1257
|
+
return code_point;
|
|
1258
|
+
// 3. Set count and offset based on the range code point is in:
|
|
1259
|
+
var count, offset;
|
|
1260
|
+
// U+0080 to U+07FF, inclusive:
|
|
1261
|
+
if (inRange(code_point, 0x0080, 0x07ff)) {
|
|
1262
|
+
// 1 and 0xC0
|
|
1263
|
+
count = 1;
|
|
1264
|
+
offset = 0xc0;
|
|
1265
|
+
}
|
|
1266
|
+
// U+0800 to U+FFFF, inclusive:
|
|
1267
|
+
else if (inRange(code_point, 0x0800, 0xffff)) {
|
|
1268
|
+
// 2 and 0xE0
|
|
1269
|
+
count = 2;
|
|
1270
|
+
offset = 0xe0;
|
|
1271
|
+
}
|
|
1272
|
+
// U+10000 to U+10FFFF, inclusive:
|
|
1273
|
+
else if (inRange(code_point, 0x10000, 0x10ffff)) {
|
|
1274
|
+
// 3 and 0xF0
|
|
1275
|
+
count = 3;
|
|
1276
|
+
offset = 0xf0;
|
|
1277
|
+
}
|
|
1278
|
+
// 4. Let bytes be a byte sequence whose first byte is (code
|
|
1279
|
+
// point >> (6 × count)) + offset.
|
|
1280
|
+
var bytes = [(code_point >> (6 * count)) + offset];
|
|
1281
|
+
// 5. Run these substeps while count is greater than 0:
|
|
1282
|
+
while (count > 0) {
|
|
1283
|
+
// 1. Set temp to code point >> (6 × (count − 1)).
|
|
1284
|
+
var temp = code_point >> (6 * (count - 1));
|
|
1285
|
+
// 2. Append to bytes 0x80 | (temp & 0x3F).
|
|
1286
|
+
bytes.push(0x80 | (temp & 0x3f));
|
|
1287
|
+
// 3. Decrease count by one.
|
|
1288
|
+
count -= 1;
|
|
1289
|
+
}
|
|
1290
|
+
// 6. Return bytes bytes, in order.
|
|
1291
|
+
return bytes;
|
|
1292
|
+
};
|
|
564
1293
|
}
|
|
1294
|
+
/** @param {{fatal: boolean}} options */
|
|
565
1295
|
encoders['UTF-8'] = function (options) {
|
|
566
|
-
|
|
1296
|
+
return new UTF8Encoder(options);
|
|
567
1297
|
};
|
|
1298
|
+
/** @param {{fatal: boolean}} options */
|
|
568
1299
|
decoders['UTF-8'] = function (options) {
|
|
569
|
-
|
|
1300
|
+
return new UTF8Decoder(options);
|
|
570
1301
|
};
|
|
1302
|
+
//
|
|
1303
|
+
// 10. Legacy single-byte encodings
|
|
1304
|
+
//
|
|
1305
|
+
// 10.1 single-byte decoder
|
|
1306
|
+
/**
|
|
1307
|
+
* @constructor
|
|
1308
|
+
* @implements {Decoder}
|
|
1309
|
+
* @param {!Array.<number>} index The encoding index.
|
|
1310
|
+
* @param {{fatal: boolean}} options
|
|
1311
|
+
*/
|
|
571
1312
|
function SingleByteDecoder(index, options) {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
1313
|
+
var fatal = options.fatal;
|
|
1314
|
+
/**
|
|
1315
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
1316
|
+
* @param {number} bite The next byte read from the stream.
|
|
1317
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
1318
|
+
* decoded, or null if not enough data exists in the input
|
|
1319
|
+
* stream to decode a complete code point.
|
|
1320
|
+
*/
|
|
1321
|
+
this.handler = function (stream, bite) {
|
|
1322
|
+
// 1. If byte is end-of-stream, return finished.
|
|
1323
|
+
if (bite === end_of_stream)
|
|
1324
|
+
return finished;
|
|
1325
|
+
// 2. If byte is an ASCII byte, return a code point whose value
|
|
1326
|
+
// is byte.
|
|
1327
|
+
if (isASCIIByte(bite))
|
|
1328
|
+
return bite;
|
|
1329
|
+
// 3. Let code point be the index code point for byte − 0x80 in
|
|
1330
|
+
// index single-byte.
|
|
1331
|
+
var code_point = index[bite - 0x80];
|
|
1332
|
+
// 4. If code point is null, return error.
|
|
1333
|
+
if (code_point === null)
|
|
1334
|
+
return decoderError(fatal);
|
|
1335
|
+
// 5. Return a code point whose value is code point.
|
|
1336
|
+
return code_point;
|
|
1337
|
+
};
|
|
580
1338
|
}
|
|
1339
|
+
// 10.2 single-byte encoder
|
|
1340
|
+
/**
|
|
1341
|
+
* @constructor
|
|
1342
|
+
* @implements {Encoder}
|
|
1343
|
+
* @param {!Array.<?number>} index The encoding index.
|
|
1344
|
+
* @param {{fatal: boolean}} options
|
|
1345
|
+
*/
|
|
581
1346
|
function SingleByteEncoder(index, options) {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
1347
|
+
var fatal = options.fatal;
|
|
1348
|
+
/**
|
|
1349
|
+
* @param {Stream} stream Input stream.
|
|
1350
|
+
* @param {number} code_point Next code point read from the stream.
|
|
1351
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
1352
|
+
*/
|
|
1353
|
+
this.handler = function (stream, code_point) {
|
|
1354
|
+
// 1. If code point is end-of-stream, return finished.
|
|
1355
|
+
if (code_point === end_of_stream)
|
|
1356
|
+
return finished;
|
|
1357
|
+
// 2. If code point is an ASCII code point, return a byte whose
|
|
1358
|
+
// value is code point.
|
|
1359
|
+
if (isASCIICodePoint(code_point))
|
|
1360
|
+
return code_point;
|
|
1361
|
+
// 3. Let pointer be the index pointer for code point in index
|
|
1362
|
+
// single-byte.
|
|
1363
|
+
var pointer = indexPointerFor(code_point, index);
|
|
1364
|
+
// 4. If pointer is null, return error with code point.
|
|
1365
|
+
if (pointer === null)
|
|
1366
|
+
encoderError(code_point);
|
|
1367
|
+
// 5. Return a byte whose value is pointer + 0x80.
|
|
1368
|
+
return pointer + 0x80;
|
|
1369
|
+
};
|
|
590
1370
|
}
|
|
591
1371
|
(function () {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
1372
|
+
if (!('encoding-indexes' in globalThis))
|
|
1373
|
+
return;
|
|
1374
|
+
encodings.forEach(function (category) {
|
|
1375
|
+
if (category.heading !== 'Legacy single-byte encodings')
|
|
1376
|
+
return;
|
|
1377
|
+
category.encodings.forEach(function (encoding) {
|
|
1378
|
+
var name = encoding.name;
|
|
1379
|
+
var idx = index(name.toLowerCase());
|
|
1380
|
+
/** @param {{fatal: boolean}} options */
|
|
1381
|
+
decoders[name] = function (options) {
|
|
1382
|
+
return new SingleByteDecoder(idx, options);
|
|
1383
|
+
};
|
|
1384
|
+
/** @param {{fatal: boolean}} options */
|
|
1385
|
+
encoders[name] = function (options) {
|
|
1386
|
+
return new SingleByteEncoder(idx, options);
|
|
1387
|
+
};
|
|
1388
|
+
});
|
|
604
1389
|
});
|
|
605
|
-
});
|
|
606
1390
|
})();
|
|
1391
|
+
//
|
|
1392
|
+
// 11. Legacy multi-byte Chinese (simplified) encodings
|
|
1393
|
+
//
|
|
1394
|
+
// 11.1 gbk
|
|
1395
|
+
// 11.1.1 gbk decoder
|
|
1396
|
+
// gbk's decoder is gb18030's decoder.
|
|
1397
|
+
/** @param {{fatal: boolean}} options */
|
|
607
1398
|
decoders['GBK'] = function (options) {
|
|
608
|
-
|
|
1399
|
+
return new GB18030Decoder(options);
|
|
609
1400
|
};
|
|
1401
|
+
// 11.1.2 gbk encoder
|
|
1402
|
+
// gbk's encoder is gb18030's encoder with its gbk flag set.
|
|
1403
|
+
/** @param {{fatal: boolean}} options */
|
|
610
1404
|
encoders['GBK'] = function (options) {
|
|
611
|
-
|
|
1405
|
+
return new GB18030Encoder(options, true);
|
|
612
1406
|
};
|
|
1407
|
+
// 11.2 gb18030
|
|
1408
|
+
// 11.2.1 gb18030 decoder
|
|
1409
|
+
/**
|
|
1410
|
+
* @constructor
|
|
1411
|
+
* @implements {Decoder}
|
|
1412
|
+
* @param {{fatal: boolean}} options
|
|
1413
|
+
*/
|
|
613
1414
|
function GB18030Decoder(options) {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
1415
|
+
var fatal = options.fatal;
|
|
1416
|
+
// gb18030's decoder has an associated gb18030 first, gb18030
|
|
1417
|
+
// second, and gb18030 third (all initially 0x00).
|
|
1418
|
+
var /** @type {number} */ gb18030_first = 0x00,
|
|
1419
|
+
/** @type {number} */ gb18030_second = 0x00,
|
|
1420
|
+
/** @type {number} */ gb18030_third = 0x00;
|
|
1421
|
+
/**
|
|
1422
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
1423
|
+
* @param {number} bite The next byte read from the stream.
|
|
1424
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
1425
|
+
* decoded, or null if not enough data exists in the input
|
|
1426
|
+
* stream to decode a complete code point.
|
|
1427
|
+
*/
|
|
1428
|
+
this.handler = function (stream, bite) {
|
|
1429
|
+
// 1. If byte is end-of-stream and gb18030 first, gb18030
|
|
1430
|
+
// second, and gb18030 third are 0x00, return finished.
|
|
1431
|
+
if (bite === end_of_stream &&
|
|
1432
|
+
gb18030_first === 0x00 &&
|
|
1433
|
+
gb18030_second === 0x00 &&
|
|
1434
|
+
gb18030_third === 0x00) {
|
|
1435
|
+
return finished;
|
|
1436
|
+
}
|
|
1437
|
+
// 2. If byte is end-of-stream, and gb18030 first, gb18030
|
|
1438
|
+
// second, or gb18030 third is not 0x00, set gb18030 first,
|
|
1439
|
+
// gb18030 second, and gb18030 third to 0x00, and return error.
|
|
1440
|
+
if (bite === end_of_stream &&
|
|
1441
|
+
(gb18030_first !== 0x00 || gb18030_second !== 0x00 || gb18030_third !== 0x00)) {
|
|
1442
|
+
gb18030_first = 0x00;
|
|
1443
|
+
gb18030_second = 0x00;
|
|
1444
|
+
gb18030_third = 0x00;
|
|
1445
|
+
decoderError(fatal);
|
|
1446
|
+
}
|
|
1447
|
+
var code_point;
|
|
1448
|
+
// 3. If gb18030 third is not 0x00, run these substeps:
|
|
1449
|
+
if (gb18030_third !== 0x00) {
|
|
1450
|
+
// 1. Let code point be null.
|
|
1451
|
+
code_point = null;
|
|
1452
|
+
// 2. If byte is in the range 0x30 to 0x39, inclusive, set
|
|
1453
|
+
// code point to the index gb18030 ranges code point for
|
|
1454
|
+
// (((gb18030 first − 0x81) × 10 + gb18030 second − 0x30) ×
|
|
1455
|
+
// 126 + gb18030 third − 0x81) × 10 + byte − 0x30.
|
|
1456
|
+
if (inRange(bite, 0x30, 0x39)) {
|
|
1457
|
+
code_point = indexGB18030RangesCodePointFor((((gb18030_first - 0x81) * 10 + gb18030_second - 0x30) * 126 + gb18030_third - 0x81) *
|
|
1458
|
+
10 +
|
|
1459
|
+
bite -
|
|
1460
|
+
0x30);
|
|
1461
|
+
}
|
|
1462
|
+
// 3. Let buffer be a byte sequence consisting of gb18030
|
|
1463
|
+
// second, gb18030 third, and byte, in order.
|
|
1464
|
+
var buffer = [gb18030_second, gb18030_third, bite];
|
|
1465
|
+
// 4. Set gb18030 first, gb18030 second, and gb18030 third to
|
|
1466
|
+
// 0x00.
|
|
1467
|
+
gb18030_first = 0x00;
|
|
1468
|
+
gb18030_second = 0x00;
|
|
1469
|
+
gb18030_third = 0x00;
|
|
1470
|
+
// 5. If code point is null, prepend buffer to stream and
|
|
1471
|
+
// return error.
|
|
1472
|
+
if (code_point === null) {
|
|
1473
|
+
stream.prepend(buffer);
|
|
1474
|
+
return decoderError(fatal);
|
|
1475
|
+
}
|
|
1476
|
+
// 6. Return a code point whose value is code point.
|
|
1477
|
+
return code_point;
|
|
1478
|
+
}
|
|
1479
|
+
// 4. If gb18030 second is not 0x00, run these substeps:
|
|
1480
|
+
if (gb18030_second !== 0x00) {
|
|
1481
|
+
// 1. If byte is in the range 0x81 to 0xFE, inclusive, set
|
|
1482
|
+
// gb18030 third to byte and return continue.
|
|
1483
|
+
if (inRange(bite, 0x81, 0xfe)) {
|
|
1484
|
+
gb18030_third = bite;
|
|
1485
|
+
return null;
|
|
1486
|
+
}
|
|
1487
|
+
// 2. Prepend gb18030 second followed by byte to stream, set
|
|
1488
|
+
// gb18030 first and gb18030 second to 0x00, and return error.
|
|
1489
|
+
stream.prepend([gb18030_second, bite]);
|
|
1490
|
+
gb18030_first = 0x00;
|
|
1491
|
+
gb18030_second = 0x00;
|
|
1492
|
+
return decoderError(fatal);
|
|
1493
|
+
}
|
|
1494
|
+
// 5. If gb18030 first is not 0x00, run these substeps:
|
|
1495
|
+
if (gb18030_first !== 0x00) {
|
|
1496
|
+
// 1. If byte is in the range 0x30 to 0x39, inclusive, set
|
|
1497
|
+
// gb18030 second to byte and return continue.
|
|
1498
|
+
if (inRange(bite, 0x30, 0x39)) {
|
|
1499
|
+
gb18030_second = bite;
|
|
1500
|
+
return null;
|
|
1501
|
+
}
|
|
1502
|
+
// 2. Let lead be gb18030 first, let pointer be null, and set
|
|
1503
|
+
// gb18030 first to 0x00.
|
|
1504
|
+
var lead = gb18030_first;
|
|
1505
|
+
var pointer = null;
|
|
1506
|
+
gb18030_first = 0x00;
|
|
1507
|
+
// 3. Let offset be 0x40 if byte is less than 0x7F and 0x41
|
|
1508
|
+
// otherwise.
|
|
1509
|
+
var offset = bite < 0x7f ? 0x40 : 0x41;
|
|
1510
|
+
// 4. If byte is in the range 0x40 to 0x7E, inclusive, or 0x80
|
|
1511
|
+
// to 0xFE, inclusive, set pointer to (lead − 0x81) × 190 +
|
|
1512
|
+
// (byte − offset).
|
|
1513
|
+
if (inRange(bite, 0x40, 0x7e) || inRange(bite, 0x80, 0xfe))
|
|
1514
|
+
pointer = (lead - 0x81) * 190 + (bite - offset);
|
|
1515
|
+
// 5. Let code point be null if pointer is null and the index
|
|
1516
|
+
// code point for pointer in index gb18030 otherwise.
|
|
1517
|
+
code_point = pointer === null ? null : indexCodePointFor(pointer, index('gb18030'));
|
|
1518
|
+
// 6. If code point is null and byte is an ASCII byte, prepend
|
|
1519
|
+
// byte to stream.
|
|
1520
|
+
if (code_point === null && isASCIIByte(bite))
|
|
1521
|
+
stream.prepend(bite);
|
|
1522
|
+
// 7. If code point is null, return error.
|
|
1523
|
+
if (code_point === null)
|
|
1524
|
+
return decoderError(fatal);
|
|
1525
|
+
// 8. Return a code point whose value is code point.
|
|
1526
|
+
return code_point;
|
|
1527
|
+
}
|
|
1528
|
+
// 6. If byte is an ASCII byte, return a code point whose value
|
|
1529
|
+
// is byte.
|
|
1530
|
+
if (isASCIIByte(bite))
|
|
1531
|
+
return bite;
|
|
1532
|
+
// 7. If byte is 0x80, return code point U+20AC.
|
|
1533
|
+
if (bite === 0x80)
|
|
1534
|
+
return 0x20ac;
|
|
1535
|
+
// 8. If byte is in the range 0x81 to 0xFE, inclusive, set
|
|
1536
|
+
// gb18030 first to byte and return continue.
|
|
1537
|
+
if (inRange(bite, 0x81, 0xfe)) {
|
|
1538
|
+
gb18030_first = bite;
|
|
1539
|
+
return null;
|
|
1540
|
+
}
|
|
1541
|
+
// 9. Return error.
|
|
640
1542
|
return decoderError(fatal);
|
|
641
|
-
|
|
642
|
-
return code_point;
|
|
643
|
-
}
|
|
644
|
-
if (gb18030_second !== 0x00) {
|
|
645
|
-
if (inRange(bite, 0x81, 0xfe)) {
|
|
646
|
-
gb18030_third = bite;
|
|
647
|
-
return null;
|
|
648
|
-
}
|
|
649
|
-
stream.prepend([gb18030_second, bite]);
|
|
650
|
-
gb18030_first = 0x00;
|
|
651
|
-
gb18030_second = 0x00;
|
|
652
|
-
return decoderError(fatal);
|
|
653
|
-
}
|
|
654
|
-
if (gb18030_first !== 0x00) {
|
|
655
|
-
if (inRange(bite, 0x30, 0x39)) {
|
|
656
|
-
gb18030_second = bite;
|
|
657
|
-
return null;
|
|
658
|
-
}
|
|
659
|
-
var lead = gb18030_first;
|
|
660
|
-
var pointer = null;
|
|
661
|
-
gb18030_first = 0x00;
|
|
662
|
-
var offset = bite < 0x7f ? 0x40 : 0x41;
|
|
663
|
-
if (inRange(bite, 0x40, 0x7e) || inRange(bite, 0x80, 0xfe)) pointer = (lead - 0x81) * 190 + (bite - offset);
|
|
664
|
-
code_point = pointer === null ? null : indexCodePointFor(pointer, index('gb18030'));
|
|
665
|
-
if (code_point === null && isASCIIByte(bite)) stream.prepend(bite);
|
|
666
|
-
if (code_point === null) return decoderError(fatal);
|
|
667
|
-
return code_point;
|
|
668
|
-
}
|
|
669
|
-
if (isASCIIByte(bite)) return bite;
|
|
670
|
-
if (bite === 0x80) return 0x20ac;
|
|
671
|
-
if (inRange(bite, 0x81, 0xfe)) {
|
|
672
|
-
gb18030_first = bite;
|
|
673
|
-
return null;
|
|
674
|
-
}
|
|
675
|
-
return decoderError(fatal);
|
|
676
|
-
};
|
|
1543
|
+
};
|
|
677
1544
|
}
|
|
1545
|
+
// 11.2.2 gb18030 encoder
|
|
1546
|
+
/**
|
|
1547
|
+
* @constructor
|
|
1548
|
+
* @implements {Encoder}
|
|
1549
|
+
* @param {{fatal: boolean}} options
|
|
1550
|
+
* @param {boolean=} gbk_flag
|
|
1551
|
+
*/
|
|
678
1552
|
function GB18030Encoder(options, gbk_flag) {
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
1553
|
+
var fatal = options.fatal;
|
|
1554
|
+
// gb18030's decoder has an associated gbk flag (initially unset).
|
|
1555
|
+
/**
|
|
1556
|
+
* @param {Stream} stream Input stream.
|
|
1557
|
+
* @param {number} code_point Next code point read from the stream.
|
|
1558
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
1559
|
+
*/
|
|
1560
|
+
this.handler = function (stream, code_point) {
|
|
1561
|
+
// 1. If code point is end-of-stream, return finished.
|
|
1562
|
+
if (code_point === end_of_stream)
|
|
1563
|
+
return finished;
|
|
1564
|
+
// 2. If code point is an ASCII code point, return a byte whose
|
|
1565
|
+
// value is code point.
|
|
1566
|
+
if (isASCIICodePoint(code_point))
|
|
1567
|
+
return code_point;
|
|
1568
|
+
// 3. If code point is U+E5E5, return error with code point.
|
|
1569
|
+
if (code_point === 0xe5e5)
|
|
1570
|
+
return encoderError(code_point);
|
|
1571
|
+
// 4. If the gbk flag is set and code point is U+20AC, return
|
|
1572
|
+
// byte 0x80.
|
|
1573
|
+
if (gbk_flag && code_point === 0x20ac)
|
|
1574
|
+
return 0x80;
|
|
1575
|
+
// 5. Let pointer be the index pointer for code point in index
|
|
1576
|
+
// gb18030.
|
|
1577
|
+
var pointer = indexPointerFor(code_point, index('gb18030'));
|
|
1578
|
+
// 6. If pointer is not null, run these substeps:
|
|
1579
|
+
if (pointer !== null) {
|
|
1580
|
+
// 1. Let lead be floor(pointer / 190) + 0x81.
|
|
1581
|
+
var lead = floor(pointer / 190) + 0x81;
|
|
1582
|
+
// 2. Let trail be pointer % 190.
|
|
1583
|
+
var trail = pointer % 190;
|
|
1584
|
+
// 3. Let offset be 0x40 if trail is less than 0x3F and 0x41 otherwise.
|
|
1585
|
+
var offset = trail < 0x3f ? 0x40 : 0x41;
|
|
1586
|
+
// 4. Return two bytes whose values are lead and trail + offset.
|
|
1587
|
+
return [lead, trail + offset];
|
|
1588
|
+
}
|
|
1589
|
+
// 7. If gbk flag is set, return error with code point.
|
|
1590
|
+
if (gbk_flag)
|
|
1591
|
+
return encoderError(code_point);
|
|
1592
|
+
// 8. Set pointer to the index gb18030 ranges pointer for code
|
|
1593
|
+
// point.
|
|
1594
|
+
pointer = indexGB18030RangesPointerFor(code_point);
|
|
1595
|
+
// 9. Let byte1 be floor(pointer / 10 / 126 / 10).
|
|
1596
|
+
var byte1 = floor(pointer / 10 / 126 / 10);
|
|
1597
|
+
// 10. Set pointer to pointer − byte1 × 10 × 126 × 10.
|
|
1598
|
+
pointer = pointer - byte1 * 10 * 126 * 10;
|
|
1599
|
+
// 11. Let byte2 be floor(pointer / 10 / 126).
|
|
1600
|
+
var byte2 = floor(pointer / 10 / 126);
|
|
1601
|
+
// 12. Set pointer to pointer − byte2 × 10 × 126.
|
|
1602
|
+
pointer = pointer - byte2 * 10 * 126;
|
|
1603
|
+
// 13. Let byte3 be floor(pointer / 10).
|
|
1604
|
+
var byte3 = floor(pointer / 10);
|
|
1605
|
+
// 14. Let byte4 be pointer − byte3 × 10.
|
|
1606
|
+
var byte4 = pointer - byte3 * 10;
|
|
1607
|
+
// 15. Return four bytes whose values are byte1 + 0x81, byte2 +
|
|
1608
|
+
// 0x30, byte3 + 0x81, byte4 + 0x30.
|
|
1609
|
+
return [byte1 + 0x81, byte2 + 0x30, byte3 + 0x81, byte4 + 0x30];
|
|
1610
|
+
};
|
|
702
1611
|
}
|
|
1612
|
+
/** @param {{fatal: boolean}} options */
|
|
703
1613
|
encoders['gb18030'] = function (options) {
|
|
704
|
-
|
|
1614
|
+
return new GB18030Encoder(options);
|
|
705
1615
|
};
|
|
1616
|
+
/** @param {{fatal: boolean}} options */
|
|
706
1617
|
decoders['gb18030'] = function (options) {
|
|
707
|
-
|
|
1618
|
+
return new GB18030Decoder(options);
|
|
708
1619
|
};
|
|
1620
|
+
//
|
|
1621
|
+
// 12. Legacy multi-byte Chinese (traditional) encodings
|
|
1622
|
+
//
|
|
1623
|
+
// 12.1 Big5
|
|
1624
|
+
// 12.1.1 Big5 decoder
|
|
1625
|
+
/**
|
|
1626
|
+
* @constructor
|
|
1627
|
+
* @implements {Decoder}
|
|
1628
|
+
* @param {{fatal: boolean}} options
|
|
1629
|
+
*/
|
|
709
1630
|
function Big5Decoder(options) {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
1631
|
+
var fatal = options.fatal;
|
|
1632
|
+
// Big5's decoder has an associated Big5 lead (initially 0x00).
|
|
1633
|
+
var /** @type {number} */ Big5_lead = 0x00;
|
|
1634
|
+
/**
|
|
1635
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
1636
|
+
* @param {number} bite The next byte read from the stream.
|
|
1637
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
1638
|
+
* decoded, or null if not enough data exists in the input
|
|
1639
|
+
* stream to decode a complete code point.
|
|
1640
|
+
*/
|
|
1641
|
+
this.handler = function (stream, bite) {
|
|
1642
|
+
// 1. If byte is end-of-stream and Big5 lead is not 0x00, set
|
|
1643
|
+
// Big5 lead to 0x00 and return error.
|
|
1644
|
+
if (bite === end_of_stream && Big5_lead !== 0x00) {
|
|
1645
|
+
Big5_lead = 0x00;
|
|
1646
|
+
return decoderError(fatal);
|
|
1647
|
+
}
|
|
1648
|
+
// 2. If byte is end-of-stream and Big5 lead is 0x00, return
|
|
1649
|
+
// finished.
|
|
1650
|
+
if (bite === end_of_stream && Big5_lead === 0x00)
|
|
1651
|
+
return finished;
|
|
1652
|
+
// 3. If Big5 lead is not 0x00, let lead be Big5 lead, let
|
|
1653
|
+
// pointer be null, set Big5 lead to 0x00, and then run these
|
|
1654
|
+
// substeps:
|
|
1655
|
+
if (Big5_lead !== 0x00) {
|
|
1656
|
+
var lead = Big5_lead;
|
|
1657
|
+
var pointer = null;
|
|
1658
|
+
Big5_lead = 0x00;
|
|
1659
|
+
// 1. Let offset be 0x40 if byte is less than 0x7F and 0x62
|
|
1660
|
+
// otherwise.
|
|
1661
|
+
var offset = bite < 0x7f ? 0x40 : 0x62;
|
|
1662
|
+
// 2. If byte is in the range 0x40 to 0x7E, inclusive, or 0xA1
|
|
1663
|
+
// to 0xFE, inclusive, set pointer to (lead − 0x81) × 157 +
|
|
1664
|
+
// (byte − offset).
|
|
1665
|
+
if (inRange(bite, 0x40, 0x7e) || inRange(bite, 0xa1, 0xfe))
|
|
1666
|
+
pointer = (lead - 0x81) * 157 + (bite - offset);
|
|
1667
|
+
// 3. If there is a row in the table below whose first column
|
|
1668
|
+
// is pointer, return the two code points listed in its second
|
|
1669
|
+
// column
|
|
1670
|
+
// Pointer | Code points
|
|
1671
|
+
// --------+--------------
|
|
1672
|
+
// 1133 | U+00CA U+0304
|
|
1673
|
+
// 1135 | U+00CA U+030C
|
|
1674
|
+
// 1164 | U+00EA U+0304
|
|
1675
|
+
// 1166 | U+00EA U+030C
|
|
1676
|
+
switch (pointer) {
|
|
1677
|
+
case 1133:
|
|
1678
|
+
return [0x00ca, 0x0304];
|
|
1679
|
+
case 1135:
|
|
1680
|
+
return [0x00ca, 0x030c];
|
|
1681
|
+
case 1164:
|
|
1682
|
+
return [0x00ea, 0x0304];
|
|
1683
|
+
case 1166:
|
|
1684
|
+
return [0x00ea, 0x030c];
|
|
1685
|
+
}
|
|
1686
|
+
// 4. Let code point be null if pointer is null and the index
|
|
1687
|
+
// code point for pointer in index Big5 otherwise.
|
|
1688
|
+
var code_point = pointer === null ? null : indexCodePointFor(pointer, index('big5'));
|
|
1689
|
+
// 5. If code point is null and byte is an ASCII byte, prepend
|
|
1690
|
+
// byte to stream.
|
|
1691
|
+
if (code_point === null && isASCIIByte(bite))
|
|
1692
|
+
stream.prepend(bite);
|
|
1693
|
+
// 6. If code point is null, return error.
|
|
1694
|
+
if (code_point === null)
|
|
1695
|
+
return decoderError(fatal);
|
|
1696
|
+
// 7. Return a code point whose value is code point.
|
|
1697
|
+
return code_point;
|
|
1698
|
+
}
|
|
1699
|
+
// 4. If byte is an ASCII byte, return a code point whose value
|
|
1700
|
+
// is byte.
|
|
1701
|
+
if (isASCIIByte(bite))
|
|
1702
|
+
return bite;
|
|
1703
|
+
// 5. If byte is in the range 0x81 to 0xFE, inclusive, set Big5
|
|
1704
|
+
// lead to byte and return continue.
|
|
1705
|
+
if (inRange(bite, 0x81, 0xfe)) {
|
|
1706
|
+
Big5_lead = bite;
|
|
1707
|
+
return null;
|
|
1708
|
+
}
|
|
1709
|
+
// 6. Return error.
|
|
1710
|
+
return decoderError(fatal);
|
|
1711
|
+
};
|
|
746
1712
|
}
|
|
1713
|
+
// 12.1.2 Big5 encoder
|
|
1714
|
+
/**
|
|
1715
|
+
* @constructor
|
|
1716
|
+
* @implements {Encoder}
|
|
1717
|
+
* @param {{fatal: boolean}} options
|
|
1718
|
+
*/
|
|
747
1719
|
function Big5Encoder(options) {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
1720
|
+
var fatal = options.fatal;
|
|
1721
|
+
/**
|
|
1722
|
+
* @param {Stream} stream Input stream.
|
|
1723
|
+
* @param {number} code_point Next code point read from the stream.
|
|
1724
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
1725
|
+
*/
|
|
1726
|
+
this.handler = function (stream, code_point) {
|
|
1727
|
+
// 1. If code point is end-of-stream, return finished.
|
|
1728
|
+
if (code_point === end_of_stream)
|
|
1729
|
+
return finished;
|
|
1730
|
+
// 2. If code point is an ASCII code point, return a byte whose
|
|
1731
|
+
// value is code point.
|
|
1732
|
+
if (isASCIICodePoint(code_point))
|
|
1733
|
+
return code_point;
|
|
1734
|
+
// 3. Let pointer be the index Big5 pointer for code point.
|
|
1735
|
+
var pointer = indexBig5PointerFor(code_point);
|
|
1736
|
+
// 4. If pointer is null, return error with code point.
|
|
1737
|
+
if (pointer === null)
|
|
1738
|
+
return encoderError(code_point);
|
|
1739
|
+
// 5. Let lead be floor(pointer / 157) + 0x81.
|
|
1740
|
+
var lead = floor(pointer / 157) + 0x81;
|
|
1741
|
+
// 6. If lead is less than 0xA1, return error with code point.
|
|
1742
|
+
if (lead < 0xa1)
|
|
1743
|
+
return encoderError(code_point);
|
|
1744
|
+
// 7. Let trail be pointer % 157.
|
|
1745
|
+
var trail = pointer % 157;
|
|
1746
|
+
// 8. Let offset be 0x40 if trail is less than 0x3F and 0x62
|
|
1747
|
+
// otherwise.
|
|
1748
|
+
var offset = trail < 0x3f ? 0x40 : 0x62;
|
|
1749
|
+
// Return two bytes whose values are lead and trail + offset.
|
|
1750
|
+
return [lead, trail + offset];
|
|
1751
|
+
};
|
|
760
1752
|
}
|
|
1753
|
+
/** @param {{fatal: boolean}} options */
|
|
761
1754
|
encoders['Big5'] = function (options) {
|
|
762
|
-
|
|
1755
|
+
return new Big5Encoder(options);
|
|
763
1756
|
};
|
|
1757
|
+
/** @param {{fatal: boolean}} options */
|
|
764
1758
|
decoders['Big5'] = function (options) {
|
|
765
|
-
|
|
1759
|
+
return new Big5Decoder(options);
|
|
766
1760
|
};
|
|
1761
|
+
//
|
|
1762
|
+
// 13. Legacy multi-byte Japanese encodings
|
|
1763
|
+
//
|
|
1764
|
+
// 13.1 euc-jp
|
|
1765
|
+
// 13.1.1 euc-jp decoder
|
|
1766
|
+
/**
|
|
1767
|
+
* @constructor
|
|
1768
|
+
* @implements {Decoder}
|
|
1769
|
+
* @param {{fatal: boolean}} options
|
|
1770
|
+
*/
|
|
767
1771
|
function EUCJPDecoder(options) {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
1772
|
+
var fatal = options.fatal;
|
|
1773
|
+
// euc-jp's decoder has an associated euc-jp jis0212 flag
|
|
1774
|
+
// (initially unset) and euc-jp lead (initially 0x00).
|
|
1775
|
+
var /** @type {boolean} */ eucjp_jis0212_flag = false,
|
|
1776
|
+
/** @type {number} */ eucjp_lead = 0x00;
|
|
1777
|
+
/**
|
|
1778
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
1779
|
+
* @param {number} bite The next byte read from the stream.
|
|
1780
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
1781
|
+
* decoded, or null if not enough data exists in the input
|
|
1782
|
+
* stream to decode a complete code point.
|
|
1783
|
+
*/
|
|
1784
|
+
this.handler = function (stream, bite) {
|
|
1785
|
+
// 1. If byte is end-of-stream and euc-jp lead is not 0x00, set
|
|
1786
|
+
// euc-jp lead to 0x00, and return error.
|
|
1787
|
+
if (bite === end_of_stream && eucjp_lead !== 0x00) {
|
|
1788
|
+
eucjp_lead = 0x00;
|
|
1789
|
+
return decoderError(fatal);
|
|
1790
|
+
}
|
|
1791
|
+
// 2. If byte is end-of-stream and euc-jp lead is 0x00, return
|
|
1792
|
+
// finished.
|
|
1793
|
+
if (bite === end_of_stream && eucjp_lead === 0x00)
|
|
1794
|
+
return finished;
|
|
1795
|
+
// 3. If euc-jp lead is 0x8E and byte is in the range 0xA1 to
|
|
1796
|
+
// 0xDF, inclusive, set euc-jp lead to 0x00 and return a code
|
|
1797
|
+
// point whose value is 0xFF61 − 0xA1 + byte.
|
|
1798
|
+
if (eucjp_lead === 0x8e && inRange(bite, 0xa1, 0xdf)) {
|
|
1799
|
+
eucjp_lead = 0x00;
|
|
1800
|
+
return 0xff61 - 0xa1 + bite;
|
|
1801
|
+
}
|
|
1802
|
+
// 4. If euc-jp lead is 0x8F and byte is in the range 0xA1 to
|
|
1803
|
+
// 0xFE, inclusive, set the euc-jp jis0212 flag, set euc-jp lead
|
|
1804
|
+
// to byte, and return continue.
|
|
1805
|
+
if (eucjp_lead === 0x8f && inRange(bite, 0xa1, 0xfe)) {
|
|
1806
|
+
eucjp_jis0212_flag = true;
|
|
1807
|
+
eucjp_lead = bite;
|
|
1808
|
+
return null;
|
|
1809
|
+
}
|
|
1810
|
+
// 5. If euc-jp lead is not 0x00, let lead be euc-jp lead, set
|
|
1811
|
+
// euc-jp lead to 0x00, and run these substeps:
|
|
1812
|
+
if (eucjp_lead !== 0x00) {
|
|
1813
|
+
var lead = eucjp_lead;
|
|
1814
|
+
eucjp_lead = 0x00;
|
|
1815
|
+
// 1. Let code point be null.
|
|
1816
|
+
var code_point = null;
|
|
1817
|
+
// 2. If lead and byte are both in the range 0xA1 to 0xFE,
|
|
1818
|
+
// inclusive, set code point to the index code point for (lead
|
|
1819
|
+
// − 0xA1) × 94 + byte − 0xA1 in index jis0208 if the euc-jp
|
|
1820
|
+
// jis0212 flag is unset and in index jis0212 otherwise.
|
|
1821
|
+
if (inRange(lead, 0xa1, 0xfe) && inRange(bite, 0xa1, 0xfe)) {
|
|
1822
|
+
code_point = indexCodePointFor((lead - 0xa1) * 94 + (bite - 0xa1), index(!eucjp_jis0212_flag ? 'jis0208' : 'jis0212'));
|
|
1823
|
+
}
|
|
1824
|
+
// 3. Unset the euc-jp jis0212 flag.
|
|
1825
|
+
eucjp_jis0212_flag = false;
|
|
1826
|
+
// 4. If byte is not in the range 0xA1 to 0xFE, inclusive,
|
|
1827
|
+
// prepend byte to stream.
|
|
1828
|
+
if (!inRange(bite, 0xa1, 0xfe))
|
|
1829
|
+
stream.prepend(bite);
|
|
1830
|
+
// 5. If code point is null, return error.
|
|
1831
|
+
if (code_point === null)
|
|
1832
|
+
return decoderError(fatal);
|
|
1833
|
+
// 6. Return a code point whose value is code point.
|
|
1834
|
+
return code_point;
|
|
1835
|
+
}
|
|
1836
|
+
// 6. If byte is an ASCII byte, return a code point whose value
|
|
1837
|
+
// is byte.
|
|
1838
|
+
if (isASCIIByte(bite))
|
|
1839
|
+
return bite;
|
|
1840
|
+
// 7. If byte is 0x8E, 0x8F, or in the range 0xA1 to 0xFE,
|
|
1841
|
+
// inclusive, set euc-jp lead to byte and return continue.
|
|
1842
|
+
if (bite === 0x8e || bite === 0x8f || inRange(bite, 0xa1, 0xfe)) {
|
|
1843
|
+
eucjp_lead = bite;
|
|
1844
|
+
return null;
|
|
1845
|
+
}
|
|
1846
|
+
// 8. Return error.
|
|
1847
|
+
return decoderError(fatal);
|
|
1848
|
+
};
|
|
805
1849
|
}
|
|
1850
|
+
// 13.1.2 euc-jp encoder
|
|
1851
|
+
/**
|
|
1852
|
+
* @constructor
|
|
1853
|
+
* @implements {Encoder}
|
|
1854
|
+
* @param {{fatal: boolean}} options
|
|
1855
|
+
*/
|
|
806
1856
|
function EUCJPEncoder(options) {
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
1857
|
+
var fatal = options.fatal;
|
|
1858
|
+
/**
|
|
1859
|
+
* @param {Stream} stream Input stream.
|
|
1860
|
+
* @param {number} code_point Next code point read from the stream.
|
|
1861
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
1862
|
+
*/
|
|
1863
|
+
this.handler = function (stream, code_point) {
|
|
1864
|
+
// 1. If code point is end-of-stream, return finished.
|
|
1865
|
+
if (code_point === end_of_stream)
|
|
1866
|
+
return finished;
|
|
1867
|
+
// 2. If code point is an ASCII code point, return a byte whose
|
|
1868
|
+
// value is code point.
|
|
1869
|
+
if (isASCIICodePoint(code_point))
|
|
1870
|
+
return code_point;
|
|
1871
|
+
// 3. If code point is U+00A5, return byte 0x5C.
|
|
1872
|
+
if (code_point === 0x00a5)
|
|
1873
|
+
return 0x5c;
|
|
1874
|
+
// 4. If code point is U+203E, return byte 0x7E.
|
|
1875
|
+
if (code_point === 0x203e)
|
|
1876
|
+
return 0x7e;
|
|
1877
|
+
// 5. If code point is in the range U+FF61 to U+FF9F, inclusive,
|
|
1878
|
+
// return two bytes whose values are 0x8E and code point −
|
|
1879
|
+
// 0xFF61 + 0xA1.
|
|
1880
|
+
if (inRange(code_point, 0xff61, 0xff9f))
|
|
1881
|
+
return [0x8e, code_point - 0xff61 + 0xa1];
|
|
1882
|
+
// 6. If code point is U+2212, set it to U+FF0D.
|
|
1883
|
+
if (code_point === 0x2212)
|
|
1884
|
+
code_point = 0xff0d;
|
|
1885
|
+
// 7. Let pointer be the index pointer for code point in index
|
|
1886
|
+
// jis0208.
|
|
1887
|
+
var pointer = indexPointerFor(code_point, index('jis0208'));
|
|
1888
|
+
// 8. If pointer is null, return error with code point.
|
|
1889
|
+
if (pointer === null)
|
|
1890
|
+
return encoderError(code_point);
|
|
1891
|
+
// 9. Let lead be floor(pointer / 94) + 0xA1.
|
|
1892
|
+
var lead = floor(pointer / 94) + 0xa1;
|
|
1893
|
+
// 10. Let trail be pointer % 94 + 0xA1.
|
|
1894
|
+
var trail = (pointer % 94) + 0xa1;
|
|
1895
|
+
// 11. Return two bytes whose values are lead and trail.
|
|
1896
|
+
return [lead, trail];
|
|
1897
|
+
};
|
|
821
1898
|
}
|
|
1899
|
+
/** @param {{fatal: boolean}} options */
|
|
822
1900
|
encoders['EUC-JP'] = function (options) {
|
|
823
|
-
|
|
1901
|
+
return new EUCJPEncoder(options);
|
|
824
1902
|
};
|
|
1903
|
+
/** @param {{fatal: boolean}} options */
|
|
825
1904
|
decoders['EUC-JP'] = function (options) {
|
|
826
|
-
|
|
1905
|
+
return new EUCJPDecoder(options);
|
|
827
1906
|
};
|
|
1907
|
+
// 13.2 iso-2022-jp
|
|
1908
|
+
// 13.2.1 iso-2022-jp decoder
|
|
1909
|
+
/**
|
|
1910
|
+
* @constructor
|
|
1911
|
+
* @implements {Decoder}
|
|
1912
|
+
* @param {{fatal: boolean}} options
|
|
1913
|
+
*/
|
|
828
1914
|
function ISO2022JPDecoder(options) {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1915
|
+
var fatal = options.fatal;
|
|
1916
|
+
/** @enum */
|
|
1917
|
+
var states = {
|
|
1918
|
+
ASCII: 0,
|
|
1919
|
+
Roman: 1,
|
|
1920
|
+
Katakana: 2,
|
|
1921
|
+
LeadByte: 3,
|
|
1922
|
+
TrailByte: 4,
|
|
1923
|
+
EscapeStart: 5,
|
|
1924
|
+
Escape: 6
|
|
1925
|
+
};
|
|
1926
|
+
// iso-2022-jp's decoder has an associated iso-2022-jp decoder
|
|
1927
|
+
// state (initially ASCII), iso-2022-jp decoder output state
|
|
1928
|
+
// (initially ASCII), iso-2022-jp lead (initially 0x00), and
|
|
1929
|
+
// iso-2022-jp output flag (initially unset).
|
|
1930
|
+
var /** @type {number} */ iso2022jp_decoder_state = states.ASCII,
|
|
1931
|
+
/** @type {number} */ iso2022jp_decoder_output_state = states.ASCII,
|
|
1932
|
+
/** @type {number} */ iso2022jp_lead = 0x00,
|
|
1933
|
+
/** @type {boolean} */ iso2022jp_output_flag = false;
|
|
1934
|
+
/**
|
|
1935
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
1936
|
+
* @param {number} bite The next byte read from the stream.
|
|
1937
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
1938
|
+
* decoded, or null if not enough data exists in the input
|
|
1939
|
+
* stream to decode a complete code point.
|
|
1940
|
+
*/
|
|
1941
|
+
this.handler = function (stream, bite) {
|
|
1942
|
+
// switching on iso-2022-jp decoder state:
|
|
1943
|
+
switch (iso2022jp_decoder_state) {
|
|
1944
|
+
default:
|
|
1945
|
+
case states.ASCII:
|
|
1946
|
+
// ASCII
|
|
1947
|
+
// Based on byte:
|
|
1948
|
+
// 0x1B
|
|
1949
|
+
if (bite === 0x1b) {
|
|
1950
|
+
// Set iso-2022-jp decoder state to escape start and return
|
|
1951
|
+
// continue.
|
|
1952
|
+
iso2022jp_decoder_state = states.EscapeStart;
|
|
1953
|
+
return null;
|
|
1954
|
+
}
|
|
1955
|
+
// 0x00 to 0x7F, excluding 0x0E, 0x0F, and 0x1B
|
|
1956
|
+
if (inRange(bite, 0x00, 0x7f) && bite !== 0x0e && bite !== 0x0f && bite !== 0x1b) {
|
|
1957
|
+
// Unset the iso-2022-jp output flag and return a code point
|
|
1958
|
+
// whose value is byte.
|
|
1959
|
+
iso2022jp_output_flag = false;
|
|
1960
|
+
return bite;
|
|
1961
|
+
}
|
|
1962
|
+
// end-of-stream
|
|
1963
|
+
if (bite === end_of_stream) {
|
|
1964
|
+
// Return finished.
|
|
1965
|
+
return finished;
|
|
1966
|
+
}
|
|
1967
|
+
// Otherwise
|
|
1968
|
+
// Unset the iso-2022-jp output flag and return error.
|
|
1969
|
+
iso2022jp_output_flag = false;
|
|
1970
|
+
return decoderError(fatal);
|
|
1971
|
+
case states.Roman:
|
|
1972
|
+
// Roman
|
|
1973
|
+
// Based on byte:
|
|
1974
|
+
// 0x1B
|
|
1975
|
+
if (bite === 0x1b) {
|
|
1976
|
+
// Set iso-2022-jp decoder state to escape start and return
|
|
1977
|
+
// continue.
|
|
1978
|
+
iso2022jp_decoder_state = states.EscapeStart;
|
|
1979
|
+
return null;
|
|
1980
|
+
}
|
|
1981
|
+
// 0x5C
|
|
1982
|
+
if (bite === 0x5c) {
|
|
1983
|
+
// Unset the iso-2022-jp output flag and return code point
|
|
1984
|
+
// U+00A5.
|
|
1985
|
+
iso2022jp_output_flag = false;
|
|
1986
|
+
return 0x00a5;
|
|
1987
|
+
}
|
|
1988
|
+
// 0x7E
|
|
1989
|
+
if (bite === 0x7e) {
|
|
1990
|
+
// Unset the iso-2022-jp output flag and return code point
|
|
1991
|
+
// U+203E.
|
|
1992
|
+
iso2022jp_output_flag = false;
|
|
1993
|
+
return 0x203e;
|
|
1994
|
+
}
|
|
1995
|
+
// 0x00 to 0x7F, excluding 0x0E, 0x0F, 0x1B, 0x5C, and 0x7E
|
|
1996
|
+
if (inRange(bite, 0x00, 0x7f) &&
|
|
1997
|
+
bite !== 0x0e &&
|
|
1998
|
+
bite !== 0x0f &&
|
|
1999
|
+
bite !== 0x1b &&
|
|
2000
|
+
bite !== 0x5c &&
|
|
2001
|
+
bite !== 0x7e) {
|
|
2002
|
+
// Unset the iso-2022-jp output flag and return a code point
|
|
2003
|
+
// whose value is byte.
|
|
2004
|
+
iso2022jp_output_flag = false;
|
|
2005
|
+
return bite;
|
|
2006
|
+
}
|
|
2007
|
+
// end-of-stream
|
|
2008
|
+
if (bite === end_of_stream) {
|
|
2009
|
+
// Return finished.
|
|
2010
|
+
return finished;
|
|
2011
|
+
}
|
|
2012
|
+
// Otherwise
|
|
2013
|
+
// Unset the iso-2022-jp output flag and return error.
|
|
2014
|
+
iso2022jp_output_flag = false;
|
|
2015
|
+
return decoderError(fatal);
|
|
2016
|
+
case states.Katakana:
|
|
2017
|
+
// Katakana
|
|
2018
|
+
// Based on byte:
|
|
2019
|
+
// 0x1B
|
|
2020
|
+
if (bite === 0x1b) {
|
|
2021
|
+
// Set iso-2022-jp decoder state to escape start and return
|
|
2022
|
+
// continue.
|
|
2023
|
+
iso2022jp_decoder_state = states.EscapeStart;
|
|
2024
|
+
return null;
|
|
2025
|
+
}
|
|
2026
|
+
// 0x21 to 0x5F
|
|
2027
|
+
if (inRange(bite, 0x21, 0x5f)) {
|
|
2028
|
+
// Unset the iso-2022-jp output flag and return a code point
|
|
2029
|
+
// whose value is 0xFF61 − 0x21 + byte.
|
|
2030
|
+
iso2022jp_output_flag = false;
|
|
2031
|
+
return 0xff61 - 0x21 + bite;
|
|
2032
|
+
}
|
|
2033
|
+
// end-of-stream
|
|
2034
|
+
if (bite === end_of_stream) {
|
|
2035
|
+
// Return finished.
|
|
2036
|
+
return finished;
|
|
2037
|
+
}
|
|
2038
|
+
// Otherwise
|
|
2039
|
+
// Unset the iso-2022-jp output flag and return error.
|
|
2040
|
+
iso2022jp_output_flag = false;
|
|
2041
|
+
return decoderError(fatal);
|
|
2042
|
+
case states.LeadByte:
|
|
2043
|
+
// Lead byte
|
|
2044
|
+
// Based on byte:
|
|
2045
|
+
// 0x1B
|
|
2046
|
+
if (bite === 0x1b) {
|
|
2047
|
+
// Set iso-2022-jp decoder state to escape start and return
|
|
2048
|
+
// continue.
|
|
2049
|
+
iso2022jp_decoder_state = states.EscapeStart;
|
|
2050
|
+
return null;
|
|
2051
|
+
}
|
|
2052
|
+
// 0x21 to 0x7E
|
|
2053
|
+
if (inRange(bite, 0x21, 0x7e)) {
|
|
2054
|
+
// Unset the iso-2022-jp output flag, set iso-2022-jp lead
|
|
2055
|
+
// to byte, iso-2022-jp decoder state to trail byte, and
|
|
2056
|
+
// return continue.
|
|
2057
|
+
iso2022jp_output_flag = false;
|
|
2058
|
+
iso2022jp_lead = bite;
|
|
2059
|
+
iso2022jp_decoder_state = states.TrailByte;
|
|
2060
|
+
return null;
|
|
2061
|
+
}
|
|
2062
|
+
// end-of-stream
|
|
2063
|
+
if (bite === end_of_stream) {
|
|
2064
|
+
// Return finished.
|
|
2065
|
+
return finished;
|
|
2066
|
+
}
|
|
2067
|
+
// Otherwise
|
|
2068
|
+
// Unset the iso-2022-jp output flag and return error.
|
|
2069
|
+
iso2022jp_output_flag = false;
|
|
2070
|
+
return decoderError(fatal);
|
|
2071
|
+
case states.TrailByte:
|
|
2072
|
+
// Trail byte
|
|
2073
|
+
// Based on byte:
|
|
2074
|
+
// 0x1B
|
|
2075
|
+
if (bite === 0x1b) {
|
|
2076
|
+
// Set iso-2022-jp decoder state to escape start and return
|
|
2077
|
+
// continue.
|
|
2078
|
+
iso2022jp_decoder_state = states.EscapeStart;
|
|
2079
|
+
return decoderError(fatal);
|
|
2080
|
+
}
|
|
2081
|
+
// 0x21 to 0x7E
|
|
2082
|
+
if (inRange(bite, 0x21, 0x7e)) {
|
|
2083
|
+
// 1. Set the iso-2022-jp decoder state to lead byte.
|
|
2084
|
+
iso2022jp_decoder_state = states.LeadByte;
|
|
2085
|
+
// 2. Let pointer be (iso-2022-jp lead − 0x21) × 94 + byte − 0x21.
|
|
2086
|
+
var pointer = (iso2022jp_lead - 0x21) * 94 + bite - 0x21;
|
|
2087
|
+
// 3. Let code point be the index code point for pointer in
|
|
2088
|
+
// index jis0208.
|
|
2089
|
+
var code_point = indexCodePointFor(pointer, index('jis0208'));
|
|
2090
|
+
// 4. If code point is null, return error.
|
|
2091
|
+
if (code_point === null)
|
|
2092
|
+
return decoderError(fatal);
|
|
2093
|
+
// 5. Return a code point whose value is code point.
|
|
2094
|
+
return code_point;
|
|
2095
|
+
}
|
|
2096
|
+
// end-of-stream
|
|
2097
|
+
if (bite === end_of_stream) {
|
|
2098
|
+
// Set the iso-2022-jp decoder state to lead byte, prepend
|
|
2099
|
+
// byte to stream, and return error.
|
|
2100
|
+
iso2022jp_decoder_state = states.LeadByte;
|
|
2101
|
+
stream.prepend(bite);
|
|
2102
|
+
return decoderError(fatal);
|
|
2103
|
+
}
|
|
2104
|
+
// Otherwise
|
|
2105
|
+
// Set iso-2022-jp decoder state to lead byte and return
|
|
2106
|
+
// error.
|
|
2107
|
+
iso2022jp_decoder_state = states.LeadByte;
|
|
2108
|
+
return decoderError(fatal);
|
|
2109
|
+
case states.EscapeStart:
|
|
2110
|
+
// Escape start
|
|
2111
|
+
// 1. If byte is either 0x24 or 0x28, set iso-2022-jp lead to
|
|
2112
|
+
// byte, iso-2022-jp decoder state to escape, and return
|
|
2113
|
+
// continue.
|
|
2114
|
+
if (bite === 0x24 || bite === 0x28) {
|
|
2115
|
+
iso2022jp_lead = bite;
|
|
2116
|
+
iso2022jp_decoder_state = states.Escape;
|
|
2117
|
+
return null;
|
|
2118
|
+
}
|
|
2119
|
+
// 2. Prepend byte to stream.
|
|
2120
|
+
stream.prepend(bite);
|
|
2121
|
+
// 3. Unset the iso-2022-jp output flag, set iso-2022-jp
|
|
2122
|
+
// decoder state to iso-2022-jp decoder output state, and
|
|
2123
|
+
// return error.
|
|
2124
|
+
iso2022jp_output_flag = false;
|
|
2125
|
+
iso2022jp_decoder_state = iso2022jp_decoder_output_state;
|
|
2126
|
+
return decoderError(fatal);
|
|
2127
|
+
case states.Escape:
|
|
2128
|
+
// Escape
|
|
2129
|
+
// 1. Let lead be iso-2022-jp lead and set iso-2022-jp lead to
|
|
2130
|
+
// 0x00.
|
|
2131
|
+
var lead = iso2022jp_lead;
|
|
2132
|
+
iso2022jp_lead = 0x00;
|
|
2133
|
+
// 2. Let state be null.
|
|
2134
|
+
var state = null;
|
|
2135
|
+
// 3. If lead is 0x28 and byte is 0x42, set state to ASCII.
|
|
2136
|
+
if (lead === 0x28 && bite === 0x42)
|
|
2137
|
+
state = states.ASCII;
|
|
2138
|
+
// 4. If lead is 0x28 and byte is 0x4A, set state to Roman.
|
|
2139
|
+
if (lead === 0x28 && bite === 0x4a)
|
|
2140
|
+
state = states.Roman;
|
|
2141
|
+
// 5. If lead is 0x28 and byte is 0x49, set state to Katakana.
|
|
2142
|
+
if (lead === 0x28 && bite === 0x49)
|
|
2143
|
+
state = states.Katakana;
|
|
2144
|
+
// 6. If lead is 0x24 and byte is either 0x40 or 0x42, set
|
|
2145
|
+
// state to lead byte.
|
|
2146
|
+
if (lead === 0x24 && (bite === 0x40 || bite === 0x42))
|
|
2147
|
+
state = states.LeadByte;
|
|
2148
|
+
// 7. If state is non-null, run these substeps:
|
|
2149
|
+
if (state !== null) {
|
|
2150
|
+
// 1. Set iso-2022-jp decoder state and iso-2022-jp decoder
|
|
2151
|
+
// output state to states.
|
|
2152
|
+
iso2022jp_decoder_state = iso2022jp_decoder_state = state;
|
|
2153
|
+
// 2. Let output flag be the iso-2022-jp output flag.
|
|
2154
|
+
var output_flag = iso2022jp_output_flag;
|
|
2155
|
+
// 3. Set the iso-2022-jp output flag.
|
|
2156
|
+
iso2022jp_output_flag = true;
|
|
2157
|
+
// 4. Return continue, if output flag is unset, and error
|
|
2158
|
+
// otherwise.
|
|
2159
|
+
return !output_flag ? null : decoderError(fatal);
|
|
2160
|
+
}
|
|
2161
|
+
// 8. Prepend lead and byte to stream.
|
|
2162
|
+
stream.prepend([lead, bite]);
|
|
2163
|
+
// 9. Unset the iso-2022-jp output flag, set iso-2022-jp
|
|
2164
|
+
// decoder state to iso-2022-jp decoder output state and
|
|
2165
|
+
// return error.
|
|
2166
|
+
iso2022jp_output_flag = false;
|
|
2167
|
+
iso2022jp_decoder_state = iso2022jp_decoder_output_state;
|
|
2168
|
+
return decoderError(fatal);
|
|
868
2169
|
}
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
2170
|
+
};
|
|
2171
|
+
}
|
|
2172
|
+
// 13.2.2 iso-2022-jp encoder
|
|
2173
|
+
/**
|
|
2174
|
+
* @constructor
|
|
2175
|
+
* @implements {Encoder}
|
|
2176
|
+
* @param {{fatal: boolean}} options
|
|
2177
|
+
*/
|
|
2178
|
+
function ISO2022JPEncoder(options) {
|
|
2179
|
+
var fatal = options.fatal;
|
|
2180
|
+
// iso-2022-jp's encoder has an associated iso-2022-jp encoder
|
|
2181
|
+
// state which is one of ASCII, Roman, and jis0208 (initially
|
|
2182
|
+
// ASCII).
|
|
2183
|
+
/** @enum */
|
|
2184
|
+
var states = {
|
|
2185
|
+
ASCII: 0,
|
|
2186
|
+
Roman: 1,
|
|
2187
|
+
jis0208: 2
|
|
2188
|
+
};
|
|
2189
|
+
var /** @type {number} */ iso2022jp_state = states.ASCII;
|
|
2190
|
+
/**
|
|
2191
|
+
* @param {Stream} stream Input stream.
|
|
2192
|
+
* @param {number} code_point Next code point read from the stream.
|
|
2193
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
2194
|
+
*/
|
|
2195
|
+
this.handler = function (stream, code_point) {
|
|
2196
|
+
// 1. If code point is end-of-stream and iso-2022-jp encoder
|
|
2197
|
+
// state is not ASCII, prepend code point to stream, set
|
|
2198
|
+
// iso-2022-jp encoder state to ASCII, and return three bytes
|
|
2199
|
+
// 0x1B 0x28 0x42.
|
|
2200
|
+
if (code_point === end_of_stream && iso2022jp_state !== states.ASCII) {
|
|
2201
|
+
stream.prepend(code_point);
|
|
2202
|
+
iso2022jp_state = states.ASCII;
|
|
2203
|
+
return [0x1b, 0x28, 0x42];
|
|
886
2204
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
2205
|
+
// 2. If code point is end-of-stream and iso-2022-jp encoder
|
|
2206
|
+
// state is ASCII, return finished.
|
|
2207
|
+
if (code_point === end_of_stream && iso2022jp_state === states.ASCII)
|
|
2208
|
+
return finished;
|
|
2209
|
+
// 3. If ISO-2022-JP encoder state is ASCII or Roman, and code
|
|
2210
|
+
// point is U+000E, U+000F, or U+001B, return error with U+FFFD.
|
|
2211
|
+
if ((iso2022jp_state === states.ASCII || iso2022jp_state === states.Roman) &&
|
|
2212
|
+
(code_point === 0x000e || code_point === 0x000f || code_point === 0x001b)) {
|
|
2213
|
+
return encoderError(0xfffd);
|
|
890
2214
|
}
|
|
891
|
-
|
|
892
|
-
|
|
2215
|
+
// 4. If iso-2022-jp encoder state is ASCII and code point is an
|
|
2216
|
+
// ASCII code point, return a byte whose value is code point.
|
|
2217
|
+
if (iso2022jp_state === states.ASCII && isASCIICodePoint(code_point))
|
|
2218
|
+
return code_point;
|
|
2219
|
+
// 5. If iso-2022-jp encoder state is Roman and code point is an
|
|
2220
|
+
// ASCII code point, excluding U+005C and U+007E, or is U+00A5
|
|
2221
|
+
// or U+203E, run these substeps:
|
|
2222
|
+
if (iso2022jp_state === states.Roman &&
|
|
2223
|
+
((isASCIICodePoint(code_point) && code_point !== 0x005c && code_point !== 0x007e) ||
|
|
2224
|
+
code_point == 0x00a5 ||
|
|
2225
|
+
code_point == 0x203e)) {
|
|
2226
|
+
// 1. If code point is an ASCII code point, return a byte
|
|
2227
|
+
// whose value is code point.
|
|
2228
|
+
if (isASCIICodePoint(code_point))
|
|
2229
|
+
return code_point;
|
|
2230
|
+
// 2. If code point is U+00A5, return byte 0x5C.
|
|
2231
|
+
if (code_point === 0x00a5)
|
|
2232
|
+
return 0x5c;
|
|
2233
|
+
// 3. If code point is U+203E, return byte 0x7E.
|
|
2234
|
+
if (code_point === 0x203e)
|
|
2235
|
+
return 0x7e;
|
|
893
2236
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
2237
|
+
// 6. If code point is an ASCII code point, and iso-2022-jp
|
|
2238
|
+
// encoder state is not ASCII, prepend code point to stream, set
|
|
2239
|
+
// iso-2022-jp encoder state to ASCII, and return three bytes
|
|
2240
|
+
// 0x1B 0x28 0x42.
|
|
2241
|
+
if (isASCIICodePoint(code_point) && iso2022jp_state !== states.ASCII) {
|
|
2242
|
+
stream.prepend(code_point);
|
|
2243
|
+
iso2022jp_state = states.ASCII;
|
|
2244
|
+
return [0x1b, 0x28, 0x42];
|
|
900
2245
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
2246
|
+
// 7. If code point is either U+00A5 or U+203E, and iso-2022-jp
|
|
2247
|
+
// encoder state is not Roman, prepend code point to stream, set
|
|
2248
|
+
// iso-2022-jp encoder state to Roman, and return three bytes
|
|
2249
|
+
// 0x1B 0x28 0x4A.
|
|
2250
|
+
if ((code_point === 0x00a5 || code_point === 0x203e) && iso2022jp_state !== states.Roman) {
|
|
2251
|
+
stream.prepend(code_point);
|
|
2252
|
+
iso2022jp_state = states.Roman;
|
|
2253
|
+
return [0x1b, 0x28, 0x4a];
|
|
906
2254
|
}
|
|
907
|
-
|
|
908
|
-
|
|
2255
|
+
// 8. If code point is U+2212, set it to U+FF0D.
|
|
2256
|
+
if (code_point === 0x2212)
|
|
2257
|
+
code_point = 0xff0d;
|
|
2258
|
+
// 9. Let pointer be the index pointer for code point in index
|
|
2259
|
+
// jis0208.
|
|
2260
|
+
var pointer = indexPointerFor(code_point, index('jis0208'));
|
|
2261
|
+
// 10. If pointer is null, return error with code point.
|
|
2262
|
+
if (pointer === null)
|
|
2263
|
+
return encoderError(code_point);
|
|
2264
|
+
// 11. If iso-2022-jp encoder state is not jis0208, prepend code
|
|
2265
|
+
// point to stream, set iso-2022-jp encoder state to jis0208,
|
|
2266
|
+
// and return three bytes 0x1B 0x24 0x42.
|
|
2267
|
+
if (iso2022jp_state !== states.jis0208) {
|
|
2268
|
+
stream.prepend(code_point);
|
|
2269
|
+
iso2022jp_state = states.jis0208;
|
|
2270
|
+
return [0x1b, 0x24, 0x42];
|
|
909
2271
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if (inRange(bite, 0x21, 0x7e)) {
|
|
918
|
-
iso2022jp_decoder_state = states.LeadByte;
|
|
919
|
-
var pointer = (iso2022jp_lead - 0x21) * 94 + bite - 0x21;
|
|
920
|
-
var code_point = indexCodePointFor(pointer, index('jis0208'));
|
|
921
|
-
if (code_point === null) return decoderError(fatal);
|
|
922
|
-
return code_point;
|
|
923
|
-
}
|
|
924
|
-
if (bite === end_of_stream) {
|
|
925
|
-
iso2022jp_decoder_state = states.LeadByte;
|
|
926
|
-
stream.prepend(bite);
|
|
927
|
-
return decoderError(fatal);
|
|
928
|
-
}
|
|
929
|
-
iso2022jp_decoder_state = states.LeadByte;
|
|
930
|
-
return decoderError(fatal);
|
|
931
|
-
case states.EscapeStart:
|
|
932
|
-
if (bite === 0x24 || bite === 0x28) {
|
|
933
|
-
iso2022jp_lead = bite;
|
|
934
|
-
iso2022jp_decoder_state = states.Escape;
|
|
935
|
-
return null;
|
|
936
|
-
}
|
|
937
|
-
stream.prepend(bite);
|
|
938
|
-
iso2022jp_output_flag = false;
|
|
939
|
-
iso2022jp_decoder_state = iso2022jp_decoder_output_state;
|
|
940
|
-
return decoderError(fatal);
|
|
941
|
-
case states.Escape:
|
|
942
|
-
var lead = iso2022jp_lead;
|
|
943
|
-
iso2022jp_lead = 0x00;
|
|
944
|
-
var state = null;
|
|
945
|
-
if (lead === 0x28 && bite === 0x42) state = states.ASCII;
|
|
946
|
-
if (lead === 0x28 && bite === 0x4a) state = states.Roman;
|
|
947
|
-
if (lead === 0x28 && bite === 0x49) state = states.Katakana;
|
|
948
|
-
if (lead === 0x24 && (bite === 0x40 || bite === 0x42)) state = states.LeadByte;
|
|
949
|
-
if (state !== null) {
|
|
950
|
-
iso2022jp_decoder_state = iso2022jp_decoder_state = state;
|
|
951
|
-
var output_flag = iso2022jp_output_flag;
|
|
952
|
-
iso2022jp_output_flag = true;
|
|
953
|
-
return !output_flag ? null : decoderError(fatal);
|
|
954
|
-
}
|
|
955
|
-
stream.prepend([lead, bite]);
|
|
956
|
-
iso2022jp_output_flag = false;
|
|
957
|
-
iso2022jp_decoder_state = iso2022jp_decoder_output_state;
|
|
958
|
-
return decoderError(fatal);
|
|
959
|
-
}
|
|
960
|
-
};
|
|
961
|
-
}
|
|
962
|
-
function ISO2022JPEncoder(options) {
|
|
963
|
-
var fatal = options.fatal;
|
|
964
|
-
var states = {
|
|
965
|
-
ASCII: 0,
|
|
966
|
-
Roman: 1,
|
|
967
|
-
jis0208: 2
|
|
968
|
-
};
|
|
969
|
-
var iso2022jp_state = states.ASCII;
|
|
970
|
-
this.handler = function (stream, code_point) {
|
|
971
|
-
if (code_point === end_of_stream && iso2022jp_state !== states.ASCII) {
|
|
972
|
-
stream.prepend(code_point);
|
|
973
|
-
iso2022jp_state = states.ASCII;
|
|
974
|
-
return [0x1b, 0x28, 0x42];
|
|
975
|
-
}
|
|
976
|
-
if (code_point === end_of_stream && iso2022jp_state === states.ASCII) return finished;
|
|
977
|
-
if ((iso2022jp_state === states.ASCII || iso2022jp_state === states.Roman) && (code_point === 0x000e || code_point === 0x000f || code_point === 0x001b)) {
|
|
978
|
-
return encoderError(0xfffd);
|
|
979
|
-
}
|
|
980
|
-
if (iso2022jp_state === states.ASCII && isASCIICodePoint(code_point)) return code_point;
|
|
981
|
-
if (iso2022jp_state === states.Roman && (isASCIICodePoint(code_point) && code_point !== 0x005c && code_point !== 0x007e || code_point == 0x00a5 || code_point == 0x203e)) {
|
|
982
|
-
if (isASCIICodePoint(code_point)) return code_point;
|
|
983
|
-
if (code_point === 0x00a5) return 0x5c;
|
|
984
|
-
if (code_point === 0x203e) return 0x7e;
|
|
985
|
-
}
|
|
986
|
-
if (isASCIICodePoint(code_point) && iso2022jp_state !== states.ASCII) {
|
|
987
|
-
stream.prepend(code_point);
|
|
988
|
-
iso2022jp_state = states.ASCII;
|
|
989
|
-
return [0x1b, 0x28, 0x42];
|
|
990
|
-
}
|
|
991
|
-
if ((code_point === 0x00a5 || code_point === 0x203e) && iso2022jp_state !== states.Roman) {
|
|
992
|
-
stream.prepend(code_point);
|
|
993
|
-
iso2022jp_state = states.Roman;
|
|
994
|
-
return [0x1b, 0x28, 0x4a];
|
|
995
|
-
}
|
|
996
|
-
if (code_point === 0x2212) code_point = 0xff0d;
|
|
997
|
-
var pointer = indexPointerFor(code_point, index('jis0208'));
|
|
998
|
-
if (pointer === null) return encoderError(code_point);
|
|
999
|
-
if (iso2022jp_state !== states.jis0208) {
|
|
1000
|
-
stream.prepend(code_point);
|
|
1001
|
-
iso2022jp_state = states.jis0208;
|
|
1002
|
-
return [0x1b, 0x24, 0x42];
|
|
1003
|
-
}
|
|
1004
|
-
var lead = floor(pointer / 94) + 0x21;
|
|
1005
|
-
var trail = pointer % 94 + 0x21;
|
|
1006
|
-
return [lead, trail];
|
|
1007
|
-
};
|
|
2272
|
+
// 12. Let lead be floor(pointer / 94) + 0x21.
|
|
2273
|
+
var lead = floor(pointer / 94) + 0x21;
|
|
2274
|
+
// 13. Let trail be pointer % 94 + 0x21.
|
|
2275
|
+
var trail = (pointer % 94) + 0x21;
|
|
2276
|
+
// 14. Return two bytes whose values are lead and trail.
|
|
2277
|
+
return [lead, trail];
|
|
2278
|
+
};
|
|
1008
2279
|
}
|
|
2280
|
+
/** @param {{fatal: boolean}} options */
|
|
1009
2281
|
encoders['ISO-2022-JP'] = function (options) {
|
|
1010
|
-
|
|
2282
|
+
return new ISO2022JPEncoder(options);
|
|
1011
2283
|
};
|
|
2284
|
+
/** @param {{fatal: boolean}} options */
|
|
1012
2285
|
decoders['ISO-2022-JP'] = function (options) {
|
|
1013
|
-
|
|
2286
|
+
return new ISO2022JPDecoder(options);
|
|
1014
2287
|
};
|
|
2288
|
+
// 13.3 Shift_JIS
|
|
2289
|
+
// 13.3.1 Shift_JIS decoder
|
|
2290
|
+
/**
|
|
2291
|
+
* @constructor
|
|
2292
|
+
* @implements {Decoder}
|
|
2293
|
+
* @param {{fatal: boolean}} options
|
|
2294
|
+
*/
|
|
1015
2295
|
function ShiftJISDecoder(options) {
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
2296
|
+
var fatal = options.fatal;
|
|
2297
|
+
// Shift_JIS's decoder has an associated Shift_JIS lead (initially
|
|
2298
|
+
// 0x00).
|
|
2299
|
+
var /** @type {number} */ Shift_JIS_lead = 0x00;
|
|
2300
|
+
/**
|
|
2301
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
2302
|
+
* @param {number} bite The next byte read from the stream.
|
|
2303
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
2304
|
+
* decoded, or null if not enough data exists in the input
|
|
2305
|
+
* stream to decode a complete code point.
|
|
2306
|
+
*/
|
|
2307
|
+
this.handler = function (stream, bite) {
|
|
2308
|
+
// 1. If byte is end-of-stream and Shift_JIS lead is not 0x00,
|
|
2309
|
+
// set Shift_JIS lead to 0x00 and return error.
|
|
2310
|
+
if (bite === end_of_stream && Shift_JIS_lead !== 0x00) {
|
|
2311
|
+
Shift_JIS_lead = 0x00;
|
|
2312
|
+
return decoderError(fatal);
|
|
2313
|
+
}
|
|
2314
|
+
// 2. If byte is end-of-stream and Shift_JIS lead is 0x00,
|
|
2315
|
+
// return finished.
|
|
2316
|
+
if (bite === end_of_stream && Shift_JIS_lead === 0x00)
|
|
2317
|
+
return finished;
|
|
2318
|
+
// 3. If Shift_JIS lead is not 0x00, let lead be Shift_JIS lead,
|
|
2319
|
+
// let pointer be null, set Shift_JIS lead to 0x00, and then run
|
|
2320
|
+
// these substeps:
|
|
2321
|
+
if (Shift_JIS_lead !== 0x00) {
|
|
2322
|
+
var lead = Shift_JIS_lead;
|
|
2323
|
+
var pointer = null;
|
|
2324
|
+
Shift_JIS_lead = 0x00;
|
|
2325
|
+
// 1. Let offset be 0x40, if byte is less than 0x7F, and 0x41
|
|
2326
|
+
// otherwise.
|
|
2327
|
+
var offset = bite < 0x7f ? 0x40 : 0x41;
|
|
2328
|
+
// 2. Let lead offset be 0x81, if lead is less than 0xA0, and
|
|
2329
|
+
// 0xC1 otherwise.
|
|
2330
|
+
var lead_offset = lead < 0xa0 ? 0x81 : 0xc1;
|
|
2331
|
+
// 3. If byte is in the range 0x40 to 0x7E, inclusive, or 0x80
|
|
2332
|
+
// to 0xFC, inclusive, set pointer to (lead − lead offset) ×
|
|
2333
|
+
// 188 + byte − offset.
|
|
2334
|
+
if (inRange(bite, 0x40, 0x7e) || inRange(bite, 0x80, 0xfc))
|
|
2335
|
+
pointer = (lead - lead_offset) * 188 + bite - offset;
|
|
2336
|
+
// 4. If pointer is in the range 8836 to 10715, inclusive,
|
|
2337
|
+
// return a code point whose value is 0xE000 − 8836 + pointer.
|
|
2338
|
+
if (inRange(pointer, 8836, 10715))
|
|
2339
|
+
return 0xe000 - 8836 + pointer;
|
|
2340
|
+
// 5. Let code point be null, if pointer is null, and the
|
|
2341
|
+
// index code point for pointer in index jis0208 otherwise.
|
|
2342
|
+
var code_point = pointer === null ? null : indexCodePointFor(pointer, index('jis0208'));
|
|
2343
|
+
// 6. If code point is null and byte is an ASCII byte, prepend
|
|
2344
|
+
// byte to stream.
|
|
2345
|
+
if (code_point === null && isASCIIByte(bite))
|
|
2346
|
+
stream.prepend(bite);
|
|
2347
|
+
// 7. If code point is null, return error.
|
|
2348
|
+
if (code_point === null)
|
|
2349
|
+
return decoderError(fatal);
|
|
2350
|
+
// 8. Return a code point whose value is code point.
|
|
2351
|
+
return code_point;
|
|
2352
|
+
}
|
|
2353
|
+
// 4. If byte is an ASCII byte or 0x80, return a code point
|
|
2354
|
+
// whose value is byte.
|
|
2355
|
+
if (isASCIIByte(bite) || bite === 0x80)
|
|
2356
|
+
return bite;
|
|
2357
|
+
// 5. If byte is in the range 0xA1 to 0xDF, inclusive, return a
|
|
2358
|
+
// code point whose value is 0xFF61 − 0xA1 + byte.
|
|
2359
|
+
if (inRange(bite, 0xa1, 0xdf))
|
|
2360
|
+
return 0xff61 - 0xa1 + bite;
|
|
2361
|
+
// 6. If byte is in the range 0x81 to 0x9F, inclusive, or 0xE0
|
|
2362
|
+
// to 0xFC, inclusive, set Shift_JIS lead to byte and return
|
|
2363
|
+
// continue.
|
|
2364
|
+
if (inRange(bite, 0x81, 0x9f) || inRange(bite, 0xe0, 0xfc)) {
|
|
2365
|
+
Shift_JIS_lead = bite;
|
|
2366
|
+
return null;
|
|
2367
|
+
}
|
|
2368
|
+
// 7. Return error.
|
|
2369
|
+
return decoderError(fatal);
|
|
2370
|
+
};
|
|
1045
2371
|
}
|
|
2372
|
+
// 13.3.2 Shift_JIS encoder
|
|
2373
|
+
/**
|
|
2374
|
+
* @constructor
|
|
2375
|
+
* @implements {Encoder}
|
|
2376
|
+
* @param {{fatal: boolean}} options
|
|
2377
|
+
*/
|
|
1046
2378
|
function ShiftJISEncoder(options) {
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
2379
|
+
var fatal = options.fatal;
|
|
2380
|
+
/**
|
|
2381
|
+
* @param {Stream} stream Input stream.
|
|
2382
|
+
* @param {number} code_point Next code point read from the stream.
|
|
2383
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
2384
|
+
*/
|
|
2385
|
+
this.handler = function (stream, code_point) {
|
|
2386
|
+
// 1. If code point is end-of-stream, return finished.
|
|
2387
|
+
if (code_point === end_of_stream)
|
|
2388
|
+
return finished;
|
|
2389
|
+
// 2. If code point is an ASCII code point or U+0080, return a
|
|
2390
|
+
// byte whose value is code point.
|
|
2391
|
+
if (isASCIICodePoint(code_point) || code_point === 0x0080)
|
|
2392
|
+
return code_point;
|
|
2393
|
+
// 3. If code point is U+00A5, return byte 0x5C.
|
|
2394
|
+
if (code_point === 0x00a5)
|
|
2395
|
+
return 0x5c;
|
|
2396
|
+
// 4. If code point is U+203E, return byte 0x7E.
|
|
2397
|
+
if (code_point === 0x203e)
|
|
2398
|
+
return 0x7e;
|
|
2399
|
+
// 5. If code point is in the range U+FF61 to U+FF9F, inclusive,
|
|
2400
|
+
// return a byte whose value is code point − 0xFF61 + 0xA1.
|
|
2401
|
+
if (inRange(code_point, 0xff61, 0xff9f))
|
|
2402
|
+
return code_point - 0xff61 + 0xa1;
|
|
2403
|
+
// 6. If code point is U+2212, set it to U+FF0D.
|
|
2404
|
+
if (code_point === 0x2212)
|
|
2405
|
+
code_point = 0xff0d;
|
|
2406
|
+
// 7. Let pointer be the index Shift_JIS pointer for code point.
|
|
2407
|
+
var pointer = indexShiftJISPointerFor(code_point);
|
|
2408
|
+
// 8. If pointer is null, return error with code point.
|
|
2409
|
+
if (pointer === null)
|
|
2410
|
+
return encoderError(code_point);
|
|
2411
|
+
// 9. Let lead be floor(pointer / 188).
|
|
2412
|
+
var lead = floor(pointer / 188);
|
|
2413
|
+
// 10. Let lead offset be 0x81, if lead is less than 0x1F, and
|
|
2414
|
+
// 0xC1 otherwise.
|
|
2415
|
+
var lead_offset = lead < 0x1f ? 0x81 : 0xc1;
|
|
2416
|
+
// 11. Let trail be pointer % 188.
|
|
2417
|
+
var trail = pointer % 188;
|
|
2418
|
+
// 12. Let offset be 0x40, if trail is less than 0x3F, and 0x41
|
|
2419
|
+
// otherwise.
|
|
2420
|
+
var offset = trail < 0x3f ? 0x40 : 0x41;
|
|
2421
|
+
// 13. Return two bytes whose values are lead + lead offset and
|
|
2422
|
+
// trail + offset.
|
|
2423
|
+
return [lead + lead_offset, trail + offset];
|
|
2424
|
+
};
|
|
1063
2425
|
}
|
|
2426
|
+
/** @param {{fatal: boolean}} options */
|
|
1064
2427
|
encoders['Shift_JIS'] = function (options) {
|
|
1065
|
-
|
|
2428
|
+
return new ShiftJISEncoder(options);
|
|
1066
2429
|
};
|
|
2430
|
+
/** @param {{fatal: boolean}} options */
|
|
1067
2431
|
decoders['Shift_JIS'] = function (options) {
|
|
1068
|
-
|
|
2432
|
+
return new ShiftJISDecoder(options);
|
|
1069
2433
|
};
|
|
2434
|
+
//
|
|
2435
|
+
// 14. Legacy multi-byte Korean encodings
|
|
2436
|
+
//
|
|
2437
|
+
// 14.1 euc-kr
|
|
2438
|
+
// 14.1.1 euc-kr decoder
|
|
2439
|
+
/**
|
|
2440
|
+
* @constructor
|
|
2441
|
+
* @implements {Decoder}
|
|
2442
|
+
* @param {{fatal: boolean}} options
|
|
2443
|
+
*/
|
|
1070
2444
|
function EUCKRDecoder(options) {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
2445
|
+
var fatal = options.fatal;
|
|
2446
|
+
// euc-kr's decoder has an associated euc-kr lead (initially 0x00).
|
|
2447
|
+
var /** @type {number} */ euckr_lead = 0x00;
|
|
2448
|
+
/**
|
|
2449
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
2450
|
+
* @param {number} bite The next byte read from the stream.
|
|
2451
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
2452
|
+
* decoded, or null if not enough data exists in the input
|
|
2453
|
+
* stream to decode a complete code point.
|
|
2454
|
+
*/
|
|
2455
|
+
this.handler = function (stream, bite) {
|
|
2456
|
+
// 1. If byte is end-of-stream and euc-kr lead is not 0x00, set
|
|
2457
|
+
// euc-kr lead to 0x00 and return error.
|
|
2458
|
+
if (bite === end_of_stream && euckr_lead !== 0) {
|
|
2459
|
+
euckr_lead = 0x00;
|
|
2460
|
+
return decoderError(fatal);
|
|
2461
|
+
}
|
|
2462
|
+
// 2. If byte is end-of-stream and euc-kr lead is 0x00, return
|
|
2463
|
+
// finished.
|
|
2464
|
+
if (bite === end_of_stream && euckr_lead === 0)
|
|
2465
|
+
return finished;
|
|
2466
|
+
// 3. If euc-kr lead is not 0x00, let lead be euc-kr lead, let
|
|
2467
|
+
// pointer be null, set euc-kr lead to 0x00, and then run these
|
|
2468
|
+
// substeps:
|
|
2469
|
+
if (euckr_lead !== 0x00) {
|
|
2470
|
+
var lead = euckr_lead;
|
|
2471
|
+
var pointer = null;
|
|
2472
|
+
euckr_lead = 0x00;
|
|
2473
|
+
// 1. If byte is in the range 0x41 to 0xFE, inclusive, set
|
|
2474
|
+
// pointer to (lead − 0x81) × 190 + (byte − 0x41).
|
|
2475
|
+
if (inRange(bite, 0x41, 0xfe))
|
|
2476
|
+
pointer = (lead - 0x81) * 190 + (bite - 0x41);
|
|
2477
|
+
// 2. Let code point be null, if pointer is null, and the
|
|
2478
|
+
// index code point for pointer in index euc-kr otherwise.
|
|
2479
|
+
var code_point = pointer === null ? null : indexCodePointFor(pointer, index('euc-kr'));
|
|
2480
|
+
// 3. If code point is null and byte is an ASCII byte, prepend
|
|
2481
|
+
// byte to stream.
|
|
2482
|
+
if (pointer === null && isASCIIByte(bite))
|
|
2483
|
+
stream.prepend(bite);
|
|
2484
|
+
// 4. If code point is null, return error.
|
|
2485
|
+
if (code_point === null)
|
|
2486
|
+
return decoderError(fatal);
|
|
2487
|
+
// 5. Return a code point whose value is code point.
|
|
2488
|
+
return code_point;
|
|
2489
|
+
}
|
|
2490
|
+
// 4. If byte is an ASCII byte, return a code point whose value
|
|
2491
|
+
// is byte.
|
|
2492
|
+
if (isASCIIByte(bite))
|
|
2493
|
+
return bite;
|
|
2494
|
+
// 5. If byte is in the range 0x81 to 0xFE, inclusive, set
|
|
2495
|
+
// euc-kr lead to byte and return continue.
|
|
2496
|
+
if (inRange(bite, 0x81, 0xfe)) {
|
|
2497
|
+
euckr_lead = bite;
|
|
2498
|
+
return null;
|
|
2499
|
+
}
|
|
2500
|
+
// 6. Return error.
|
|
2501
|
+
return decoderError(fatal);
|
|
2502
|
+
};
|
|
1096
2503
|
}
|
|
2504
|
+
// 14.1.2 euc-kr encoder
|
|
2505
|
+
/**
|
|
2506
|
+
* @constructor
|
|
2507
|
+
* @implements {Encoder}
|
|
2508
|
+
* @param {{fatal: boolean}} options
|
|
2509
|
+
*/
|
|
1097
2510
|
function EUCKREncoder(options) {
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
2511
|
+
var fatal = options.fatal;
|
|
2512
|
+
/**
|
|
2513
|
+
* @param {Stream} stream Input stream.
|
|
2514
|
+
* @param {number} code_point Next code point read from the stream.
|
|
2515
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
2516
|
+
*/
|
|
2517
|
+
this.handler = function (stream, code_point) {
|
|
2518
|
+
// 1. If code point is end-of-stream, return finished.
|
|
2519
|
+
if (code_point === end_of_stream)
|
|
2520
|
+
return finished;
|
|
2521
|
+
// 2. If code point is an ASCII code point, return a byte whose
|
|
2522
|
+
// value is code point.
|
|
2523
|
+
if (isASCIICodePoint(code_point))
|
|
2524
|
+
return code_point;
|
|
2525
|
+
// 3. Let pointer be the index pointer for code point in index
|
|
2526
|
+
// euc-kr.
|
|
2527
|
+
var pointer = indexPointerFor(code_point, index('euc-kr'));
|
|
2528
|
+
// 4. If pointer is null, return error with code point.
|
|
2529
|
+
if (pointer === null)
|
|
2530
|
+
return encoderError(code_point);
|
|
2531
|
+
// 5. Let lead be floor(pointer / 190) + 0x81.
|
|
2532
|
+
var lead = floor(pointer / 190) + 0x81;
|
|
2533
|
+
// 6. Let trail be pointer % 190 + 0x41.
|
|
2534
|
+
var trail = (pointer % 190) + 0x41;
|
|
2535
|
+
// 7. Return two bytes whose values are lead and trail.
|
|
2536
|
+
return [lead, trail];
|
|
2537
|
+
};
|
|
1108
2538
|
}
|
|
2539
|
+
/** @param {{fatal: boolean}} options */
|
|
1109
2540
|
encoders['EUC-KR'] = function (options) {
|
|
1110
|
-
|
|
2541
|
+
return new EUCKREncoder(options);
|
|
1111
2542
|
};
|
|
2543
|
+
/** @param {{fatal: boolean}} options */
|
|
1112
2544
|
decoders['EUC-KR'] = function (options) {
|
|
1113
|
-
|
|
2545
|
+
return new EUCKRDecoder(options);
|
|
1114
2546
|
};
|
|
2547
|
+
//
|
|
2548
|
+
// 15. Legacy miscellaneous encodings
|
|
2549
|
+
//
|
|
2550
|
+
// 15.1 replacement
|
|
2551
|
+
// Not needed - API throws RangeError
|
|
2552
|
+
// 15.2 Common infrastructure for utf-16be and utf-16le
|
|
2553
|
+
/**
|
|
2554
|
+
* @param {number} code_unit
|
|
2555
|
+
* @param {boolean} utf16be
|
|
2556
|
+
* @return {!Array.<number>} bytes
|
|
2557
|
+
*/
|
|
1115
2558
|
function convertCodeUnitToBytes(code_unit, utf16be) {
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
2559
|
+
// 1. Let byte1 be code unit >> 8.
|
|
2560
|
+
var byte1 = code_unit >> 8;
|
|
2561
|
+
// 2. Let byte2 be code unit & 0x00FF.
|
|
2562
|
+
var byte2 = code_unit & 0x00ff;
|
|
2563
|
+
// 3. Then return the bytes in order:
|
|
2564
|
+
// utf-16be flag is set: byte1, then byte2.
|
|
2565
|
+
if (utf16be)
|
|
2566
|
+
return [byte1, byte2];
|
|
2567
|
+
// utf-16be flag is unset: byte2, then byte1.
|
|
2568
|
+
return [byte2, byte1];
|
|
1120
2569
|
}
|
|
2570
|
+
// 15.2.1 shared utf-16 decoder
|
|
2571
|
+
/**
|
|
2572
|
+
* @constructor
|
|
2573
|
+
* @implements {Decoder}
|
|
2574
|
+
* @param {boolean} utf16_be True if big-endian, false if little-endian.
|
|
2575
|
+
* @param {{fatal: boolean}} options
|
|
2576
|
+
*/
|
|
1121
2577
|
function UTF16Decoder(utf16_be, options) {
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
utf16_lead_surrogate = null;
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
2578
|
+
var fatal = options.fatal;
|
|
2579
|
+
var /** @type {?number} */ utf16_lead_byte = null,
|
|
2580
|
+
/** @type {?number} */ utf16_lead_surrogate = null;
|
|
2581
|
+
/**
|
|
2582
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
2583
|
+
* @param {number} bite The next byte read from the stream.
|
|
2584
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
2585
|
+
* decoded, or null if not enough data exists in the input
|
|
2586
|
+
* stream to decode a complete code point.
|
|
2587
|
+
*/
|
|
2588
|
+
this.handler = function (stream, bite) {
|
|
2589
|
+
// 1. If byte is end-of-stream and either utf-16 lead byte or
|
|
2590
|
+
// utf-16 lead surrogate is not null, set utf-16 lead byte and
|
|
2591
|
+
// utf-16 lead surrogate to null, and return error.
|
|
2592
|
+
if (bite === end_of_stream && (utf16_lead_byte !== null || utf16_lead_surrogate !== null)) {
|
|
2593
|
+
return decoderError(fatal);
|
|
2594
|
+
}
|
|
2595
|
+
// 2. If byte is end-of-stream and utf-16 lead byte and utf-16
|
|
2596
|
+
// lead surrogate are null, return finished.
|
|
2597
|
+
if (bite === end_of_stream && utf16_lead_byte === null && utf16_lead_surrogate === null) {
|
|
2598
|
+
return finished;
|
|
2599
|
+
}
|
|
2600
|
+
// 3. If utf-16 lead byte is null, set utf-16 lead byte to byte
|
|
2601
|
+
// and return continue.
|
|
2602
|
+
if (utf16_lead_byte === null) {
|
|
2603
|
+
utf16_lead_byte = bite;
|
|
2604
|
+
return null;
|
|
2605
|
+
}
|
|
2606
|
+
// 4. Let code unit be the result of:
|
|
2607
|
+
var code_unit;
|
|
2608
|
+
if (utf16_be) {
|
|
2609
|
+
// utf-16be decoder flag is set
|
|
2610
|
+
// (utf-16 lead byte << 8) + byte.
|
|
2611
|
+
code_unit = (utf16_lead_byte << 8) + bite;
|
|
2612
|
+
}
|
|
2613
|
+
else {
|
|
2614
|
+
// utf-16be decoder flag is unset
|
|
2615
|
+
// (byte << 8) + utf-16 lead byte.
|
|
2616
|
+
code_unit = (bite << 8) + utf16_lead_byte;
|
|
2617
|
+
}
|
|
2618
|
+
// Then set utf-16 lead byte to null.
|
|
2619
|
+
utf16_lead_byte = null;
|
|
2620
|
+
// 5. If utf-16 lead surrogate is not null, let lead surrogate
|
|
2621
|
+
// be utf-16 lead surrogate, set utf-16 lead surrogate to null,
|
|
2622
|
+
// and then run these substeps:
|
|
2623
|
+
if (utf16_lead_surrogate !== null) {
|
|
2624
|
+
var lead_surrogate = utf16_lead_surrogate;
|
|
2625
|
+
utf16_lead_surrogate = null;
|
|
2626
|
+
// 1. If code unit is in the range U+DC00 to U+DFFF,
|
|
2627
|
+
// inclusive, return a code point whose value is 0x10000 +
|
|
2628
|
+
// ((lead surrogate − 0xD800) << 10) + (code unit − 0xDC00).
|
|
2629
|
+
if (inRange(code_unit, 0xdc00, 0xdfff)) {
|
|
2630
|
+
return 0x10000 + (lead_surrogate - 0xd800) * 0x400 + (code_unit - 0xdc00);
|
|
2631
|
+
}
|
|
2632
|
+
// 2. Prepend the sequence resulting of converting code unit
|
|
2633
|
+
// to bytes using utf-16be decoder flag to stream and return
|
|
2634
|
+
// error.
|
|
2635
|
+
stream.prepend(convertCodeUnitToBytes(code_unit, utf16_be));
|
|
2636
|
+
return decoderError(fatal);
|
|
2637
|
+
}
|
|
2638
|
+
// 6. If code unit is in the range U+D800 to U+DBFF, inclusive,
|
|
2639
|
+
// set utf-16 lead surrogate to code unit and return continue.
|
|
2640
|
+
if (inRange(code_unit, 0xd800, 0xdbff)) {
|
|
2641
|
+
utf16_lead_surrogate = code_unit;
|
|
2642
|
+
return null;
|
|
2643
|
+
}
|
|
2644
|
+
// 7. If code unit is in the range U+DC00 to U+DFFF, inclusive,
|
|
2645
|
+
// return error.
|
|
2646
|
+
if (inRange(code_unit, 0xdc00, 0xdfff))
|
|
2647
|
+
return decoderError(fatal);
|
|
2648
|
+
// 8. Return code point code unit.
|
|
2649
|
+
return code_unit;
|
|
2650
|
+
};
|
|
1159
2651
|
}
|
|
2652
|
+
// 15.2.2 shared utf-16 encoder
|
|
2653
|
+
/**
|
|
2654
|
+
* @constructor
|
|
2655
|
+
* @implements {Encoder}
|
|
2656
|
+
* @param {boolean} utf16_be True if big-endian, false if little-endian.
|
|
2657
|
+
* @param {{fatal: boolean}} options
|
|
2658
|
+
*/
|
|
1160
2659
|
function UTF16Encoder(utf16_be, options) {
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
2660
|
+
var fatal = options.fatal;
|
|
2661
|
+
/**
|
|
2662
|
+
* @param {Stream} stream Input stream.
|
|
2663
|
+
* @param {number} code_point Next code point read from the stream.
|
|
2664
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
2665
|
+
*/
|
|
2666
|
+
this.handler = function (stream, code_point) {
|
|
2667
|
+
// 1. If code point is end-of-stream, return finished.
|
|
2668
|
+
if (code_point === end_of_stream)
|
|
2669
|
+
return finished;
|
|
2670
|
+
// 2. If code point is in the range U+0000 to U+FFFF, inclusive,
|
|
2671
|
+
// return the sequence resulting of converting code point to
|
|
2672
|
+
// bytes using utf-16be encoder flag.
|
|
2673
|
+
if (inRange(code_point, 0x0000, 0xffff))
|
|
2674
|
+
return convertCodeUnitToBytes(code_point, utf16_be);
|
|
2675
|
+
// 3. Let lead be ((code point − 0x10000) >> 10) + 0xD800,
|
|
2676
|
+
// converted to bytes using utf-16be encoder flag.
|
|
2677
|
+
var lead = convertCodeUnitToBytes(((code_point - 0x10000) >> 10) + 0xd800, utf16_be);
|
|
2678
|
+
// 4. Let trail be ((code point − 0x10000) & 0x3FF) + 0xDC00,
|
|
2679
|
+
// converted to bytes using utf-16be encoder flag.
|
|
2680
|
+
var trail = convertCodeUnitToBytes(((code_point - 0x10000) & 0x3ff) + 0xdc00, utf16_be);
|
|
2681
|
+
// 5. Return a byte sequence of lead followed by trail.
|
|
2682
|
+
return lead.concat(trail);
|
|
2683
|
+
};
|
|
1169
2684
|
}
|
|
2685
|
+
// 15.3 utf-16be
|
|
2686
|
+
// 15.3.1 utf-16be decoder
|
|
2687
|
+
/** @param {{fatal: boolean}} options */
|
|
1170
2688
|
encoders['UTF-16BE'] = function (options) {
|
|
1171
|
-
|
|
2689
|
+
return new UTF16Encoder(true, options);
|
|
1172
2690
|
};
|
|
2691
|
+
// 15.3.2 utf-16be encoder
|
|
2692
|
+
/** @param {{fatal: boolean}} options */
|
|
1173
2693
|
decoders['UTF-16BE'] = function (options) {
|
|
1174
|
-
|
|
2694
|
+
return new UTF16Decoder(true, options);
|
|
1175
2695
|
};
|
|
2696
|
+
// 15.4 utf-16le
|
|
2697
|
+
// 15.4.1 utf-16le decoder
|
|
2698
|
+
/** @param {{fatal: boolean}} options */
|
|
1176
2699
|
encoders['UTF-16LE'] = function (options) {
|
|
1177
|
-
|
|
2700
|
+
return new UTF16Encoder(false, options);
|
|
1178
2701
|
};
|
|
2702
|
+
// 15.4.2 utf-16le encoder
|
|
2703
|
+
/** @param {{fatal: boolean}} options */
|
|
1179
2704
|
decoders['UTF-16LE'] = function (options) {
|
|
1180
|
-
|
|
2705
|
+
return new UTF16Decoder(false, options);
|
|
1181
2706
|
};
|
|
2707
|
+
// 15.5 x-user-defined
|
|
2708
|
+
// 15.5.1 x-user-defined decoder
|
|
2709
|
+
/**
|
|
2710
|
+
* @constructor
|
|
2711
|
+
* @implements {Decoder}
|
|
2712
|
+
* @param {{fatal: boolean}} options
|
|
2713
|
+
*/
|
|
1182
2714
|
function XUserDefinedDecoder(options) {
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
2715
|
+
var fatal = options.fatal;
|
|
2716
|
+
/**
|
|
2717
|
+
* @param {Stream} stream The stream of bytes being decoded.
|
|
2718
|
+
* @param {number} bite The next byte read from the stream.
|
|
2719
|
+
* @return {?(number|!Array.<number>)} The next code point(s)
|
|
2720
|
+
* decoded, or null if not enough data exists in the input
|
|
2721
|
+
* stream to decode a complete code point.
|
|
2722
|
+
*/
|
|
2723
|
+
this.handler = function (stream, bite) {
|
|
2724
|
+
// 1. If byte is end-of-stream, return finished.
|
|
2725
|
+
if (bite === end_of_stream)
|
|
2726
|
+
return finished;
|
|
2727
|
+
// 2. If byte is an ASCII byte, return a code point whose value
|
|
2728
|
+
// is byte.
|
|
2729
|
+
if (isASCIIByte(bite))
|
|
2730
|
+
return bite;
|
|
2731
|
+
// 3. Return a code point whose value is 0xF780 + byte − 0x80.
|
|
2732
|
+
return 0xf780 + bite - 0x80;
|
|
2733
|
+
};
|
|
1189
2734
|
}
|
|
2735
|
+
// 15.5.2 x-user-defined encoder
|
|
2736
|
+
/**
|
|
2737
|
+
* @constructor
|
|
2738
|
+
* @implements {Encoder}
|
|
2739
|
+
* @param {{fatal: boolean}} options
|
|
2740
|
+
*/
|
|
1190
2741
|
function XUserDefinedEncoder(options) {
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
2742
|
+
var fatal = options.fatal;
|
|
2743
|
+
/**
|
|
2744
|
+
* @param {Stream} stream Input stream.
|
|
2745
|
+
* @param {number} code_point Next code point read from the stream.
|
|
2746
|
+
* @return {(number|!Array.<number>)} Byte(s) to emit.
|
|
2747
|
+
*/
|
|
2748
|
+
this.handler = function (stream, code_point) {
|
|
2749
|
+
// 1.If code point is end-of-stream, return finished.
|
|
2750
|
+
if (code_point === end_of_stream)
|
|
2751
|
+
return finished;
|
|
2752
|
+
// 2. If code point is an ASCII code point, return a byte whose
|
|
2753
|
+
// value is code point.
|
|
2754
|
+
if (isASCIICodePoint(code_point))
|
|
2755
|
+
return code_point;
|
|
2756
|
+
// 3. If code point is in the range U+F780 to U+F7FF, inclusive,
|
|
2757
|
+
// return a byte whose value is code point − 0xF780 + 0x80.
|
|
2758
|
+
if (inRange(code_point, 0xf780, 0xf7ff))
|
|
2759
|
+
return code_point - 0xf780 + 0x80;
|
|
2760
|
+
// 4. Return error with code point.
|
|
2761
|
+
return encoderError(code_point);
|
|
2762
|
+
};
|
|
1198
2763
|
}
|
|
2764
|
+
/** @param {{fatal: boolean}} options */
|
|
1199
2765
|
encoders['x-user-defined'] = function (options) {
|
|
1200
|
-
|
|
2766
|
+
return new XUserDefinedEncoder(options);
|
|
1201
2767
|
};
|
|
2768
|
+
/** @param {{fatal: boolean}} options */
|
|
1202
2769
|
decoders['x-user-defined'] = function (options) {
|
|
1203
|
-
|
|
2770
|
+
return new XUserDefinedDecoder(options);
|
|
1204
2771
|
};
|
|
2772
|
+
// FORK
|
|
2773
|
+
// if (!globalThis['TextEncoder']) globalThis['TextEncoder'] = TextEncoder;
|
|
2774
|
+
// if (!globalThis['TextDecoder']) globalThis['TextDecoder'] = TextDecoder;
|
|
2775
|
+
// babel.config.js skip transpiling files in `libs/`
|
|
2776
|
+
// module.exports = {TextEncoder, TextDecoder};
|
|
1205
2777
|
export { TextEncoder, TextDecoder };
|
|
1206
|
-
//# sourceMappingURL=text-encoder.js.map
|