11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ObjectDefineProperties, 51cb0ef41Sopenharmony_ci String, 61cb0ef41Sopenharmony_ci StringPrototypeCharCodeAt, 71cb0ef41Sopenharmony_ci Symbol, 81cb0ef41Sopenharmony_ci Uint8Array, 91cb0ef41Sopenharmony_ci} = primordials; 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ciconst { 121cb0ef41Sopenharmony_ci TextDecoder, 131cb0ef41Sopenharmony_ci TextEncoder, 141cb0ef41Sopenharmony_ci} = require('internal/encoding'); 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciconst { 171cb0ef41Sopenharmony_ci TransformStream, 181cb0ef41Sopenharmony_ci} = require('internal/webstreams/transformstream'); 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ciconst { customInspect } = require('internal/webstreams/util'); 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ciconst { 231cb0ef41Sopenharmony_ci codes: { 241cb0ef41Sopenharmony_ci ERR_INVALID_THIS, 251cb0ef41Sopenharmony_ci }, 261cb0ef41Sopenharmony_ci} = require('internal/errors'); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciconst { 291cb0ef41Sopenharmony_ci customInspectSymbol: kInspect, 301cb0ef41Sopenharmony_ci kEmptyObject, 311cb0ef41Sopenharmony_ci kEnumerableProperty, 321cb0ef41Sopenharmony_ci} = require('internal/util'); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ciconst kHandle = Symbol('kHandle'); 351cb0ef41Sopenharmony_ciconst kTransform = Symbol('kTransform'); 361cb0ef41Sopenharmony_ciconst kType = Symbol('kType'); 371cb0ef41Sopenharmony_ciconst kPendingHighSurrogate = Symbol('kPendingHighSurrogate'); 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci/** 401cb0ef41Sopenharmony_ci * @typedef {import('./readablestream').ReadableStream} ReadableStream 411cb0ef41Sopenharmony_ci * @typedef {import('./writablestream').WritableStream} WritableStream 421cb0ef41Sopenharmony_ci */ 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_cifunction isTextEncoderStream(value) { 451cb0ef41Sopenharmony_ci return typeof value?.[kHandle] === 'object' && 461cb0ef41Sopenharmony_ci value?.[kType] === 'TextEncoderStream'; 471cb0ef41Sopenharmony_ci} 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_cifunction isTextDecoderStream(value) { 501cb0ef41Sopenharmony_ci return typeof value?.[kHandle] === 'object' && 511cb0ef41Sopenharmony_ci value?.[kType] === 'TextDecoderStream'; 521cb0ef41Sopenharmony_ci} 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ciclass TextEncoderStream { 551cb0ef41Sopenharmony_ci constructor() { 561cb0ef41Sopenharmony_ci this[kPendingHighSurrogate] = null; 571cb0ef41Sopenharmony_ci this[kType] = 'TextEncoderStream'; 581cb0ef41Sopenharmony_ci this[kHandle] = new TextEncoder(); 591cb0ef41Sopenharmony_ci this[kTransform] = new TransformStream({ 601cb0ef41Sopenharmony_ci transform: (chunk, controller) => { 611cb0ef41Sopenharmony_ci // https://encoding.spec.whatwg.org/#encode-and-enqueue-a-chunk 621cb0ef41Sopenharmony_ci chunk = String(chunk); 631cb0ef41Sopenharmony_ci let finalChunk = ''; 641cb0ef41Sopenharmony_ci for (let i = 0; i < chunk.length; i++) { 651cb0ef41Sopenharmony_ci const item = chunk[i]; 661cb0ef41Sopenharmony_ci const codeUnit = StringPrototypeCharCodeAt(item, 0); 671cb0ef41Sopenharmony_ci if (this[kPendingHighSurrogate] !== null) { 681cb0ef41Sopenharmony_ci const highSurrogate = this[kPendingHighSurrogate]; 691cb0ef41Sopenharmony_ci this[kPendingHighSurrogate] = null; 701cb0ef41Sopenharmony_ci if (0xDC00 <= codeUnit && codeUnit <= 0xDFFF) { 711cb0ef41Sopenharmony_ci finalChunk += highSurrogate + item; 721cb0ef41Sopenharmony_ci continue; 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci finalChunk += '\uFFFD'; 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci if (0xD800 <= codeUnit && codeUnit <= 0xDBFF) { 771cb0ef41Sopenharmony_ci this[kPendingHighSurrogate] = item; 781cb0ef41Sopenharmony_ci continue; 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci if (0xDC00 <= codeUnit && codeUnit <= 0xDFFF) { 811cb0ef41Sopenharmony_ci finalChunk += '\uFFFD'; 821cb0ef41Sopenharmony_ci continue; 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci finalChunk += item; 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci if (finalChunk) { 871cb0ef41Sopenharmony_ci const value = this[kHandle].encode(finalChunk); 881cb0ef41Sopenharmony_ci controller.enqueue(value); 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci }, 911cb0ef41Sopenharmony_ci flush: (controller) => { 921cb0ef41Sopenharmony_ci // https://encoding.spec.whatwg.org/#encode-and-flush 931cb0ef41Sopenharmony_ci if (this[kPendingHighSurrogate] !== null) { 941cb0ef41Sopenharmony_ci controller.enqueue(new Uint8Array([0xEF, 0xBF, 0xBD])); 951cb0ef41Sopenharmony_ci } 961cb0ef41Sopenharmony_ci }, 971cb0ef41Sopenharmony_ci }); 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci /** 1011cb0ef41Sopenharmony_ci * @readonly 1021cb0ef41Sopenharmony_ci * @type {string} 1031cb0ef41Sopenharmony_ci */ 1041cb0ef41Sopenharmony_ci get encoding() { 1051cb0ef41Sopenharmony_ci if (!isTextEncoderStream(this)) 1061cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextEncoderStream'); 1071cb0ef41Sopenharmony_ci return this[kHandle].encoding; 1081cb0ef41Sopenharmony_ci } 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci /** 1111cb0ef41Sopenharmony_ci * @readonly 1121cb0ef41Sopenharmony_ci * @type {ReadableStream} 1131cb0ef41Sopenharmony_ci */ 1141cb0ef41Sopenharmony_ci get readable() { 1151cb0ef41Sopenharmony_ci if (!isTextEncoderStream(this)) 1161cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextEncoderStream'); 1171cb0ef41Sopenharmony_ci return this[kTransform].readable; 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci /** 1211cb0ef41Sopenharmony_ci * @readonly 1221cb0ef41Sopenharmony_ci * @type {WritableStream} 1231cb0ef41Sopenharmony_ci */ 1241cb0ef41Sopenharmony_ci get writable() { 1251cb0ef41Sopenharmony_ci if (!isTextEncoderStream(this)) 1261cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextEncoderStream'); 1271cb0ef41Sopenharmony_ci return this[kTransform].writable; 1281cb0ef41Sopenharmony_ci } 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci [kInspect](depth, options) { 1311cb0ef41Sopenharmony_ci if (!isTextEncoderStream(this)) 1321cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextEncoderStream'); 1331cb0ef41Sopenharmony_ci return customInspect(depth, options, 'TextEncoderStream', { 1341cb0ef41Sopenharmony_ci encoding: this[kHandle].encoding, 1351cb0ef41Sopenharmony_ci readable: this[kTransform].readable, 1361cb0ef41Sopenharmony_ci writable: this[kTransform].writable, 1371cb0ef41Sopenharmony_ci }); 1381cb0ef41Sopenharmony_ci } 1391cb0ef41Sopenharmony_ci} 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ciclass TextDecoderStream { 1421cb0ef41Sopenharmony_ci /** 1431cb0ef41Sopenharmony_ci * @param {string} [encoding] 1441cb0ef41Sopenharmony_ci * @param {{ 1451cb0ef41Sopenharmony_ci * fatal? : boolean, 1461cb0ef41Sopenharmony_ci * ignoreBOM? : boolean, 1471cb0ef41Sopenharmony_ci * }} [options] 1481cb0ef41Sopenharmony_ci */ 1491cb0ef41Sopenharmony_ci constructor(encoding = 'utf-8', options = kEmptyObject) { 1501cb0ef41Sopenharmony_ci this[kType] = 'TextDecoderStream'; 1511cb0ef41Sopenharmony_ci this[kHandle] = new TextDecoder(encoding, options); 1521cb0ef41Sopenharmony_ci this[kTransform] = new TransformStream({ 1531cb0ef41Sopenharmony_ci transform: (chunk, controller) => { 1541cb0ef41Sopenharmony_ci const value = this[kHandle].decode(chunk, { stream: true }); 1551cb0ef41Sopenharmony_ci if (value) 1561cb0ef41Sopenharmony_ci controller.enqueue(value); 1571cb0ef41Sopenharmony_ci }, 1581cb0ef41Sopenharmony_ci flush: (controller) => { 1591cb0ef41Sopenharmony_ci const value = this[kHandle].decode(); 1601cb0ef41Sopenharmony_ci if (value) 1611cb0ef41Sopenharmony_ci controller.enqueue(value); 1621cb0ef41Sopenharmony_ci controller.terminate(); 1631cb0ef41Sopenharmony_ci }, 1641cb0ef41Sopenharmony_ci }); 1651cb0ef41Sopenharmony_ci } 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci /** 1681cb0ef41Sopenharmony_ci * @readonly 1691cb0ef41Sopenharmony_ci * @type {string} 1701cb0ef41Sopenharmony_ci */ 1711cb0ef41Sopenharmony_ci get encoding() { 1721cb0ef41Sopenharmony_ci if (!isTextDecoderStream(this)) 1731cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextDecoderStream'); 1741cb0ef41Sopenharmony_ci return this[kHandle].encoding; 1751cb0ef41Sopenharmony_ci } 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci /** 1781cb0ef41Sopenharmony_ci * @readonly 1791cb0ef41Sopenharmony_ci * @type {boolean} 1801cb0ef41Sopenharmony_ci */ 1811cb0ef41Sopenharmony_ci get fatal() { 1821cb0ef41Sopenharmony_ci if (!isTextDecoderStream(this)) 1831cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextDecoderStream'); 1841cb0ef41Sopenharmony_ci return this[kHandle].fatal; 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci /** 1881cb0ef41Sopenharmony_ci * @readonly 1891cb0ef41Sopenharmony_ci * @type {boolean} 1901cb0ef41Sopenharmony_ci */ 1911cb0ef41Sopenharmony_ci get ignoreBOM() { 1921cb0ef41Sopenharmony_ci if (!isTextDecoderStream(this)) 1931cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextDecoderStream'); 1941cb0ef41Sopenharmony_ci return this[kHandle].ignoreBOM; 1951cb0ef41Sopenharmony_ci } 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci /** 1981cb0ef41Sopenharmony_ci * @readonly 1991cb0ef41Sopenharmony_ci * @type {ReadableStream} 2001cb0ef41Sopenharmony_ci */ 2011cb0ef41Sopenharmony_ci get readable() { 2021cb0ef41Sopenharmony_ci if (!isTextDecoderStream(this)) 2031cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextDecoderStream'); 2041cb0ef41Sopenharmony_ci return this[kTransform].readable; 2051cb0ef41Sopenharmony_ci } 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci /** 2081cb0ef41Sopenharmony_ci * @readonly 2091cb0ef41Sopenharmony_ci * @type {WritableStream} 2101cb0ef41Sopenharmony_ci */ 2111cb0ef41Sopenharmony_ci get writable() { 2121cb0ef41Sopenharmony_ci if (!isTextDecoderStream(this)) 2131cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextDecoderStream'); 2141cb0ef41Sopenharmony_ci return this[kTransform].writable; 2151cb0ef41Sopenharmony_ci } 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci [kInspect](depth, options) { 2181cb0ef41Sopenharmony_ci if (!isTextDecoderStream(this)) 2191cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('TextDecoderStream'); 2201cb0ef41Sopenharmony_ci return customInspect(depth, options, 'TextDecoderStream', { 2211cb0ef41Sopenharmony_ci encoding: this[kHandle].encoding, 2221cb0ef41Sopenharmony_ci fatal: this[kHandle].fatal, 2231cb0ef41Sopenharmony_ci ignoreBOM: this[kHandle].ignoreBOM, 2241cb0ef41Sopenharmony_ci readable: this[kTransform].readable, 2251cb0ef41Sopenharmony_ci writable: this[kTransform].writable, 2261cb0ef41Sopenharmony_ci }); 2271cb0ef41Sopenharmony_ci } 2281cb0ef41Sopenharmony_ci} 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ciObjectDefineProperties(TextEncoderStream.prototype, { 2311cb0ef41Sopenharmony_ci encoding: kEnumerableProperty, 2321cb0ef41Sopenharmony_ci readable: kEnumerableProperty, 2331cb0ef41Sopenharmony_ci writable: kEnumerableProperty, 2341cb0ef41Sopenharmony_ci}); 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ciObjectDefineProperties(TextDecoderStream.prototype, { 2371cb0ef41Sopenharmony_ci encoding: kEnumerableProperty, 2381cb0ef41Sopenharmony_ci fatal: kEnumerableProperty, 2391cb0ef41Sopenharmony_ci ignoreBOM: kEnumerableProperty, 2401cb0ef41Sopenharmony_ci readable: kEnumerableProperty, 2411cb0ef41Sopenharmony_ci writable: kEnumerableProperty, 2421cb0ef41Sopenharmony_ci}); 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_cimodule.exports = { 2451cb0ef41Sopenharmony_ci TextEncoderStream, 2461cb0ef41Sopenharmony_ci TextDecoderStream, 2471cb0ef41Sopenharmony_ci}; 248