Add bit flag manipulation
This commit is contained in:
parent
f7bcf8896b
commit
a6b57c92a9
@ -27,15 +27,16 @@ type State struct {
|
||||
execPath []string // Command symbols stack
|
||||
arg *string // Optional argument. Nil if not set.
|
||||
sizes map[string]uint16 // Size limits for all loaded symbols.
|
||||
sink *string //
|
||||
sink *string // Sink symbol set for level
|
||||
bitSize uint32 // size of (32-bit capacity) bit flag byte array
|
||||
//sizeIdx uint16
|
||||
}
|
||||
|
||||
// NewState creates a new State object with bitSize number of error condition states.
|
||||
func NewState(bitSize uint64) State {
|
||||
func NewState(bitSize uint32) State {
|
||||
if bitSize == 0 {
|
||||
panic("bitsize cannot be 0")
|
||||
}
|
||||
}
|
||||
n := bitSize % 8
|
||||
if n > 0 {
|
||||
bitSize += (8 - n)
|
||||
@ -45,11 +46,63 @@ func NewState(bitSize uint64) State {
|
||||
Flags: make([]byte, bitSize / 8),
|
||||
CacheSize: 0,
|
||||
CacheUseSize: 0,
|
||||
bitSize: bitSize,
|
||||
}
|
||||
st.Down("")
|
||||
return st
|
||||
}
|
||||
|
||||
// SetFlag sets the flag at the given bit field index.
|
||||
//
|
||||
// Returns true if bit state was changed.
|
||||
//
|
||||
// Fails if bitindex is out of range.
|
||||
func(st *State) SetFlag(bitIndex uint32) (bool, error) {
|
||||
if bitIndex + 1 > st.bitSize {
|
||||
return false, fmt.Errorf("bit index %v is out of range of bitfield size %v", bitIndex, st.bitSize)
|
||||
}
|
||||
r :=st.getFlag(bitIndex)
|
||||
if r {
|
||||
return false, nil
|
||||
}
|
||||
byteIndex := bitIndex / 8
|
||||
localBitIndex := bitIndex % 8
|
||||
b := st.Flags[byteIndex]
|
||||
st.Flags[byteIndex] = b | (1 << localBitIndex)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
||||
// ResetFlag resets the flag at the given bit field index.
|
||||
//
|
||||
// Returns true if bit state was changed.
|
||||
//
|
||||
// Fails if bitindex is out of range.
|
||||
func(st *State) ResetFlag(bitIndex uint32) (bool, error) {
|
||||
if bitIndex + 1 > st.bitSize {
|
||||
return false, fmt.Errorf("bit index %v is out of range of bitfield size %v", bitIndex, st.bitSize)
|
||||
}
|
||||
r :=st.getFlag(bitIndex)
|
||||
if !r {
|
||||
return false, nil
|
||||
}
|
||||
byteIndex := bitIndex / 8
|
||||
localBitIndex := bitIndex % 8
|
||||
b := st.Flags[byteIndex]
|
||||
st.Flags[byteIndex] = b & (^(1 << localBitIndex))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetFlag returns the state of the flag at the given bit field index.
|
||||
//
|
||||
// Fails if bit field index is out of range.
|
||||
func(st *State) GetFlag(bitIndex uint32) (bool, error) {
|
||||
if bitIndex + 1 > st.bitSize {
|
||||
return false, fmt.Errorf("bit index %v is out of range of bitfield size %v", bitIndex, st.bitSize)
|
||||
}
|
||||
return st.getFlag(bitIndex), nil
|
||||
}
|
||||
|
||||
// WithCacheSize applies a cumulative cache size limitation for all cached items.
|
||||
func(st State) WithCacheSize(cacheSize uint32) State {
|
||||
st.CacheSize = cacheSize
|
||||
@ -288,7 +341,16 @@ func(st *State) checkCapacity(v string) uint32 {
|
||||
return sz
|
||||
}
|
||||
|
||||
// flush relveant properties for level change
|
||||
func(st *State) resetCurrent() {
|
||||
st.sink = nil
|
||||
st.CacheMap = make(map[string]string)
|
||||
}
|
||||
|
||||
// Retrieve the state of a state flag
|
||||
func(st *State) getFlag(bitIndex uint32) bool {
|
||||
byteIndex := bitIndex / 8
|
||||
localBitIndex := bitIndex % 8
|
||||
b := st.Flags[byteIndex]
|
||||
return (b & (1 << localBitIndex)) > 0
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Check creation and testing of state flags
|
||||
func TestNewStateFlags(t *testing.T) {
|
||||
// Check creation
|
||||
func TestNewState(t *testing.T) {
|
||||
st := NewState(5)
|
||||
if len(st.Flags) != 1 {
|
||||
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
||||
@ -17,7 +17,73 @@ func TestNewStateFlags(t *testing.T) {
|
||||
st = NewState(17)
|
||||
if len(st.Flags) != 3 {
|
||||
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestStateFlags(t *testing.T) {
|
||||
st := NewState(17)
|
||||
v, err := st.GetFlag(2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if v {
|
||||
t.Errorf("Expected bit 2 not to be set")
|
||||
}
|
||||
v, err = st.SetFlag(2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !v {
|
||||
t.Errorf("Expected change to be set for bit 2")
|
||||
}
|
||||
v, err = st.GetFlag(2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !v {
|
||||
t.Errorf("Expected bit 2 to be set")
|
||||
}
|
||||
v, err = st.SetFlag(10)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !v {
|
||||
t.Errorf("Expected change to be set for bit 10")
|
||||
}
|
||||
v, err = st.GetFlag(10)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !v {
|
||||
t.Errorf("Expected bit 10 to be set")
|
||||
}
|
||||
v, err = st.ResetFlag(2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !v {
|
||||
t.Errorf("Expected change to be set for bit 10")
|
||||
}
|
||||
v, err = st.GetFlag(2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if v {
|
||||
t.Errorf("Expected bit 2 not to be set")
|
||||
}
|
||||
v, err = st.GetFlag(10)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !v {
|
||||
t.Errorf("Expected bit 10 to be set")
|
||||
}
|
||||
v, err = st.SetFlag(10)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if v {
|
||||
t.Errorf("Expected change not to be set for bit 10")
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user