Skip to content

Commit e0bf542

Browse files
committed
Adding support for stream based on iconv-lite
1 parent f665f0d commit e0bf542

File tree

4 files changed

+43
-29
lines changed

4 files changed

+43
-29
lines changed

lib/TextDecoder-impl.js

+26-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use strict";
22

3-
const { labelToName, isSupported, decode } = require("./whatwg-encoding");
3+
const { labelToName, isSupported } = require("./whatwg-encoding");
4+
const iconvLite = require("iconv-lite");
45

56
exports.implementation = class TextDecoderImpl {
67
constructor(globalObject, [label, options = {}]) {
@@ -26,16 +27,32 @@ exports.implementation = class TextDecoderImpl {
2627
}
2728

2829
decode(input, options = {}) {
29-
if (options.stream === true) {
30-
// TODO: Implement stream support
30+
let bytes;
31+
if (input === undefined) {
32+
bytes = new Uint8Array(0);
33+
} else if (input.buffer === undefined) {
34+
bytes = Buffer.from(input);
35+
} else {
36+
bytes = input;
3137
}
32-
try {
33-
return decode(input, this._encoding, this._ignoreBOM);
34-
} catch (exception) {
35-
if (this._errorMode === "fatal") {
36-
throw new TypeError(exception);
38+
39+
let output = "";
40+
41+
if (options.stream === true) {
42+
if (this._decoder === undefined) {
43+
this._decoder = iconvLite.decodeStream(this._encoding);
44+
}
45+
this._decoder.write(input);
46+
let chunk;
47+
while ((chunk = this._decoder.read()) !== null) {
48+
output += chunk;
3749
}
38-
return exception;
50+
} else {
51+
output = iconvLite.decode(bytes, this._encoding, {
52+
stripBOM: !this.ignoreBOM
53+
});
3954
}
55+
56+
return output;
4057
}
4158
};

lib/whatwg-encoding.js

+3-11
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,22 @@ exports.labelToName = label => {
1313
};
1414

1515
// https://encoding.spec.whatwg.org/#decode
16-
exports.decode = (input, fallbackEncodingName, ignoreBOM) => {
16+
exports.decode = (buffer, fallbackEncodingName) => {
1717
let encoding = fallbackEncodingName;
1818
if (!exports.isSupported(encoding)) {
1919
throw new RangeError(`"${encoding}" is not a supported encoding name`);
2020
}
2121

22-
const bomEncoding = exports.getBOMEncoding(input);
22+
const bomEncoding = exports.getBOMEncoding(buffer);
2323
if (bomEncoding !== null) {
2424
encoding = bomEncoding;
2525
}
2626

2727
// iconv-lite will strip BOMs for us, so no need to do the stuff the spec does
2828

29-
const decodeOptions = {
30-
stripBOM: !ignoreBOM
31-
};
32-
33-
if (input.buffer !== undefined)
34-
return iconvLite.decode(input, encoding, decodeOptions);
35-
else
36-
return iconvLite.decode(Buffer.from(input), encoding, decodeOptions);
29+
return iconvLite.decode(buffer, encoding);
3730
};
3831

39-
4032
// https://encoding.spec.whatwg.org/#encode
4133
exports.encode = (buffer) => {
4234
return iconvLite.encode(buffer, "UTF-8")

scripts/get-latest-platform-tests.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -48,28 +48,33 @@ for (const file of [
4848
// Missing testharness 'createBuffer' function
4949
// "textdecoder-copy.any.js",
5050

51-
// Package 'iconv-lite' does not support 'x-mac-cyrillic'
51+
// Package 'iconv-lite' does not support fatal throw and encoding 'x-mac-cyrillic'
5252
// "textdecoder-fatal-single-byte.any.js",
5353

5454
// Stream support not implemented
55+
// Package 'iconv-lite' does not support fatal throw
5556
// "textdecoder-fatal-streaming.any.js",
5657

58+
// Package 'iconv-lite' does not support fatal throw
5759
// "textdecoder-fatal.any.js",
5860

61+
// Package 'iconv-lite'
5962
"textdecoder-ignorebom.any.js",
6063

61-
// Infinite looping
64+
// Infinite looping does not support many encodings
6265
// "textdecoder-labels.any.js",
6366

6467
// Stream support not implemented
68+
// Missing testharness 'createBuffer' function
6569
// "textdecoder-streaming.any.js",
6670

67-
// "textdecoder-utf16-surrogates.any.js"
71+
// Issue with package 'iconv-lite' not converting all inputs properly
72+
// "textdecoder-utf16-surrogates.any.js",
6873

69-
// Package 'iconv-lite' does not support 'x-mac-cyrillic', 'ISO-8859-8-I', 'ISO-2022-JP', 'x-user-defined'
74+
// Package 'iconv-lite' does not support encoding 'x-mac-cyrillic', 'ISO-8859-8-I', 'ISO-2022-JP', 'x-user-defined'
7075
// "textencoder-constructor-non-utf.any.js",
7176

72-
"textencoder-utf16-surrogates.any.js",
77+
"textencoder-utf16-surrogates.any.js"
7378

7479
// Missing testharness 'decode_test' function
7580
// "unsupported-encodings.any.js"

test/testharness.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ module.exports = {
3535
assert.deepStrictEqual([...actual], [...expected]);
3636
},
3737

38-
assert_throws(code, func) {
39-
assert.throws(func);
38+
assert_throws(code, func, message) {
39+
assert.throws(func, message);
4040
},
4141

42-
assert_throws_js(code, func) {
43-
assert.throws(func);
42+
assert_throws_js(code, func, message) {
43+
assert.throws(func, message);
4444
},
4545

4646
assert_unreached() {

0 commit comments

Comments
 (0)