mirror of
https://github.com/zellyn/diskii.git
synced 2024-06-08 13:29:28 +00:00
dos3: implement GetFile. Also add StartAddress
This commit is contained in:
parent
8eb11c7b93
commit
76f229ac2f
|
@ -87,8 +87,9 @@ type Operator interface {
|
||||||
|
|
||||||
// FileInfo represents a file descriptor plus the content.
|
// FileInfo represents a file descriptor plus the content.
|
||||||
type FileInfo struct {
|
type FileInfo struct {
|
||||||
Descriptor Descriptor
|
Descriptor Descriptor
|
||||||
Data []byte
|
Data []byte
|
||||||
|
StartAddress uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// operatorFactory is the type of functions that accept a SectorDisk,
|
// operatorFactory is the type of functions that accept a SectorDisk,
|
||||||
|
|
107
lib/dos3/dos3.go
107
lib/dos3/dos3.go
|
@ -350,6 +350,37 @@ func (fd *FileDesc) FilenameString() string {
|
||||||
return strings.TrimRight(string(slice), " ")
|
return strings.TrimRight(string(slice), " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// descriptor returns a disk.Descriptor for a FileDesc, but with the
|
||||||
|
// length set to -1, since we can't know it without reading the file
|
||||||
|
// contents.
|
||||||
|
func (fd FileDesc) descriptor() disk.Descriptor {
|
||||||
|
desc := disk.Descriptor{
|
||||||
|
Name: fd.FilenameString(),
|
||||||
|
Sectors: int(fd.SectorCount),
|
||||||
|
Length: -1,
|
||||||
|
Locked: (fd.Filetype & FiletypeLocked) > 0,
|
||||||
|
}
|
||||||
|
switch fd.Filetype & 0x7f {
|
||||||
|
case FiletypeText: // Text file
|
||||||
|
desc.Type = disk.FiletypeASCIIText
|
||||||
|
case FiletypeInteger: // INTEGER BASIC file
|
||||||
|
desc.Type = disk.FiletypeIntegerBASIC
|
||||||
|
case FiletypeApplesoft: // APPLESOFT BASIC file
|
||||||
|
desc.Type = disk.FiletypeApplesoftBASIC
|
||||||
|
case FiletypeBinary: // BINARY file
|
||||||
|
desc.Type = disk.FiletypeBinary
|
||||||
|
case FiletypeS: // S type file
|
||||||
|
desc.Type = disk.FiletypeS
|
||||||
|
case FiletypeRelocatable: // RELOCATABLE object module file
|
||||||
|
desc.Type = disk.FiletypeRelocatable
|
||||||
|
case FiletypeA: // A type file
|
||||||
|
desc.Type = disk.FiletypeA
|
||||||
|
case FiletypeB: // B type file
|
||||||
|
desc.Type = disk.FiletypeB
|
||||||
|
}
|
||||||
|
return desc
|
||||||
|
}
|
||||||
|
|
||||||
// Contents returns the on-disk contents of a file represented by a
|
// Contents returns the on-disk contents of a file represented by a
|
||||||
// FileDesc.
|
// FileDesc.
|
||||||
func (fd *FileDesc) Contents(lsd disk.LogicalSectorDisk) ([]byte, error) {
|
func (fd *FileDesc) Contents(lsd disk.LogicalSectorDisk) ([]byte, error) {
|
||||||
|
@ -544,20 +575,80 @@ func (o operator) Catalog(subdir string) ([]disk.Descriptor, error) {
|
||||||
}
|
}
|
||||||
descs := make([]disk.Descriptor, 0, len(fds))
|
descs := make([]disk.Descriptor, 0, len(fds))
|
||||||
for _, fd := range fds {
|
for _, fd := range fds {
|
||||||
descs = append(descs, disk.Descriptor{
|
descs = append(descs, fd.descriptor())
|
||||||
Name: fd.FilenameString(),
|
|
||||||
Sectors: int(fd.SectorCount),
|
|
||||||
Length: -1, // TODO(zellyn): read actual file length
|
|
||||||
Locked: (fd.Filetype & FiletypeLocked) > 0,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return descs, nil
|
return descs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fileForFilename returns the FileDesc corresponding to the given
|
||||||
|
// filename, or an error.
|
||||||
|
func (o operator) fileForFilename(filename string) (FileDesc, error) {
|
||||||
|
fds, _, err := ReadCatalog(o.lsd)
|
||||||
|
if err != nil {
|
||||||
|
return FileDesc{}, err
|
||||||
|
}
|
||||||
|
for _, fd := range fds {
|
||||||
|
if fd.FilenameString() == filename {
|
||||||
|
return fd, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FileDesc{}, fmt.Errorf("Filename %q not found", filename)
|
||||||
|
}
|
||||||
|
|
||||||
// GetFile retrieves a file by name.
|
// GetFile retrieves a file by name.
|
||||||
func (o operator) GetFile(filename string) (disk.FileInfo, error) {
|
func (o operator) GetFile(filename string) (disk.FileInfo, error) {
|
||||||
// TODO(zellyn): Implement GetFile
|
fd, err := o.fileForFilename(filename)
|
||||||
return disk.FileInfo{}, fmt.Errorf("%s does not yet implement `GetFile`", operatorName)
|
if err != nil {
|
||||||
|
return disk.FileInfo{}, err
|
||||||
|
}
|
||||||
|
desc := fd.descriptor()
|
||||||
|
data, err := fd.Contents(o.lsd)
|
||||||
|
if err != nil {
|
||||||
|
return disk.FileInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fi := disk.FileInfo{
|
||||||
|
Descriptor: desc,
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
|
||||||
|
errType := "UNKNOWN"
|
||||||
|
switch fd.Filetype & 0x7f {
|
||||||
|
case FiletypeText: // Text file
|
||||||
|
for data[len(data)-1] == 0 {
|
||||||
|
data = data[:len(data)-1]
|
||||||
|
}
|
||||||
|
fi.Descriptor.Length = len(data)
|
||||||
|
fi.Data = data
|
||||||
|
return fi, nil
|
||||||
|
|
||||||
|
case FiletypeInteger, FiletypeApplesoft, FiletypeBinary:
|
||||||
|
switch fd.Filetype & 0x7f {
|
||||||
|
case FiletypeApplesoft:
|
||||||
|
fi.StartAddress = 0x801
|
||||||
|
case FiletypeInteger:
|
||||||
|
// TODO(zellyn): figure out what address integer basic programs are stored at.
|
||||||
|
case FiletypeBinary:
|
||||||
|
fi.StartAddress = uint16(data[0]) + uint16(data[1])<<8
|
||||||
|
data = data[2:]
|
||||||
|
}
|
||||||
|
length := int(data[0]) + int(data[1])*256
|
||||||
|
data = data[2 : length+2]
|
||||||
|
fi.Descriptor.Length = length
|
||||||
|
fi.Data = data
|
||||||
|
return fi, nil
|
||||||
|
|
||||||
|
case FiletypeS: // S type file
|
||||||
|
errType = "S"
|
||||||
|
case FiletypeRelocatable: // RELOCATABLE object module file
|
||||||
|
errType = "REL"
|
||||||
|
case FiletypeA: // A type file
|
||||||
|
errType = "A"
|
||||||
|
case FiletypeB: // B type file
|
||||||
|
errType = "B"
|
||||||
|
}
|
||||||
|
|
||||||
|
return disk.FileInfo{}, fmt.Errorf("%s does not yet implement `GetFile` for filetype %s", operatorName, errType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// operatorFactory is the factory that returns dos3 operators given
|
// operatorFactory is the factory that returns dos3 operators given
|
||||||
|
|
|
@ -319,6 +319,7 @@ func (o operator) GetFile(filename string) (disk.FileInfo, error) {
|
||||||
Length: len(data),
|
Length: len(data),
|
||||||
Locked: false,
|
Locked: false,
|
||||||
Type: disk.FiletypeBinary,
|
Type: disk.FiletypeBinary,
|
||||||
|
// TODO(zellyn): Set StartAddress if we know it.
|
||||||
}
|
}
|
||||||
return disk.FileInfo{
|
return disk.FileInfo{
|
||||||
Descriptor: desc,
|
Descriptor: desc,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user