Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
Refactored DirectoryRecord into a struct
Browse files Browse the repository at this point in the history
Refactored `SLComponentRecord` into a struct
Added `ShortFormDate` struct
  • Loading branch information
james-pre committed Oct 3, 2024
1 parent 68e68c6 commit 99bcd7d
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 102 deletions.
82 changes: 39 additions & 43 deletions src/DirectoryRecord.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import { decode, Errno, ErrnoError } from '@zenfs/core';
import { deserialize, member, struct, types as t } from 'utilium';
import { type Directory, ISODirectory, JolietDirectory } from './Directory.js';
import { SLComponentFlags } from './SLComponentRecord.js';
import { FileFlags, rockRidgeIdentifier } from './constants.js';
import { CLEntry, EREntry, NMEntry, NMFlags, RREntry, SLEntry, SPEntry, SystemUseEntry, constructSystemUseEntries } from './entries.js';
import { TGetString, getASCIIString, getJolietString, getShortFormDate } from './utils.js';
import { ShortFormDate, getJolietString } from './utils.js';

@struct()
export abstract class DirectoryRecord {
protected _view: DataView;
// Offset at which system use entries begin. Set to -1 if not enabled.
protected _rockRidgeOffset: number;
protected _suEntries?: SystemUseEntry[];
protected _file?: Uint8Array;
protected _dir?: Directory<DirectoryRecord>;

public constructor(
protected data: Uint8Array,
rockRidgeOffset: number
/**
* Offset at which system use entries begin. Set to -1 if not enabled.
*/
protected _rockRidgeOffset: number
) {
deserialize(this, data);
this._view = new DataView(data.buffer);
this._rockRidgeOffset = rockRidgeOffset;
}

public get hasRockRidge(): boolean {
Expand All @@ -27,6 +31,7 @@ export abstract class DirectoryRecord {
public get rockRidgeOffset(): number {
return this._rockRidgeOffset;
}

/**
* !!ONLY VALID ON ROOT NODE!!
* Checks if Rock Ridge is enabled, and sets the offset.
Expand All @@ -40,44 +45,44 @@ export abstract class DirectoryRecord {
}
}

public get length(): number {
return this.data[0];
}
@t.uint8 public length!: number;

public get extendedAttributeRecordLength(): number {
return this.data[1];
}
@t.uint8 public extendedAttributeRecordLength!: number;

@t.uint32 protected _lba!: number;

public get lba(): number {
return this._view.getUint32(2, true) * 2048;
return this._lba * 2048;
}

public get dataLength(): number {
return this._view.getUint32(10, true);
public set lba(value: number) {
if (!Number.isInteger(value / 2048)) {
throw new ErrnoError(Errno.EINVAL, 'Invalid LBA value');
}
this._lba = value / 2048;
}

@t.uint32 public dataLength!: number;

@member(ShortFormDate) protected date: ShortFormDate = new ShortFormDate();

public get recordingDate(): Date {
return getShortFormDate(this.data, 18);
return this.date.date;
}

public get fileFlags(): number {
return this.data[25];
}
@t.uint8 public fileFlags!: number;

public get fileUnitSize(): number {
return this.data[26];
}
@t.uint8 public fileUnitSize!: number;

public get interleaveGapSize(): number {
return this.data[27];
}
@t.uint8 public interleaveGapSize!: number;

public get volumeSequenceNumber(): number {
return this._view.getUint16(28, true);
}
@t.uint16 public volumeSequenceNumber!: number;

@t.uint8 protected identifierLength!: number;

public get identifier(): string {
return this._getString(this.data, 33, this.data[32]);
const stringData = this.data.slice(33, 33 + this.identifierLength);
return this._getString(stringData);
}

public fileName(isoData: Uint8Array): string {
Expand Down Expand Up @@ -179,10 +184,10 @@ export abstract class DirectoryRecord {
}
return this._suEntries!;
}
protected getString(i: number, len: number): string {
return this._getString(this.data, i, len);
protected getString(): string {
return this._getString(this.data);
}
protected abstract _getString: TGetString;
protected abstract _getString: (data: Uint8Array) => string;
protected abstract _constructDirectory(isoData: Uint8Array): Directory<DirectoryRecord>;
protected _rockRidgeFilename(isoData: Uint8Array): string | null {
const nmEntries = <NMEntry[]>this.getSUEntries(isoData).filter(e => e instanceof NMEntry);
Expand Down Expand Up @@ -237,25 +242,16 @@ export abstract class DirectoryRecord {
}

export class ISODirectoryRecord extends DirectoryRecord {
public constructor(data: Uint8Array, rockRidgeOffset: number) {
super(data, rockRidgeOffset);
}
protected _constructDirectory(isoData: Uint8Array): Directory<DirectoryRecord> {
return new ISODirectory(this, isoData);
}
protected get _getString(): TGetString {
return getASCIIString;
}

protected _getString = decode;
}

export class JolietDirectoryRecord extends DirectoryRecord {
public constructor(data: Uint8Array, rockRidgeOffset: number) {
super(data, rockRidgeOffset);
}
protected _constructDirectory(isoData: Uint8Array): Directory<DirectoryRecord> {
return new JolietDirectory(this, isoData);
}
protected get _getString(): TGetString {
return getJolietString;
}
protected _getString = getJolietString;
}
17 changes: 7 additions & 10 deletions src/SLComponentRecord.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TGetString } from './utils.js';
import { struct, types as t } from 'utilium';

export const enum SLComponentFlags {
CONTINUE = 1,
Expand All @@ -7,22 +7,19 @@ export const enum SLComponentFlags {
ROOT = 1 << 3,
}

@struct()
export class SLComponentRecord {
public constructor(protected data: Uint8Array) {}

public get flags(): SLComponentFlags {
return this.data[0];
}
@t.uint8 public flags!: SLComponentFlags;

@t.uint8 public componentLength!: number;

public get length(): number {
return 2 + this.componentLength;
}

public get componentLength(): number {
return this.data[1];
}

public content(getString: TGetString): string {
return getString(this.data, 2, this.componentLength);
public content(getString: (data: Uint8Array) => string): string {
return getString(this.data.slice(2, 2 + this.componentLength));
}
}
17 changes: 9 additions & 8 deletions src/VolumeDescriptor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ErrnoError, Errno } from '@zenfs/core/error.js';
import { DirectoryRecord, ISODirectoryRecord, JolietDirectoryRecord } from './DirectoryRecord.js';
import { getASCIIString, getDate, getJolietString } from './utils.js';
import { getDate, getJolietString } from './utils.js';
import { decode } from '@zenfs/core';

export const enum VolumeDescriptorType {
BootRecord = 0,
Expand All @@ -21,7 +22,7 @@ export class VolumeDescriptor {
}

public get standardIdentifier(): string {
return getASCIIString(this._data, 1, 5);
return decode(this._data.slice(1, 5));
}

public get version(): number {
Expand Down Expand Up @@ -117,19 +118,19 @@ export abstract class PrimaryOrSupplementaryVolumeDescriptor extends VolumeDescr
}

public get volumeCreationDate(): Date {
return getDate(this._data, 813);
return getDate(this._data.slice(813));
}

public get volumeModificationDate(): Date {
return getDate(this._data, 830);
return getDate(this._data.slice(830));
}

public get volumeExpirationDate(): Date {
return getDate(this._data, 847);
return getDate(this._data.slice(847));
}

public get volumeEffectiveDate(): Date {
return getDate(this._data, 864);
return getDate(this._data.slice(864));
}

public get fileStructureVersion(): number {
Expand Down Expand Up @@ -193,7 +194,7 @@ export class SupplementaryVolumeDescriptor extends PrimaryOrSupplementaryVolumeD
protected _constructRootDirectoryRecord(data: Uint8Array): DirectoryRecord {
return new JolietDirectoryRecord(data, -1);
}
protected _getString(idx: number, len: number): string {
return getJolietString(this._data, idx, len);
protected _getString(index: number, length: number): string {
return getJolietString(this._data.slice(index, length));
}
}
28 changes: 15 additions & 13 deletions src/entries.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { deserialize, struct, types as t, type Tuple } from 'utilium';
import { SLComponentRecord } from './SLComponentRecord.js';
import { TGetString, getASCIIString, getDate, getShortFormDate } from './utils.js';
import { getDate, getShortFormDate } from './utils.js';
import { decode } from '@zenfs/core';

export const enum EntrySignature {
CE = 0x4345,
Expand Down Expand Up @@ -39,7 +40,7 @@ class SystemUseEntry {
@t.uint16 public signature!: EntrySignature;

public get signatureString(): string {
return getASCIIString(this.data, 0, 2);
return decode(this.data.slice(0, 2));
}

@t.uint8 public length!: number;
Expand Down Expand Up @@ -110,15 +111,16 @@ export class EREntry extends SystemUseEntry {
@t.uint8 public extensionVersion!: number;

public get extensionIdentifier(): string {
return getASCIIString(this.data, 8, this.idLength);
return decode(this.data.slice(8, 8 + this.idLength));
}

public get extensionDescriptor(): string {
return getASCIIString(this.data, 8 + this.idLength, this.descriptorLength);
return decode(this.data.slice(8 + this.idLength, 8 + this.idLength + this.descriptorLength));
}

public get extensionSource(): string {
return getASCIIString(this.data, 8 + this.idLength + this.descriptorLength, this.sourceLength);
const start = 8 + this.idLength + this.descriptorLength;
return decode(this.data.slice(start, start + this.sourceLength));
}
}

Expand Down Expand Up @@ -260,8 +262,8 @@ export const enum NMFlags {
export class NMEntry extends SystemUseEntry {
@t.uint8 public flags!: NMFlags;

public name(getString: TGetString): string {
return getString(this.data, 5, this.length - 5);
public name(getString: (data: Uint8Array) => string): string {
return getString(this.data.slice(5, this.length));
}
}

Expand Down Expand Up @@ -309,15 +311,15 @@ export class TFEntry extends SystemUseEntry {
return;
}

return this._longFormDates() ? getDate(this.data, 5) : getShortFormDate(this.data, 5);
return this._longFormDates() ? getDate(this.data.slice(5)) : getShortFormDate(this.data.slice(5));
}

public get modify(): Date | undefined {
if (!(this.flags & TFFlags.MODIFY)) {
return;
}
const previousDates = this.flags & TFFlags.CREATION ? 1 : 0;
return this._longFormDates() ? getDate(this.data, 5 + previousDates * 17) : getShortFormDate(this.data, 5 + previousDates * 7);
return this._longFormDates() ? getDate(this.data.slice(5 + previousDates * 17)) : getShortFormDate(this.data.slice(5 + previousDates * 7));
}

public get access(): Date | undefined {
Expand All @@ -326,7 +328,7 @@ export class TFEntry extends SystemUseEntry {
}
let previousDates = this.flags & TFFlags.CREATION ? 1 : 0;
previousDates += this.flags & TFFlags.MODIFY ? 1 : 0;
return this._longFormDates() ? getDate(this.data, 5 + previousDates * 17) : getShortFormDate(this.data, 5 + previousDates * 7);
return this._longFormDates() ? getDate(this.data.slice(5 + previousDates * 17)) : getShortFormDate(this.data.slice(5 + previousDates * 7));
}

public get backup(): Date | undefined {
Expand All @@ -336,7 +338,7 @@ export class TFEntry extends SystemUseEntry {
let previousDates = this.flags & TFFlags.CREATION ? 1 : 0;
previousDates += this.flags & TFFlags.MODIFY ? 1 : 0;
previousDates += this.flags & TFFlags.ACCESS ? 1 : 0;
return this._longFormDates() ? getDate(this.data, 5 + previousDates * 17) : getShortFormDate(this.data, 5 + previousDates * 7);
return this._longFormDates() ? getDate(this.data.slice(5 + previousDates * 17)) : getShortFormDate(this.data.slice(5 + previousDates * 7));
}

public get expiration(): Date | undefined {
Expand All @@ -347,7 +349,7 @@ export class TFEntry extends SystemUseEntry {
previousDates += this.flags & TFFlags.MODIFY ? 1 : 0;
previousDates += this.flags & TFFlags.ACCESS ? 1 : 0;
previousDates += this.flags & TFFlags.BACKUP ? 1 : 0;
return this._longFormDates() ? getDate(this.data, 5 + previousDates * 17) : getShortFormDate(this.data, 5 + previousDates * 7);
return this._longFormDates() ? getDate(this.data.slice(5 + previousDates * 17)) : getShortFormDate(this.data.slice(5 + previousDates * 7));
}

public get effective(): Date | undefined {
Expand All @@ -359,7 +361,7 @@ export class TFEntry extends SystemUseEntry {
previousDates += this.flags & TFFlags.ACCESS ? 1 : 0;
previousDates += this.flags & TFFlags.BACKUP ? 1 : 0;
previousDates += this.flags & TFFlags.EXPIRATION ? 1 : 0;
return this._longFormDates() ? getDate(this.data, 5 + previousDates * 17) : getShortFormDate(this.data, 5 + previousDates * 7);
return this._longFormDates() ? getDate(this.data.slice(5 + previousDates * 17)) : getShortFormDate(this.data.slice(5 + previousDates * 7));
}

private _longFormDates(): boolean {
Expand Down
Loading

0 comments on commit 99bcd7d

Please sign in to comment.