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