first commit
This commit is contained in:
+10
@@ -0,0 +1,10 @@
|
||||
import { Extractor } from './js/Extractor';
|
||||
export * from './index.esm';
|
||||
export interface ExtractorFromFileOptions {
|
||||
wasmBinary?: ArrayBuffer;
|
||||
filepath: string;
|
||||
targetPath?: string;
|
||||
password?: string;
|
||||
filenameTransform?: (filename: string) => string;
|
||||
}
|
||||
export declare function createExtractorFromFile({ wasmBinary, filepath, targetPath, password, filenameTransform, }: ExtractorFromFileOptions): Promise<Extractor>;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { Extractor } from './js/Extractor';
|
||||
export * from './js/Extractor';
|
||||
export interface ExtractorFromDataOptions {
|
||||
wasmBinary?: ArrayBuffer;
|
||||
data: ArrayBuffer;
|
||||
password?: string;
|
||||
}
|
||||
export declare function createExtractorFromData({ wasmBinary, data, password, }: ExtractorFromDataOptions): Promise<Extractor<Uint8Array>>;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { ExtractorData } from './js/ExtractorData';
|
||||
import { getUnrar } from './js/unrar.singleton';
|
||||
export * from './js/Extractor';
|
||||
export async function createExtractorFromData({ wasmBinary, data, password = '', }) {
|
||||
const unrar = await getUnrar(wasmBinary && { wasmBinary });
|
||||
const extractor = new ExtractorData(unrar, data, password);
|
||||
unrar.extractor = extractor;
|
||||
return extractor;
|
||||
}
|
||||
//# sourceMappingURL=index.esm.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.esm.js","sourceRoot":"","sources":["../src/index.esm.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,cAAc,gBAAgB,CAAC;AAQ/B,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,EAC5C,UAAU,EACV,IAAI,EACJ,QAAQ,GAAG,EAAE,GACY;IACzB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC3D,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5B,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { ExtractorFile } from './js/ExtractorFile';
|
||||
import { getUnrar } from './js/unrar.singleton';
|
||||
export * from './index.esm';
|
||||
export async function createExtractorFromFile({ wasmBinary, filepath, targetPath = '', password = '', filenameTransform = (filename) => filename, }) {
|
||||
const unrar = await getUnrar(wasmBinary && { wasmBinary });
|
||||
const extractor = new ExtractorFile(unrar, filepath, targetPath, password, filenameTransform);
|
||||
unrar.extractor = extractor;
|
||||
return extractor;
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,cAAc,aAAa,CAAC;AAU5B,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,EAC5C,UAAU,EACV,QAAQ,EACR,UAAU,GAAG,EAAE,EACf,QAAQ,GAAG,EAAE,EACb,iBAAiB,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,QAAQ,GACzB;IACzB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IAC9F,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5B,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
export type SeekMethod = 'CUR' | 'SET' | 'END';
|
||||
declare const ERROR_CODE: {
|
||||
readonly 0: "ERAR_SUCCESS";
|
||||
readonly 10: "ERAR_END_ARCHIVE";
|
||||
readonly 11: "ERAR_NO_MEMORY";
|
||||
readonly 12: "ERAR_BAD_DATA";
|
||||
readonly 13: "ERAR_BAD_ARCHIVE";
|
||||
readonly 14: "ERAR_UNKNOWN_FORMAT";
|
||||
readonly 15: "ERAR_EOPEN";
|
||||
readonly 16: "ERAR_ECREATE";
|
||||
readonly 17: "ERAR_ECLOSE";
|
||||
readonly 18: "ERAR_EREAD";
|
||||
readonly 19: "ERAR_EWRITE";
|
||||
readonly 20: "ERAR_SMALL_BUF";
|
||||
readonly 21: "ERAR_UNKNOWN";
|
||||
readonly 22: "ERAR_MISSING_PASSWORD";
|
||||
readonly 23: "ERAR_EREFERENCE";
|
||||
readonly 24: "ERAR_BAD_PASSWORD";
|
||||
};
|
||||
export type FailReason = Exclude<(typeof ERROR_CODE)[keyof typeof ERROR_CODE], 'ERAR_SUCCESS' | 'ERAR_END_ARCHIVE'>;
|
||||
export declare class UnrarError extends Error {
|
||||
reason: FailReason;
|
||||
file?: string | undefined;
|
||||
constructor(reason: FailReason, message: string, file?: string | undefined);
|
||||
}
|
||||
export type CompressMethod = 'Storing' | 'Fastest' | 'Fast' | 'Normal' | 'Good' | 'Best' | 'Unknown';
|
||||
export interface FileHeader {
|
||||
name: string;
|
||||
flags: {
|
||||
encrypted: boolean;
|
||||
solid: boolean;
|
||||
directory: boolean;
|
||||
};
|
||||
packSize: number;
|
||||
unpSize: number;
|
||||
crc: number;
|
||||
time: string;
|
||||
unpVer: string;
|
||||
method: CompressMethod;
|
||||
comment: string;
|
||||
}
|
||||
export interface ArcHeader {
|
||||
comment: string;
|
||||
flags: {
|
||||
volume: boolean;
|
||||
lock: boolean;
|
||||
solid: boolean;
|
||||
authInfo: boolean;
|
||||
recoveryRecord: boolean;
|
||||
headerEncrypted: boolean;
|
||||
};
|
||||
}
|
||||
export interface ArcList {
|
||||
arcHeader: ArcHeader;
|
||||
fileHeaders: Generator<FileHeader>;
|
||||
}
|
||||
export type ArcFile<withContent = never> = {
|
||||
fileHeader: FileHeader;
|
||||
extraction?: withContent;
|
||||
};
|
||||
export interface ArcFiles<withContent = never> {
|
||||
arcHeader: ArcHeader;
|
||||
files: Generator<ArcFile<withContent>>;
|
||||
}
|
||||
export interface ExtractOptions {
|
||||
files?: string[] | ((fileHeader: FileHeader) => boolean);
|
||||
password?: string;
|
||||
}
|
||||
export declare abstract class Extractor<withContent = never> {
|
||||
protected unrar: any;
|
||||
protected abstract _filePath: string;
|
||||
private _password;
|
||||
private _archive;
|
||||
constructor(unrar: any, password?: string);
|
||||
getFileList(): ArcList;
|
||||
extract({ files, password }?: ExtractOptions): ArcFiles<withContent>;
|
||||
protected fileCreated(filename: string): void;
|
||||
protected abstract open(filename: string): number;
|
||||
protected abstract create(filename: string): number;
|
||||
protected abstract read(fd: number, buf: number, size: number): number;
|
||||
protected abstract write(fd: number, buf: number, size: number): boolean;
|
||||
protected abstract tell(fd: number): number;
|
||||
protected abstract seek(fd: number, pos: number, method: SeekMethod): boolean;
|
||||
protected abstract closeFile(fd: number): void;
|
||||
protected close(fd: number): void;
|
||||
private openArc;
|
||||
private processNextFile;
|
||||
private closeArc;
|
||||
private getFailException;
|
||||
}
|
||||
export {};
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
const ERROR_CODE = {
|
||||
0: 'ERAR_SUCCESS',
|
||||
10: 'ERAR_END_ARCHIVE',
|
||||
11: 'ERAR_NO_MEMORY',
|
||||
12: 'ERAR_BAD_DATA',
|
||||
13: 'ERAR_BAD_ARCHIVE',
|
||||
14: 'ERAR_UNKNOWN_FORMAT',
|
||||
15: 'ERAR_EOPEN',
|
||||
16: 'ERAR_ECREATE',
|
||||
17: 'ERAR_ECLOSE',
|
||||
18: 'ERAR_EREAD',
|
||||
19: 'ERAR_EWRITE',
|
||||
20: 'ERAR_SMALL_BUF',
|
||||
21: 'ERAR_UNKNOWN',
|
||||
22: 'ERAR_MISSING_PASSWORD',
|
||||
23: 'ERAR_EREFERENCE',
|
||||
24: 'ERAR_BAD_PASSWORD',
|
||||
};
|
||||
const ERROR_MSG = {
|
||||
ERAR_NO_MEMORY: 'Not enough memory',
|
||||
ERAR_BAD_DATA: 'Archive header or data are damaged',
|
||||
ERAR_BAD_ARCHIVE: 'File is not RAR archive',
|
||||
ERAR_UNKNOWN_FORMAT: 'Unknown archive format',
|
||||
ERAR_EOPEN: 'File open error',
|
||||
ERAR_ECREATE: 'File create error',
|
||||
ERAR_ECLOSE: 'File close error',
|
||||
ERAR_EREAD: 'File read error',
|
||||
ERAR_EWRITE: 'File write error',
|
||||
ERAR_SMALL_BUF: 'Buffer for archive comment is too small, comment truncated',
|
||||
ERAR_UNKNOWN: 'Unknown error',
|
||||
ERAR_MISSING_PASSWORD: 'Password for encrypted file or header is not specified',
|
||||
ERAR_EREFERENCE: 'Cannot open file source for reference record',
|
||||
ERAR_BAD_PASSWORD: 'Wrong password is specified',
|
||||
};
|
||||
export class UnrarError extends Error {
|
||||
constructor(reason, message, file) {
|
||||
super(message);
|
||||
this.reason = reason;
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
export class Extractor {
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
constructor(unrar, password = '') {
|
||||
this.unrar = unrar;
|
||||
this._password = password;
|
||||
this._archive = null;
|
||||
}
|
||||
getFileList() {
|
||||
const arcHeader = this.openArc(true);
|
||||
function* getFileHeaders() {
|
||||
while (true) {
|
||||
const arcFile = this.processNextFile(() => true);
|
||||
if (arcFile === 'ERAR_END_ARCHIVE') {
|
||||
break;
|
||||
}
|
||||
yield arcFile.fileHeader;
|
||||
}
|
||||
this.closeArc();
|
||||
}
|
||||
return { arcHeader, fileHeaders: getFileHeaders.call(this) };
|
||||
}
|
||||
extract({ files, password } = {}) {
|
||||
const arcHeader = this.openArc(false, password);
|
||||
function* getFiles() {
|
||||
let count = 0;
|
||||
while (true) {
|
||||
let shouldSkip = () => false;
|
||||
if (Array.isArray(files)) {
|
||||
if (count === files.length) {
|
||||
break;
|
||||
}
|
||||
shouldSkip = ({ name }) => !files.includes(name);
|
||||
}
|
||||
else if (files) {
|
||||
shouldSkip = (fileHeader) => !files(fileHeader);
|
||||
}
|
||||
const arcFile = this.processNextFile(shouldSkip);
|
||||
if (arcFile === 'ERAR_END_ARCHIVE') {
|
||||
break;
|
||||
}
|
||||
if (arcFile.extraction === 'skipped') {
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
yield {
|
||||
fileHeader: arcFile.fileHeader,
|
||||
};
|
||||
}
|
||||
this.closeArc();
|
||||
}
|
||||
return { arcHeader, files: getFiles.call(this) };
|
||||
}
|
||||
fileCreated(filename) {
|
||||
return;
|
||||
}
|
||||
close(fd) {
|
||||
this.closeFile(fd);
|
||||
}
|
||||
openArc(listOnly, password) {
|
||||
this._archive = new this.unrar.RarArchive();
|
||||
const header = this._archive.open(this._filePath, password ? password : this._password, listOnly);
|
||||
if (header.state.errCode !== 0) {
|
||||
throw this.getFailException(header.state.errCode, header.state.errType);
|
||||
}
|
||||
return {
|
||||
comment: header.comment,
|
||||
flags: {
|
||||
volume: (header.flags & 0x0001) !== 0,
|
||||
lock: (header.flags & 0x0004) !== 0,
|
||||
solid: (header.flags & 0x0008) !== 0,
|
||||
authInfo: (header.flags & 0x0020) !== 0,
|
||||
recoveryRecord: (header.flags & 0x0040) !== 0,
|
||||
headerEncrypted: (header.flags & 0x0080) !== 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
processNextFile(shouldSkip) {
|
||||
function getDateString(dosTime) {
|
||||
const bitLen = [5, 6, 5, 5, 4, 7];
|
||||
let parts = [];
|
||||
for (const len of bitLen) {
|
||||
parts.push(dosTime & ((1 << len) - 1));
|
||||
dosTime >>= len;
|
||||
}
|
||||
parts = parts.reverse();
|
||||
const pad = (num) => (num < 10 ? '0' + num : '' + num);
|
||||
return (`${1980 + parts[0]}-${pad(parts[1])}-${pad(parts[2])}` +
|
||||
`T${pad(parts[3])}:${pad(parts[4])}:${pad(parts[5] * 2)}.000`);
|
||||
}
|
||||
function getMethod(method) {
|
||||
const methodMap = {
|
||||
0x30: 'Storing',
|
||||
0x31: 'Fastest',
|
||||
0x32: 'Fast',
|
||||
0x33: 'Normal',
|
||||
0x34: 'Good',
|
||||
0x35: 'Best',
|
||||
};
|
||||
return methodMap[method] || 'Unknown';
|
||||
}
|
||||
const arcFileHeader = this._archive.getFileHeader();
|
||||
if (arcFileHeader.state.errCode === 10) {
|
||||
return 'ERAR_END_ARCHIVE';
|
||||
}
|
||||
if (arcFileHeader.state.errCode !== 0) {
|
||||
throw this.getFailException(arcFileHeader.state.errCode, arcFileHeader.state.errType);
|
||||
}
|
||||
const fileHeader = {
|
||||
name: arcFileHeader.name,
|
||||
flags: {
|
||||
encrypted: (arcFileHeader.flags & 0x04) !== 0,
|
||||
solid: (arcFileHeader.flags & 0x10) !== 0,
|
||||
directory: (arcFileHeader.flags & 0x20) !== 0,
|
||||
},
|
||||
packSize: arcFileHeader.packSize,
|
||||
unpSize: arcFileHeader.unpSize,
|
||||
// hostOS: arcFileHeader.hostOS
|
||||
crc: arcFileHeader.crc,
|
||||
time: getDateString(arcFileHeader.time),
|
||||
unpVer: `${Math.floor(arcFileHeader.unpVer / 10)}.${arcFileHeader.unpVer % 10}`,
|
||||
method: getMethod(arcFileHeader.method),
|
||||
comment: arcFileHeader.comment,
|
||||
// // fileAttr: arcFileHeader.fileAttr,
|
||||
};
|
||||
const skip = shouldSkip(fileHeader);
|
||||
const fileState = this._archive.readFile(skip);
|
||||
if (fileState.errCode !== 0) {
|
||||
throw this.getFailException(fileState.errCode, fileState.errType, fileHeader.name);
|
||||
}
|
||||
return {
|
||||
fileHeader,
|
||||
extraction: skip ? 'skipped' : 'extracted',
|
||||
};
|
||||
}
|
||||
closeArc() {
|
||||
this._archive.delete();
|
||||
this._archive = null;
|
||||
}
|
||||
getFailException(errCode, _errType, file) {
|
||||
const reason = ERROR_CODE[errCode];
|
||||
this.closeArc();
|
||||
return new UnrarError(reason, ERROR_MSG[reason], file);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=Extractor.js.map
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { ArcFiles, ExtractOptions, Extractor, SeekMethod } from './Extractor';
|
||||
export declare class ExtractorData extends Extractor<Uint8Array> {
|
||||
protected _filePath: string;
|
||||
private dataFiles;
|
||||
private dataFileMap;
|
||||
private currentFd;
|
||||
constructor(unrar: any, data: ArrayBuffer, password: string);
|
||||
extract(options?: ExtractOptions): ArcFiles<Uint8Array>;
|
||||
private getExtractedFileName;
|
||||
protected open(filename: string): number;
|
||||
protected create(filename: string): number;
|
||||
protected closeFile(fd: number): void;
|
||||
protected read(fd: number, buf: number, size: number): number;
|
||||
protected write(fd: number, buf: number, size: number): boolean;
|
||||
protected tell(fd: number): number;
|
||||
protected seek(fd: number, pos: number, method: SeekMethod): boolean;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import { SeekMethod } from './Extractor';
|
||||
export declare class DataFile {
|
||||
private buffers;
|
||||
private size;
|
||||
private pos;
|
||||
constructor(data?: Uint8Array);
|
||||
read(size: number): Uint8Array | null;
|
||||
readAll(): Uint8Array;
|
||||
write(data: Uint8Array): boolean;
|
||||
tell(): number;
|
||||
seek(pos: number, method: SeekMethod): boolean;
|
||||
private flatten;
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
export class DataFile {
|
||||
constructor(data) {
|
||||
this.buffers = [];
|
||||
this.pos = 0;
|
||||
this.size = 0;
|
||||
if (data) {
|
||||
this.buffers.push(data);
|
||||
this.size = data.byteLength;
|
||||
this.pos = 0;
|
||||
}
|
||||
}
|
||||
read(size) {
|
||||
this.flatten();
|
||||
if (size + this.pos > this.size) {
|
||||
// size = this.size - this.pos;
|
||||
return null;
|
||||
}
|
||||
const oldPos = this.pos;
|
||||
this.pos += size;
|
||||
// return this.buffers[0].subarray(oldPos, this.pos);
|
||||
return this.buffers[0].slice(oldPos, this.pos);
|
||||
}
|
||||
readAll() {
|
||||
this.flatten();
|
||||
return this.buffers[0] || new Uint8Array();
|
||||
}
|
||||
write(data) {
|
||||
this.buffers.push(data);
|
||||
this.size += data.byteLength;
|
||||
this.pos += data.byteLength;
|
||||
return true;
|
||||
}
|
||||
tell() {
|
||||
return this.pos;
|
||||
}
|
||||
seek(pos, method) {
|
||||
let newPos = this.pos;
|
||||
if (method === 'SET') {
|
||||
newPos = pos;
|
||||
}
|
||||
else if (method === 'CUR') {
|
||||
newPos += pos;
|
||||
}
|
||||
else {
|
||||
newPos = this.size - pos;
|
||||
}
|
||||
if (newPos < 0 || newPos > this.size) {
|
||||
return false;
|
||||
}
|
||||
this.pos = newPos;
|
||||
return true;
|
||||
}
|
||||
flatten() {
|
||||
if (this.buffers.length <= 1) {
|
||||
return;
|
||||
}
|
||||
const newBuffer = new Uint8Array(this.size);
|
||||
let offset = 0;
|
||||
for (const buffer of this.buffers) {
|
||||
newBuffer.set(buffer, offset);
|
||||
offset += buffer.byteLength;
|
||||
}
|
||||
this.buffers = [newBuffer];
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=ExtractorData.helper.js.map
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
import { DataFile } from './ExtractorData.helper';
|
||||
import { Extractor } from './Extractor';
|
||||
export class ExtractorData extends Extractor {
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,@typescript-eslint/no-explicit-any
|
||||
constructor(unrar, data, password) {
|
||||
super(unrar, password);
|
||||
this.dataFiles = {};
|
||||
this.dataFileMap = {};
|
||||
this.currentFd = 1;
|
||||
const rarFile = {
|
||||
file: new DataFile(new Uint8Array(data)),
|
||||
fd: this.currentFd++,
|
||||
};
|
||||
this._filePath = '_defaultUnrarJS_.rar';
|
||||
this.dataFiles[this._filePath] = rarFile;
|
||||
this.dataFileMap[rarFile.fd] = this._filePath;
|
||||
}
|
||||
extract(options = {}) {
|
||||
const { arcHeader, files } = super.extract(options);
|
||||
function* getFiles() {
|
||||
for (const file of files) {
|
||||
if (!file.fileHeader.flags.directory) {
|
||||
file.extraction =
|
||||
this.dataFiles[this.getExtractedFileName(file.fileHeader.name)].file.readAll();
|
||||
}
|
||||
yield file;
|
||||
}
|
||||
}
|
||||
return { arcHeader, files: getFiles.call(this) };
|
||||
}
|
||||
getExtractedFileName(filename) {
|
||||
return `*Extracted*/${filename}`;
|
||||
}
|
||||
open(filename) {
|
||||
const dataFile = this.dataFiles[filename];
|
||||
if (!dataFile) {
|
||||
return 0;
|
||||
}
|
||||
return dataFile.fd;
|
||||
}
|
||||
create(filename) {
|
||||
const fd = this.currentFd++;
|
||||
this.dataFiles[this.getExtractedFileName(filename)] = {
|
||||
file: new DataFile(),
|
||||
fd: this.currentFd++,
|
||||
};
|
||||
this.dataFileMap[fd] = this.getExtractedFileName(filename);
|
||||
return fd;
|
||||
}
|
||||
closeFile(fd) {
|
||||
const fileData = this.dataFiles[this.dataFileMap[fd]];
|
||||
if (!fileData) {
|
||||
return;
|
||||
}
|
||||
fileData.file.seek(0, 'SET');
|
||||
}
|
||||
read(fd, buf, size) {
|
||||
const fileData = this.dataFiles[this.dataFileMap[fd]];
|
||||
if (!fileData) {
|
||||
return -1;
|
||||
}
|
||||
const data = fileData.file.read(size);
|
||||
if (data === null) {
|
||||
return -1;
|
||||
}
|
||||
this.unrar.HEAPU8.set(data, buf);
|
||||
return data.byteLength;
|
||||
}
|
||||
write(fd, buf, size) {
|
||||
const fileData = this.dataFiles[this.dataFileMap[fd]];
|
||||
if (!fileData) {
|
||||
return false;
|
||||
}
|
||||
fileData.file.write(this.unrar.HEAPU8.slice(buf, buf + size));
|
||||
return true;
|
||||
}
|
||||
tell(fd) {
|
||||
const fileData = this.dataFiles[this.dataFileMap[fd]];
|
||||
if (!fileData) {
|
||||
return -1;
|
||||
}
|
||||
return fileData.file.tell();
|
||||
}
|
||||
seek(fd, pos, method) {
|
||||
const fileData = this.dataFiles[this.dataFileMap[fd]];
|
||||
if (!fileData) {
|
||||
return false;
|
||||
}
|
||||
return fileData.file.seek(pos, method);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=ExtractorData.js.map
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { Extractor, SeekMethod } from './Extractor';
|
||||
export declare class ExtractorFile extends Extractor {
|
||||
private filenameTransform;
|
||||
protected _filePath: string;
|
||||
private _target;
|
||||
private fileMap;
|
||||
constructor(unrar: any, filepath: string, targetPath: string, password: string, filenameTransform: (filename: string) => string);
|
||||
protected open(filename: string): number;
|
||||
protected create(filename: string): number;
|
||||
protected closeFile(fd: number): void;
|
||||
protected read(fd: number, buf: number, size: number): number;
|
||||
protected write(fd: number, buf: number, size: number): boolean;
|
||||
protected tell(fd: number): number;
|
||||
protected seek(fd: number, pos: number, method: SeekMethod): boolean;
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { Extractor } from './Extractor';
|
||||
export class ExtractorFile extends Extractor {
|
||||
constructor(
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,@typescript-eslint/no-explicit-any
|
||||
unrar, filepath, targetPath, password, filenameTransform) {
|
||||
super(unrar, password);
|
||||
this.filenameTransform = filenameTransform;
|
||||
this._filePath = filepath;
|
||||
this.fileMap = {};
|
||||
this._target = targetPath;
|
||||
}
|
||||
open(filename) {
|
||||
const fd = fs.openSync(filename, 'r');
|
||||
this.fileMap[fd] = {
|
||||
size: fs.fstatSync(fd).size,
|
||||
pos: 0,
|
||||
name: filename,
|
||||
};
|
||||
return fd;
|
||||
}
|
||||
create(filename) {
|
||||
const fullpath = path.join(this._target, this.filenameTransform(filename));
|
||||
const dir = path.parse(fullpath).dir;
|
||||
// Skip if directory is the current directory
|
||||
if (dir !== '') {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
const fd = fs.openSync(fullpath, 'w');
|
||||
this.fileMap[fd] = {
|
||||
size: 0,
|
||||
pos: 0,
|
||||
name: filename,
|
||||
};
|
||||
return fd;
|
||||
}
|
||||
closeFile(fd) {
|
||||
delete this.fileMap[fd];
|
||||
fs.closeSync(fd);
|
||||
}
|
||||
read(fd, buf, size) {
|
||||
const file = this.fileMap[fd];
|
||||
const buffer = Buffer.allocUnsafe(size);
|
||||
const readed = fs.readSync(fd, buffer, 0, size, file.pos);
|
||||
this.unrar.HEAPU8.set(buffer, buf);
|
||||
file.pos += readed;
|
||||
return readed;
|
||||
}
|
||||
write(fd, buf, size) {
|
||||
const file = this.fileMap[fd];
|
||||
const writeNum = fs.writeSync(fd, Buffer.from(this.unrar.HEAPU8.subarray(buf, buf + size)), 0, size);
|
||||
file.pos += writeNum;
|
||||
file.size += writeNum;
|
||||
return writeNum === size;
|
||||
}
|
||||
tell(fd) {
|
||||
return this.fileMap[fd].pos;
|
||||
}
|
||||
seek(fd, pos, method) {
|
||||
const file = this.fileMap[fd];
|
||||
let newPos = file.pos;
|
||||
if (method === 'SET') {
|
||||
newPos = 0;
|
||||
}
|
||||
else if (method === 'END') {
|
||||
newPos = file.size;
|
||||
}
|
||||
newPos += pos;
|
||||
if (newPos < 0 || newPos > file.size) {
|
||||
return false;
|
||||
}
|
||||
file.pos = newPos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=ExtractorFile.js.map
|
||||
+16
File diff suppressed because one or more lines are too long
+3
@@ -0,0 +1,3 @@
|
||||
export declare function getUnrar(options?: {
|
||||
wasmBinary?: ArrayBuffer;
|
||||
}): Promise<any>;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import unrarFactory from './unrar';
|
||||
let unrar;
|
||||
export async function getUnrar(options) {
|
||||
if (!unrar) {
|
||||
unrar = await unrarFactory(options);
|
||||
}
|
||||
return unrar;
|
||||
}
|
||||
//# sourceMappingURL=unrar.singleton.js.map
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user