summaryrefslogtreecommitdiff
path: root/pkg/btrfs/btrfssum
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-07-02 16:25:03 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-07-02 16:43:01 -0600
commit9ddcd2c3ed2f85247161c5ffa653f33e6a01a9cd (patch)
tree5d673cf90f37ae7e75b1b4bbe41bc700cfe98c1f /pkg/btrfs/btrfssum
parenteab4dbebf66fa92597a2804c39eb4a4670f5e2ca (diff)
move things around
Diffstat (limited to 'pkg/btrfs/btrfssum')
-rw-r--r--pkg/btrfs/btrfssum/csum.go78
-rw-r--r--pkg/btrfs/btrfssum/csum_test.go35
2 files changed, 113 insertions, 0 deletions
diff --git a/pkg/btrfs/btrfssum/csum.go b/pkg/btrfs/btrfssum/csum.go
new file mode 100644
index 0000000..22d8149
--- /dev/null
+++ b/pkg/btrfs/btrfssum/csum.go
@@ -0,0 +1,78 @@
+package btrfssum
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+ "hash/crc32"
+
+ "lukeshu.com/btrfs-tools/pkg/util"
+)
+
+type CSum [0x20]byte
+
+func (csum CSum) String() string {
+ return hex.EncodeToString(csum[:])
+}
+
+func (csum CSum) Fmt(typ CSumType) string {
+ return hex.EncodeToString(csum[:typ.Size()])
+}
+
+func (csum CSum) Format(f fmt.State, verb rune) {
+ util.FormatByteArrayStringer(csum, csum[:], f, verb)
+}
+
+type CSumType uint16
+
+const (
+ TYPE_CRC32 = CSumType(iota)
+ TYPE_XXHASH
+ TYPE_SHA256
+ TYPE_BLAKE2
+)
+
+func (typ CSumType) String() string {
+ names := map[CSumType]string{
+ TYPE_CRC32: "crc32c",
+ TYPE_XXHASH: "xxhash64",
+ TYPE_SHA256: "sha256",
+ TYPE_BLAKE2: "blake2",
+ }
+ if name, ok := names[typ]; ok {
+ return name
+ }
+ return fmt.Sprintf("%d", typ)
+}
+
+func (typ CSumType) Size() int {
+ sizes := map[CSumType]int{
+ TYPE_CRC32: 4,
+ TYPE_XXHASH: 8,
+ TYPE_SHA256: 32,
+ TYPE_BLAKE2: 32,
+ }
+ if size, ok := sizes[typ]; ok {
+ return size
+ }
+ return len(CSum{})
+}
+
+func (typ CSumType) Sum(data []byte) (CSum, error) {
+ switch typ {
+ case TYPE_CRC32:
+ crc := crc32.Update(0, crc32.MakeTable(crc32.Castagnoli), data)
+
+ var ret CSum
+ binary.LittleEndian.PutUint32(ret[:], crc)
+ return ret, nil
+ case TYPE_XXHASH:
+ panic("not implemented")
+ case TYPE_SHA256:
+ panic("not implemented")
+ case TYPE_BLAKE2:
+ panic("not implemented")
+ default:
+ return CSum{}, fmt.Errorf("unknown checksum type: %v", typ)
+ }
+}
diff --git a/pkg/btrfs/btrfssum/csum_test.go b/pkg/btrfs/btrfssum/csum_test.go
new file mode 100644
index 0000000..c47409c
--- /dev/null
+++ b/pkg/btrfs/btrfssum/csum_test.go
@@ -0,0 +1,35 @@
+package btrfssum_test
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "lukeshu.com/btrfs-tools/pkg/btrfs/btrfssum"
+)
+
+func TestCSumFormat(t *testing.T) {
+ t.Parallel()
+ type TestCase struct {
+ InputSum btrfssum.CSum
+ InputFmt string
+ Output string
+ }
+ csum := btrfssum.CSum{0xbd, 0x7b, 0x41, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
+ testcases := map[string]TestCase{
+ "s": {InputSum: csum, InputFmt: "%s", Output: "bd7b41f400000000000000000000000000000000000000000000000000000000"},
+ "x": {InputSum: csum, InputFmt: "%x", Output: "bd7b41f400000000000000000000000000000000000000000000000000000000"},
+ "v": {InputSum: csum, InputFmt: "%v", Output: "bd7b41f400000000000000000000000000000000000000000000000000000000"},
+ "70s": {InputSum: csum, InputFmt: "|% 70s", Output: "| bd7b41f400000000000000000000000000000000000000000000000000000000"},
+ "#180v": {InputSum: csum, InputFmt: "%#180v", Output: " btrfssum.CSum{0xbd, 0x7b, 0x41, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}"},
+ }
+ for tcName, tc := range testcases {
+ tc := tc
+ t.Run(tcName, func(t *testing.T) {
+ t.Parallel()
+ actual := fmt.Sprintf(tc.InputFmt, tc.InputSum)
+ assert.Equal(t, tc.Output, actual)
+ })
+ }
+}