mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
TEVD disk drive now uses PartialDOM
This commit is contained in:
@@ -23,7 +23,7 @@ const actions = {
|
||||
graphics.setBackground(34,51,68)
|
||||
sys.poke(-1299460, 20)
|
||||
sys.poke(-1299460, 21)
|
||||
}
|
||||
},
|
||||
"audio": ()=>{
|
||||
for (let k = 0; k < 4; k++) {
|
||||
audio.stop(k)
|
||||
@@ -46,7 +46,7 @@ if (!verb) {
|
||||
return 10
|
||||
}
|
||||
|
||||
let actionfun = actions[verb][target]
|
||||
let actionfun = actions[verb.toLowerCase()][target.toLowerCase()]
|
||||
if (actionfun) actionfun()
|
||||
else {
|
||||
printerrln(`sysctl: unknown target ${target}`)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -23,7 +23,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
}
|
||||
|
||||
private val tevdPath = File(theTevdPath)
|
||||
private val DOM = VDUtil.readDiskArchive(tevdPath, charset = VM.CHARSET)
|
||||
private val DOM = PartialDOM(tevdPath, VM.CHARSET)//VDUtil.readDiskArchive(tevdPath, charset = VM.CHARSET)
|
||||
|
||||
private var fileOpen = false
|
||||
private var fileOpenMode = -1 // 1: 'W", 2: 'A'
|
||||
@@ -131,7 +131,8 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
val file = EntryFile(BLOCK_SIZE.toLong())
|
||||
file.getContent().appendBytes(inputData)
|
||||
|
||||
DOM.entries[1] = DiskEntry(1, 1, "TEVDBOOT".toByteArray(VM.CHARSET), creationTime, creationTime, file)
|
||||
DOM.addNewFile(DiskEntry(1, 1, "TEVDBOOT".toByteArray(VM.CHARSET), creationTime, creationTime, file))
|
||||
|
||||
|
||||
fileOpenMode = -1
|
||||
|
||||
@@ -345,7 +346,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
|
||||
// TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it
|
||||
|
||||
val bootFile = DOM.entries[1]
|
||||
val bootFile = DOM.requestFile(1)
|
||||
|
||||
printdbg("bootFile = $bootFile, ID: 1, exists = ${bootFile != null}")
|
||||
|
||||
@@ -355,7 +356,7 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
return
|
||||
}
|
||||
try {
|
||||
val retMsg = VDUtil.getAsNormalFile(DOM, 1).getContent().sliceArray(0 until BLOCK_SIZE)
|
||||
val retMsg = (bootFile.contents as EntryFile).getContent().sliceArray(0 until BLOCK_SIZE) //VDUtil.getAsNormalFile(DOM, 1).getContent().sliceArray(0 until BLOCK_SIZE)
|
||||
|
||||
printdbg("retMsg = ${retMsg.toString(VM.CHARSET)}")
|
||||
|
||||
@@ -488,8 +489,9 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
|
||||
|
||||
// TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it
|
||||
|
||||
DOM.entries.clear()
|
||||
DOM.diskName = newName.toByteArray(VM.CHARSET)
|
||||
TODO()
|
||||
// DOM.entries.clear()
|
||||
// DOM.diskName = newName.toByteArray(VM.CHARSET)
|
||||
}
|
||||
else
|
||||
statusCode.set(TestDiskDrive.STATE_CODE_ILLEGAL_COMMAND)
|
||||
|
||||
@@ -7,13 +7,13 @@ import java.io.IOException
|
||||
/**
|
||||
* Created by minjaesong on 2022-12-17.
|
||||
*/
|
||||
class TevdFileDescriptor(val DOM: VirtualDisk, _pathstr: String) {
|
||||
class TevdFileDescriptor(val DOM: PartialDOM, _pathstr: String) {
|
||||
|
||||
val path = _pathstr.replace('\\', '/')
|
||||
val vdPath = VDUtil.VDPath(path, VM.CHARSET)
|
||||
|
||||
val entryID: EntryID?
|
||||
get() = VDUtil.getFile(DOM, vdPath)?.entryID
|
||||
get() = DOM.requestFile(path)?.entryID
|
||||
|
||||
val canonicalPath = path.replace('/', '\\')
|
||||
|
||||
@@ -29,25 +29,34 @@ class TevdFileDescriptor(val DOM: VirtualDisk, _pathstr: String) {
|
||||
|
||||
|
||||
val isFile: Boolean
|
||||
get() = entryID.let { if (it == null) false else VDUtil.isFileFollowSymlink(DOM, it) }
|
||||
get() = DOM.requestFile(path)?.contents is EntryFile // TODO follow symlink
|
||||
|
||||
val isDirectory: Boolean
|
||||
get() = entryID.let { if (it == null) false else VDUtil.isDirectoryFollowSymlink(DOM, it) }
|
||||
get() = DOM.requestFile(path)?.contents is EntryDirectory // TODO follow symlink
|
||||
|
||||
|
||||
private fun requestFile(): Pair<DiskEntry, DiskEntryContent> {
|
||||
val file = DOM.requestFile(path) ?: throw IOException("File not found")
|
||||
val fileContent = file.contents
|
||||
|
||||
return file to fileContent
|
||||
}
|
||||
|
||||
|
||||
fun appendBytes(bytes: ByteArray) {
|
||||
val fileContent = VDUtil.getAsNormalFile(DOM, vdPath) // this is not an object properties: the reference to the file may have been changed
|
||||
fileContent.getContent().appendBytes(bytes)
|
||||
VDUtil.getFile(DOM, vdPath)!!.modificationDate = VDUtil.currentUnixtime
|
||||
// val fileContent = VDUtil.getAsNormalFile(DOM, vdPath) // this is not an object properties: the reference to the file may have been changed
|
||||
val (file, fileContent) = requestFile()
|
||||
(fileContent as EntryFile).getContent().appendBytes(bytes) // TODO follow symlink
|
||||
file.modificationDate = VDUtil.currentUnixtime
|
||||
}
|
||||
|
||||
fun writeBytes(bytes: ByteArray) {
|
||||
val fileContent = VDUtil.getAsNormalFile(DOM, vdPath)
|
||||
val (file, fileContent) = requestFile()
|
||||
// println("[TevdFileDesc] ${path} writing ${bytes.size} bytes...")
|
||||
// println("Old: ${fileContent.getContent().toByteArray().toString(VM.CHARSET)}")
|
||||
fileContent.replaceContent(ByteArray64.fromByteArray(bytes))
|
||||
(fileContent as EntryFile).replaceContent(ByteArray64.fromByteArray(bytes)) // TODO follow symlink
|
||||
// println("New: ${fileContent.getContent().toByteArray().toString(VM.CHARSET)}")
|
||||
VDUtil.getFile(DOM, vdPath)!!.modificationDate = VDUtil.currentUnixtime
|
||||
file.modificationDate = VDUtil.currentUnixtime
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,12 +64,8 @@ class TevdFileDescriptor(val DOM: VirtualDisk, _pathstr: String) {
|
||||
* @return actual bytes read, the size may be less than `length` if the actual file size is smaller
|
||||
*/
|
||||
fun getHeadBytes64(length: Long): ByteArray64 {
|
||||
if (isDirectory) throw RuntimeException("Not a file")
|
||||
if (!exists()) throw IOException("File not found")
|
||||
|
||||
val fileContent = VDUtil.getAsNormalFile(DOM, vdPath)
|
||||
|
||||
return fileContent.getContent().let {
|
||||
val (file, fileContent) = requestFile()
|
||||
return (fileContent as EntryFile).getContent().let {
|
||||
it.sliceArray64(0L until minOf(length, it.size))
|
||||
}
|
||||
}
|
||||
@@ -69,25 +74,22 @@ class TevdFileDescriptor(val DOM: VirtualDisk, _pathstr: String) {
|
||||
* @return actual bytes read, the size may be less than `length` if the actual file size is smaller
|
||||
*/
|
||||
fun getHeadBytes(length: Int): ByteArray {
|
||||
if (isDirectory) throw RuntimeException("Not a file")
|
||||
if (!exists()) throw IOException("File not found")
|
||||
|
||||
val fileContent = VDUtil.getAsNormalFile(DOM, vdPath)
|
||||
|
||||
return fileContent.getContent().let {
|
||||
val (file, fileContent) = requestFile()
|
||||
return (fileContent as EntryFile).getContent().let {
|
||||
it.sliceArray(0 until minOf(length.toLong(), it.size).toInt())
|
||||
}
|
||||
}
|
||||
|
||||
fun exists(): Boolean {
|
||||
return VDUtil.getFile(DOM, vdPath) != null
|
||||
return (DOM.requestFile(path) != null)
|
||||
}
|
||||
|
||||
fun delete(): Boolean {
|
||||
return try {
|
||||
val parentDir = vdPath.getParent()
|
||||
VDUtil.deleteFile(DOM, vdPath)
|
||||
VDUtil.getFile(DOM, parentDir)!!.modificationDate = VDUtil.currentUnixtime
|
||||
val parentDir = vdPath.getParent().toString()
|
||||
DOM.removeFile(path)
|
||||
DOM.requestFile(parentDir)!!.modificationDate = VDUtil.currentUnixtime
|
||||
|
||||
true
|
||||
}
|
||||
catch (e: KotlinNullPointerException) {
|
||||
@@ -96,33 +98,43 @@ class TevdFileDescriptor(val DOM: VirtualDisk, _pathstr: String) {
|
||||
}
|
||||
|
||||
fun length(): Long {
|
||||
return if (isFile) VDUtil.getAsNormalFileOrNull(DOM, vdPath)?.getSizePure() ?: 0L
|
||||
val (file, fileContent) = requestFile()
|
||||
return if (fileContent is EntryFile)
|
||||
fileContent.getSizePure()
|
||||
else -1L
|
||||
}
|
||||
|
||||
fun listFiles(): Array<TevdFileDescriptor>? {
|
||||
if (isFile) return null
|
||||
|
||||
entryID.let {
|
||||
if (it == null) return null
|
||||
|
||||
return VDUtil.getDirectoryEntries(DOM, it).map {
|
||||
TevdFileDescriptor(DOM, path + '/' + it.getFilenameString(VM.CHARSET))
|
||||
}.toTypedArray()
|
||||
}
|
||||
val (file, fileContent) = requestFile()
|
||||
return if (fileContent !is EntryDirectory) null // TODO follow symlink
|
||||
else (DOM.requestFile(path)?.contents as EntryDirectory).getContent().map { id -> DOM.requestFile(id)!! }.map {
|
||||
TevdFileDescriptor(DOM, path + '/' + it.getFilenameString(VM.CHARSET))
|
||||
}.toTypedArray()
|
||||
}
|
||||
|
||||
fun readBytes(): ByteArray {
|
||||
if (isDirectory) throw RuntimeException("Not a file")
|
||||
if (!exists()) throw IOException("File not found")
|
||||
return VDUtil.getAsNormalFile(DOM, vdPath).getContent().toByteArray()
|
||||
val (file, fileContent) = requestFile()
|
||||
if (fileContent !is EntryFile) throw RuntimeException("Not a file") // TODO follow symlink
|
||||
else
|
||||
return fileContent.getContent().toByteArray()
|
||||
}
|
||||
|
||||
fun mkdir(): Boolean {
|
||||
return try {
|
||||
val parentDir = vdPath.getParent()
|
||||
VDUtil.addDir(DOM, parentDir, nameBytes)
|
||||
VDUtil.getFile(DOM, parentDir)!!.modificationDate = VDUtil.currentUnixtime
|
||||
val parentDir = vdPath.getParent().toString()
|
||||
|
||||
val dir = DOM.requestFile(parentDir)!!
|
||||
val dirContent = dir.contents as EntryDirectory
|
||||
|
||||
val newTime = VDUtil.currentUnixtime
|
||||
val newID = DOM.generateUniqueID()
|
||||
val newDir = DiskEntry(newID, dir.entryID, nameBytes, newTime, newTime, EntryDirectory())
|
||||
|
||||
DOM.addNewFile(newDir)
|
||||
dirContent.add(newID)
|
||||
|
||||
dir.modificationDate = newTime
|
||||
|
||||
true
|
||||
}
|
||||
catch (e: KotlinNullPointerException) {
|
||||
@@ -135,9 +147,22 @@ class TevdFileDescriptor(val DOM: VirtualDisk, _pathstr: String) {
|
||||
val time_t = System.currentTimeMillis() / 1000
|
||||
val newFile = DiskEntry(-1, -1, nameBytes, time_t, time_t, fileContent)
|
||||
return try {
|
||||
val parentDir = vdPath.getParent()
|
||||
VDUtil.addFile(DOM, parentDir, newFile)
|
||||
VDUtil.getFile(DOM, parentDir)!!.modificationDate = VDUtil.currentUnixtime
|
||||
val parentDir = vdPath.getParent().toString()
|
||||
|
||||
val dir = DOM.requestFile(parentDir)!!
|
||||
val dirContent = dir.contents as EntryDirectory
|
||||
|
||||
val newTime = VDUtil.currentUnixtime
|
||||
val newID = DOM.generateUniqueID()
|
||||
|
||||
newFile.entryID = newID
|
||||
newFile.parentEntryID = dir.entryID
|
||||
|
||||
DOM.addNewFile(newFile)
|
||||
dirContent.add(newID)
|
||||
|
||||
dir.modificationDate = newTime
|
||||
|
||||
true
|
||||
}
|
||||
catch (e: KotlinNullPointerException) {
|
||||
@@ -146,12 +171,12 @@ class TevdFileDescriptor(val DOM: VirtualDisk, _pathstr: String) {
|
||||
}
|
||||
|
||||
fun setLastModified(newTime_t: Long): Boolean {
|
||||
return VDUtil.getFile(DOM, vdPath).let {
|
||||
if (it != null) {
|
||||
it.modificationDate = newTime_t
|
||||
true
|
||||
}
|
||||
else false
|
||||
return try {
|
||||
DOM.requestFile(path)!!.modificationDate = newTime_t
|
||||
true
|
||||
}
|
||||
catch (e: KotlinNullPointerException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user