Skip to content

Commit

Permalink
Fixed PreloadFile not working with async only FS
Browse files Browse the repository at this point in the history
  • Loading branch information
james-pre committed May 23, 2024
1 parent 6a3c596 commit 3a472c5
Showing 1 changed file with 85 additions and 68 deletions.
153 changes: 85 additions & 68 deletions src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,35 +439,66 @@ export class PreloadFile<FS extends FileSystem> extends File {
return new Stats(this.stats);
}

protected _truncate(length: number): void {
this.dirty = true;
if (!isWriteable(this.flag)) {
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
}
this.stats.mtimeMs = Date.now();
if (length > this._buffer.length) {
const data = new Uint8Array(length - this._buffer.length);
// Write will set stats.size and handle syncing.
this.writeSync(data, 0, data.length, this._buffer.length);
return;
}
this.stats.size = length;
// Truncate.
this._buffer = this._buffer.slice(0, length);
}

/**
* Asynchronous truncate.
* @param length
*/
public async truncate(length: number): Promise<void> {
this.truncateSync(length);
return this.sync();
this._truncate(length);
await this.sync();
}

/**
* Synchronous truncate.
* @param length
*/
public truncateSync(length: number): void {
this._truncate(length);
this.syncSync();
}

protected _write(buffer: Uint8Array, offset: number = 0, length: number = this.stats.size, position: number = this.position): number {
this.dirty = true;
if (!isWriteable(this.flag)) {
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
}
this.stats.mtimeMs = Date.now();
if (length > this._buffer.length) {
const data = new Uint8Array(length - this._buffer.length);
// Write will set stats.size and handle syncing.
this.writeSync(data, 0, data.length, this._buffer.length);
return;
const end = position + length;

if (end > this.stats.size) {
this.stats.size = end;
if (end > this._buffer.byteLength) {
if (this._buffer.buffer.resizable && this._buffer.buffer.maxByteLength! <= end) {
this._buffer.buffer.resize(end);
} else {
// Extend the buffer!
const newBuffer = new Uint8Array(new ArrayBuffer(end, this.fs.metadata().noResizableBuffers ? {} : { maxByteLength: size_max }));
newBuffer.set(this._buffer);
this._buffer = newBuffer;
}
}
}
this.stats.size = length;
// Truncate.
this._buffer = this._buffer.slice(0, length);
this.syncSync();
const slice = buffer.slice(offset, offset + length);
this._buffer.set(slice, position);
this.stats.mtimeMs = Date.now();
this.position = position + slice.byteLength;
return slice.byteLength;
}

/**
Expand All @@ -482,8 +513,8 @@ export class PreloadFile<FS extends FileSystem> extends File {
* data should be written. If position is null, the data will be written at
* the current position.
*/
public async write(buffer: Uint8Array, offset: number = 0, length: number = this.stats.size, position: number = this.position): Promise<number> {
const bytesWritten = this.writeSync(buffer, offset, length, position);
public async write(buffer: Uint8Array, offset?: number, length?: number, position?: number): Promise<number> {
const bytesWritten = this._write(buffer, offset, length, position);
await this.sync();
return bytesWritten;
}
Expand All @@ -502,32 +533,30 @@ export class PreloadFile<FS extends FileSystem> extends File {
* @returns bytes written
*/
public writeSync(buffer: Uint8Array, offset: number = 0, length: number = this.stats.size, position: number = this.position): number {
this.dirty = true;
if (!isWriteable(this.flag)) {
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
}
const end = position + length;
const bytesWritten = this._write(buffer, offset, length, position);
this.syncSync();
return bytesWritten;
}

protected _read(buffer: ArrayBufferView, offset: number = 0, length: number = this.stats.size, position?: number): number {
if (!isReadable(this.flag)) {
throw new ErrnoError(Errno.EPERM, 'File not opened with a readable mode.');
}
this.dirty = true;
position ??= this.position;
let end = position + length;
if (end > this.stats.size) {
this.stats.size = end;
if (end > this._buffer.byteLength) {
if (this._buffer.buffer.resizable && this._buffer.buffer.maxByteLength! <= end) {
this._buffer.buffer.resize(end);
} else {
// Extend the buffer!
const newBuffer = new Uint8Array(new ArrayBuffer(end, this.fs.metadata().noResizableBuffers ? {} : { maxByteLength: size_max }));
newBuffer.set(this._buffer);
this._buffer = newBuffer;
}
}
end = position + Math.max(this.stats.size - position, 0);
}
const slice = buffer.slice(offset, offset + length);
this._buffer.set(slice, position);
const bytesWritten = slice.byteLength;
this.stats.mtimeMs = Date.now();
this.position = position + bytesWritten;
this.syncSync();
return bytesWritten;
this.stats.atimeMs = Date.now();
this._position = end;
const bytesRead = end - position;
if (bytesRead == 0) {
// No copy/read. Return immediatly for better performance
return bytesRead;
}
new Uint8Array(buffer.buffer, offset, length).set(this._buffer.slice(position, end));
return bytesRead;
}

/**
Expand All @@ -541,13 +570,10 @@ export class PreloadFile<FS extends FileSystem> extends File {
* in the file. If position is null, data will be read from the current file
* position.
*/
public async read<TBuffer extends ArrayBufferView>(
buffer: TBuffer,
offset: number = 0,
length: number = this.stats.size,
position: number = 0
): Promise<{ bytesRead: number; buffer: TBuffer }> {
return { bytesRead: this.readSync(buffer, offset, length, position), buffer };
public async read<TBuffer extends ArrayBufferView>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{ bytesRead: number; buffer: TBuffer }> {
const bytesRead = this._read(buffer, offset, length, position);
await this.sync();
return { bytesRead, buffer };
}

/**
Expand All @@ -561,25 +587,9 @@ export class PreloadFile<FS extends FileSystem> extends File {
* position.
* @returns number of bytes written
*/
public readSync(buffer: ArrayBufferView, offset: number = 0, length: number = this.stats.size, position?: number): number {
if (!isReadable(this.flag)) {
throw new ErrnoError(Errno.EPERM, 'File not opened with a readable mode.');
}
this.dirty = true;
position ??= this.position;
let end = position + length;
if (end > this.stats.size) {
end = position + Math.max(this.stats.size - position, 0);
}
this.stats.atimeMs = Date.now();
this._position = end;
const bytesRead = end - position;
this.syncSync();
if (bytesRead == 0) {
// No copy/read. Return immediatly for better performance
return bytesRead;
}
new Uint8Array(buffer.buffer, offset, length).set(this._buffer.slice(position, end));
public readSync(buffer: ArrayBufferView, offset?: number, length?: number, position?: number): number {
const bytesRead = this._read(buffer, offset, length, position);
this.statSync();
return bytesRead;
}

Expand All @@ -588,7 +598,9 @@ export class PreloadFile<FS extends FileSystem> extends File {
* @param mode the mode
*/
public async chmod(mode: number): Promise<void> {
this.chmodSync(mode);
this.dirty = true;
this.stats.chmod(mode);
await this.sync();
}

/**
Expand All @@ -607,7 +619,9 @@ export class PreloadFile<FS extends FileSystem> extends File {
* @param gid
*/
public async chown(uid: number, gid: number): Promise<void> {
this.chownSync(uid, gid);
this.dirty = true;
this.stats.chown(uid, gid);
await this.sync();
}

/**
Expand All @@ -622,7 +636,10 @@ export class PreloadFile<FS extends FileSystem> extends File {
}

public async utimes(atime: Date, mtime: Date): Promise<void> {
this.utimesSync(atime, mtime);
this.dirty = true;
this.stats.atime = atime;
this.stats.mtime = mtime;
await this.sync();
}

public utimesSync(atime: Date, mtime: Date): void {
Expand All @@ -632,10 +649,10 @@ export class PreloadFile<FS extends FileSystem> extends File {
this.syncSync();
}

public _setType(type: FileType): Promise<void> {
public async _setType(type: FileType): Promise<void> {
this.dirty = true;
this.stats.mode = (this.stats.mode & ~S_IFMT) | type;
return this.sync();
await this.sync();
}

public _setTypeSync(type: FileType): void {
Expand Down

0 comments on commit 3a472c5

Please sign in to comment.