refactor: Decompose archive func

This commit is contained in:
Felix Pojtinger
2021-12-07 21:12:23 +01:00
parent 23784eed97
commit ff7803416d
20 changed files with 966 additions and 914 deletions
+4 -4
View File
@@ -2,15 +2,15 @@ package tape
import "os"
func OpenTapeReadOnly(tape string) (f *os.File, isRegular bool, err error) {
fileDescription, err := os.Stat(tape)
func OpenTapeReadOnly(drive string) (f *os.File, isRegular bool, err error) {
fileDescription, err := os.Stat(drive)
if err != nil {
return nil, false, err
}
isRegular = fileDescription.Mode().IsRegular()
if isRegular {
f, err = os.Open(tape)
f, err = os.Open(drive)
if err != nil {
return f, isRegular, err
}
@@ -18,7 +18,7 @@ func OpenTapeReadOnly(tape string) (f *os.File, isRegular bool, err error) {
return f, isRegular, nil
}
f, err = os.OpenFile(tape, os.O_RDONLY, os.ModeCharDevice)
f, err = os.OpenFile(drive, os.O_RDONLY, os.ModeCharDevice)
if err != nil {
return f, isRegular, err
}
+79
View File
@@ -0,0 +1,79 @@
package tape
import (
"archive/tar"
"bufio"
"os"
"github.com/pojntfx/stfs/internal/controllers"
"github.com/pojntfx/stfs/internal/counters"
)
func OpenTapeWriteOnly(drive string, recordSize int, overwrite bool) (tw *tar.Writer, isRegular bool, cleanup func(dirty *bool) error, err error) {
stat, err := os.Stat(drive)
if err == nil {
isRegular = stat.Mode().IsRegular()
} else {
if os.IsNotExist(err) {
isRegular = true
} else {
return nil, false, nil, err
}
}
var f *os.File
if isRegular {
f, err = os.OpenFile(drive, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return nil, false, nil, err
}
// No need to go to end manually due to `os.O_APPEND`
} else {
f, err = os.OpenFile(drive, os.O_APPEND|os.O_WRONLY, os.ModeCharDevice)
if err != nil {
return nil, false, nil, err
}
if !overwrite {
// Go to end of tape
if err := controllers.GoToEndOfTape(f); err != nil {
return nil, false, nil, err
}
}
}
var bw *bufio.Writer
var counter *counters.CounterWriter
if isRegular {
tw = tar.NewWriter(f)
} else {
bw = bufio.NewWriterSize(f, controllers.BlockSize*recordSize)
counter = &counters.CounterWriter{Writer: bw, BytesRead: 0}
tw = tar.NewWriter(counter)
}
return tw, isRegular, func(dirty *bool) error {
// Only write the trailer if we wrote to the archive
if *dirty {
if err := tw.Close(); err != nil {
return err
}
if !isRegular {
if controllers.BlockSize*recordSize-counter.BytesRead > 0 {
// Fill the rest of the record with zeros
if _, err := bw.Write(make([]byte, controllers.BlockSize*recordSize-counter.BytesRead)); err != nil {
return err
}
}
if err := bw.Flush(); err != nil {
return err
}
}
}
return f.Close()
}, nil
}