summaryrefslogtreecommitdiff
path: root/pkg/btrfs/btrfsitem
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-06-01 10:22:09 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-06-01 10:45:36 -0600
commit774b5baa5aa5772b29865e8a570025d94ec34d2a (patch)
tree0ce0704bd1a39b3b7b0b4a000fe9f9206907d3ac /pkg/btrfs/btrfsitem
parent8dde45b09728fb753b072c73ff624dde832c073b (diff)
better error tolerance
Diffstat (limited to 'pkg/btrfs/btrfsitem')
-rw-r--r--pkg/btrfs/btrfsitem/item_empty.go2
-rw-r--r--pkg/btrfs/btrfsitem/items.go39
2 files changed, 34 insertions, 7 deletions
diff --git a/pkg/btrfs/btrfsitem/item_empty.go b/pkg/btrfs/btrfsitem/item_empty.go
index ed0f66f..fe7ae90 100644
--- a/pkg/btrfs/btrfsitem/item_empty.go
+++ b/pkg/btrfs/btrfsitem/item_empty.go
@@ -5,5 +5,5 @@ import (
)
type Empty struct { // UNTYPED=0, QGROUP_RELATION=246
- binstruct.End `bin:"off=48"`
+ binstruct.End `bin:"off=0"`
}
diff --git a/pkg/btrfs/btrfsitem/items.go b/pkg/btrfs/btrfsitem/items.go
index 91b7029..3c4392e 100644
--- a/pkg/btrfs/btrfsitem/items.go
+++ b/pkg/btrfs/btrfsitem/items.go
@@ -14,19 +14,46 @@ type Item interface {
isItem()
}
-func UnmarshalItem(keytyp Type, dat []byte) (Item, error) {
+type Error struct {
+ Dat []byte
+ Err error
+}
+
+func (Error) isItem() {}
+
+func (o Error) MarshalBinary() ([]byte, error) {
+ return o.Dat, nil
+}
+
+func (o *Error) UnmarshalBinary(dat []byte) (int, error) {
+ o.Dat = dat
+ return len(dat), nil
+}
+
+// Rather than returning a separate error value, return an Error item.
+func UnmarshalItem(keytyp Type, dat []byte) Item {
gotyp, ok := keytype2gotype[keytyp]
if !ok {
- return nil, fmt.Errorf("btrfsitem.UnmarshalItem: unknown item type: %v", keytyp)
+ return Error{
+ Dat: dat,
+ Err: fmt.Errorf("btrfsitem.UnmarshalItem(typ=%v, dat): unknown item type", keytyp),
+ }
}
retPtr := reflect.New(gotyp)
n, err := binstruct.Unmarshal(dat, retPtr.Interface())
if err != nil {
- return nil, fmt.Errorf("btrfsitem.UnmarshalItem: %w", err)
+ return Error{
+ Dat: dat,
+ Err: fmt.Errorf("btrfsitem.UnmarshalItem(typ=%v, dat): %w", keytyp, err),
+ }
+
}
if n < len(dat) {
- return nil, fmt.Errorf("btrfsitem.UnmarshalItem: left over data: got %d bytes but only consumed %d",
- len(dat), n)
+ return Error{
+ Dat: dat,
+ Err: fmt.Errorf("btrfsitem.UnmarshalItem(typ=%v, dat): left over data: got %d bytes but only consumed %d",
+ keytyp, len(dat), n),
+ }
}
- return retPtr.Elem().Interface().(Item), nil
+ return retPtr.Elem().Interface().(Item)
}