14d6c458bSopenharmony_ci/* 24d6c458bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License. 54d6c458bSopenharmony_ci * You may obtain a copy of the License at 64d6c458bSopenharmony_ci * 74d6c458bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84d6c458bSopenharmony_ci * 94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and 134d6c458bSopenharmony_ci * limitations under the License. 144d6c458bSopenharmony_ci */ 154d6c458bSopenharmony_citype AnyType = Object | null | undefined | unknown; 164d6c458bSopenharmony_cideclare function requireNapi(napiModuleName: string): AnyType; 174d6c458bSopenharmony_ciconst emitter = requireNapi('events.emitter'); 184d6c458bSopenharmony_ci// @ts-ignore 194d6c458bSopenharmony_ciconst { TextEncoder, StringDecoder } = requireNapi('util'); 204d6c458bSopenharmony_ci 214d6c458bSopenharmony_ciconst DEFAULT_HIGH_WATER_MARK = 16 * 1024; 224d6c458bSopenharmony_ciconst DEFAULT_ENCODING = 'utf-8'; 234d6c458bSopenharmony_ciconst TypeErrorCodeId = 401; 244d6c458bSopenharmony_ciclass BusinessError extends Error { 254d6c458bSopenharmony_ci code: number | string; 264d6c458bSopenharmony_ci 274d6c458bSopenharmony_ci constructor(msg: string, code?: number) { 284d6c458bSopenharmony_ci super(msg); 294d6c458bSopenharmony_ci this.name = 'BusinessError'; 304d6c458bSopenharmony_ci this.code = code ? code : TypeErrorCodeId; 314d6c458bSopenharmony_ci } 324d6c458bSopenharmony_ci} 334d6c458bSopenharmony_ciconst ERR_DOWRITE_NOT_IMPLEMENTED:BusinessError = new BusinessError('The doWrite() method is not implemented', 10200035); 344d6c458bSopenharmony_ciconst ERR_DOWRITEV_NOT_IMPLEMENTED:BusinessError = new BusinessError('The doWritev() method is not implemented', 10200035); 354d6c458bSopenharmony_ciconst ERR_MULTIPLE_CALLBACK:BusinessError = new BusinessError('Callback called multiple times', 10200037); 364d6c458bSopenharmony_ciconst ERR_STREAM_ALREADY_FINISHED:BusinessError = new BusinessError('stream already finished', 10200036); 374d6c458bSopenharmony_ciconst ERR_WRITE_AFTER_END:BusinessError = new BusinessError('write after end', 10200036); 384d6c458bSopenharmony_ciconst ENCODING_SET: Array<string> = ['ascii', 'utf-8', 'UTF-8', 'gbk', 'GBK', 'GB2312', 'gb2312', 394d6c458bSopenharmony_ci 'GB18030', 'gb18030', 'ibm866', 'iso-8859-2', 'iso-8859-3', 404d6c458bSopenharmony_ci 'iso-8859-4', 'iso-8859-5', 'iso-8859-6', 'iso-8859-7', 414d6c458bSopenharmony_ci 'iso-8859-8', 'iso-8859-8-i', 'iso-8859-10', 'iso-8859-13', 424d6c458bSopenharmony_ci 'iso-8859-14', 'iso-8859-15', 'koi8-r', 'koi8-u', 'macintosh', 434d6c458bSopenharmony_ci 'windows-874', 'windows-1250', 'windows-1251', 'windows-1252', 444d6c458bSopenharmony_ci 'windows-1253', 'windows-1254', 'windows-1255', 'windows-1256', 454d6c458bSopenharmony_ci 'windows-1257', 'windows-1258', 'big5', 'euc-jp', 'iso-2022-jp', 464d6c458bSopenharmony_ci 'shift_jis', 'euc-kr', 'x-mac-cyrillic', 'utf-16be', 474d6c458bSopenharmony_ci 'utf-16le']; 484d6c458bSopenharmony_ciclass EventEmitter { 494d6c458bSopenharmony_ci handlers: { [key: string]: Function[] }; 504d6c458bSopenharmony_ci 514d6c458bSopenharmony_ci constructor() { 524d6c458bSopenharmony_ci this.handlers = {}; 534d6c458bSopenharmony_ci } 544d6c458bSopenharmony_ci 554d6c458bSopenharmony_ci on(event: string, callback: Function): void { 564d6c458bSopenharmony_ci if (!this.handlers[event]) { 574d6c458bSopenharmony_ci this.handlers[event] = []; 584d6c458bSopenharmony_ci } 594d6c458bSopenharmony_ci this.handlers[event].push(callback); 604d6c458bSopenharmony_ci } 614d6c458bSopenharmony_ci 624d6c458bSopenharmony_ci off(event: string, callback: Function): void { 634d6c458bSopenharmony_ci if (this.handlers[event]) { 644d6c458bSopenharmony_ci const idx = this.handlers[event].findIndex((value: Function): boolean => value === callback); 654d6c458bSopenharmony_ci if (idx !== -1) { 664d6c458bSopenharmony_ci this.handlers[event].splice(idx, 1); 674d6c458bSopenharmony_ci } 684d6c458bSopenharmony_ci } 694d6c458bSopenharmony_ci } 704d6c458bSopenharmony_ci 714d6c458bSopenharmony_ci emit(event: string, ...args: AnyType[]): void { 724d6c458bSopenharmony_ci if (this.handlers[event]) { 734d6c458bSopenharmony_ci this.handlers[event].forEach((item: any) => { 744d6c458bSopenharmony_ci if (args.length > 0) { 754d6c458bSopenharmony_ci item({ data: args[0] }); 764d6c458bSopenharmony_ci } else { 774d6c458bSopenharmony_ci item({}); 784d6c458bSopenharmony_ci } 794d6c458bSopenharmony_ci }); 804d6c458bSopenharmony_ci } 814d6c458bSopenharmony_ci } 824d6c458bSopenharmony_ci 834d6c458bSopenharmony_ci isOn(event: string): boolean { 844d6c458bSopenharmony_ci const handler:Function[] = this.handlers[event]; 854d6c458bSopenharmony_ci return handler && handler.length > 0; 864d6c458bSopenharmony_ci } 874d6c458bSopenharmony_ci 884d6c458bSopenharmony_ci listenerCount(event: string): number { 894d6c458bSopenharmony_ci return this.handlers[event]?.length || 0; 904d6c458bSopenharmony_ci } 914d6c458bSopenharmony_ci} 924d6c458bSopenharmony_cifunction runOnce(runFn: Function, callback?: (multipleTimes: boolean, error: Error) => void): Function { 934d6c458bSopenharmony_ci let executed = false; 944d6c458bSopenharmony_ci return function (...args: Function[]) { 954d6c458bSopenharmony_ci if (!executed) { 964d6c458bSopenharmony_ci executed = true; 974d6c458bSopenharmony_ci return runFn(...args); 984d6c458bSopenharmony_ci } else { 994d6c458bSopenharmony_ci if (callback) { 1004d6c458bSopenharmony_ci Promise.resolve().then(():void => { 1014d6c458bSopenharmony_ci // @ts-ignore 1024d6c458bSopenharmony_ci callback(); 1034d6c458bSopenharmony_ci }); 1044d6c458bSopenharmony_ci } 1054d6c458bSopenharmony_ci } 1064d6c458bSopenharmony_ci }; 1074d6c458bSopenharmony_ci} 1084d6c458bSopenharmony_cifunction asyncFn(asyncFn: Function) { 1094d6c458bSopenharmony_ci return function (...args: Function[]): void { 1104d6c458bSopenharmony_ci setTimeout(() => asyncFn(...args)); 1114d6c458bSopenharmony_ci }; 1124d6c458bSopenharmony_ci} 1134d6c458bSopenharmony_cienum ReadableEvent { 1144d6c458bSopenharmony_ci CLOSE = 'close', 1154d6c458bSopenharmony_ci DATA = 'data', 1164d6c458bSopenharmony_ci END = 'end', 1174d6c458bSopenharmony_ci ERROR = 'error', 1184d6c458bSopenharmony_ci READABLE = 'readable', 1194d6c458bSopenharmony_ci PAUSE = 'pause', 1204d6c458bSopenharmony_ci RESUME = 'resume', 1214d6c458bSopenharmony_ci} 1224d6c458bSopenharmony_cienum WritableEvent { 1234d6c458bSopenharmony_ci CLOSE = 'close', 1244d6c458bSopenharmony_ci DRAIN = 'drain', 1254d6c458bSopenharmony_ci ERROR = 'error', 1264d6c458bSopenharmony_ci FINISH = 'finish', 1274d6c458bSopenharmony_ci PIPE = 'pipe', 1284d6c458bSopenharmony_ci UNPIPE = 'unpipe', 1294d6c458bSopenharmony_ci} 1304d6c458bSopenharmony_ci 1314d6c458bSopenharmony_ciinterface ReadablePipeStream { 1324d6c458bSopenharmony_ci write: Writable; 1334d6c458bSopenharmony_ci dataCallback: Function; 1344d6c458bSopenharmony_ci drainCallback: Function; 1354d6c458bSopenharmony_ci endCallback: Function; 1364d6c458bSopenharmony_ci} 1374d6c458bSopenharmony_ciclass Readable { 1384d6c458bSopenharmony_ci private buf: Array<number>; 1394d6c458bSopenharmony_ci private listener: EventEmitter | undefined; 1404d6c458bSopenharmony_ci private callbacks: { [key: string]: Function[] } = {}; 1414d6c458bSopenharmony_ci protected encoder = new TextEncoder(); 1424d6c458bSopenharmony_ci protected stringDecoder = new StringDecoder(); 1434d6c458bSopenharmony_ci private isInitialized: boolean = false; 1444d6c458bSopenharmony_ci private pauseInner: boolean; 1454d6c458bSopenharmony_ci private pipeWritableArrayInner: ReadablePipeStream[] = []; 1464d6c458bSopenharmony_ci private readableObjectModeInner: boolean | undefined; 1474d6c458bSopenharmony_ci private readableInner: boolean; 1484d6c458bSopenharmony_ci private readableHighWatermarkInner: number; 1494d6c458bSopenharmony_ci private readableFlowingInner: boolean; 1504d6c458bSopenharmony_ci private readableLengthInner: number; 1514d6c458bSopenharmony_ci private readableEncodingInner: string; 1524d6c458bSopenharmony_ci private readableEndedInner: boolean; 1534d6c458bSopenharmony_ci private erroredInner: Error | undefined; 1544d6c458bSopenharmony_ci private closedInner: boolean | undefined; 1554d6c458bSopenharmony_ci 1564d6c458bSopenharmony_ci /** 1574d6c458bSopenharmony_ci * The Readable constructor. 1584d6c458bSopenharmony_ci * 1594d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 1604d6c458bSopenharmony_ci * @throws { BusinessError } 401 - Parameter error. Possible causes: 1614d6c458bSopenharmony_ci * 1.Incorrect parameter types. 1624d6c458bSopenharmony_ci * @crossplatform 1634d6c458bSopenharmony_ci * @since 12 1644d6c458bSopenharmony_ci */ 1654d6c458bSopenharmony_ci constructor(options?: { encoding: string | null; highWatermark?: number; doRead?: (size: number) => void }) { 1664d6c458bSopenharmony_ci this.readableEncodingInner = options?.encoding || DEFAULT_ENCODING; 1674d6c458bSopenharmony_ci this.readableHighWatermarkInner = options?.highWatermark || DEFAULT_HIGH_WATER_MARK; 1684d6c458bSopenharmony_ci this.readableObjectModeInner = false; 1694d6c458bSopenharmony_ci this.readableLengthInner = 0; 1704d6c458bSopenharmony_ci this.pauseInner = false; 1714d6c458bSopenharmony_ci this.readableFlowingInner = true; 1724d6c458bSopenharmony_ci this.readableInner = true; 1734d6c458bSopenharmony_ci this.readableEndedInner = false; 1744d6c458bSopenharmony_ci this.listener = new EventEmitter(); 1754d6c458bSopenharmony_ci this.buf = []; 1764d6c458bSopenharmony_ci if (arguments.length !== 0) { 1774d6c458bSopenharmony_ci if (typeof options?.doRead === 'function') { 1784d6c458bSopenharmony_ci this.doRead = options.doRead; 1794d6c458bSopenharmony_ci } 1804d6c458bSopenharmony_ci if (this.readableEncodingInner.toLowerCase() === 'utf8') { 1814d6c458bSopenharmony_ci this.readableEncodingInner = DEFAULT_ENCODING; 1824d6c458bSopenharmony_ci } 1834d6c458bSopenharmony_ci if (ENCODING_SET.indexOf(this.readableEncodingInner.toLowerCase()) === -1) { 1844d6c458bSopenharmony_ci let error = new BusinessError('Parameter error. Incorrect parameter types.', 401); 1854d6c458bSopenharmony_ci throw error; 1864d6c458bSopenharmony_ci } 1874d6c458bSopenharmony_ci this.stringDecoder = new StringDecoder(this.readableEncodingInner); 1884d6c458bSopenharmony_ci this.encoder = new TextEncoder(this.readableEncodingInner); 1894d6c458bSopenharmony_ci } 1904d6c458bSopenharmony_ci } 1914d6c458bSopenharmony_ci 1924d6c458bSopenharmony_ci /** 1934d6c458bSopenharmony_ci * Returns boolean indicating whether it is in ObjectMode. 1944d6c458bSopenharmony_ci * 1954d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 1964d6c458bSopenharmony_ci * @crossplatform 1974d6c458bSopenharmony_ci * @since 12 1984d6c458bSopenharmony_ci */ 1994d6c458bSopenharmony_ci get readableObjectMode(): boolean | undefined { 2004d6c458bSopenharmony_ci return this.readableObjectModeInner; 2014d6c458bSopenharmony_ci } 2024d6c458bSopenharmony_ci 2034d6c458bSopenharmony_ci /** 2044d6c458bSopenharmony_ci * Is true if it is safe to call readable.read(), which means 2054d6c458bSopenharmony_ci * the stream has not been destroyed or emitted 'error' or 'end'. 2064d6c458bSopenharmony_ci * 2074d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 2084d6c458bSopenharmony_ci * @crossplatform 2094d6c458bSopenharmony_ci * @since 12 2104d6c458bSopenharmony_ci */ 2114d6c458bSopenharmony_ci get readable(): boolean { 2124d6c458bSopenharmony_ci if (this.readableInner) { 2134d6c458bSopenharmony_ci return true; 2144d6c458bSopenharmony_ci } else if (!this.readableInner && this.readableEndedInner) { 2154d6c458bSopenharmony_ci return false; 2164d6c458bSopenharmony_ci } 2174d6c458bSopenharmony_ci return true; 2184d6c458bSopenharmony_ci } 2194d6c458bSopenharmony_ci 2204d6c458bSopenharmony_ci /** 2214d6c458bSopenharmony_ci * Returns the value of highWatermark passed when creating this Readable. 2224d6c458bSopenharmony_ci * 2234d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 2244d6c458bSopenharmony_ci * @crossplatform 2254d6c458bSopenharmony_ci * @since 12 2264d6c458bSopenharmony_ci */ 2274d6c458bSopenharmony_ci get readableHighWatermark(): number { 2284d6c458bSopenharmony_ci return this.readableHighWatermarkInner; 2294d6c458bSopenharmony_ci } 2304d6c458bSopenharmony_ci 2314d6c458bSopenharmony_ci /** 2324d6c458bSopenharmony_ci * This property reflects the current state of the readable stream null/true/false. 2334d6c458bSopenharmony_ci * 2344d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 2354d6c458bSopenharmony_ci * @crossplatform 2364d6c458bSopenharmony_ci * @since 12 2374d6c458bSopenharmony_ci */ 2384d6c458bSopenharmony_ci get readableFlowing(): boolean { 2394d6c458bSopenharmony_ci return this.readableFlowingInner; 2404d6c458bSopenharmony_ci } 2414d6c458bSopenharmony_ci 2424d6c458bSopenharmony_ci /** 2434d6c458bSopenharmony_ci * Size of the data that can be read, in bytes or objects. 2444d6c458bSopenharmony_ci * 2454d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 2464d6c458bSopenharmony_ci * @crossplatform 2474d6c458bSopenharmony_ci * @since 12 2484d6c458bSopenharmony_ci */ 2494d6c458bSopenharmony_ci get readableLength(): number { 2504d6c458bSopenharmony_ci return this.readableLengthInner; 2514d6c458bSopenharmony_ci } 2524d6c458bSopenharmony_ci 2534d6c458bSopenharmony_ci /** 2544d6c458bSopenharmony_ci * Getter for the property encoding of a given Readable stream. The encoding property can be set using the 2554d6c458bSopenharmony_ci * readable.setEncoding() method. 2564d6c458bSopenharmony_ci * 2574d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 2584d6c458bSopenharmony_ci * @crossplatform 2594d6c458bSopenharmony_ci * @since 12 2604d6c458bSopenharmony_ci */ 2614d6c458bSopenharmony_ci get readableEncoding(): string | null { 2624d6c458bSopenharmony_ci return this.readableEncodingInner; 2634d6c458bSopenharmony_ci } 2644d6c458bSopenharmony_ci 2654d6c458bSopenharmony_ci /** 2664d6c458bSopenharmony_ci * Whether all data has been generated. 2674d6c458bSopenharmony_ci * 2684d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 2694d6c458bSopenharmony_ci * @crossplatform 2704d6c458bSopenharmony_ci * @since 12 2714d6c458bSopenharmony_ci */ 2724d6c458bSopenharmony_ci get readableEnded(): boolean { 2734d6c458bSopenharmony_ci return this.readableEndedInner; 2744d6c458bSopenharmony_ci } 2754d6c458bSopenharmony_ci 2764d6c458bSopenharmony_ci /** 2774d6c458bSopenharmony_ci * Returns error if the stream has been destroyed with an error. 2784d6c458bSopenharmony_ci * 2794d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 2804d6c458bSopenharmony_ci * @crossplatform 2814d6c458bSopenharmony_ci * @since 12 2824d6c458bSopenharmony_ci */ 2834d6c458bSopenharmony_ci get errored(): Error | undefined { 2844d6c458bSopenharmony_ci return this.erroredInner; 2854d6c458bSopenharmony_ci } 2864d6c458bSopenharmony_ci 2874d6c458bSopenharmony_ci /** 2884d6c458bSopenharmony_ci * Readable completes destroyfile and returns true, otherwise returns false. 2894d6c458bSopenharmony_ci * 2904d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 2914d6c458bSopenharmony_ci * @crossplatform 2924d6c458bSopenharmony_ci * @since 12 2934d6c458bSopenharmony_ci */ 2944d6c458bSopenharmony_ci get closed(): boolean { 2954d6c458bSopenharmony_ci return this.closedInner || false; 2964d6c458bSopenharmony_ci } 2974d6c458bSopenharmony_ci 2984d6c458bSopenharmony_ci private computeNewReadableHighWatermark(readSize: number): number { 2994d6c458bSopenharmony_ci readSize--; 3004d6c458bSopenharmony_ci readSize |= readSize >>> 1; 3014d6c458bSopenharmony_ci readSize |= readSize >>> 2; 3024d6c458bSopenharmony_ci readSize |= readSize >>> 4; 3034d6c458bSopenharmony_ci readSize |= readSize >>> 8; 3044d6c458bSopenharmony_ci readSize |= readSize >>> 16; 3054d6c458bSopenharmony_ci readSize++; 3064d6c458bSopenharmony_ci return readSize; 3074d6c458bSopenharmony_ci } 3084d6c458bSopenharmony_ci 3094d6c458bSopenharmony_ci setEndType(): void { 3104d6c458bSopenharmony_ci Promise.resolve().then((): void => { 3114d6c458bSopenharmony_ci this.readableInner = false; 3124d6c458bSopenharmony_ci this.readableEndedInner = true; 3134d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.END); 3144d6c458bSopenharmony_ci }); 3154d6c458bSopenharmony_ci } 3164d6c458bSopenharmony_ci 3174d6c458bSopenharmony_ci /** 3184d6c458bSopenharmony_ci * Reads a buffer of a specified size from the buffer. If the available buffer is sufficient, the result 3194d6c458bSopenharmony_ci * of the specified size is returned. Otherwise, if Readable has ended, all remaining buffers are returned. 3204d6c458bSopenharmony_ci * 3214d6c458bSopenharmony_ci * @param { number } size - Expected length of the data to be read. 3224d6c458bSopenharmony_ci * @returns { string | null } If no data is available to read, null is returned. 3234d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 3244d6c458bSopenharmony_ci * @throws { BusinessError } 10200038 - if the doRead method has not been implemented, an error will be thrown. 3254d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 3264d6c458bSopenharmony_ci * @crossplatform 3274d6c458bSopenharmony_ci * @since 12 3284d6c458bSopenharmony_ci */ 3294d6c458bSopenharmony_ci read(size?: number): string | null { 3304d6c458bSopenharmony_ci if (size && typeof size !== 'number') { 3314d6c458bSopenharmony_ci this.throwError(new BusinessError(`Parameter error. The type of ${size} must be object`, 401)); 3324d6c458bSopenharmony_ci return null; 3334d6c458bSopenharmony_ci } 3344d6c458bSopenharmony_ci if (this.doRead === null && this.readableInner) { 3354d6c458bSopenharmony_ci this.readableInner = false; 3364d6c458bSopenharmony_ci Promise.resolve().then(() => { 3374d6c458bSopenharmony_ci this.closedInner = true; 3384d6c458bSopenharmony_ci this.erroredInner = new BusinessError('The doRead() method is not implemented', 10200038); 3394d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.ERROR, this.erroredInner); 3404d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.CLOSE); 3414d6c458bSopenharmony_ci }); 3424d6c458bSopenharmony_ci return null; 3434d6c458bSopenharmony_ci } 3444d6c458bSopenharmony_ci size = size ?? this.readableLengthInner; 3454d6c458bSopenharmony_ci if (size > this.readableHighWatermarkInner) { 3464d6c458bSopenharmony_ci this.readableHighWatermarkInner = this.computeNewReadableHighWatermark(size); 3474d6c458bSopenharmony_ci } 3484d6c458bSopenharmony_ci if (size > this.readableLengthInner) { 3494d6c458bSopenharmony_ci if (!this.readableFlowingInner) { 3504d6c458bSopenharmony_ci return null; 3514d6c458bSopenharmony_ci } else { 3524d6c458bSopenharmony_ci size = this.readableLengthInner; 3534d6c458bSopenharmony_ci } 3544d6c458bSopenharmony_ci } 3554d6c458bSopenharmony_ci let buffer = null; 3564d6c458bSopenharmony_ci if (size > 0 && size <= this.readableLengthInner) { 3574d6c458bSopenharmony_ci this.readableLengthInner -= size; 3584d6c458bSopenharmony_ci buffer = this.stringDecoder.write(new Uint8Array(this.buf.splice(0, size))); 3594d6c458bSopenharmony_ci this.doRead !== null && this.listener?.emit(ReadableEvent.DATA, buffer); 3604d6c458bSopenharmony_ci } 3614d6c458bSopenharmony_ci if ((!this.readableInner || size <= -1) && this.readableFlowingInner) { 3624d6c458bSopenharmony_ci return null; 3634d6c458bSopenharmony_ci } 3644d6c458bSopenharmony_ci if (this.readableFlowingInner) { 3654d6c458bSopenharmony_ci try { 3664d6c458bSopenharmony_ci this.doRead(this.readableHighWatermarkInner); 3674d6c458bSopenharmony_ci } catch (error) { 3684d6c458bSopenharmony_ci this.readableInner = false; 3694d6c458bSopenharmony_ci this.readableEndedInner = true; 3704d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.ERROR, error); 3714d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.CLOSE); 3724d6c458bSopenharmony_ci } 3734d6c458bSopenharmony_ci } 3744d6c458bSopenharmony_ci return buffer; 3754d6c458bSopenharmony_ci }; 3764d6c458bSopenharmony_ci 3774d6c458bSopenharmony_ci /** 3784d6c458bSopenharmony_ci * Switch Readable to Streaming Mode. 3794d6c458bSopenharmony_ci * 3804d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 3814d6c458bSopenharmony_ci * @crossplatform 3824d6c458bSopenharmony_ci * @since 12 3834d6c458bSopenharmony_ci */ 3844d6c458bSopenharmony_ci resume(): Readable { 3854d6c458bSopenharmony_ci if (this.readableLengthInner === 0) { 3864d6c458bSopenharmony_ci Promise.resolve().then((): void => { 3874d6c458bSopenharmony_ci this.read(this.readableHighWatermarkInner < this.readableLengthInner ? -1 : this.readableLengthInner); 3884d6c458bSopenharmony_ci }); 3894d6c458bSopenharmony_ci } 3904d6c458bSopenharmony_ci this.pauseInner = false; 3914d6c458bSopenharmony_ci this.readableFlowingInner = true; 3924d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.RESUME); 3934d6c458bSopenharmony_ci return this; 3944d6c458bSopenharmony_ci } 3954d6c458bSopenharmony_ci 3964d6c458bSopenharmony_ci /** 3974d6c458bSopenharmony_ci * Toggle Readable to Suspend Mode. 3984d6c458bSopenharmony_ci * 3994d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 4004d6c458bSopenharmony_ci * @crossplatform 4014d6c458bSopenharmony_ci * @since 12 4024d6c458bSopenharmony_ci */ 4034d6c458bSopenharmony_ci pause(): Readable { 4044d6c458bSopenharmony_ci this.pauseInner = true; 4054d6c458bSopenharmony_ci Promise.resolve().then((): void => { 4064d6c458bSopenharmony_ci this.readableFlowingInner = false; 4074d6c458bSopenharmony_ci }); 4084d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.PAUSE); 4094d6c458bSopenharmony_ci return this; 4104d6c458bSopenharmony_ci } 4114d6c458bSopenharmony_ci 4124d6c458bSopenharmony_ci /** 4134d6c458bSopenharmony_ci * Sets the encoding format of the input binary data.Default: utf8. 4144d6c458bSopenharmony_ci * 4154d6c458bSopenharmony_ci * @param { string } [encoding] - Original Data Encoding Type. 4164d6c458bSopenharmony_ci * @returns { boolean } Setting successful returns true, setting failed returns false. 4174d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 4184d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 4194d6c458bSopenharmony_ci * @crossplatform 4204d6c458bSopenharmony_ci * @since 12 4214d6c458bSopenharmony_ci */ 4224d6c458bSopenharmony_ci setEncoding(encoding?: string): boolean { 4234d6c458bSopenharmony_ci if(this.readableEncodingInner === encoding) { 4244d6c458bSopenharmony_ci return true; 4254d6c458bSopenharmony_ci } 4264d6c458bSopenharmony_ci if (!encoding) { 4274d6c458bSopenharmony_ci this.readableEncodingInner = DEFAULT_ENCODING; 4284d6c458bSopenharmony_ci this.encoder = new TextEncoder(this.readableEncodingInner); 4294d6c458bSopenharmony_ci this.stringDecoder = new StringDecoder(this.readableEncodingInner); 4304d6c458bSopenharmony_ci return false; 4314d6c458bSopenharmony_ci } 4324d6c458bSopenharmony_ci if (encoding.toLowerCase() === 'utf8') { 4334d6c458bSopenharmony_ci encoding = 'utf-8'; 4344d6c458bSopenharmony_ci } 4354d6c458bSopenharmony_ci if (this.buf.length !== 0) { 4364d6c458bSopenharmony_ci console.error('stream: The buffer also has data, and encoding is not allowed'); 4374d6c458bSopenharmony_ci return false; 4384d6c458bSopenharmony_ci } 4394d6c458bSopenharmony_ci if (ENCODING_SET.indexOf(encoding.toLowerCase()) !== -1) { 4404d6c458bSopenharmony_ci try { 4414d6c458bSopenharmony_ci this.encoder = new TextEncoder(encoding); 4424d6c458bSopenharmony_ci this.stringDecoder = new StringDecoder(encoding); 4434d6c458bSopenharmony_ci this.readableEncodingInner = encoding.toLowerCase(); 4444d6c458bSopenharmony_ci } catch (e) { 4454d6c458bSopenharmony_ci this.throwError(e as Error); 4464d6c458bSopenharmony_ci return false; 4474d6c458bSopenharmony_ci } 4484d6c458bSopenharmony_ci return true; 4494d6c458bSopenharmony_ci } else { 4504d6c458bSopenharmony_ci const err: BusinessError = new BusinessError(`Parameter error. The type of ${encoding} must be string.`); 4514d6c458bSopenharmony_ci this.throwError(err); 4524d6c458bSopenharmony_ci return false; 4534d6c458bSopenharmony_ci } 4544d6c458bSopenharmony_ci } 4554d6c458bSopenharmony_ci 4564d6c458bSopenharmony_ci /** 4574d6c458bSopenharmony_ci * Query whether it is in pause state. 4584d6c458bSopenharmony_ci * 4594d6c458bSopenharmony_ci * @returns { boolean } Pause state returns true, otherwise returns false. 4604d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 4614d6c458bSopenharmony_ci * @crossplatform 4624d6c458bSopenharmony_ci * @since 12 4634d6c458bSopenharmony_ci */ 4644d6c458bSopenharmony_ci isPaused(): boolean { 4654d6c458bSopenharmony_ci return this.pauseInner; 4664d6c458bSopenharmony_ci } 4674d6c458bSopenharmony_ci 4684d6c458bSopenharmony_ci /** 4694d6c458bSopenharmony_ci * Concatenates a Writable to a Readable and switches the Readable to stream mode. 4704d6c458bSopenharmony_ci * 4714d6c458bSopenharmony_ci * @param { Writable } destination - Output writable stream. 4724d6c458bSopenharmony_ci * @param { Object } [option] - Pipeline Options. 4734d6c458bSopenharmony_ci * @returns { Writable } Returns the Writable object. 4744d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 4754d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 4764d6c458bSopenharmony_ci * @crossplatform 4774d6c458bSopenharmony_ci * @since 12 4784d6c458bSopenharmony_ci */ 4794d6c458bSopenharmony_ci pipe(destination: Writable, option?: Object): Writable { 4804d6c458bSopenharmony_ci this.pauseInner = false; 4814d6c458bSopenharmony_ci const obj: ReadablePipeStream = { 4824d6c458bSopenharmony_ci write: destination, 4834d6c458bSopenharmony_ci dataCallback: (data: { data: string | Uint8Array }): void => { 4844d6c458bSopenharmony_ci destination.write(data.data); 4854d6c458bSopenharmony_ci if ((destination.writableLength || 0) > (destination.writableHighWatermark || DEFAULT_HIGH_WATER_MARK)) { 4864d6c458bSopenharmony_ci this.pauseInner = true; 4874d6c458bSopenharmony_ci this.readableFlowingInner = false; 4884d6c458bSopenharmony_ci } 4894d6c458bSopenharmony_ci }, 4904d6c458bSopenharmony_ci drainCallback: (): void => { 4914d6c458bSopenharmony_ci this.pauseInner = false; 4924d6c458bSopenharmony_ci this.readableFlowingInner = true; 4934d6c458bSopenharmony_ci this.read(this.readableLengthInner); 4944d6c458bSopenharmony_ci }, 4954d6c458bSopenharmony_ci endCallback: (): void => { 4964d6c458bSopenharmony_ci destination.end(); 4974d6c458bSopenharmony_ci } 4984d6c458bSopenharmony_ci }; 4994d6c458bSopenharmony_ci this.pipeWritableArrayInner.push(obj); 5004d6c458bSopenharmony_ci this.on(ReadableEvent.DATA, (data: { data: Function }) => { 5014d6c458bSopenharmony_ci obj.dataCallback(data); 5024d6c458bSopenharmony_ci }); 5034d6c458bSopenharmony_ci destination.on('drain', (): void => { 5044d6c458bSopenharmony_ci obj.drainCallback(); 5054d6c458bSopenharmony_ci }); 5064d6c458bSopenharmony_ci this.on(ReadableEvent.END, (): void => { 5074d6c458bSopenharmony_ci obj.endCallback(); 5084d6c458bSopenharmony_ci }); 5094d6c458bSopenharmony_ci destination?.listener?.emit('pipe', this); 5104d6c458bSopenharmony_ci return destination; 5114d6c458bSopenharmony_ci } 5124d6c458bSopenharmony_ci 5134d6c458bSopenharmony_ci /** 5144d6c458bSopenharmony_ci * Disconnect Writable from Readable. 5154d6c458bSopenharmony_ci * 5164d6c458bSopenharmony_ci * @param { Writable } [destination] - Writable Streams Needing to Be Disconnected. 5174d6c458bSopenharmony_ci * @returns { Readable } Returns the Readable object. 5184d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 5194d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 5204d6c458bSopenharmony_ci * @crossplatform 5214d6c458bSopenharmony_ci * @since 12 5224d6c458bSopenharmony_ci */ 5234d6c458bSopenharmony_ci unpipe(destination?: Writable): Readable { 5244d6c458bSopenharmony_ci const objIdx: number = this.pipeWritableArrayInner.findIndex((value: ReadablePipeStream) => value.write === destination); 5254d6c458bSopenharmony_ci if (objIdx !== -1) { 5264d6c458bSopenharmony_ci this.readableInner = false; 5274d6c458bSopenharmony_ci const obj: ReadablePipeStream = this.pipeWritableArrayInner[objIdx]; 5284d6c458bSopenharmony_ci this.listener?.off(ReadableEvent.DATA, obj.dataCallback); 5294d6c458bSopenharmony_ci destination?.listener?.off('drain', obj.drainCallback); 5304d6c458bSopenharmony_ci this.listener?.off(ReadableEvent.END, obj.endCallback); 5314d6c458bSopenharmony_ci destination?.listener?.emit('unpipe', this); 5324d6c458bSopenharmony_ci } 5334d6c458bSopenharmony_ci return this; 5344d6c458bSopenharmony_ci } 5354d6c458bSopenharmony_ci 5364d6c458bSopenharmony_ci /** 5374d6c458bSopenharmony_ci * Registering Event Messages. 5384d6c458bSopenharmony_ci * 5394d6c458bSopenharmony_ci * @param { string } event - Registering Events. 5404d6c458bSopenharmony_ci * @param { Callback } callback - Event callback. 5414d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 5424d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 5434d6c458bSopenharmony_ci * @crossplatform 5444d6c458bSopenharmony_ci * @since 12 5454d6c458bSopenharmony_ci */ 5464d6c458bSopenharmony_ci on(event: string, callback: Function): void { 5474d6c458bSopenharmony_ci const that = this; 5484d6c458bSopenharmony_ci if (!this.isInitialized) { 5494d6c458bSopenharmony_ci this.isInitialized = true; 5504d6c458bSopenharmony_ci this.doInitialize?.(() => { 5514d6c458bSopenharmony_ci }); 5524d6c458bSopenharmony_ci } 5534d6c458bSopenharmony_ci this.callbacks[event] = this.callbacks[event] ?? []; 5544d6c458bSopenharmony_ci const callbackFn = callback; 5554d6c458bSopenharmony_ci this.callbacks[event].push(callbackFn); 5564d6c458bSopenharmony_ci this.listener?.on(event, callbackFn); 5574d6c458bSopenharmony_ci Promise.resolve().then((): void => { 5584d6c458bSopenharmony_ci if (event === ReadableEvent.READABLE) { 5594d6c458bSopenharmony_ci this.readableFlowingInner = false; 5604d6c458bSopenharmony_ci if (this.readableInner) { 5614d6c458bSopenharmony_ci this.doRead?.(this.readableHighWatermarkInner); 5624d6c458bSopenharmony_ci } 5634d6c458bSopenharmony_ci } else if (event === ReadableEvent.DATA) { 5644d6c458bSopenharmony_ci this.readableFlowingInner = true; 5654d6c458bSopenharmony_ci if (!this.pauseInner) { 5664d6c458bSopenharmony_ci this.read(); 5674d6c458bSopenharmony_ci } 5684d6c458bSopenharmony_ci } 5694d6c458bSopenharmony_ci }); 5704d6c458bSopenharmony_ci } 5714d6c458bSopenharmony_ci 5724d6c458bSopenharmony_ci /** 5734d6c458bSopenharmony_ci * Cancel event message. 5744d6c458bSopenharmony_ci * 5754d6c458bSopenharmony_ci * @param { string } event - Registering Events. 5764d6c458bSopenharmony_ci * @param { Callback<emitter.EventData> } callback - Event callback. 5774d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 5784d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 5794d6c458bSopenharmony_ci * @crossplatform 5804d6c458bSopenharmony_ci * @since 12 5814d6c458bSopenharmony_ci */ 5824d6c458bSopenharmony_ci off(event: string, callback?: Function): void { 5834d6c458bSopenharmony_ci if (!event) { 5844d6c458bSopenharmony_ci this.throwError(new BusinessError(`Parameter error. The value of ${event} is null`, 401)); 5854d6c458bSopenharmony_ci return; 5864d6c458bSopenharmony_ci } 5874d6c458bSopenharmony_ci if (event && typeof event !== 'string') { 5884d6c458bSopenharmony_ci this.throwError(new BusinessError(`Parameter error. The type of ${event} must be string`, 401)); 5894d6c458bSopenharmony_ci return; 5904d6c458bSopenharmony_ci } 5914d6c458bSopenharmony_ci if (callback) { 5924d6c458bSopenharmony_ci this.callbacks[event]?.forEach((it: Function): void => { 5934d6c458bSopenharmony_ci if (callback === it) { 5944d6c458bSopenharmony_ci this.listener?.off(event, it); 5954d6c458bSopenharmony_ci } 5964d6c458bSopenharmony_ci }); 5974d6c458bSopenharmony_ci } else { 5984d6c458bSopenharmony_ci this.callbacks[event]?.forEach((it : Function) => this.listener?.off(event, it)); 5994d6c458bSopenharmony_ci } 6004d6c458bSopenharmony_ci } 6014d6c458bSopenharmony_ci 6024d6c458bSopenharmony_ci /** 6034d6c458bSopenharmony_ci * Called by the Readable during initialization. It should not be called actively. Call callback () after the 6044d6c458bSopenharmony_ci * resource has been initialized within the doInitialize, or call callback (err) when an error occurs. 6054d6c458bSopenharmony_ci * 6064d6c458bSopenharmony_ci * @param { Function } callback - Callback when the stream has completed the initial. 6074d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 6084d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 6094d6c458bSopenharmony_ci * @crossplatform 6104d6c458bSopenharmony_ci * @since 12 6114d6c458bSopenharmony_ci */ 6124d6c458bSopenharmony_ci doInitialize(callback: Function): void { 6134d6c458bSopenharmony_ci } 6144d6c458bSopenharmony_ci 6154d6c458bSopenharmony_ci /** 6164d6c458bSopenharmony_ci * The specific implementation of data production should not be actively called. Readable.read controls the 6174d6c458bSopenharmony_ci * calling. After data production, Readable.push should be called to push the produced data into the buffer. 6184d6c458bSopenharmony_ci * If push is not called, doRead will not be called again. 6194d6c458bSopenharmony_ci * 6204d6c458bSopenharmony_ci * @param { number } size -Expected length of the data to be read. 6214d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 6224d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 6234d6c458bSopenharmony_ci * @crossplatform 6244d6c458bSopenharmony_ci * @since 12 6254d6c458bSopenharmony_ci */ 6264d6c458bSopenharmony_ci doRead(size: number): void { 6274d6c458bSopenharmony_ci }; 6284d6c458bSopenharmony_ci 6294d6c458bSopenharmony_ci /** 6304d6c458bSopenharmony_ci * Adds the generated data to the buffer. The return value indicates whether the data in the buffer has not 6314d6c458bSopenharmony_ci * reached the highWaterMark (similar to Writable.write). If the chunk is null, all data has been generated. 6324d6c458bSopenharmony_ci * 6334d6c458bSopenharmony_ci * @param { Uint8Array | string | null } chunk - Binary data to be stored in the buffer. 6344d6c458bSopenharmony_ci * @param { string } [encoding] - Binary data encoding type. 6354d6c458bSopenharmony_ci * @returns { boolean } If true is returned, the data in the buffer reaches the highWaterMark. Otherwise, the 6364d6c458bSopenharmony_ci * data in the buffer does not reach the highWaterMark. 6374d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 6384d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 6394d6c458bSopenharmony_ci * @crossplatform 6404d6c458bSopenharmony_ci * @since 12 6414d6c458bSopenharmony_ci */ 6424d6c458bSopenharmony_ci push(chunk: Uint8Array | string | null, encoding?: string): boolean { 6434d6c458bSopenharmony_ci let bufferArr: Uint8Array; 6444d6c458bSopenharmony_ci if (encoding) { 6454d6c458bSopenharmony_ci this.setEncoding(encoding); 6464d6c458bSopenharmony_ci } 6474d6c458bSopenharmony_ci if (typeof chunk === 'string' || chunk instanceof Uint8Array) { 6484d6c458bSopenharmony_ci if (typeof chunk === 'string') { 6494d6c458bSopenharmony_ci bufferArr = this.encoder.encodeInto(chunk); 6504d6c458bSopenharmony_ci this.buf.push(...bufferArr); 6514d6c458bSopenharmony_ci this.readableLengthInner += bufferArr.length; 6524d6c458bSopenharmony_ci } else if (chunk instanceof Uint8Array) { 6534d6c458bSopenharmony_ci this.buf.push(...chunk); 6544d6c458bSopenharmony_ci this.readableLengthInner += chunk.length; 6554d6c458bSopenharmony_ci } 6564d6c458bSopenharmony_ci const highWaterMark = this.readableLengthInner <= this.readableHighWatermarkInner; 6574d6c458bSopenharmony_ci Promise.resolve().then((): void => { 6584d6c458bSopenharmony_ci try { 6594d6c458bSopenharmony_ci if (this.readableFlowingInner) { 6604d6c458bSopenharmony_ci !this.pauseInner && this.read(highWaterMark ? this.readableLengthInner : -1); 6614d6c458bSopenharmony_ci } else { 6624d6c458bSopenharmony_ci if (highWaterMark) { 6634d6c458bSopenharmony_ci this.doRead?.(this.readableHighWatermarkInner); 6644d6c458bSopenharmony_ci } 6654d6c458bSopenharmony_ci } 6664d6c458bSopenharmony_ci } catch (error) { 6674d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.ERROR, error); 6684d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.CLOSE); 6694d6c458bSopenharmony_ci } 6704d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.READABLE); 6714d6c458bSopenharmony_ci }); 6724d6c458bSopenharmony_ci return this.readableLengthInner < this.readableHighWatermarkInner; 6734d6c458bSopenharmony_ci } else if (chunk === null) { 6744d6c458bSopenharmony_ci if (!this.readableEndedInner && this.readableInner) { 6754d6c458bSopenharmony_ci !this.readableFlowingInner && this.listener?.emit(ReadableEvent.READABLE); 6764d6c458bSopenharmony_ci this.readableInner = false; 6774d6c458bSopenharmony_ci Promise.resolve().then((): void => { 6784d6c458bSopenharmony_ci this.readableEndedInner = true; 6794d6c458bSopenharmony_ci this.pauseInner = true; 6804d6c458bSopenharmony_ci this.closedInner = true; 6814d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.END); 6824d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.CLOSE); 6834d6c458bSopenharmony_ci }); 6844d6c458bSopenharmony_ci } 6854d6c458bSopenharmony_ci return false; 6864d6c458bSopenharmony_ci } else { 6874d6c458bSopenharmony_ci this.readableInner = false; 6884d6c458bSopenharmony_ci this.erroredInner = new BusinessError('ERR_INVALID_ARG_TYPE'); 6894d6c458bSopenharmony_ci this.listener?.emit(ReadableEvent.ERROR, this.erroredInner); 6904d6c458bSopenharmony_ci return false; 6914d6c458bSopenharmony_ci } 6924d6c458bSopenharmony_ci }; 6934d6c458bSopenharmony_ci 6944d6c458bSopenharmony_ci throwError(error: Error): void { 6954d6c458bSopenharmony_ci this.erroredInner = error; 6964d6c458bSopenharmony_ci if (this.listener && this.listener.listenerCount(WritableEvent.ERROR) > 0) { 6974d6c458bSopenharmony_ci setTimeout((): void => { 6984d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.ERROR, error); 6994d6c458bSopenharmony_ci }); 7004d6c458bSopenharmony_ci } else { 7014d6c458bSopenharmony_ci throw error; 7024d6c458bSopenharmony_ci } 7034d6c458bSopenharmony_ci } 7044d6c458bSopenharmony_ci} 7054d6c458bSopenharmony_ci 7064d6c458bSopenharmony_ci// @ts-ignore 7074d6c458bSopenharmony_ciReadable.prototype.doRead = null; 7084d6c458bSopenharmony_ci 7094d6c458bSopenharmony_ciclass Writable { 7104d6c458bSopenharmony_ci public listener: EventEmitter | undefined; 7114d6c458bSopenharmony_ci private callbacks: { [key: string]: Function[] } = {}; 7124d6c458bSopenharmony_ci private buffer: ({ encoding?: string, chunk: string | Uint8Array, callback: Function })[] = []; 7134d6c458bSopenharmony_ci private writing: boolean = false; 7144d6c458bSopenharmony_ci private encoding: string | undefined; 7154d6c458bSopenharmony_ci protected encoder = new TextEncoder(); 7164d6c458bSopenharmony_ci private ending: boolean = false; 7174d6c458bSopenharmony_ci private writableObjectModeInner: boolean | undefined; 7184d6c458bSopenharmony_ci private writableHighWatermarkInner: number; 7194d6c458bSopenharmony_ci private writableInner: boolean | undefined; 7204d6c458bSopenharmony_ci private writableLengthInner: number | undefined; 7214d6c458bSopenharmony_ci private writableNeedDrainInner: boolean | undefined; 7224d6c458bSopenharmony_ci private writableCorkedInner: number = 0; 7234d6c458bSopenharmony_ci private writableEndedInner: boolean | undefined; 7244d6c458bSopenharmony_ci private writableFinishedInner: boolean | undefined; 7254d6c458bSopenharmony_ci private erroredInner: Error | undefined | null; 7264d6c458bSopenharmony_ci private closedInner: boolean | undefined; 7274d6c458bSopenharmony_ci 7284d6c458bSopenharmony_ci /** 7294d6c458bSopenharmony_ci * The Writable constructor. 7304d6c458bSopenharmony_ci * 7314d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 7324d6c458bSopenharmony_ci * @crossplatform 7334d6c458bSopenharmony_ci * @since 12 7344d6c458bSopenharmony_ci */ 7354d6c458bSopenharmony_ci constructor(options?: { 7364d6c458bSopenharmony_ci highWaterMark?: number | undefined; 7374d6c458bSopenharmony_ci objectMode?: boolean | undefined; 7384d6c458bSopenharmony_ci }) { 7394d6c458bSopenharmony_ci this.listener = new EventEmitter(); 7404d6c458bSopenharmony_ci if (!options) { 7414d6c458bSopenharmony_ci options = { 7424d6c458bSopenharmony_ci highWaterMark: DEFAULT_HIGH_WATER_MARK, 7434d6c458bSopenharmony_ci objectMode: false, 7444d6c458bSopenharmony_ci }; 7454d6c458bSopenharmony_ci } 7464d6c458bSopenharmony_ci this.writableHighWatermarkInner = options.highWaterMark ?? DEFAULT_HIGH_WATER_MARK; 7474d6c458bSopenharmony_ci this.writableObjectModeInner = options.objectMode || false; 7484d6c458bSopenharmony_ci this.writableLengthInner = 0; 7494d6c458bSopenharmony_ci this.writableEndedInner = false; 7504d6c458bSopenharmony_ci this.writableNeedDrainInner = false; 7514d6c458bSopenharmony_ci this.writableInner = true; 7524d6c458bSopenharmony_ci this.writableCorkedInner = 0; 7534d6c458bSopenharmony_ci this.writableFinishedInner = false; 7544d6c458bSopenharmony_ci this.erroredInner = null; 7554d6c458bSopenharmony_ci this.encoding = 'utf8'; 7564d6c458bSopenharmony_ci this.closedInner = false; 7574d6c458bSopenharmony_ci this.doInitialize((error: Error): void => { 7584d6c458bSopenharmony_ci if (error) { 7594d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.ERROR, error); 7604d6c458bSopenharmony_ci } 7614d6c458bSopenharmony_ci }); 7624d6c458bSopenharmony_ci } 7634d6c458bSopenharmony_ci 7644d6c458bSopenharmony_ci /** 7654d6c458bSopenharmony_ci * Returns boolean indicating whether it is in ObjectMode. 7664d6c458bSopenharmony_ci * 7674d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 7684d6c458bSopenharmony_ci * @crossplatform 7694d6c458bSopenharmony_ci * @since 12 7704d6c458bSopenharmony_ci */ 7714d6c458bSopenharmony_ci get writableObjectMode(): boolean | undefined { 7724d6c458bSopenharmony_ci return this.writableObjectModeInner; 7734d6c458bSopenharmony_ci } 7744d6c458bSopenharmony_ci 7754d6c458bSopenharmony_ci /** 7764d6c458bSopenharmony_ci * Value of highWaterMark. 7774d6c458bSopenharmony_ci * 7784d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 7794d6c458bSopenharmony_ci * @crossplatform 7804d6c458bSopenharmony_ci * @since 12 7814d6c458bSopenharmony_ci */ 7824d6c458bSopenharmony_ci get writableHighWatermark(): number | undefined { 7834d6c458bSopenharmony_ci return this.writableHighWatermarkInner; 7844d6c458bSopenharmony_ci } 7854d6c458bSopenharmony_ci 7864d6c458bSopenharmony_ci /** 7874d6c458bSopenharmony_ci * Is true if it is safe to call writable.write(), which means the stream has not been destroyed, errored, or ended. 7884d6c458bSopenharmony_ci * 7894d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 7904d6c458bSopenharmony_ci * @crossplatform 7914d6c458bSopenharmony_ci * @since 12 7924d6c458bSopenharmony_ci */ 7934d6c458bSopenharmony_ci get writable(): boolean | undefined { 7944d6c458bSopenharmony_ci return this.writableInner; 7954d6c458bSopenharmony_ci } 7964d6c458bSopenharmony_ci 7974d6c458bSopenharmony_ci /** 7984d6c458bSopenharmony_ci * Size of data this can be flushed, in bytes or objects. 7994d6c458bSopenharmony_ci * 8004d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 8014d6c458bSopenharmony_ci * @crossplatform 8024d6c458bSopenharmony_ci * @since 12 8034d6c458bSopenharmony_ci */ 8044d6c458bSopenharmony_ci get writableLength(): number | undefined { 8054d6c458bSopenharmony_ci return this.writableLengthInner; 8064d6c458bSopenharmony_ci } 8074d6c458bSopenharmony_ci 8084d6c458bSopenharmony_ci /** 8094d6c458bSopenharmony_ci * If the buffer of the stream is full and true, otherwise it is false. 8104d6c458bSopenharmony_ci * 8114d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 8124d6c458bSopenharmony_ci * @crossplatform 8134d6c458bSopenharmony_ci * @since 12 8144d6c458bSopenharmony_ci */ 8154d6c458bSopenharmony_ci get writableNeedDrain(): boolean | undefined { 8164d6c458bSopenharmony_ci return this.writableNeedDrainInner; 8174d6c458bSopenharmony_ci } 8184d6c458bSopenharmony_ci 8194d6c458bSopenharmony_ci /** 8204d6c458bSopenharmony_ci * Number of times writable.uncork() needs to be called in order to fully uncork the stream. 8214d6c458bSopenharmony_ci * 8224d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 8234d6c458bSopenharmony_ci * @crossplatform 8244d6c458bSopenharmony_ci * @since 12 8254d6c458bSopenharmony_ci */ 8264d6c458bSopenharmony_ci get writableCorked(): number | undefined { 8274d6c458bSopenharmony_ci return this.writableCorkedInner; 8284d6c458bSopenharmony_ci }; 8294d6c458bSopenharmony_ci 8304d6c458bSopenharmony_ci /** 8314d6c458bSopenharmony_ci * Whether Writable.end has been called. 8324d6c458bSopenharmony_ci * 8334d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 8344d6c458bSopenharmony_ci * @crossplatform 8354d6c458bSopenharmony_ci * @since 12 8364d6c458bSopenharmony_ci */ 8374d6c458bSopenharmony_ci get writableEnded(): boolean | undefined { 8384d6c458bSopenharmony_ci return this.writableEndedInner; 8394d6c458bSopenharmony_ci } 8404d6c458bSopenharmony_ci 8414d6c458bSopenharmony_ci /** 8424d6c458bSopenharmony_ci * Whether Writable.end has been called and all buffers have been flushed. 8434d6c458bSopenharmony_ci * 8444d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 8454d6c458bSopenharmony_ci * @crossplatform 8464d6c458bSopenharmony_ci * @since 12 8474d6c458bSopenharmony_ci */ 8484d6c458bSopenharmony_ci get writableFinished(): boolean | undefined { 8494d6c458bSopenharmony_ci return this.writableFinishedInner; 8504d6c458bSopenharmony_ci } 8514d6c458bSopenharmony_ci 8524d6c458bSopenharmony_ci /** 8534d6c458bSopenharmony_ci * Returns error if the stream has been destroyed with an error. 8544d6c458bSopenharmony_ci * 8554d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 8564d6c458bSopenharmony_ci * @crossplatform 8574d6c458bSopenharmony_ci * @since 12 8584d6c458bSopenharmony_ci */ 8594d6c458bSopenharmony_ci get errored(): Error | undefined | null { 8604d6c458bSopenharmony_ci return this.erroredInner; 8614d6c458bSopenharmony_ci } 8624d6c458bSopenharmony_ci 8634d6c458bSopenharmony_ci /** 8644d6c458bSopenharmony_ci * Writable completes destroyfile and returns true, otherwise returns false. 8654d6c458bSopenharmony_ci * 8664d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 8674d6c458bSopenharmony_ci * @crossplatform 8684d6c458bSopenharmony_ci * @since 12 8694d6c458bSopenharmony_ci */ 8704d6c458bSopenharmony_ci get closed(): boolean | undefined { 8714d6c458bSopenharmony_ci return this.closedInner; 8724d6c458bSopenharmony_ci } 8734d6c458bSopenharmony_ci 8744d6c458bSopenharmony_ci /** 8754d6c458bSopenharmony_ci * writes a chunk to Writable and invokes callback when the chunk is flushed. The return value indicates 8764d6c458bSopenharmony_ci * whether the internal buffer of the Writable reaches the hightWaterMark. If true is returned, the buffer 8774d6c458bSopenharmony_ci * does not reach the hightWaterMark. If false is returned, the buffer has been reached. The write function 8784d6c458bSopenharmony_ci * should be called after the drain event is triggered. If the write function is called continuously, 8794d6c458bSopenharmony_ci * the chunk is still added to the buffer until the memory overflows 8804d6c458bSopenharmony_ci * 8814d6c458bSopenharmony_ci * @param { string | Uint8Array } [chunk] - Data to be written. 8824d6c458bSopenharmony_ci * @param { string } [encoding] - Encoding type. 8834d6c458bSopenharmony_ci * @param { Function } [callback] - Callback after writing. 8844d6c458bSopenharmony_ci * @returns { boolean } Write success returns true, write failure returns false. 8854d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 8864d6c458bSopenharmony_ci * @throws { BusinessError } 10200035 - if doWrite not implemented, an exception will be thrown. 8874d6c458bSopenharmony_ci * @throws { BusinessError } 10200036 - if stream has been ended, writing data to it will throw an error. 8884d6c458bSopenharmony_ci * @throws { BusinessError } 10200037 - if the callback is called multiple times consecutively, an error will be thrown. 8894d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 8904d6c458bSopenharmony_ci * @crossplatform 8914d6c458bSopenharmony_ci * @since 12 8924d6c458bSopenharmony_ci */ 8934d6c458bSopenharmony_ci write(chunk?: string | Uint8Array, encoding?: string, callback?: Function): boolean { 8944d6c458bSopenharmony_ci if (encoding) { 8954d6c458bSopenharmony_ci this.setDefaultEncoding(encoding); 8964d6c458bSopenharmony_ci } 8974d6c458bSopenharmony_ci if (chunk === null) { 8984d6c458bSopenharmony_ci throw new BusinessError(`Parameter error. The type of ${chunk} must be string or UintArray`, 401); 8994d6c458bSopenharmony_ci } 9004d6c458bSopenharmony_ci if (typeof chunk !== 'string' && !(chunk instanceof Uint8Array)) { 9014d6c458bSopenharmony_ci throw new BusinessError(`Parameter error. The type of ${chunk} must be string or UintArray`, 401); 9024d6c458bSopenharmony_ci } 9034d6c458bSopenharmony_ci if (this.ending && !this.writing) { 9044d6c458bSopenharmony_ci setTimeout((): void => { 9054d6c458bSopenharmony_ci this.erroredInner = new BusinessError('write after end', 10200036); 9064d6c458bSopenharmony_ci callback?.(this.erroredInner); 9074d6c458bSopenharmony_ci this.throwError(this.erroredInner); 9084d6c458bSopenharmony_ci }); 9094d6c458bSopenharmony_ci return false; 9104d6c458bSopenharmony_ci } 9114d6c458bSopenharmony_ci if (this.erroredInner) { 9124d6c458bSopenharmony_ci return false; 9134d6c458bSopenharmony_ci } 9144d6c458bSopenharmony_ci let flag = false; 9154d6c458bSopenharmony_ci if (chunk instanceof Uint8Array) { 9164d6c458bSopenharmony_ci flag = this.writeUint8Array(chunk, encoding ?? this.encoding, callback); 9174d6c458bSopenharmony_ci } else { 9184d6c458bSopenharmony_ci flag = this.writeString(chunk!, encoding ?? this.encoding, callback); 9194d6c458bSopenharmony_ci } 9204d6c458bSopenharmony_ci if (!flag) { 9214d6c458bSopenharmony_ci this.writableNeedDrainInner = true; 9224d6c458bSopenharmony_ci } 9234d6c458bSopenharmony_ci return flag; 9244d6c458bSopenharmony_ci } 9254d6c458bSopenharmony_ci 9264d6c458bSopenharmony_ci private getChunkLength(chunk: string | Uint8Array): number { 9274d6c458bSopenharmony_ci if (chunk instanceof Uint8Array) { 9284d6c458bSopenharmony_ci return chunk.byteLength; 9294d6c458bSopenharmony_ci } else { 9304d6c458bSopenharmony_ci return this.encoder.encodeInto(chunk).byteLength; 9314d6c458bSopenharmony_ci } 9324d6c458bSopenharmony_ci } 9334d6c458bSopenharmony_ci 9344d6c458bSopenharmony_ci private writeUint8Array(chunk: Uint8Array, encoding?: string, callback?: Function): boolean { 9354d6c458bSopenharmony_ci this.writableLengthInner! += this.getChunkLength(chunk); 9364d6c458bSopenharmony_ci const hasRemaining = this.writableLengthInner! < this.writableHighWatermark!; 9374d6c458bSopenharmony_ci const fnBack = runOnce((error?: Error): void => { 9384d6c458bSopenharmony_ci if (error && error instanceof Error) { 9394d6c458bSopenharmony_ci this.writableInner = false; 9404d6c458bSopenharmony_ci this.throwError(error); 9414d6c458bSopenharmony_ci return; 9424d6c458bSopenharmony_ci } 9434d6c458bSopenharmony_ci callback?.(error ?? null); 9444d6c458bSopenharmony_ci this.freshCache(); 9454d6c458bSopenharmony_ci }, (multipleTimes: boolean, err: Error): void => { 9464d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.ERROR, ERR_MULTIPLE_CALLBACK); 9474d6c458bSopenharmony_ci }); 9484d6c458bSopenharmony_ci if (this.writableCorkedInner === 0) { 9494d6c458bSopenharmony_ci if (!this.writing) { 9504d6c458bSopenharmony_ci this.writing = true; 9514d6c458bSopenharmony_ci this.doWrite(chunk, encoding ?? 'utf8', fnBack); 9524d6c458bSopenharmony_ci } else { 9534d6c458bSopenharmony_ci this.buffer.push({ chunk: chunk, encoding: encoding, callback: fnBack }); 9544d6c458bSopenharmony_ci } 9554d6c458bSopenharmony_ci } else { 9564d6c458bSopenharmony_ci this.buffer.push({ chunk: chunk, encoding: encoding, callback: fnBack }); 9574d6c458bSopenharmony_ci } 9584d6c458bSopenharmony_ci return hasRemaining; 9594d6c458bSopenharmony_ci } 9604d6c458bSopenharmony_ci 9614d6c458bSopenharmony_ci private writeString(chunk: string, encoding?: string, callback?: Function): boolean { 9624d6c458bSopenharmony_ci this.writableLengthInner! += this.getChunkLength(chunk); 9634d6c458bSopenharmony_ci const hasRemaining = this.writableLengthInner! < this.writableHighWatermark!; 9644d6c458bSopenharmony_ci const fb = runOnce((error?: Error): void => { 9654d6c458bSopenharmony_ci if (error) { 9664d6c458bSopenharmony_ci this.erroredInner = error; 9674d6c458bSopenharmony_ci } 9684d6c458bSopenharmony_ci callback?.(error ?? null); 9694d6c458bSopenharmony_ci this.freshCache(); 9704d6c458bSopenharmony_ci if (error && error instanceof Error) { 9714d6c458bSopenharmony_ci this.writableInner = false; 9724d6c458bSopenharmony_ci this.erroredInner = error; 9734d6c458bSopenharmony_ci Promise.resolve().then((): void => { 9744d6c458bSopenharmony_ci if (this.isOnError()) { 9754d6c458bSopenharmony_ci this.emitErrorOnce(error); 9764d6c458bSopenharmony_ci } else { 9774d6c458bSopenharmony_ci this.emitErrorOnce(error); 9784d6c458bSopenharmony_ci throw error; 9794d6c458bSopenharmony_ci } 9804d6c458bSopenharmony_ci }); 9814d6c458bSopenharmony_ci return; 9824d6c458bSopenharmony_ci } 9834d6c458bSopenharmony_ci }, () => { 9844d6c458bSopenharmony_ci this.emitErrorOnce(ERR_MULTIPLE_CALLBACK, true); 9854d6c458bSopenharmony_ci }); 9864d6c458bSopenharmony_ci 9874d6c458bSopenharmony_ci if (this.writableCorkedInner === 0) { 9884d6c458bSopenharmony_ci if (!this.writing) { 9894d6c458bSopenharmony_ci this.writing = true; 9904d6c458bSopenharmony_ci this.doWrite?.(chunk, encoding ?? 'utf8', fb); 9914d6c458bSopenharmony_ci if (!this.doWrite && !hasRemaining) { 9924d6c458bSopenharmony_ci Promise.resolve().then(() => { 9934d6c458bSopenharmony_ci this.writableLengthInner = 0; 9944d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.DRAIN); 9954d6c458bSopenharmony_ci }); 9964d6c458bSopenharmony_ci } 9974d6c458bSopenharmony_ci } else { 9984d6c458bSopenharmony_ci this.buffer.push({ chunk: chunk, encoding: encoding, callback: fb }); 9994d6c458bSopenharmony_ci } 10004d6c458bSopenharmony_ci } else { 10014d6c458bSopenharmony_ci this.buffer.push({ chunk: chunk, encoding: encoding, callback: fb }); 10024d6c458bSopenharmony_ci } 10034d6c458bSopenharmony_ci return this.erroredInner ? false : hasRemaining; 10044d6c458bSopenharmony_ci } 10054d6c458bSopenharmony_ci 10064d6c458bSopenharmony_ci private freshCache(): void { 10074d6c458bSopenharmony_ci const current = this.buffer.shift(); 10084d6c458bSopenharmony_ci if (current) { 10094d6c458bSopenharmony_ci this.doWrite?.(current.chunk, current.encoding ?? 'utf8', current.callback); 10104d6c458bSopenharmony_ci this.writableLengthInner! -= this.getChunkLength(current.chunk); 10114d6c458bSopenharmony_ci } else { 10124d6c458bSopenharmony_ci this.writing = false; 10134d6c458bSopenharmony_ci this.writableLengthInner = 0; 10144d6c458bSopenharmony_ci if (!this.finishMayBe()) { 10154d6c458bSopenharmony_ci this.writableNeedDrainInner = false; 10164d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.DRAIN); 10174d6c458bSopenharmony_ci } 10184d6c458bSopenharmony_ci } 10194d6c458bSopenharmony_ci } 10204d6c458bSopenharmony_ci 10214d6c458bSopenharmony_ci private freshCacheV(): void { 10224d6c458bSopenharmony_ci if (this.buffer.length > 0) { 10234d6c458bSopenharmony_ci if (this.doWritev) { 10244d6c458bSopenharmony_ci const funCallback = runOnce((error?: Error): void => { 10254d6c458bSopenharmony_ci if (error && error instanceof Error) { 10264d6c458bSopenharmony_ci this.erroredInner = error; 10274d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.ERROR, error); 10284d6c458bSopenharmony_ci return; 10294d6c458bSopenharmony_ci } 10304d6c458bSopenharmony_ci this.buffer = []; 10314d6c458bSopenharmony_ci }, () => { 10324d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.ERROR, ERR_MULTIPLE_CALLBACK); 10334d6c458bSopenharmony_ci }); 10344d6c458bSopenharmony_ci // @ts-ignore 10354d6c458bSopenharmony_ci this.doWritev(this.buffer.map((item: { encoding?: string; chunk: string | Uint8Array; callback: Function }) => { 10364d6c458bSopenharmony_ci return item.chunk; 10374d6c458bSopenharmony_ci }), funCallback); 10384d6c458bSopenharmony_ci if (!this.finishMayBe()) { 10394d6c458bSopenharmony_ci this.writableNeedDrainInner = true; 10404d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.DRAIN); 10414d6c458bSopenharmony_ci } 10424d6c458bSopenharmony_ci } else { 10434d6c458bSopenharmony_ci this.freshCache(); 10444d6c458bSopenharmony_ci } 10454d6c458bSopenharmony_ci } 10464d6c458bSopenharmony_ci } 10474d6c458bSopenharmony_ci 10484d6c458bSopenharmony_ci endInner(chunk?: string | Uint8Array, encoding?: string, callback?: Function): void { 10494d6c458bSopenharmony_ci if (chunk) { 10504d6c458bSopenharmony_ci if (this.writing) { 10514d6c458bSopenharmony_ci this.write(chunk, encoding, callback); 10524d6c458bSopenharmony_ci } else { 10534d6c458bSopenharmony_ci this.doWrite?.(chunk!, encoding ?? 'utf8', (error?: Error): void => { 10544d6c458bSopenharmony_ci if (error && error instanceof Error) { 10554d6c458bSopenharmony_ci this.erroredInner = error; 10564d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.ERROR, error); 10574d6c458bSopenharmony_ci } else { 10584d6c458bSopenharmony_ci this.writableLengthInner! -= this.getChunkLength(chunk); 10594d6c458bSopenharmony_ci this.writing = false; 10604d6c458bSopenharmony_ci this.finishMayBe(); 10614d6c458bSopenharmony_ci } 10624d6c458bSopenharmony_ci this.writableEndedInner = true; 10634d6c458bSopenharmony_ci this.writableInner = false; 10644d6c458bSopenharmony_ci asyncFn((): void => { 10654d6c458bSopenharmony_ci callback?.(this.erroredInner ?? error ?? null); 10664d6c458bSopenharmony_ci })(); 10674d6c458bSopenharmony_ci if (!this.writableFinishedInner) { 10684d6c458bSopenharmony_ci this.writableFinishedInner = true; 10694d6c458bSopenharmony_ci asyncFn((): void => { 10704d6c458bSopenharmony_ci if ((!this.erroredInner || this.erroredInner.message === 'write after end') && !this.isOnError()) { 10714d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.FINISH); 10724d6c458bSopenharmony_ci } 10734d6c458bSopenharmony_ci })(); 10744d6c458bSopenharmony_ci } 10754d6c458bSopenharmony_ci }); 10764d6c458bSopenharmony_ci } 10774d6c458bSopenharmony_ci } else { 10784d6c458bSopenharmony_ci if (this.writableEndedInner) { 10794d6c458bSopenharmony_ci this.erroredInner = new BusinessError('write after end', 10200036); 10804d6c458bSopenharmony_ci callback?.(this.erroredInner); 10814d6c458bSopenharmony_ci } else { 10824d6c458bSopenharmony_ci setTimeout(() => callback?.(this.erroredInner)); 10834d6c458bSopenharmony_ci } 10844d6c458bSopenharmony_ci if (!this.writableFinishedInner && !this.writableEndedInner) { 10854d6c458bSopenharmony_ci this.writableFinishedInner = true; 10864d6c458bSopenharmony_ci asyncFn((): void => { 10874d6c458bSopenharmony_ci if (!this.erroredInner || this.erroredInner.message === 'write after end') { 10884d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.FINISH); 10894d6c458bSopenharmony_ci } 10904d6c458bSopenharmony_ci })(); 10914d6c458bSopenharmony_ci } 10924d6c458bSopenharmony_ci } 10934d6c458bSopenharmony_ci } 10944d6c458bSopenharmony_ci 10954d6c458bSopenharmony_ci /** 10964d6c458bSopenharmony_ci * Write the last chunk to Writable. 10974d6c458bSopenharmony_ci * 10984d6c458bSopenharmony_ci * @param { string | Uint8Array } [chunk] - Data to be written. 10994d6c458bSopenharmony_ci * @param { string } [encoding] - Encoding type. 11004d6c458bSopenharmony_ci * @param { Function } [callback] - Callback after writing. 11014d6c458bSopenharmony_ci * @returns { Writable } Returns the Writable object. 11024d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 11034d6c458bSopenharmony_ci * @throws { BusinessError } 10200035 - if doWrite not implemented, an exception will be thrown. 11044d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 11054d6c458bSopenharmony_ci * @crossplatform 11064d6c458bSopenharmony_ci * @since 12 11074d6c458bSopenharmony_ci */ 11084d6c458bSopenharmony_ci end(chunk?: string | Uint8Array, encoding?: string, callback?: Function): Writable { 11094d6c458bSopenharmony_ci if (this.writableFinishedInner) { 11104d6c458bSopenharmony_ci this.erroredInner = ERR_STREAM_ALREADY_FINISHED; 11114d6c458bSopenharmony_ci setTimeout(() => callback?.(this.erroredInner)); 11124d6c458bSopenharmony_ci this.emitErrorOnce(this.erroredInner); 11134d6c458bSopenharmony_ci return this; 11144d6c458bSopenharmony_ci } else if (this.writableEndedInner) { 11154d6c458bSopenharmony_ci this.erroredInner = ERR_WRITE_AFTER_END; 11164d6c458bSopenharmony_ci setTimeout(() => callback?.(this.erroredInner)); 11174d6c458bSopenharmony_ci this.emitErrorOnce(this.erroredInner); 11184d6c458bSopenharmony_ci return this; 11194d6c458bSopenharmony_ci } 11204d6c458bSopenharmony_ci if (this.erroredInner) { 11214d6c458bSopenharmony_ci setTimeout(() => callback?.(this.erroredInner)); 11224d6c458bSopenharmony_ci return this; 11234d6c458bSopenharmony_ci } 11244d6c458bSopenharmony_ci this.writableNeedDrainInner = false; 11254d6c458bSopenharmony_ci this.closedInner = true; 11264d6c458bSopenharmony_ci this.ending = true; 11274d6c458bSopenharmony_ci this.writableInner = false; 11284d6c458bSopenharmony_ci if (!this.writableEndedInner) { 11294d6c458bSopenharmony_ci if (this.writableCorkedInner === 0) { 11304d6c458bSopenharmony_ci this.endInner(chunk, encoding, callback); 11314d6c458bSopenharmony_ci } else { 11324d6c458bSopenharmony_ci this.writableCorkedInner = 1; 11334d6c458bSopenharmony_ci this.uncork(); 11344d6c458bSopenharmony_ci } 11354d6c458bSopenharmony_ci } 11364d6c458bSopenharmony_ci this.writableEndedInner = true; 11374d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.CLOSE); 11384d6c458bSopenharmony_ci return this; 11394d6c458bSopenharmony_ci } 11404d6c458bSopenharmony_ci 11414d6c458bSopenharmony_ci private finishMayBe(): boolean { 11424d6c458bSopenharmony_ci return !this.writing && this.writableCorkedInner === 0 && this.ending; 11434d6c458bSopenharmony_ci } 11444d6c458bSopenharmony_ci 11454d6c458bSopenharmony_ci /** 11464d6c458bSopenharmony_ci * Set the default encoding mode. 11474d6c458bSopenharmony_ci * 11484d6c458bSopenharmony_ci * @param { string } [encoding] - Encoding type.Default: utf8. 11494d6c458bSopenharmony_ci * @returns { boolean } Setting successful returns true, setting failed returns false. 11504d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 11514d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 11524d6c458bSopenharmony_ci * @crossplatform 11534d6c458bSopenharmony_ci * @since 12 11544d6c458bSopenharmony_ci */ 11554d6c458bSopenharmony_ci 11564d6c458bSopenharmony_ci setDefaultEncoding(encoding?: string): boolean { 11574d6c458bSopenharmony_ci if (!encoding) { 11584d6c458bSopenharmony_ci return false; 11594d6c458bSopenharmony_ci } 11604d6c458bSopenharmony_ci if (encoding.toLowerCase() === 'utf8') { 11614d6c458bSopenharmony_ci encoding = 'utf-8'; 11624d6c458bSopenharmony_ci } 11634d6c458bSopenharmony_ci if (ENCODING_SET.indexOf(encoding.toLowerCase()) !== -1) { 11644d6c458bSopenharmony_ci this.encoding = encoding.toLowerCase(); 11654d6c458bSopenharmony_ci try { 11664d6c458bSopenharmony_ci if (encoding.toLowerCase() !== 'ascii') { 11674d6c458bSopenharmony_ci this.encoder = new TextEncoder(encoding); 11684d6c458bSopenharmony_ci } 11694d6c458bSopenharmony_ci } catch (e) { 11704d6c458bSopenharmony_ci this.throwError(e as Error); 11714d6c458bSopenharmony_ci return false; 11724d6c458bSopenharmony_ci } 11734d6c458bSopenharmony_ci return true; 11744d6c458bSopenharmony_ci } else { 11754d6c458bSopenharmony_ci const err: BusinessError = new BusinessError(`Unknown encoding: ${encoding}`); 11764d6c458bSopenharmony_ci this.throwError(err); 11774d6c458bSopenharmony_ci return false; 11784d6c458bSopenharmony_ci } 11794d6c458bSopenharmony_ci } 11804d6c458bSopenharmony_ci 11814d6c458bSopenharmony_ci /** 11824d6c458bSopenharmony_ci * After the call, all Write operations will be forced to write to the buffer instead of being flushed. 11834d6c458bSopenharmony_ci * 11844d6c458bSopenharmony_ci * @returns { boolean } Setting successful returns true, setting failed returns false. 11854d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 11864d6c458bSopenharmony_ci * @crossplatform 11874d6c458bSopenharmony_ci * @since 12 11884d6c458bSopenharmony_ci */ 11894d6c458bSopenharmony_ci cork(): boolean { 11904d6c458bSopenharmony_ci this.writableCorkedInner += 1; 11914d6c458bSopenharmony_ci return true; 11924d6c458bSopenharmony_ci } 11934d6c458bSopenharmony_ci 11944d6c458bSopenharmony_ci /** 11954d6c458bSopenharmony_ci * After calling, flush all buffers. 11964d6c458bSopenharmony_ci * 11974d6c458bSopenharmony_ci * @returns { boolean } Setting successful returns true, setting failed returns false. 11984d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 11994d6c458bSopenharmony_ci * @crossplatform 12004d6c458bSopenharmony_ci * @since 12 12014d6c458bSopenharmony_ci */ 12024d6c458bSopenharmony_ci uncork(): boolean { 12034d6c458bSopenharmony_ci if (this.writableCorkedInner > 0) { 12044d6c458bSopenharmony_ci this.writableCorkedInner -= 1; 12054d6c458bSopenharmony_ci } 12064d6c458bSopenharmony_ci if (this.writableCorkedInner === 0) { 12074d6c458bSopenharmony_ci this.freshCacheV(); 12084d6c458bSopenharmony_ci } 12094d6c458bSopenharmony_ci return true; 12104d6c458bSopenharmony_ci } 12114d6c458bSopenharmony_ci 12124d6c458bSopenharmony_ci /** 12134d6c458bSopenharmony_ci * Registering Event Messages. 12144d6c458bSopenharmony_ci * 12154d6c458bSopenharmony_ci * @param { string } event - Register Event. 12164d6c458bSopenharmony_ci * @param { Callback<emitter.EventData> } callback - event callbacks. 12174d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 12184d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 12194d6c458bSopenharmony_ci * @crossplatform 12204d6c458bSopenharmony_ci * @since 12 12214d6c458bSopenharmony_ci */ 12224d6c458bSopenharmony_ci on(event: string, callback: Function): void { 12234d6c458bSopenharmony_ci this.callbacks[event] = this.callbacks[event] ?? []; 12244d6c458bSopenharmony_ci const callbackFn = callback.bind(this); 12254d6c458bSopenharmony_ci this.callbacks[event].push(callbackFn); 12264d6c458bSopenharmony_ci this.listener?.on(event, callbackFn); 12274d6c458bSopenharmony_ci } 12284d6c458bSopenharmony_ci 12294d6c458bSopenharmony_ci /** 12304d6c458bSopenharmony_ci * Cancel event message. 12314d6c458bSopenharmony_ci * 12324d6c458bSopenharmony_ci * @param { string } event - Register Event. 12334d6c458bSopenharmony_ci * @param { Callback<emitter.EventData> } callback - event callbacks. 12344d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 12354d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 12364d6c458bSopenharmony_ci * @crossplatform 12374d6c458bSopenharmony_ci * @since 12 12384d6c458bSopenharmony_ci */ 12394d6c458bSopenharmony_ci off(event: string, callback?: Function): void { 12404d6c458bSopenharmony_ci if (!event) { 12414d6c458bSopenharmony_ci this.throwError(new BusinessError(`Parameter error. The value of event is null `, 401)); 12424d6c458bSopenharmony_ci return; 12434d6c458bSopenharmony_ci } 12444d6c458bSopenharmony_ci if (callback) { 12454d6c458bSopenharmony_ci this.callbacks[event]?.forEach((it: Function): void => { 12464d6c458bSopenharmony_ci if (callback && callback === it) { 12474d6c458bSopenharmony_ci this.listener?.off(event, it); 12484d6c458bSopenharmony_ci } 12494d6c458bSopenharmony_ci }); 12504d6c458bSopenharmony_ci } else { 12514d6c458bSopenharmony_ci this.callbacks[event]?.forEach((it: Function) => this.listener?.off(event, it)); 12524d6c458bSopenharmony_ci } 12534d6c458bSopenharmony_ci } 12544d6c458bSopenharmony_ci 12554d6c458bSopenharmony_ci noWriteOpes(chunk: string | Uint8Array, encoding: string, callback: Function): void { 12564d6c458bSopenharmony_ci if (this.doWritev === null) { 12574d6c458bSopenharmony_ci this.throwError(ERR_DOWRITE_NOT_IMPLEMENTED); 12584d6c458bSopenharmony_ci } else { 12594d6c458bSopenharmony_ci // @ts-ignore 12604d6c458bSopenharmony_ci this.doWritev([chunk], callback); 12614d6c458bSopenharmony_ci } 12624d6c458bSopenharmony_ci } 12634d6c458bSopenharmony_ci 12644d6c458bSopenharmony_ci /** 12654d6c458bSopenharmony_ci * This method is invoked by the Writable method during initialization and should not be invoked actively. 12664d6c458bSopenharmony_ci * After the resource is initialized in the doInitialize method, the callback () method is invoked. 12674d6c458bSopenharmony_ci * 12684d6c458bSopenharmony_ci * @param { Function } callback - Callback when the stream has completed the initial. 12694d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 12704d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 12714d6c458bSopenharmony_ci * @crossplatform 12724d6c458bSopenharmony_ci * @since 12 12734d6c458bSopenharmony_ci */ 12744d6c458bSopenharmony_ci doInitialize(callback: Function): void { 12754d6c458bSopenharmony_ci } 12764d6c458bSopenharmony_ci 12774d6c458bSopenharmony_ci /** 12784d6c458bSopenharmony_ci * Implemented by subclass inheritance. The implementation logic of flushing chunks in the buffer should not be 12794d6c458bSopenharmony_ci * actively called. The call is controlled by Writable.write. 12804d6c458bSopenharmony_ci * 12814d6c458bSopenharmony_ci * @param { string | Uint8Array } chunk - Data to be written. 12824d6c458bSopenharmony_ci * @param { string } encoding - Encoding type. 12834d6c458bSopenharmony_ci * @param { Function } callback - Callback after writing. 12844d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 12854d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 12864d6c458bSopenharmony_ci * @crossplatform 12874d6c458bSopenharmony_ci * @since 12 12884d6c458bSopenharmony_ci */ 12894d6c458bSopenharmony_ci doWrite(chunk: string | Uint8Array, encoding: string, callback: Function): void { 12904d6c458bSopenharmony_ci throw ERR_DOWRITE_NOT_IMPLEMENTED; 12914d6c458bSopenharmony_ci } 12924d6c458bSopenharmony_ci 12934d6c458bSopenharmony_ci /** 12944d6c458bSopenharmony_ci * The implementation logic of flushing chunks in the buffer in batches should not be actively called. 12954d6c458bSopenharmony_ci * The call is controlled by Writable.write. 12964d6c458bSopenharmony_ci * 12974d6c458bSopenharmony_ci * @param { string[] | Uint8Array[] } chunk - Data to be written. 12984d6c458bSopenharmony_ci * @param { Function } callback - Callback after writing. 12994d6c458bSopenharmony_ci * @returns { Writable } Returns the Writable object. 13004d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 13014d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 13024d6c458bSopenharmony_ci * @crossplatform 13034d6c458bSopenharmony_ci * @since 12 13044d6c458bSopenharmony_ci */ 13054d6c458bSopenharmony_ci doWritev(chunk: string[] | Uint8Array[], callback: Function): void { 13064d6c458bSopenharmony_ci throw ERR_DOWRITEV_NOT_IMPLEMENTED; 13074d6c458bSopenharmony_ci } 13084d6c458bSopenharmony_ci 13094d6c458bSopenharmony_ci throwError(error: Error): void { 13104d6c458bSopenharmony_ci this.erroredInner = error; 13114d6c458bSopenharmony_ci if (this.listener && this.listener.listenerCount(WritableEvent.ERROR) > 0) { 13124d6c458bSopenharmony_ci setTimeout(() => { 13134d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.ERROR, error); 13144d6c458bSopenharmony_ci }); 13154d6c458bSopenharmony_ci } else { 13164d6c458bSopenharmony_ci throw error; 13174d6c458bSopenharmony_ci } 13184d6c458bSopenharmony_ci } 13194d6c458bSopenharmony_ci 13204d6c458bSopenharmony_ci private isOnError(): boolean { 13214d6c458bSopenharmony_ci return this.listener?.isOn(WritableEvent.ERROR) || false; 13224d6c458bSopenharmony_ci } 13234d6c458bSopenharmony_ci 13244d6c458bSopenharmony_ci private emitErrorExecutedInner = false; 13254d6c458bSopenharmony_ci // @ts-ignore 13264d6c458bSopenharmony_ci private emitErrorIdInner: number; 13274d6c458bSopenharmony_ci 13284d6c458bSopenharmony_ci private emitErrorOnce(error: Error, reset?: boolean): void { 13294d6c458bSopenharmony_ci if (reset) { 13304d6c458bSopenharmony_ci this.emitErrorExecutedInner = false; 13314d6c458bSopenharmony_ci clearTimeout(this.emitErrorIdInner); 13324d6c458bSopenharmony_ci } 13334d6c458bSopenharmony_ci if (!this.emitErrorExecutedInner) { 13344d6c458bSopenharmony_ci this.emitErrorExecutedInner = true; 13354d6c458bSopenharmony_ci // @ts-ignore 13364d6c458bSopenharmony_ci this.emitErrorIdInner = setTimeout((): void => { 13374d6c458bSopenharmony_ci this.listener?.emit(WritableEvent.ERROR, this.erroredInner ?? error); 13384d6c458bSopenharmony_ci }); 13394d6c458bSopenharmony_ci } 13404d6c458bSopenharmony_ci } 13414d6c458bSopenharmony_ci} 13424d6c458bSopenharmony_ci 13434d6c458bSopenharmony_ci// @ts-ignore 13444d6c458bSopenharmony_ciWritable.prototype.doWritev = null; 13454d6c458bSopenharmony_ciWritable.prototype.doWrite = Writable.prototype.noWriteOpes; 13464d6c458bSopenharmony_ci 13474d6c458bSopenharmony_ciclass Duplex extends Readable { 13484d6c458bSopenharmony_ci private _writable: Writable; 13494d6c458bSopenharmony_ci 13504d6c458bSopenharmony_ci constructor() { 13514d6c458bSopenharmony_ci super(); 13524d6c458bSopenharmony_ci this._writable = new Writable(); 13534d6c458bSopenharmony_ci const that = this; 13544d6c458bSopenharmony_ci if (this.doWrite) { 13554d6c458bSopenharmony_ci this._writable.doWrite = this.doWrite?.bind(that); 13564d6c458bSopenharmony_ci } 13574d6c458bSopenharmony_ci this._writable.doWritev = this.doWritev?.bind(that); 13584d6c458bSopenharmony_ci Object.defineProperties(that, { 13594d6c458bSopenharmony_ci doWrite: { 13604d6c458bSopenharmony_ci get(): Function { 13614d6c458bSopenharmony_ci return that._writable.doWrite?.bind(that); 13624d6c458bSopenharmony_ci }, 13634d6c458bSopenharmony_ci set(value: Function):void { 13644d6c458bSopenharmony_ci that._writable.doWrite = value.bind(that); 13654d6c458bSopenharmony_ci } 13664d6c458bSopenharmony_ci }, 13674d6c458bSopenharmony_ci doWritev: { 13684d6c458bSopenharmony_ci get(): Function { 13694d6c458bSopenharmony_ci return that._writable.doWritev?.bind(that); 13704d6c458bSopenharmony_ci }, 13714d6c458bSopenharmony_ci set(value: Function):void { 13724d6c458bSopenharmony_ci // @ts-ignore 13734d6c458bSopenharmony_ci that._writable.doWritev = value?.bind(that); 13744d6c458bSopenharmony_ci } 13754d6c458bSopenharmony_ci } 13764d6c458bSopenharmony_ci }); 13774d6c458bSopenharmony_ci } 13784d6c458bSopenharmony_ci 13794d6c458bSopenharmony_ci /** 13804d6c458bSopenharmony_ci * writes a chunk to Writable and invokes callback when the chunk is flushed. The return value indicates 13814d6c458bSopenharmony_ci * whether the internal buffer of the Writable reaches the hightWaterMark. If true is returned, the buffer 13824d6c458bSopenharmony_ci * does not reach the hightWaterMark. If false is returned, the buffer has been reached. The write function 13834d6c458bSopenharmony_ci * should be called after the drain event is triggered. If the write function is called continuously, 13844d6c458bSopenharmony_ci * the chunk is still added to the buffer until the memory overflows 13854d6c458bSopenharmony_ci * 13864d6c458bSopenharmony_ci * @param { string | Uint8Array } [chunk] - Data to be written. 13874d6c458bSopenharmony_ci * @param { string } [encoding] - Encoding type. 13884d6c458bSopenharmony_ci * @param { Function } [callback] - Callback after writing. 13894d6c458bSopenharmony_ci * @returns { boolean } Write success returns true, write failure returns false. 13904d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 13914d6c458bSopenharmony_ci * @throws { BusinessError } 10200036 - if stream has been ended, writing data to it will throw an error. 13924d6c458bSopenharmony_ci * @throws { BusinessError } 10200037 - if the callback is called multiple times consecutively, an error will be thrown. 13934d6c458bSopenharmony_ci * @throws { BusinessError } 10200039 - if a class inherits from Transform, it must implement doTransform; otherwise, an error will be raised. 13944d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 13954d6c458bSopenharmony_ci * @crossplatform 13964d6c458bSopenharmony_ci * @since 12 13974d6c458bSopenharmony_ci */ 13984d6c458bSopenharmony_ci write(chunk?: string | Uint8Array, encoding?: string, callback?: Function): boolean { 13994d6c458bSopenharmony_ci return this._writable.write(chunk, encoding, callback); 14004d6c458bSopenharmony_ci } 14014d6c458bSopenharmony_ci 14024d6c458bSopenharmony_ci /** 14034d6c458bSopenharmony_ci * Write the last chunk to Writable. 14044d6c458bSopenharmony_ci * 14054d6c458bSopenharmony_ci * @param { string | Uint8Array } [chunk] - Data to be written. 14064d6c458bSopenharmony_ci * @param { string } [encoding] - Encoding type. 14074d6c458bSopenharmony_ci * @param { Function } [callback] - Callback after writing. 14084d6c458bSopenharmony_ci * @returns { Writable } Returns the Writable object. 14094d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 14104d6c458bSopenharmony_ci * @throws { BusinessError } 10200039 - if a class inherits from Transform, it must implement doTransform; otherwise, an error will be raised. 14114d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 14124d6c458bSopenharmony_ci * @crossplatform 14134d6c458bSopenharmony_ci * @since 12 14144d6c458bSopenharmony_ci */ 14154d6c458bSopenharmony_ci end(chunk?: string | Uint8Array, encoding?: string, callback?: Function): Writable { 14164d6c458bSopenharmony_ci super.setEndType(); 14174d6c458bSopenharmony_ci return this._writable.end(chunk, encoding, callback); 14184d6c458bSopenharmony_ci } 14194d6c458bSopenharmony_ci 14204d6c458bSopenharmony_ci on(event: string, callback: Function): void { 14214d6c458bSopenharmony_ci super.on(event, callback); 14224d6c458bSopenharmony_ci this._writable.on(event, callback); 14234d6c458bSopenharmony_ci } 14244d6c458bSopenharmony_ci 14254d6c458bSopenharmony_ci off(event: string, callback?: Function): void { 14264d6c458bSopenharmony_ci super.off(event); 14274d6c458bSopenharmony_ci this._writable.off(event, callback); 14284d6c458bSopenharmony_ci } 14294d6c458bSopenharmony_ci 14304d6c458bSopenharmony_ci getListener(): EventEmitter | undefined { 14314d6c458bSopenharmony_ci return this._writable.listener; 14324d6c458bSopenharmony_ci } 14334d6c458bSopenharmony_ci 14344d6c458bSopenharmony_ci setDefaultEncoding(encoding?: string): boolean { 14354d6c458bSopenharmony_ci return this._writable.setDefaultEncoding(encoding); 14364d6c458bSopenharmony_ci } 14374d6c458bSopenharmony_ci 14384d6c458bSopenharmony_ci cork(): boolean { 14394d6c458bSopenharmony_ci return this._writable.cork(); 14404d6c458bSopenharmony_ci } 14414d6c458bSopenharmony_ci 14424d6c458bSopenharmony_ci uncork(): boolean { 14434d6c458bSopenharmony_ci return this._writable.uncork(); 14444d6c458bSopenharmony_ci } 14454d6c458bSopenharmony_ci 14464d6c458bSopenharmony_ci doInitialize(callback: Function): void { 14474d6c458bSopenharmony_ci super.doInitialize(callback); 14484d6c458bSopenharmony_ci this._writable.doInitialize(callback); 14494d6c458bSopenharmony_ci } 14504d6c458bSopenharmony_ci 14514d6c458bSopenharmony_ci doWrite(chunk: string | Uint8Array, encoding: string, callback: Function): void { 14524d6c458bSopenharmony_ci } 14534d6c458bSopenharmony_ci 14544d6c458bSopenharmony_ci doWritev(chunk: string[] | Uint8Array[], callback: Function): void { 14554d6c458bSopenharmony_ci this._writable.doWritev?.(chunk, callback); 14564d6c458bSopenharmony_ci } 14574d6c458bSopenharmony_ci 14584d6c458bSopenharmony_ci get writableObjectMode(): boolean { 14594d6c458bSopenharmony_ci return this._writable.writableObjectMode || false; 14604d6c458bSopenharmony_ci } 14614d6c458bSopenharmony_ci 14624d6c458bSopenharmony_ci get writableHighWatermark(): number { 14634d6c458bSopenharmony_ci return this._writable.writableHighWatermark || 0; 14644d6c458bSopenharmony_ci } 14654d6c458bSopenharmony_ci 14664d6c458bSopenharmony_ci get writable(): boolean { 14674d6c458bSopenharmony_ci return this._writable.writable || false; 14684d6c458bSopenharmony_ci } 14694d6c458bSopenharmony_ci 14704d6c458bSopenharmony_ci get writableLength(): number { 14714d6c458bSopenharmony_ci return this._writable.writableLength || 0; 14724d6c458bSopenharmony_ci } 14734d6c458bSopenharmony_ci 14744d6c458bSopenharmony_ci get writableNeedDrain(): boolean { 14754d6c458bSopenharmony_ci return this._writable.writableNeedDrain || false; 14764d6c458bSopenharmony_ci } 14774d6c458bSopenharmony_ci 14784d6c458bSopenharmony_ci get writableCorked(): number { 14794d6c458bSopenharmony_ci return this._writable.writableCorked || 0; 14804d6c458bSopenharmony_ci } 14814d6c458bSopenharmony_ci 14824d6c458bSopenharmony_ci get writableEnded(): boolean { 14834d6c458bSopenharmony_ci return this._writable.writableEnded || false; 14844d6c458bSopenharmony_ci } 14854d6c458bSopenharmony_ci 14864d6c458bSopenharmony_ci get writableFinished(): boolean { 14874d6c458bSopenharmony_ci return this._writable.writableFinished || false; 14884d6c458bSopenharmony_ci } 14894d6c458bSopenharmony_ci} 14904d6c458bSopenharmony_ci 14914d6c458bSopenharmony_ci// @ts-ignore 14924d6c458bSopenharmony_ciDuplex.prototype.doWrite = null; 14934d6c458bSopenharmony_ci// @ts-ignore 14944d6c458bSopenharmony_ciDuplex.prototype.doWritev = null; 14954d6c458bSopenharmony_ci 14964d6c458bSopenharmony_ciclass Transform extends Duplex { 14974d6c458bSopenharmony_ci /** 14984d6c458bSopenharmony_ci * The Transform constructor. 14994d6c458bSopenharmony_ci * 15004d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 15014d6c458bSopenharmony_ci * @crossplatform 15024d6c458bSopenharmony_ci * @since 12 15034d6c458bSopenharmony_ci */ 15044d6c458bSopenharmony_ci constructor() { 15054d6c458bSopenharmony_ci super(); 15064d6c458bSopenharmony_ci } 15074d6c458bSopenharmony_ci 15084d6c458bSopenharmony_ci on(event: string, callback: Function): void { 15094d6c458bSopenharmony_ci super.on(event, callback); 15104d6c458bSopenharmony_ci } 15114d6c458bSopenharmony_ci 15124d6c458bSopenharmony_ci /** 15134d6c458bSopenharmony_ci * Write the last chunk to Writable. 15144d6c458bSopenharmony_ci * 15154d6c458bSopenharmony_ci * @param { string | Uint8Array } [chunk] - Data to be written. 15164d6c458bSopenharmony_ci * @param { string } [encoding] - Encoding type. 15174d6c458bSopenharmony_ci * @param { Function } [callback] - Callback after writing. 15184d6c458bSopenharmony_ci * @returns { Writable } Returns the Writable object. 15194d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 15204d6c458bSopenharmony_ci * @throws { BusinessError } 10200039 - if a class inherits from Transform, it must implement doTransform; otherwise, an error will be raised. 15214d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 15224d6c458bSopenharmony_ci * @crossplatform 15234d6c458bSopenharmony_ci * @since 12 15244d6c458bSopenharmony_ci */ 15254d6c458bSopenharmony_ci end(chunk?: string | Uint8Array, encoding?: string, callback?: Function): Writable { 15264d6c458bSopenharmony_ci if (!this.doTransform) { 15274d6c458bSopenharmony_ci throw new BusinessError('The doTransform() method is not implemented', 10200039); 15284d6c458bSopenharmony_ci } 15294d6c458bSopenharmony_ci if (chunk instanceof Uint8Array) { 15304d6c458bSopenharmony_ci const chunkString = this.stringDecoder.write(chunk); 15314d6c458bSopenharmony_ci this.doTransform(chunkString, encoding || 'utf8', callback || ((): void => { 15324d6c458bSopenharmony_ci })); 15334d6c458bSopenharmony_ci } else if (typeof chunk === 'string') { 15344d6c458bSopenharmony_ci this.doTransform(chunk, encoding || 'utf8', callback || ((): void => { 15354d6c458bSopenharmony_ci })); 15364d6c458bSopenharmony_ci } 15374d6c458bSopenharmony_ci this.doFlush?.((...args: (string | Uint8Array)[]) => { 15384d6c458bSopenharmony_ci args.forEach((it: string | Uint8Array) => { 15394d6c458bSopenharmony_ci if (it) { 15404d6c458bSopenharmony_ci this.push(it ?? '', encoding); 15414d6c458bSopenharmony_ci } 15424d6c458bSopenharmony_ci }); 15434d6c458bSopenharmony_ci }); 15444d6c458bSopenharmony_ci const write:Writable = super.end(chunk, encoding, callback); 15454d6c458bSopenharmony_ci return write; 15464d6c458bSopenharmony_ci } 15474d6c458bSopenharmony_ci 15484d6c458bSopenharmony_ci push(chunk: Uint8Array | string | null, encoding?: string): boolean { 15494d6c458bSopenharmony_ci return super.push(chunk, encoding); 15504d6c458bSopenharmony_ci } 15514d6c458bSopenharmony_ci 15524d6c458bSopenharmony_ci /** 15534d6c458bSopenharmony_ci * Convert the input data. After the conversion, Transform.push can be called to send the input to the read stream. 15544d6c458bSopenharmony_ci * Transform.push should not be called Transform.write to call. 15554d6c458bSopenharmony_ci * 15564d6c458bSopenharmony_ci * @param { string } chunk - Input data to be converted. 15574d6c458bSopenharmony_ci * @param { string } encoding - If the chunk is a string, then this is the encoding type. If chunk is a buffer, 15584d6c458bSopenharmony_ci * then this is the special value 'buffer'. Ignore it in that case. 15594d6c458bSopenharmony_ci * @param { Function } callback - Callback after conversion. 15604d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 15614d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 15624d6c458bSopenharmony_ci * @crossplatform 15634d6c458bSopenharmony_ci * @since 12 15644d6c458bSopenharmony_ci */ 15654d6c458bSopenharmony_ci doTransform(chunk: string, encoding: string, callback: Function): void { 15664d6c458bSopenharmony_ci throw new BusinessError('The doTransform() method is not implemented'); 15674d6c458bSopenharmony_ci } 15684d6c458bSopenharmony_ci 15694d6c458bSopenharmony_ci /** 15704d6c458bSopenharmony_ci * After all data is flushed to the write stream, you can use the Transform.doFlush writes some extra data, should 15714d6c458bSopenharmony_ci * not be called actively, only called by Writable after flushing all data. 15724d6c458bSopenharmony_ci * 15734d6c458bSopenharmony_ci * @param { Function } callback - Callback after flush completion. 15744d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 15754d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 15764d6c458bSopenharmony_ci * @crossplatform 15774d6c458bSopenharmony_ci * @since 12 15784d6c458bSopenharmony_ci */ 15794d6c458bSopenharmony_ci doFlush(callback: Function): void { 15804d6c458bSopenharmony_ci } 15814d6c458bSopenharmony_ci 15824d6c458bSopenharmony_ci /** 15834d6c458bSopenharmony_ci * writes a chunk to Writable and invokes callback when the chunk is flushed. The return value indicates 15844d6c458bSopenharmony_ci * whether the internal buffer of the Writable reaches the hightWaterMark. If true is returned, the buffer 15854d6c458bSopenharmony_ci * does not reach the hightWaterMark. If false is returned, the buffer has been reached. The write function 15864d6c458bSopenharmony_ci * should be called after the drain event is triggered. If the write function is called continuously, 15874d6c458bSopenharmony_ci * the chunk is still added to the buffer until the memory overflows 15884d6c458bSopenharmony_ci * 15894d6c458bSopenharmony_ci * @param { string | Uint8Array } [chunk] - Data to be written. 15904d6c458bSopenharmony_ci * @param { string } [encoding] - Encoding type. 15914d6c458bSopenharmony_ci * @param { Function } [callback] - Callback after writing. 15924d6c458bSopenharmony_ci * @returns { boolean } Write success returns true, write failure returns false. 15934d6c458bSopenharmony_ci * @throws { BusinessError } 401 - if the input parameters are invalid. 15944d6c458bSopenharmony_ci * @throws { BusinessError } 10200036 - if stream has been ended, writing data to it will throw an error. 15954d6c458bSopenharmony_ci * @throws { BusinessError } 10200037 - if the callback is called multiple times consecutively, an error will be thrown. 15964d6c458bSopenharmony_ci * @throws { BusinessError } 10200039 - if a class inherits from Transform, it must implement doTransform; otherwise, an error will be raised. 15974d6c458bSopenharmony_ci * @syscap SystemCapability.Utils.Lang 15984d6c458bSopenharmony_ci * @crossplatform 15994d6c458bSopenharmony_ci * @since 12 16004d6c458bSopenharmony_ci */ 16014d6c458bSopenharmony_ci write(chunk?: string | Uint8Array, encoding?: string, callback?: Function): boolean { 16024d6c458bSopenharmony_ci if (typeof chunk === 'string') { 16034d6c458bSopenharmony_ci const callBackFunction = runOnce((error: Error) => { 16044d6c458bSopenharmony_ci if (error) { 16054d6c458bSopenharmony_ci this.getListener()?.emit(WritableEvent.ERROR, error); 16064d6c458bSopenharmony_ci } 16074d6c458bSopenharmony_ci }, () => { 16084d6c458bSopenharmony_ci const err:BusinessError = new BusinessError('Callback called multiple times', 10200037); 16094d6c458bSopenharmony_ci this.getListener()?.emit(WritableEvent.ERROR, err); 16104d6c458bSopenharmony_ci }); 16114d6c458bSopenharmony_ci this.doTransform?.(chunk ?? '', encoding ?? 'utf8', callBackFunction); 16124d6c458bSopenharmony_ci } 16134d6c458bSopenharmony_ci return super.write(chunk, encoding, callback); 16144d6c458bSopenharmony_ci } 16154d6c458bSopenharmony_ci 16164d6c458bSopenharmony_ci doRead(size: number): void { 16174d6c458bSopenharmony_ci } 16184d6c458bSopenharmony_ci 16194d6c458bSopenharmony_ci doWrite(chunk: string | Uint8Array, encoding: string, callback: Function):void { 16204d6c458bSopenharmony_ci super.doWrite?.(chunk, encoding, callback); 16214d6c458bSopenharmony_ci } 16224d6c458bSopenharmony_ci} 16234d6c458bSopenharmony_ci 16244d6c458bSopenharmony_ci// @ts-ignore 16254d6c458bSopenharmony_ciTransform.prototype.doTransform = null; 16264d6c458bSopenharmony_ci// @ts-ignore 16274d6c458bSopenharmony_ciTransform.prototype.doFlush = null; 16284d6c458bSopenharmony_ci 16294d6c458bSopenharmony_ciexport default { 16304d6c458bSopenharmony_ci Readable: Readable, 16314d6c458bSopenharmony_ci Writable: Writable, 16324d6c458bSopenharmony_ci Duplex: Duplex, 16334d6c458bSopenharmony_ci Transform: Transform, 16344d6c458bSopenharmony_ci}; 1635