diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2022-07-13 21:44:18 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2022-07-13 21:44:18 -0600 |
commit | 296e9fc0f8812ce0c5684ff99f84e80eef07cd4c (patch) | |
tree | f2c0219b5a5db0603af6c55acb6f1684742989fd /lib/util | |
parent | 436e1681c9fcda246c6d84526fc79c87adc7b28d (diff) |
Move files to different packages [ci-skip]
Diffstat (limited to 'lib/util')
-rw-r--r-- | lib/util/bitfield.go | 54 | ||||
-rw-r--r-- | lib/util/fmt.go | 71 | ||||
-rw-r--r-- | lib/util/fmt_test.go | 103 | ||||
-rw-r--r-- | lib/util/lru.go | 77 | ||||
-rw-r--r-- | lib/util/ref.go | 58 | ||||
-rw-r--r-- | lib/util/uuid.go | 76 | ||||
-rw-r--r-- | lib/util/uuid_test.go | 67 |
7 files changed, 0 insertions, 506 deletions
diff --git a/lib/util/bitfield.go b/lib/util/bitfield.go deleted file mode 100644 index b3dbe0a..0000000 --- a/lib/util/bitfield.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util - -import ( - "fmt" - "strings" -) - -type BitfieldFormat uint8 - -const ( - HexNone = BitfieldFormat(iota) - HexLower - HexUpper -) - -func BitfieldString[T ~uint8 | ~uint16 | ~uint32 | ~uint64](bitfield T, bitnames []string, cfg BitfieldFormat) string { - var out strings.Builder - switch cfg { - case HexNone: - // do nothing - case HexLower: - fmt.Fprintf(&out, "0x%0x(", uint64(bitfield)) - case HexUpper: - fmt.Fprintf(&out, "0x%0X(", uint64(bitfield)) - } - if bitfield == 0 { - out.WriteString("none") - } else { - rest := bitfield - first := true - for i := 0; rest != 0; i++ { - if rest&(1<<i) != 0 { - if !first { - out.WriteRune('|') - } - if i < len(bitnames) { - out.WriteString(bitnames[i]) - } else { - fmt.Fprintf(&out, "(1<<%v)", i) - } - first = false - } - rest &^= 1 << i - } - } - if cfg != HexNone { - out.WriteRune(')') - } - return out.String() -} diff --git a/lib/util/fmt.go b/lib/util/fmt.go deleted file mode 100644 index c36ba2a..0000000 --- a/lib/util/fmt.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util - -import ( - "fmt" - "strings" -) - -// FmtStateString returns the fmt.Printf string that produced a given -// fmt.State and verb. -func FmtStateString(st fmt.State, verb rune) string { - var ret strings.Builder - ret.WriteByte('%') - for _, flag := range []int{'-', '+', '#', ' ', '0'} { - if st.Flag(flag) { - ret.WriteByte(byte(flag)) - } - } - if width, ok := st.Width(); ok { - fmt.Fprintf(&ret, "%v", width) - } - if prec, ok := st.Precision(); ok { - if prec == 0 { - ret.WriteByte('.') - } else { - fmt.Fprintf(&ret, ".%v", prec) - } - } - ret.WriteRune(verb) - return ret.String() -} - -// FormatByteArrayStringer is function for helping to implement -// fmt.Formatter for []byte or [n]byte types that have a custom string -// representation. Use it like: -// -// type MyType [16]byte -// -// func (val MyType) String() string { -// … -// } -// -// func (val MyType) Format(f fmt.State, verb rune) { -// util.FormatByteArrayStringer(val, val[:], f, verb) -// } -func FormatByteArrayStringer( - obj interface { - fmt.Stringer - fmt.Formatter - }, - objBytes []byte, - f fmt.State, verb rune) { - switch verb { - case 'v': - if !f.Flag('#') { - FormatByteArrayStringer(obj, objBytes, f, 's') // as a string - } else { - byteStr := fmt.Sprintf("%#v", objBytes) - objType := fmt.Sprintf("%T", obj) - objStr := objType + strings.TrimPrefix(byteStr, "[]byte") - fmt.Fprintf(f, FmtStateString(f, 's'), objStr) - } - case 's', 'q': // string - fmt.Fprintf(f, FmtStateString(f, verb), obj.String()) - default: - fmt.Fprintf(f, FmtStateString(f, verb), objBytes) - } -} diff --git a/lib/util/fmt_test.go b/lib/util/fmt_test.go deleted file mode 100644 index 0aaebb5..0000000 --- a/lib/util/fmt_test.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util_test - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - - "git.lukeshu.com/btrfs-progs-ng/lib/util" -) - -type FmtState struct { - MWidth int - MPrec int - MFlagMinus bool - MFlagPlus bool - MFlagSharp bool - MFlagSpace bool - MFlagZero bool -} - -func (st FmtState) Width() (int, bool) { - if st.MWidth < 1 { - return 0, false - } - return st.MWidth, true -} - -func (st FmtState) Precision() (int, bool) { - if st.MPrec < 1 { - return 0, false - } - return st.MPrec, true -} - -func (st FmtState) Flag(b int) bool { - switch b { - case '-': - return st.MFlagMinus - case '+': - return st.MFlagPlus - case '#': - return st.MFlagSharp - case ' ': - return st.MFlagSpace - case '0': - return st.MFlagZero - } - return false -} - -func (st FmtState) Write([]byte) (int, error) { - panic("not implemented") -} - -func (dst *FmtState) Format(src fmt.State, verb rune) { - if width, ok := src.Width(); ok { - dst.MWidth = width - } - if prec, ok := src.Precision(); ok { - dst.MPrec = prec - } - dst.MFlagMinus = src.Flag('-') - dst.MFlagPlus = src.Flag('+') - dst.MFlagSharp = src.Flag('#') - dst.MFlagSpace = src.Flag(' ') - dst.MFlagZero = src.Flag('0') -} - -// letters only? No 'p', 'T', or 'w'. -const verbs = "abcdefghijklmnoqrstuvxyzABCDEFGHIJKLMNOPQRSUVWXYZ" - -func FuzzFmtStateString(f *testing.F) { - f.Fuzz(func(t *testing.T, - width, prec uint8, - flagMinus, flagPlus, flagSharp, flagSpace, flagZero bool, - verbIdx uint8, - ) { - if flagMinus { - flagZero = false - } - input := FmtState{ - MWidth: int(width), - MPrec: int(prec), - MFlagMinus: flagMinus, - MFlagPlus: flagPlus, - MFlagSharp: flagSharp, - MFlagSpace: flagSpace, - MFlagZero: flagZero, - } - verb := rune(verbs[int(verbIdx)%len(verbs)]) - - t.Logf("(%#v, %c) => %q", input, verb, util.FmtStateString(input, verb)) - - var output FmtState - assert.Equal(t, "", fmt.Sprintf(util.FmtStateString(input, verb), &output)) - assert.Equal(t, input, output) - }) -} diff --git a/lib/util/lru.go b/lib/util/lru.go deleted file mode 100644 index 80f5ff5..0000000 --- a/lib/util/lru.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util - -import ( - "sync" - - lru "github.com/hashicorp/golang-lru" -) - -type LRUCache[K comparable, V any] struct { - initOnce sync.Once - inner *lru.ARCCache -} - -func (c *LRUCache[K, V]) init() { - c.initOnce.Do(func() { - c.inner, _ = lru.NewARC(128) - }) -} - -func (c *LRUCache[K, V]) Add(key K, value V) { - c.init() - c.inner.Add(key, value) -} -func (c *LRUCache[K, V]) Contains(key K) bool { - c.init() - return c.inner.Contains(key) -} -func (c *LRUCache[K, V]) Get(key K) (value V, ok bool) { - c.init() - _value, ok := c.inner.Get(key) - if ok { - value = _value.(V) - } - return value, ok -} -func (c *LRUCache[K, V]) Keys() []K { - c.init() - untyped := c.inner.Keys() - typed := make([]K, len(untyped)) - for i := range untyped { - typed[i] = untyped[i].(K) - } - return typed -} -func (c *LRUCache[K, V]) Len() int { - c.init() - return c.inner.Len() -} -func (c *LRUCache[K, V]) Peek(key K) (value V, ok bool) { - c.init() - _value, ok := c.inner.Peek(key) - if ok { - value = _value.(V) - } - return value, ok -} -func (c *LRUCache[K, V]) Purge() { - c.init() - c.inner.Purge() -} -func (c *LRUCache[K, V]) Remove(key K) { - c.init() - c.inner.Remove(key) -} - -func (c *LRUCache[K, V]) GetOrElse(key K, fn func() V) V { - var value V - var ok bool - for value, ok = c.Get(key); !ok; value, ok = c.Get(key) { - c.Add(key, fn()) - } - return value -} diff --git a/lib/util/ref.go b/lib/util/ref.go deleted file mode 100644 index fe284d7..0000000 --- a/lib/util/ref.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util - -import ( - "fmt" - "io" - - "git.lukeshu.com/btrfs-progs-ng/lib/binstruct" -) - -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 - Data T -} - -func (r *Ref[A, T]) Read() error { - size := binstruct.StaticSize(r.Data) - buf := make([]byte, size) - if _, err := r.File.ReadAt(buf, r.Addr); err != nil { - return err - } - 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 %v bytes but only consumed %v", - r.Data, size, n) - } - return nil -} - -func (r *Ref[A, T]) Write() error { - buf, err := binstruct.Marshal(r.Data) - if err != nil { - return err - } - if _, err = r.File.WriteAt(buf, r.Addr); err != nil { - return err - } - return nil -} diff --git a/lib/util/uuid.go b/lib/util/uuid.go deleted file mode 100644 index a16d10f..0000000 --- a/lib/util/uuid.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util - -import ( - "encoding/hex" - "fmt" - "strings" -) - -type UUID [16]byte - -func (uuid UUID) String() string { - str := hex.EncodeToString(uuid[:]) - return strings.Join([]string{ - str[:8], - str[8:12], - str[12:16], - str[16:20], - str[20:32], - }, "-") -} - -func (a UUID) Cmp(b UUID) int { - for i := range a { - if d := int(a[i]) - int(b[i]); d != 0 { - return d - } - } - return 0 -} - -func (uuid UUID) Format(f fmt.State, verb rune) { - FormatByteArrayStringer(uuid, uuid[:], f, verb) -} - -func ParseUUID(str string) (UUID, error) { - var ret UUID - j := 0 - for i := 0; i < len(str); i++ { - if j >= len(ret)*2 { - return UUID{}, fmt.Errorf("too long to be a UUID: %q|%q", str[:i], str[i:]) - } - c := str[i] - var v byte - switch { - case '0' <= c && c <= '9': - v = c - '0' - case 'a' <= c && c <= 'f': - v = c - 'a' + 10 - case 'A' <= c && c <= 'F': - v = c - 'A' + 10 - case c == '-': - continue - default: - return UUID{}, fmt.Errorf("illegal byte in UUID: %q|%q|%q", str[:i], str[i:i+1], str[i+1:]) - } - if j%2 == 0 { - ret[j/2] = v << 4 - } else { - ret[j/2] = (ret[j/2] & 0xf0) | (v & 0x0f) - } - j++ - } - return ret, nil -} - -func MustParseUUID(str string) UUID { - ret, err := ParseUUID(str) - if err != nil { - panic(err) - } - return ret -} diff --git a/lib/util/uuid_test.go b/lib/util/uuid_test.go deleted file mode 100644 index 747ff6b..0000000 --- a/lib/util/uuid_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util_test - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - - "git.lukeshu.com/btrfs-progs-ng/lib/util" -) - -func TestParseUUID(t *testing.T) { - t.Parallel() - type TestCase struct { - Input string - OutputVal util.UUID - OutputErr string - } - testcases := map[string]TestCase{ - "basic": {Input: "a0dd94ed-e60c-42e8-8632-64e8d4765a43", OutputVal: util.UUID{0xa0, 0xdd, 0x94, 0xed, 0xe6, 0x0c, 0x42, 0xe8, 0x86, 0x32, 0x64, 0xe8, 0xd4, 0x76, 0x5a, 0x43}}, - "too-long": {Input: "a0dd94ed-e60c-42e8-8632-64e8d4765a43a", OutputErr: `too long to be a UUID: "a0dd94ed-e60c-42e8-8632-64e8d4765a43"|"a"`}, - "bad char": {Input: "a0dd94ej-e60c-42e8-8632-64e8d4765a43a", OutputErr: `illegal byte in UUID: "a0dd94e"|"j"|"-e60c-42e8-8632-64e8d4765a43a"`}, - } - for tcName, tc := range testcases { - tc := tc - t.Run(tcName, func(t *testing.T) { - t.Parallel() - val, err := util.ParseUUID(tc.Input) - assert.Equal(t, tc.OutputVal, val) - if tc.OutputErr == "" { - assert.NoError(t, err) - } else { - assert.EqualError(t, err, tc.OutputErr) - } - }) - } -} - -func TestUUIDFormat(t *testing.T) { - t.Parallel() - type TestCase struct { - InputUUID util.UUID - InputFmt string - Output string - } - uuid := util.MustParseUUID("a0dd94ed-e60c-42e8-8632-64e8d4765a43") - testcases := map[string]TestCase{ - "s": {InputUUID: uuid, InputFmt: "%s", Output: "a0dd94ed-e60c-42e8-8632-64e8d4765a43"}, - "x": {InputUUID: uuid, InputFmt: "%x", Output: "a0dd94ede60c42e8863264e8d4765a43"}, - "X": {InputUUID: uuid, InputFmt: "%X", Output: "A0DD94EDE60C42E8863264E8D4765A43"}, - "v": {InputUUID: uuid, InputFmt: "%v", Output: "a0dd94ed-e60c-42e8-8632-64e8d4765a43"}, - "40s": {InputUUID: uuid, InputFmt: "|% 40s", Output: "| a0dd94ed-e60c-42e8-8632-64e8d4765a43"}, - "#115v": {InputUUID: uuid, InputFmt: "|%#115v", Output: "| util.UUID{0xa0, 0xdd, 0x94, 0xed, 0xe6, 0xc, 0x42, 0xe8, 0x86, 0x32, 0x64, 0xe8, 0xd4, 0x76, 0x5a, 0x43}"}, - } - for tcName, tc := range testcases { - tc := tc - t.Run(tcName, func(t *testing.T) { - t.Parallel() - actual := fmt.Sprintf(tc.InputFmt, tc.InputUUID) - assert.Equal(t, tc.Output, actual) - }) - } -} |