diff options
Diffstat (limited to 'pkg/btrfs/btrfssum')
-rw-r--r-- | pkg/btrfs/btrfssum/csum.go | 78 | ||||
-rw-r--r-- | pkg/btrfs/btrfssum/csum_test.go | 35 |
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) + }) + } +} |