network/bitvector: Multibit set/unset + string rep (#1530)
* network/bitvector: Multibit set/unset + string rep * network/bitvector: Add code comments * network/bitvector: Make Unset -> Set with bool false * network/bitvector: Revert to Set/Unset * network/stream: Update to new bitvector signature
This commit is contained in:
@@ -22,15 +22,20 @@ import (
|
||||
|
||||
var errInvalidLength = errors.New("invalid length")
|
||||
|
||||
// BitVector is a convenience object for manipulating and representing bit vectors
|
||||
type BitVector struct {
|
||||
len int
|
||||
b []byte
|
||||
}
|
||||
|
||||
// New creates a new bit vector with the given length
|
||||
func New(l int) (bv *BitVector, err error) {
|
||||
return NewFromBytes(make([]byte, l/8+1), l)
|
||||
}
|
||||
|
||||
// NewFromBytes creates a bit vector from the passed byte slice.
|
||||
//
|
||||
// Leftmost bit in byte slice becomes leftmost bit in bit vector
|
||||
func NewFromBytes(b []byte, l int) (bv *BitVector, err error) {
|
||||
if l <= 0 {
|
||||
return nil, errInvalidLength
|
||||
@@ -44,12 +49,14 @@ func NewFromBytes(b []byte, l int) (bv *BitVector, err error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Get gets the corresponding bit, counted from left to right
|
||||
func (bv *BitVector) Get(i int) bool {
|
||||
bi := i / 8
|
||||
return bv.b[bi]&(0x1<<uint(i%8)) != 0
|
||||
}
|
||||
|
||||
func (bv *BitVector) Set(i int, v bool) {
|
||||
// Set sets the bit corresponding to the index in the bitvector, counted from left to right
|
||||
func (bv *BitVector) set(i int, v bool) {
|
||||
bi := i / 8
|
||||
cv := bv.Get(i)
|
||||
if cv != v {
|
||||
@@ -57,6 +64,61 @@ func (bv *BitVector) Set(i int, v bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// Set sets the bit corresponding to the index in the bitvector, counted from left to right
|
||||
func (bv *BitVector) Set(i int) {
|
||||
bv.set(i, true)
|
||||
}
|
||||
|
||||
// Unset UNSETS the corresponding bit, counted from left to right
|
||||
func (bv *BitVector) Unset(i int) {
|
||||
bv.set(i, false)
|
||||
}
|
||||
|
||||
// SetBytes sets all bits in the bitvector that are set in the argument
|
||||
//
|
||||
// The argument must be the same as the bitvector length
|
||||
func (bv *BitVector) SetBytes(bs []byte) error {
|
||||
if len(bs) != bv.len {
|
||||
return errors.New("invalid length")
|
||||
}
|
||||
for i := 0; i < bv.len*8; i++ {
|
||||
bi := i / 8
|
||||
if bs[bi]&(0x01<<uint(i%8)) > 0 {
|
||||
bv.set(i, true)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnsetBytes UNSETS all bits in the bitvector that are set in the argument
|
||||
//
|
||||
// The argument must be the same as the bitvector length
|
||||
func (bv *BitVector) UnsetBytes(bs []byte) error {
|
||||
if len(bs) != bv.len {
|
||||
return errors.New("invalid length")
|
||||
}
|
||||
for i := 0; i < bv.len*8; i++ {
|
||||
bi := i / 8
|
||||
if bs[bi]&(0x01<<uint(i%8)) > 0 {
|
||||
bv.set(i, false)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements Stringer interface
|
||||
func (bv *BitVector) String() (s string) {
|
||||
for i := 0; i < bv.len*8; i++ {
|
||||
if bv.Get(i) {
|
||||
s += "1"
|
||||
} else {
|
||||
s += "0"
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Bytes retrieves the underlying bytes of the bitvector
|
||||
func (bv *BitVector) Bytes() []byte {
|
||||
return bv.b
|
||||
}
|
||||
|
Reference in New Issue
Block a user