diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2022-06-06 10:20:01 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2022-06-06 10:20:01 -0600 |
commit | 28f09b784b5741f044b755dc7033a82075d2d98c (patch) | |
tree | db80cd6bfda920ec700fd20aee112eedf6e9dd7a /pkg/util/ref.go | |
parent | 20c21bf5ebc085f6f318e9199a1fee5f44c6ea61 (diff) |
write support
Diffstat (limited to 'pkg/util/ref.go')
-rw-r--r-- | pkg/util/ref.go | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/pkg/util/ref.go b/pkg/util/ref.go index 69f7db4..05ef08f 100644 --- a/pkg/util/ref.go +++ b/pkg/util/ref.go @@ -1,6 +1,9 @@ package util import ( + "fmt" + "io" + "lukeshu.com/btrfs-tools/pkg/binstruct" ) @@ -8,8 +11,14 @@ type File[A ~int64] interface { Name() string Size() (A, error) ReadAt(p []byte, off A) (n int, err error) + WriteAt(p []byte, off A) (n int, err error) } +var ( + _ io.WriterAt = File[int64](nil) + _ io.ReaderAt = File[int64](nil) +) + type Ref[A ~int64, T any] struct { File File[A] Addr A @@ -22,7 +31,28 @@ func (r *Ref[A, T]) Read() error { if _, err := r.File.ReadAt(buf, r.Addr); err != nil { return err } - if _, err := binstruct.Unmarshal(buf, &r.Data); err != nil { + n, err := binstruct.Unmarshal(buf, &r.Data) + if err != nil { + return err + } + if n != size { + return fmt.Errorf("util.Ref[%T].Read: left over data: read %d bytes but only consumed %d", + r.Data, size, n) + } + return nil +} + +func (r *Ref[A, T]) Write() error { + size := binstruct.StaticSize(r.Data) + buf, err := binstruct.Marshal(r.Data) + if err != nil { + return err + } + if len(buf) != size { + return fmt.Errorf("util.Ref[%T].Write: expected to want to write %d bytes, but got %d bytes to write", + r.Data, size, len(buf)) + } + if _, err = r.File.WriteAt(buf, r.Addr); err != nil { return err } return nil |