| import { DEFAULT_ENCODING } from "../encoding/defaultEncoding"; | |
| import { decoders } from "../encoding/encoding-factory"; | |
| import { getEncoding } from "../encoding/encodings"; | |
| import { finished } from "../encoding/finished"; | |
| import { end_of_stream } from "../encoding/terminology"; | |
| import { codePointsToString, includes, ToDictionary } from "../encoding/utilities"; | |
| import { Stream } from "./Stream"; | |
| /** | |
| * @constructor | |
| * @param {string=} label The label of the encoding; | |
| * defaults to 'utf-8'. | |
| * @param {Object=} options | |
| */ | |
| var TextDecoder = /** @class */ (function () { | |
| function TextDecoder(label, options) { | |
| label = label !== undefined ? String(label) : DEFAULT_ENCODING; | |
| var optionsMap = ToDictionary(options); | |
| // A TextDecoder object has an associated encoding, decoder, | |
| // stream, ignore BOM flag (initially unset), BOM seen flag | |
| // (initially unset), error mode (initially replacement), and do | |
| // not flush flag (initially unset). | |
| /** @private */ | |
| this._encoding = null; | |
| /** @private @type {?Decoder} */ | |
| this._decoder = null; | |
| /** @private @type {boolean} */ | |
| this._ignoreBOM = false; | |
| /** @private @type {boolean} */ | |
| this._BOMseen = false; | |
| /** @private @type {string} */ | |
| this._error_mode = 'replacement'; | |
| /** @private @type {boolean} */ | |
| this._do_not_flush = false; | |
| // 1. Let encoding be the result of getting an encoding from | |
| // label. | |
| var encoding = getEncoding(label); | |
| // 2. If encoding is failure or replacement, throw a RangeError. | |
| if (encoding === null || encoding.name === 'replacement') | |
| throw RangeError('Unknown encoding: ' + label); | |
| if (!decoders[encoding.name]) { | |
| throw Error('Decoder not present.' + | |
| ' Did you forget to include encoding-indexes.js first?'); | |
| } | |
| // 3. Let dec be a new TextDecoder object. | |
| // const dec = this; | |
| // no need to do this as this is a proper class | |
| // now and TSC will handle transpilation to older platforms | |
| // 4. Set dec's encoding to encoding. | |
| this._encoding = encoding; | |
| // 5. If options's fatal member is true, set dec's error mode to | |
| // fatal. | |
| if (Boolean(optionsMap['fatal'])) | |
| this._error_mode = 'fatal'; | |
| // 6. If options's ignoreBOM member is true, set dec's ignore BOM | |
| // flag. | |
| if (Boolean(optionsMap['ignoreBOM'])) | |
| this._ignoreBOM = true; | |
| // For pre-ES5 runtimes: | |
| // if (!Object.defineProperty) { | |
| // this.encoding = dec._encoding.name.toLowerCase(); | |
| // this.fatal = dec._error_mode === 'fatal'; | |
| // this.ignoreBOM = dec._ignoreBOM; | |
| // } | |
| // 7. Return dec. | |
| // return dec; | |
| } | |
| Object.defineProperty(TextDecoder.prototype, "encoding", { | |
| // if (Object.defineProperty) { | |
| // The encoding attribute's getter must return encoding's name. | |
| // Object.defineProperty(TextDecoder.prototype, 'encoding', { | |
| // /** @this {TextDecoder} */ | |
| // get: function () { return this._encoding.name.toLowerCase(); } | |
| // }); | |
| get: function () { | |
| return this._encoding.name.toLowerCase(); | |
| }, | |
| enumerable: true, | |
| configurable: true | |
| }); | |
| Object.defineProperty(TextDecoder.prototype, "fatal", { | |
| // The fatal attribute's getter must return true if error mode | |
| // is fatal, and false otherwise. | |
| // Object.defineProperty(TextDecoder.prototype, 'fatal', { | |
| // /** @this {TextDecoder} */ | |
| // get: function () { return this._error_mode === 'fatal'; } | |
| // }); | |
| get: function () { | |
| return this._error_mode === 'fatal'; | |
| }, | |
| enumerable: true, | |
| configurable: true | |
| }); | |
| Object.defineProperty(TextDecoder.prototype, "ignoreBOM", { | |
| // The ignoreBOM attribute's getter must return true if ignore | |
| // BOM flag is set, and false otherwise. | |
| // Object.defineProperty(TextDecoder.prototype, 'ignoreBOM', { | |
| // /** @this {TextDecoder} */ | |
| // get: function () { return this._ignoreBOM; } | |
| // }); | |
| get: function () { | |
| return this._ignoreBOM; | |
| }, | |
| enumerable: true, | |
| configurable: true | |
| }); | |
| // } | |
| /** | |
| * @param {BufferSource=} input The buffer of bytes to decode. | |
| * @param {Object=} options | |
| * @return {string} The decoded string. | |
| */ | |
| TextDecoder.prototype.decode = function (input, options) { | |
| var bytes = getBytesFromInput(input); | |
| var optionsMap = ToDictionary(options); | |
| // 1. If the do not flush flag is unset, set decoder to a new | |
| // encoding's decoder, set stream to a new stream, and unset the | |
| // BOM seen flag. | |
| if (!this._do_not_flush) { | |
| this._decoder = decoders[this._encoding.name]({ | |
| fatal: this._error_mode === 'fatal' | |
| }); | |
| this._BOMseen = false; | |
| } | |
| // 2. If options's stream is true, set the do not flush flag, and | |
| // unset the do not flush flag otherwise. | |
| this._do_not_flush = Boolean(optionsMap['stream']); | |
| // 3. If input is given, push a copy of input to stream. | |
| // TODO: Align with spec algorithm - maintain stream on instance. | |
| var input_stream = new Stream(bytes); | |
| // 4. Let output be a new stream. | |
| var output = []; | |
| /** @type {?(number|!Array.<number>)} */ | |
| var result; | |
| // 5. While true: | |
| while (true) { | |
| // 1. Let token be the result of reading from stream. | |
| var token = input_stream.read(); | |
| // 2. If token is end-of-stream and the do not flush flag is | |
| // set, return output, serialized. | |
| // TODO: Align with spec algorithm. | |
| if (token === end_of_stream) | |
| break; | |
| // 3. Otherwise, run these subsubsteps: | |
| // 1. Let result be the result of processing token for decoder, | |
| // stream, output, and error mode. | |
| result = this._decoder.handler(input_stream, token); | |
| // 2. If result is finished, return output, serialized. | |
| if (result === finished) | |
| break; | |
| if (result !== null) { | |
| if (Array.isArray(result)) | |
| output.push.apply(output, /**@type {!Array.<number>}*/ (result)); | |
| else | |
| output.push(result); | |
| } | |
| // 3. Otherwise, if result is error, throw a TypeError. | |
| // (Thrown in handler) | |
| // 4. Otherwise, do nothing. | |
| } | |
| // TODO: Align with spec algorithm. | |
| if (!this._do_not_flush) { | |
| do { | |
| result = this._decoder.handler(input_stream, input_stream.read()); | |
| if (result === finished) | |
| break; | |
| if (!result) | |
| continue; | |
| if (Array.isArray(result)) | |
| output.push.apply(output, /**@type {!Array.<number>}*/ (result)); | |
| else | |
| output.push(result); | |
| } while (!input_stream.endOfStream()); | |
| this._decoder = null; | |
| } | |
| return this.serializeStream(output); | |
| }; | |
| // A TextDecoder object also has an associated serialize stream | |
| // algorithm... | |
| /** | |
| * @param {!Array.<number>} stream | |
| * @return {string} | |
| * @this {TextDecoder} | |
| */ | |
| TextDecoder.prototype.serializeStream = function (stream) { | |
| // 1. Let token be the result of reading from stream. | |
| // (Done in-place on array, rather than as a stream) | |
| // 2. If encoding is UTF-8, UTF-16BE, or UTF-16LE, and ignore | |
| // BOM flag and BOM seen flag are unset, run these subsubsteps: | |
| if (includes(['UTF-8', 'UTF-16LE', 'UTF-16BE'], this._encoding.name) && | |
| !this._ignoreBOM && !this._BOMseen) { | |
| if (stream.length > 0 && stream[0] === 0xFEFF) { | |
| // 1. If token is U+FEFF, set BOM seen flag. | |
| this._BOMseen = true; | |
| stream.shift(); | |
| } | |
| else if (stream.length > 0) { | |
| // 2. Otherwise, if token is not end-of-stream, set BOM seen | |
| // flag and append token to stream. | |
| this._BOMseen = true; | |
| } | |
| else { | |
| // 3. Otherwise, if token is not end-of-stream, append token | |
| // to output. | |
| // (no-op) | |
| } | |
| } | |
| // 4. Otherwise, return output. | |
| return codePointsToString(stream); | |
| }; | |
| return TextDecoder; | |
| }()); | |
| export { TextDecoder }; | |
| function isBufferInstance(input) { | |
| try { | |
| return input instanceof ArrayBuffer; | |
| } | |
| catch (e) { | |
| console.error(e); | |
| return false; | |
| } | |
| } | |
| function getBytesFromInput(input) { | |
| if (typeof input !== 'object') | |
| return new Uint8Array(0); | |
| if (isBufferInstance(input)) { | |
| return new Uint8Array(input); | |
| } | |
| if ('buffer' in input && isBufferInstance(input.buffer)) { | |
| return new Uint8Array(input.buffer, input.byteOffset, input.byteLength); | |
| } | |
| return new Uint8Array(0); | |
| } | |
| //# sourceMappingURL=TextDecoder.js.map |
Xet Storage Details
- Size:
- 9.42 kB
- Xet hash:
- 8bfe6a24bb9afac9551f9e45eeb9f50442a7808369abf492e4640d85847ab656
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.