github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/ledger/common/bitutils/utils.go (about) 1 package bitutils 2 3 // ReadBit returns the bit at index `idx` in the byte array `b` (big endian) 4 // The function panics, if the byte slice is too short. 5 func ReadBit(b []byte, idx int) int { 6 byteValue := int(b[idx>>3]) 7 idx &= 7 8 return (byteValue >> (7 - idx)) & 1 9 } 10 11 // WriteBit assigns value `v` to the bit at index `i` in the byte array `b`. 12 // The function panics, if the byte slice is too short. We follow the common 13 // convention of converting between integer and boolean/bit values: 14 // - int value == 0 <=> false <=> bit 0 15 // - int value != 0 <=> true <=> bit 1 16 func WriteBit(b []byte, i int, value int) { 17 if value == 0 { 18 ClearBit(b, i) 19 } else { 20 SetBit(b, i) 21 } 22 } 23 24 // SetBit sets the bit at index `i` in the byte array `b`, i.e. it assigns 25 // value 1 to the bit. The function panics, if the byte slice is too short. 26 func SetBit(b []byte, i int) { 27 byteIndex := i >> 3 28 i &= 7 29 mask := byte(1 << (7 - i)) 30 b[byteIndex] |= mask 31 } 32 33 // ClearBit clears the bit at index `i` in the byte slice `b`, i.e. it assigns 34 // value 0 to the bit. The function panics, if the byte slice is too short. 35 func ClearBit(b []byte, i int) { 36 byteIndex := i >> 3 37 i &= 7 38 mask := byte(1 << (7 - i)) 39 b[byteIndex] &= ^mask 40 } 41 42 // MakeBitVector allocates a byte slice of minimal size that can hold numberBits. 43 func MakeBitVector(numberBits int) []byte { 44 return make([]byte, MinimalByteSliceLength(numberBits)) 45 } 46 47 // MinimalByteSliceLength returns the minimal length of a byte slice that can store n bits. 48 func MinimalByteSliceLength(n int) int { 49 return (n + 7) >> 3 50 }