15bebb993Sopenharmony_ci/* 25bebb993Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 35bebb993Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 45bebb993Sopenharmony_ci * you may not use this file except in compliance with the License. 55bebb993Sopenharmony_ci * You may obtain a copy of the License at 65bebb993Sopenharmony_ci * 75bebb993Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 85bebb993Sopenharmony_ci * 95bebb993Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 105bebb993Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 115bebb993Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125bebb993Sopenharmony_ci * See the License for the specific language governing permissions and 135bebb993Sopenharmony_ci * limitations under the License. 145bebb993Sopenharmony_ci */ 155bebb993Sopenharmony_ci 165bebb993Sopenharmony_cideclare function requireNapi(napiModuleName: string): any; 175bebb993Sopenharmony_ciconst stream = requireNapi('util.stream'); 185bebb993Sopenharmony_ciconst fileIo = requireNapi('file.fs'); 195bebb993Sopenharmony_ci 205bebb993Sopenharmony_ciinterface ReadStreamOptions { 215bebb993Sopenharmony_ci start?: number; 225bebb993Sopenharmony_ci end?: number; 235bebb993Sopenharmony_ci} 245bebb993Sopenharmony_ci 255bebb993Sopenharmony_ciinterface WriteStreamOptions { 265bebb993Sopenharmony_ci start?: number; 275bebb993Sopenharmony_ci mode?: number; 285bebb993Sopenharmony_ci} 295bebb993Sopenharmony_ci 305bebb993Sopenharmony_ciclass ReadStream extends stream.Readable { 315bebb993Sopenharmony_ci private pathInner: string; 325bebb993Sopenharmony_ci private bytesReadInner: number; 335bebb993Sopenharmony_ci private offset: number; 345bebb993Sopenharmony_ci private start?: number; 355bebb993Sopenharmony_ci private end?: number; 365bebb993Sopenharmony_ci // @ts-ignore 375bebb993Sopenharmony_ci private stream?: fileIo.Stream; 385bebb993Sopenharmony_ci 395bebb993Sopenharmony_ci constructor(path: string, options?: ReadStreamOptions) { 405bebb993Sopenharmony_ci super(); 415bebb993Sopenharmony_ci this.pathInner = path; 425bebb993Sopenharmony_ci this.bytesReadInner = 0; 435bebb993Sopenharmony_ci this.start = options?.start; 445bebb993Sopenharmony_ci this.end = options?.end; 455bebb993Sopenharmony_ci this.stream = fileIo.createStreamSync(this.pathInner, 'r'); 465bebb993Sopenharmony_ci this.offset = this.start ?? 0; 475bebb993Sopenharmony_ci } 485bebb993Sopenharmony_ci 495bebb993Sopenharmony_ci get path(): string { 505bebb993Sopenharmony_ci return this.pathInner; 515bebb993Sopenharmony_ci } 525bebb993Sopenharmony_ci 535bebb993Sopenharmony_ci get bytesRead(): number { 545bebb993Sopenharmony_ci return this.bytesReadInner; 555bebb993Sopenharmony_ci } 565bebb993Sopenharmony_ci 575bebb993Sopenharmony_ci // @ts-ignore 585bebb993Sopenharmony_ci seek(offset: number, whence?: fileIo.WhenceType): number { 595bebb993Sopenharmony_ci if (whence === undefined) { 605bebb993Sopenharmony_ci this.offset = this.stream?.seek(offset); 615bebb993Sopenharmony_ci } else { 625bebb993Sopenharmony_ci this.offset = this.stream?.seek(offset, whence); 635bebb993Sopenharmony_ci } 645bebb993Sopenharmony_ci return this.offset; 655bebb993Sopenharmony_ci } 665bebb993Sopenharmony_ci 675bebb993Sopenharmony_ci close(): void { 685bebb993Sopenharmony_ci this.stream?.close(); 695bebb993Sopenharmony_ci } 705bebb993Sopenharmony_ci 715bebb993Sopenharmony_ci doInitialize(callback: Function): void { 725bebb993Sopenharmony_ci callback(); 735bebb993Sopenharmony_ci } 745bebb993Sopenharmony_ci 755bebb993Sopenharmony_ci doRead(size: number): void { 765bebb993Sopenharmony_ci let readSize = size; 775bebb993Sopenharmony_ci if (this.end !== undefined) { 785bebb993Sopenharmony_ci if (this.offset > this.end) { 795bebb993Sopenharmony_ci this.push(null); 805bebb993Sopenharmony_ci return; 815bebb993Sopenharmony_ci } 825bebb993Sopenharmony_ci if (this.offset + readSize > this.end) { 835bebb993Sopenharmony_ci readSize = this.end - this.offset; 845bebb993Sopenharmony_ci } 855bebb993Sopenharmony_ci } 865bebb993Sopenharmony_ci let buffer = new ArrayBuffer(readSize); 875bebb993Sopenharmony_ci const off = this.offset; 885bebb993Sopenharmony_ci this.offset += readSize; 895bebb993Sopenharmony_ci this.stream?.read(buffer, { offset: off, length: readSize }) 905bebb993Sopenharmony_ci .then((readOut: number) => { 915bebb993Sopenharmony_ci if (readOut > 0) { 925bebb993Sopenharmony_ci this.bytesReadInner += readOut; 935bebb993Sopenharmony_ci this.push(new Uint8Array(buffer.slice(0, readOut))); 945bebb993Sopenharmony_ci } 955bebb993Sopenharmony_ci if (readOut !== readSize || readOut < size) { 965bebb993Sopenharmony_ci this.offset = this.offset - readSize + readOut; 975bebb993Sopenharmony_ci this.push(null); 985bebb993Sopenharmony_ci } 995bebb993Sopenharmony_ci }); 1005bebb993Sopenharmony_ci } 1015bebb993Sopenharmony_ci} 1025bebb993Sopenharmony_ci 1035bebb993Sopenharmony_ciclass WriteStream extends stream.Writable { 1045bebb993Sopenharmony_ci private pathInner: string; 1055bebb993Sopenharmony_ci private bytesWrittenInner: number; 1065bebb993Sopenharmony_ci private offset: number; 1075bebb993Sopenharmony_ci private mode: string; 1085bebb993Sopenharmony_ci private start?: number; 1095bebb993Sopenharmony_ci // @ts-ignore 1105bebb993Sopenharmony_ci private stream?: fileIo.Stream; 1115bebb993Sopenharmony_ci 1125bebb993Sopenharmony_ci constructor(path: string, options?: WriteStreamOptions) { 1135bebb993Sopenharmony_ci super(); 1145bebb993Sopenharmony_ci this.pathInner = path; 1155bebb993Sopenharmony_ci this.bytesWrittenInner = 0; 1165bebb993Sopenharmony_ci this.start = options?.start; 1175bebb993Sopenharmony_ci this.mode = this.convertOpenMode(options?.mode); 1185bebb993Sopenharmony_ci this.stream = fileIo.createStreamSync(this.pathInner, this.mode); 1195bebb993Sopenharmony_ci this.offset = this.start ?? 0; 1205bebb993Sopenharmony_ci } 1215bebb993Sopenharmony_ci 1225bebb993Sopenharmony_ci get path(): string { 1235bebb993Sopenharmony_ci return this.pathInner; 1245bebb993Sopenharmony_ci } 1255bebb993Sopenharmony_ci 1265bebb993Sopenharmony_ci get bytesWritten(): number { 1275bebb993Sopenharmony_ci return this.bytesWrittenInner; 1285bebb993Sopenharmony_ci } 1295bebb993Sopenharmony_ci 1305bebb993Sopenharmony_ci // @ts-ignore 1315bebb993Sopenharmony_ci seek(offset: number, whence?: fileIo.WhenceType): number { 1325bebb993Sopenharmony_ci if (whence === undefined) { 1335bebb993Sopenharmony_ci this.offset = this.stream?.seek(offset); 1345bebb993Sopenharmony_ci } else { 1355bebb993Sopenharmony_ci this.offset = this.stream?.seek(offset, whence); 1365bebb993Sopenharmony_ci } 1375bebb993Sopenharmony_ci return this.offset; 1385bebb993Sopenharmony_ci } 1395bebb993Sopenharmony_ci 1405bebb993Sopenharmony_ci close(): void { 1415bebb993Sopenharmony_ci this.stream?.close(); 1425bebb993Sopenharmony_ci } 1435bebb993Sopenharmony_ci 1445bebb993Sopenharmony_ci doInitialize(callback: Function): void { 1455bebb993Sopenharmony_ci callback(); 1465bebb993Sopenharmony_ci } 1475bebb993Sopenharmony_ci 1485bebb993Sopenharmony_ci doWrite(chunk: string | Uint8Array, encoding: string, callback: Function): void { 1495bebb993Sopenharmony_ci this.stream?.write(chunk, { offset: this.offset }) 1505bebb993Sopenharmony_ci .then((writeIn: number) => { 1515bebb993Sopenharmony_ci this.offset += writeIn; 1525bebb993Sopenharmony_ci this.bytesWrittenInner += writeIn; 1535bebb993Sopenharmony_ci callback(); 1545bebb993Sopenharmony_ci }) 1555bebb993Sopenharmony_ci .finally(() => { 1565bebb993Sopenharmony_ci this.stream?.flush(); 1575bebb993Sopenharmony_ci }); 1585bebb993Sopenharmony_ci } 1595bebb993Sopenharmony_ci 1605bebb993Sopenharmony_ci convertOpenMode(mode?: number): string { 1615bebb993Sopenharmony_ci let modeStr = 'w'; 1625bebb993Sopenharmony_ci if (mode === undefined) { 1635bebb993Sopenharmony_ci return modeStr; 1645bebb993Sopenharmony_ci } 1655bebb993Sopenharmony_ci if (mode & fileIo.OpenMode.WRITE_ONLY) { 1665bebb993Sopenharmony_ci modeStr = 'w'; 1675bebb993Sopenharmony_ci } 1685bebb993Sopenharmony_ci if (mode & fileIo.OpenMode.READ_WRITE) { 1695bebb993Sopenharmony_ci modeStr = 'w+'; 1705bebb993Sopenharmony_ci } 1715bebb993Sopenharmony_ci if ((mode & fileIo.OpenMode.WRITE_ONLY) && (mode & fileIo.OpenMode.APPEND)) { 1725bebb993Sopenharmony_ci modeStr = 'a'; 1735bebb993Sopenharmony_ci } 1745bebb993Sopenharmony_ci if ((mode & fileIo.OpenMode.READ_WRITE) && (mode & fileIo.OpenMode.APPEND)) { 1755bebb993Sopenharmony_ci modeStr = 'a+'; 1765bebb993Sopenharmony_ci } 1775bebb993Sopenharmony_ci return modeStr; 1785bebb993Sopenharmony_ci } 1795bebb993Sopenharmony_ci} 1805bebb993Sopenharmony_ci 1815bebb993Sopenharmony_ciexport default { 1825bebb993Sopenharmony_ci ReadStream: ReadStream, 1835bebb993Sopenharmony_ci WriteStream: WriteStream, 1845bebb993Sopenharmony_ci}; 185