Read file data of root directory entries
This commit is contained in:
parent
442253b953
commit
a6503ae65b
@ -46,6 +46,8 @@ export interface IStandardDirEntry {
|
||||
attributes: IAttributes
|
||||
size: number
|
||||
firstCluster: number
|
||||
clusterChain: number[]
|
||||
data: ArrayBuffer
|
||||
}
|
||||
|
||||
export interface ILongFileNameDirEntry {
|
||||
@ -84,7 +86,45 @@ export class FloppyDisk {
|
||||
new DataView(this._buffer, this.rootDirOffset, this.rootDirSize),
|
||||
)
|
||||
}
|
||||
|
||||
if (this._rootDirEntries === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (const entry of this._rootDirEntries) {
|
||||
if (entry.type === 'standard-entry' && (entry.size > 0 || entry.attributes.directory)) {
|
||||
entry.clusterChain = this.clusterChain(entry.firstCluster)
|
||||
|
||||
const dataSize = entry.clusterChain.length * this.bytesPerCluster
|
||||
if (dataSize === 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
const data = new Uint8Array(dataSize)
|
||||
for (let i = 0; i < entry.clusterChain.length; i++) {
|
||||
const offset = (entry.clusterChain[i] - 2) * this.bytesPerCluster
|
||||
const view = new Uint8Array(
|
||||
this._buffer,
|
||||
this.dataOffset + offset,
|
||||
this.bytesPerCluster,
|
||||
)
|
||||
data.set(view, i * this.bytesPerCluster)
|
||||
}
|
||||
console.log(
|
||||
entry.name.trim() + (entry.extension.trim() ? '.' + entry.extension.trim() : ''),
|
||||
)
|
||||
entry.data = data.slice(0, entry.size > 0 ? entry.size : data.byteLength)
|
||||
if (
|
||||
!entry.attributes.directory &&
|
||||
(['BAT', 'TXT', 'BAS'].includes(entry.extension) || entry.name.trim() === 'LICENSE')
|
||||
) {
|
||||
const decoder = new TextDecoder()
|
||||
console.log(decoder.decode(entry.data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this._rootDirEntries
|
||||
}
|
||||
|
||||
@ -116,6 +156,14 @@ export class FloppyDisk {
|
||||
return this.bootSectorInfo?.biosParameterBlock?.bytesPerSector ?? 0
|
||||
}
|
||||
|
||||
get sectorsPerCluster() {
|
||||
return this.bootSectorInfo?.biosParameterBlock?.sectorsPerCluster ?? 0
|
||||
}
|
||||
|
||||
get bytesPerCluster() {
|
||||
return this.bytesPerSector * this.sectorsPerCluster
|
||||
}
|
||||
|
||||
get rootDirSectors() {
|
||||
if (this.bytesPerSector === 0) {
|
||||
return 0
|
||||
@ -143,6 +191,34 @@ export class FloppyDisk {
|
||||
get rootDirSize() {
|
||||
return this.rootDirSectors * this.bytesPerSector
|
||||
}
|
||||
|
||||
nextCluster(current: number): number {
|
||||
const tableOffset = Math.floor(current + current / 2)
|
||||
const tableSector = Math.floor(this.reservedSectorCount + tableOffset / this.bytesPerSector)
|
||||
const entityOffset = tableOffset % this.bytesPerSector
|
||||
|
||||
const table = new DataView(
|
||||
this._buffer,
|
||||
tableSector * this.bytesPerSector,
|
||||
2 * this.bytesPerSector,
|
||||
)
|
||||
|
||||
const value = table.getUint16(entityOffset, true)
|
||||
|
||||
return current & 1 ? value >> 4 : value & 0x0fff
|
||||
}
|
||||
|
||||
clusterChain(start: number): number[] {
|
||||
const chain = [start]
|
||||
|
||||
let next = this.nextCluster(start)
|
||||
while (next > 1 && next < 0xff7) {
|
||||
chain.push(next)
|
||||
next = this.nextCluster(next)
|
||||
}
|
||||
|
||||
return chain
|
||||
}
|
||||
}
|
||||
|
||||
function decodeBootSector(data: DataView): IBootSectorInfo | null {
|
||||
@ -262,6 +338,8 @@ function decodeDirectoryEntry(data: DataView): DirEntry | null {
|
||||
extension,
|
||||
attributes,
|
||||
firstCluster,
|
||||
clusterChain: [],
|
||||
data: new ArrayBuffer(0),
|
||||
size,
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user