From 28f09b784b5741f044b755dc7033a82075d2d98c Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 6 Jun 2022 10:20:01 -0600 Subject: write support --- pkg/util/ref.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'pkg/util/ref.go') 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 -- cgit v1.2.3-2-g168b