Skip to content

Commit

Permalink
Changed encode/decode to use Array.from for perf
Browse files Browse the repository at this point in the history
Improved writeSync arguments
  • Loading branch information
james-pre committed Mar 6, 2024
1 parent 5aab518 commit b99b2c7
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 21 deletions.
30 changes: 16 additions & 14 deletions src/emulation/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ import { Dir, Dirent } from './dir.js';
import { dirname, join } from './path.js';

type FileSystemMethod = {
[K in keyof FileSystem]: FileSystem[K] extends (...args) => any ? (name: K, resolveSymlinks: boolean, ...args: Parameters<FileSystem[K]>) => ReturnType<FileSystem[K]> : never;
[K in keyof FileSystem]: FileSystem[K] extends (...args) => unknown
? (name: K, resolveSymlinks: boolean, ...args: Parameters<FileSystem[K]>) => ReturnType<FileSystem[K]>
: never;
}[keyof FileSystem]; // https://stackoverflow.com/a/76335220/17637456

function doOp<M extends FileSystemMethod, RT extends ReturnType<M>>(...[name, resolveSymlinks, path, ...args]: Parameters<M>): RT {
Expand Down Expand Up @@ -389,34 +391,34 @@ fdatasyncSync satisfies typeof Node.fdatasyncSync;
* Note that it is unsafe to use fs.write multiple times on the same file
* without waiting for it to return.
* @param fd
* @param buffer Uint8Array containing the data to write to
* @param data Uint8Array containing the data to write to
* the file.
* @param offset Offset in the buffer to start reading data from.
* @param length The amount of bytes to write to the file.
* @param position Offset from the beginning of the file where this
* data should be written. If position is null, the data will be written at
* the current position.
*/
export function writeSync(fd: number, buffer: Uint8Array, offset: number, length: number, position?: number | null): number;
export function writeSync(fd: number, data: string, position?: number | null, encoding?: BufferEncoding): number;
export function writeSync(fd: number, arg2: Uint8Array | string, arg3?: number, arg4?: BufferEncoding | number, arg5?: number): number {
export function writeSync(fd: number, data: Uint8Array, offset: number, length: number, position?: number): number;
export function writeSync(fd: number, data: string, position?: number, encoding?: BufferEncoding): number;
export function writeSync(fd: number, data: FileContents, posOrOff?: number, lenOrEnc?: BufferEncoding | number, pos?: number): number {
let buffer: Uint8Array,
offset: number = 0,
length: number,
position: number | null;
if (typeof arg2 === 'string') {
position: number;
if (typeof data === 'string') {
// Signature 1: (fd, string, [position?, [encoding?]])
position = typeof arg3 === 'number' ? arg3 : null;
const encoding = <BufferEncoding>(typeof arg4 === 'string' ? arg4 : 'utf8');
position = typeof posOrOff === 'number' ? posOrOff : null;
const encoding = <BufferEncoding>(typeof lenOrEnc === 'string' ? lenOrEnc : 'utf8');
offset = 0;
buffer = encode(arg2);
buffer = encode(data, encoding);
length = buffer.length;
} else {
// Signature 2: (fd, buffer, offset, length, position?)
buffer = arg2;
offset = arg3;
length = arg4 as number;
position = typeof arg5 === 'number' ? arg5 : null;
buffer = data;
offset = posOrOff;
length = lenOrEnc as number;
position = typeof pos === 'number' ? pos : null;
}

const file = fd2file(fd);
Expand Down
24 changes: 17 additions & 7 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,19 @@ export function encode(input: string, encoding: BufferEncoding = 'utf8'): Uint8A
case 'utf-8':
case 'latin1':
case 'binary':
return new Uint8Array([...input].map(v => v.charCodeAt(0)));
return new Uint8Array(Array.from(input).map(v => v.charCodeAt(0)));
case 'utf16le':
case 'ucs2':
case 'ucs-2':
return new Uint8Array([...input].map(char => char.charCodeAt(0)).flatMap(code => [code & 0xff, (code >> 8) & 0xff]));
return new Uint8Array(
Array.from(input)
.map(char => char.charCodeAt(0))
.flatMap(code => [code & 0xff, (code >> 8) & 0xff])
);
case 'base64':
return new Uint8Array([...btoa(input)].map(v => v.charCodeAt(0)));
return new Uint8Array(Array.from(btoa(input)).map(v => v.charCodeAt(0)));
case 'base64url':
return new Uint8Array([...btoa(input).replace('/', '_').replace('+', '-')].map(v => v.charCodeAt(0)));
return new Uint8Array(Array.from(btoa(input).replace('/', '_').replace('+', '-')).map(v => v.charCodeAt(0)));
case 'hex':
const hexBytes = [];
for (let i = 0; i < input.length; i += 2) {
Expand All @@ -188,7 +192,9 @@ export function decode(input?: Uint8Array, encoding: BufferEncoding = 'utf8'): s
case 'utf-8':
case 'latin1':
case 'binary':
return [...input].map(v => String.fromCharCode(v)).join('');
return Array.from(input)
.map(v => String.fromCharCode(v))
.join('');
case 'utf16le':
case 'ucs2':
case 'ucs-2':
Expand All @@ -199,10 +205,14 @@ export function decode(input?: Uint8Array, encoding: BufferEncoding = 'utf8'): s
}
return utf16leString;
case 'base64':
return atob([...input].map(v => String.fromCharCode(v)).join(''));
return atob(
Array.from(input)
.map(v => String.fromCharCode(v))
.join('')
);
case 'base64url':
return atob(
[...input]
Array.from(input)
.map(v => String.fromCharCode(v))
.join('')
.replace('_', '/')
Expand Down

0 comments on commit b99b2c7

Please sign in to comment.