Partial fixes for write file

This commit is contained in:
Terence Boldt 2021-06-30 05:04:59 +01:00
parent e828fcc99a
commit a9b1a9e482
3 changed files with 59 additions and 22 deletions

10
main.go
View File

@ -61,7 +61,10 @@ func main() {
fmt.Println("Missing pathname")
os.Exit(1)
}
getFile := prodos.LoadFile(file, pathName)
getFile, err := prodos.LoadFile(file, pathName)
if err != nil {
fmt.Printf("Failed to read file %s: %s", pathName, err)
}
if len(outFileName) == 0 {
_, outFileName = prodos.GetDirectoryAndFileNameFromPath(pathName)
}
@ -87,7 +90,10 @@ func main() {
if err != nil {
os.Exit(1)
}
prodos.WriteFile(file, pathName, fileType, auxType, inFile)
err = prodos.WriteFile(file, pathName, fileType, auxType, inFile)
if err != nil {
fmt.Printf("Failed to write file %s: %s", pathName, err)
}
case "readblock":
file, err := os.OpenFile(fileName, os.O_RDWR, 0755)
if err != nil {

View File

@ -1,6 +1,7 @@
package prodos
import (
"errors"
"fmt"
"os"
"strings"
@ -72,9 +73,9 @@ func ReadDirectory(file *os.File, path string) (VolumeHeader, DirectoryHeader, [
return volumeHeader, directoryHeader, fileEntries
}
func GetFreeFileEntryInDirectory(file *os.File, directory string) FileEntry {
func GetFreeFileEntryInDirectory(file *os.File, directory string) (FileEntry, error) {
_, directoryHeader, _ := ReadDirectory(file, directory)
DumpDirectoryHeader(directoryHeader)
//DumpDirectoryHeader(directoryHeader)
blockNumber := directoryHeader.StartingBlock
buffer := ReadBlock(file, blockNumber)
@ -87,7 +88,7 @@ func GetFreeFileEntryInDirectory(file *os.File, directory string) FileEntry {
// if we ran out of blocks in the directory, return empty
// TODO: expand the directory to add more entries
if blockNumber == 0 {
return FileEntry{}
return FileEntry{}, errors.New("No free file entries found")
}
// else read the next block in the directory
buffer = ReadBlock(file, blockNumber)
@ -100,7 +101,7 @@ func GetFreeFileEntryInDirectory(file *os.File, directory string) FileEntry {
fileEntry.DirectoryBlock = blockNumber
fileEntry.DirectoryOffset = entryOffset
fileEntry.HeaderPointer = directoryHeader.StartingBlock
return fileEntry
return fileEntry, nil
}
entryNumber++

View File

@ -1,13 +1,18 @@
package prodos
import (
"errors"
"fmt"
"os"
"strings"
"time"
)
func LoadFile(file *os.File, path string) []byte {
fileEntry := GetFileEntry(file, path)
func LoadFile(file *os.File, path string) ([]byte, error) {
fileEntry, err := GetFileEntry(file, path)
if err != nil {
return nil, err
}
blockList := getBlocklist(file, fileEntry)
@ -20,10 +25,10 @@ func LoadFile(file *os.File, path string) []byte {
}
}
return buffer
return buffer, nil
}
func WriteFile(file *os.File, path string, fileType int, auxType int, buffer []byte) {
func WriteFile(file *os.File, path string, fileType int, auxType int, buffer []byte) error {
directory, fileName := GetDirectoryAndFileNameFromPath(path)
DeleteFile(file, path)
@ -31,7 +36,10 @@ func WriteFile(file *os.File, path string, fileType int, auxType int, buffer []b
// get list of blocks to write file to
blockList := createBlockList(file, len(buffer))
fileEntry := GetFreeFileEntryInDirectory(file, directory)
fileEntry, err := GetFreeFileEntryInDirectory(file, directory)
if err != nil {
return err
}
// seedling file
if len(buffer) <= 0x200 {
@ -45,12 +53,13 @@ func WriteFile(file *os.File, path string, fileType int, auxType int, buffer []b
// write index block with pointers to data blocks
indexBuffer := make([]byte, 512)
for i := 0; i < 256; i++ {
for i := 1; i < 256; i++ {
if i < len(blockList) {
indexBuffer[i] = byte(blockList[i] & 0x00FF)
indexBuffer[i+256] = byte(blockList[i] >> 8)
}
}
fmt.Println("writing index block")
WriteBlock(file, blockList[0], indexBuffer)
// write all data blocks
@ -59,22 +68,33 @@ func WriteFile(file *os.File, path string, fileType int, auxType int, buffer []b
blockIndexNumber := 1
for i := 0; i < len(buffer); i++ {
blockBuffer[blockPointer] = buffer[i]
if blockPointer == 512 {
if blockPointer == 511 {
fmt.Printf("A i: %d, blockIndexNumber: %d, blockPointer: %d blockList[blockIndexNumber]: %d\n", i, blockIndexNumber, blockPointer, blockList[blockIndexNumber])
fmt.Println(blockIndexNumber)
WriteBlock(file, blockList[blockIndexNumber], blockBuffer)
blockPointer = 0
blockIndexNumber++
}
if i == len(buffer)-1 {
} else if i == len(buffer)-1 {
fmt.Printf("B i: %d, blockIndexNumber: %d, blockPointer: %d\n", i, blockIndexNumber, blockPointer)
for j := blockPointer; j < 512; j++ {
blockBuffer[j] = 0
}
WriteBlock(file, blockList[blockIndexNumber], blockBuffer)
} else {
blockPointer++
}
}
}
// TODO: add tree file
// update volume bitmap
volumeBitmap := ReadVolumeBitmap(file)
for i := 0; i < len(blockList); i++ {
markBlockInVolumeBitmap(volumeBitmap, blockList[i])
}
writeVolumeBitmap(file, volumeBitmap)
// add file entry to directory
fileEntry.FileName = fileName
fileEntry.BlocksUsed = len(blockList)
@ -84,8 +104,11 @@ func WriteFile(file *os.File, path string, fileType int, auxType int, buffer []b
fileEntry.EndOfFile = len(buffer)
fileEntry.FileType = fileType
fileEntry.KeyPointer = blockList[0]
fileEntry.Access = 0b11100011
writeFileEntry(file, fileEntry)
return nil
}
func getBlocklist(file *os.File, fileEntry FileEntry) []int {
@ -96,11 +119,13 @@ func getBlocklist(file *os.File, fileEntry FileEntry) []int {
blocks[0] = fileEntry.KeyPointer
case StorageSapling:
index := ReadBlock(file, fileEntry.KeyPointer)
for i := 0; i < fileEntry.BlocksUsed-1; i++ {
blocks[0] = fileEntry.KeyPointer
for i := 1; i < fileEntry.BlocksUsed-1; i++ {
blocks[i] = int(index[i]) + int(index[i+256])*256
}
case StorageTree:
masterIndex := ReadBlock(file, fileEntry.KeyPointer)
blocks[0] = fileEntry.KeyPointer
for i := 0; i < 128; i++ {
index := ReadBlock(file, int(masterIndex[i])+int(masterIndex[i+256])*256)
for j := 0; j < 256 && i*256+j < fileEntry.BlocksUsed; j++ {
@ -136,13 +161,13 @@ func createBlockList(file *os.File, fileSize int) []int {
return blockList
}
func GetFileEntry(file *os.File, path string) FileEntry {
func GetFileEntry(file *os.File, path string) (FileEntry, error) {
directory, fileName := GetDirectoryAndFileNameFromPath(path)
_, _, fileEntries := ReadDirectory(file, directory)
if fileEntries == nil {
return FileEntry{}
return FileEntry{}, errors.New("File entry not found")
}
var fileEntry FileEntry
@ -153,7 +178,7 @@ func GetFileEntry(file *os.File, path string) FileEntry {
}
}
return fileEntry
return fileEntry, nil
}
func GetDirectoryAndFileNameFromPath(path string) (string, string) {
@ -173,10 +198,13 @@ func GetDirectoryAndFileNameFromPath(path string) (string, string) {
return directory, fileName
}
func DeleteFile(file *os.File, path string) {
fileEntry := GetFileEntry(file, path)
func DeleteFile(file *os.File, path string) error {
fileEntry, err := GetFileEntry(file, path)
if err != nil {
return errors.New("File not found")
}
if fileEntry.StorageType == StorageDeleted {
return
return errors.New("File already deleted")
}
// free the blocks
@ -198,4 +226,6 @@ func DeleteFile(file *os.File, path string) {
directoryHeader.ActiveFileCount--
writeDirectoryHeader(file, directoryHeader, fileEntry.HeaderPointer)
return nil
}