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