Skip to content

Commit

Permalink
Add error helper, supermon write/delete
Browse files Browse the repository at this point in the history
  • Loading branch information
zellyn committed Nov 28, 2016
1 parent a74a047 commit 821c2c5
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 0 deletions.
114 changes: 114 additions & 0 deletions lib/errors/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright © 2016 Zellyn Hunter <[email protected]>

// Package errors contains helpers for creating and testing for
// certain types of errors.
package errors

import (
"errors"
"fmt"
)

// Copy of errors.New, so you this package can be imported instead.
func New(text string) error {
return errors.New(text)
}

// --------------------- Out of space

// outOfSpace is an error that signals being out of space on a disk
// image.
type outOfSpace string

// OutOfSpaceI is the tag interface used to mark out of space errors.
type OutOfSpaceI interface {
IsOutOfSpace()
}

var _ OutOfSpaceI = outOfSpace("test")

// Error returns the string message of an OutOfSpace error.
func (o outOfSpace) Error() string {
return string(o)
}

// Tag method on our outOfSpace implementation.
func (o outOfSpace) IsOutOfSpace() {
}

// OutOfSpacef is fmt.Errorf for OutOfSpace errors.
func OutOfSpacef(format string, a ...interface{}) error {
return outOfSpace(fmt.Sprintf(format, a...))
}

// IsOutOfSpace returns true if a given error is an OutOfSpace error.
func IsOutOfSpace(err error) bool {
_, ok := err.(OutOfSpaceI)
return ok
}

// --------------------- File exists

// fileExists is an error returned when a problem is caused by a file
// with the given name already existing.
type fileExists string

// FileExistsI is the tag interface used to mark FileExists errors.
type FileExistsI interface {
IsFileExists()
}

var _ FileExistsI = fileExists("test")

// Error returns the string message of a FileExists error.
func (o fileExists) Error() string {
return string(o)
}

// Tag method on our fileExists implementation.
func (o fileExists) IsFileExists() {
}

// FileExistsf is fmt.Errorf for FileExists errors.
func FileExistsf(format string, a ...interface{}) error {
return fileExists(fmt.Sprintf(format, a...))
}

// IsFileExists returns true if a given error is a FileExists error.
func IsFileExists(err error) bool {
_, ok := err.(FileExistsI)
return ok
}

// --------------------- File not found

// fileNotFound is an error returned when a file with the given name
// cannot be found.
type fileNotFound string

// FileNotFoundI is the tag interface used to mark FileNotFound errors.
type FileNotFoundI interface {
IsFileNotFound()
}

var _ FileNotFoundI = fileNotFound("test")

// Error returns the string message of a FileNotFound error.
func (o fileNotFound) Error() string {
return string(o)
}

// Tag method on our fileNotFound implementation.
func (o fileNotFound) IsFileNotFound() {
}

// FileNotFoundf is fmt.Errorf for FileNotFound errors.
func FileNotFoundf(format string, a ...interface{}) error {
return fileNotFound(fmt.Sprintf(format, a...))
}

// IsFileNotFound returns true if a given error is a FileNotFound error.
func IsFileNotFound(err error) bool {
_, ok := err.(FileNotFoundI)
return ok
}
75 changes: 75 additions & 0 deletions lib/supermon/supermon.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strings"

"github.com/zellyn/diskii/lib/disk"
"github.com/zellyn/diskii/lib/errors"
)

const (
Expand Down Expand Up @@ -47,6 +48,37 @@ func LoadSectorMap(sd disk.SectorDisk) (SectorMap, error) {
return sm, nil
}

// Persist writes the current contenst of a sector map back back to
// disk.
func (sm SectorMap) Persist(sd disk.SectorDisk) error {
sector09, err := sd.ReadPhysicalSector(0, 9)
if err != nil {
return err
}
copy(sector09[0xd0:], sm[0:0x30])
if err := sd.WritePhysicalSector(0, 9, sector09); err != nil {
return err
}
if err := sd.WritePhysicalSector(0, 0xA, sm[0x30:0x130]); err != nil {
return err
}
if err := sd.WritePhysicalSector(0, 0xB, sm[0x130:0x230]); err != nil {
return err
}
return nil
}

// FreeSectors returns the number of blocks free in a sector map.
func (sm SectorMap) FreeSectors() int {
count := 0
for _, file := range sm {
if file == FileFree {
count++
}
}
return count
}

// Verify checks that we actually have a NakedOS disk.
func (sm SectorMap) Verify() error {
for sector := byte(0); sector <= 0xB; sector++ {
Expand Down Expand Up @@ -118,6 +150,49 @@ func (sm SectorMap) ReadFile(sd disk.SectorDisk, file byte) ([]byte, error) {
return result, nil
}

// Delete deletes a file from the sector map. It does not persist the changes.
func (sm SectorMap) Delete(file byte) {
for i, f := range sm {
if f == file {
sm[i] = FileFree
}
}
}

// WriteFile writes the contents of a file.
func (sm SectorMap) WriteFile(sd disk.SectorDisk, file byte, contents []byte, overwrite bool) error {
sectorsNeeded := (len(contents) + 255) / 256
cts := make([]byte, 256*sectorsNeeded)
copy(cts, contents)
free := sm.FreeSectors() + len(sm.SectorsForFile(file))
if free < sectorsNeeded {
return errors.OutOfSpacef("file requires %d sectors, but only %d are available")
}
sm.Delete(file)

// TODO(zellyn): continue implementation.
return fmt.Errorf("WriteFile not implemented yet")
i := 0
OUTER:
for track := byte(0); track < sd.Tracks(); track++ {
for sector := byte(0); sector < sd.Sectors(); sector++ {
if sm.FileForSector(track, sector) == file {
if err := sd.WritePhysicalSector(track, sector, cts[i*256:(i+1)*256]); err != nil {
return err
}
i++
if i == sectorsNeeded {
break OUTER
}
}
}
}
if err := sm.Persist(sd); err != nil {
return err
}
return nil
}

// Symbol represents a single Super-Mon symbol.
type Symbol struct {
// Address is the memory address the symbol points to, or 0 for an
Expand Down

0 comments on commit 821c2c5

Please sign in to comment.