Add bit flag manipulation
This commit is contained in:
parent
f7bcf8896b
commit
a6b57c92a9
@ -27,12 +27,13 @@ type State struct {
|
|||||||
execPath []string // Command symbols stack
|
execPath []string // Command symbols stack
|
||||||
arg *string // Optional argument. Nil if not set.
|
arg *string // Optional argument. Nil if not set.
|
||||||
sizes map[string]uint16 // Size limits for all loaded symbols.
|
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
|
//sizeIdx uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewState creates a new State object with bitSize number of error condition states.
|
// 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 {
|
if bitSize == 0 {
|
||||||
panic("bitsize cannot be 0")
|
panic("bitsize cannot be 0")
|
||||||
}
|
}
|
||||||
@ -45,11 +46,63 @@ func NewState(bitSize uint64) State {
|
|||||||
Flags: make([]byte, bitSize / 8),
|
Flags: make([]byte, bitSize / 8),
|
||||||
CacheSize: 0,
|
CacheSize: 0,
|
||||||
CacheUseSize: 0,
|
CacheUseSize: 0,
|
||||||
|
bitSize: bitSize,
|
||||||
}
|
}
|
||||||
st.Down("")
|
st.Down("")
|
||||||
return st
|
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.
|
// WithCacheSize applies a cumulative cache size limitation for all cached items.
|
||||||
func(st State) WithCacheSize(cacheSize uint32) State {
|
func(st State) WithCacheSize(cacheSize uint32) State {
|
||||||
st.CacheSize = cacheSize
|
st.CacheSize = cacheSize
|
||||||
@ -288,7 +341,16 @@ func(st *State) checkCapacity(v string) uint32 {
|
|||||||
return sz
|
return sz
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// flush relveant properties for level change
|
||||||
func(st *State) resetCurrent() {
|
func(st *State) resetCurrent() {
|
||||||
st.sink = nil
|
st.sink = nil
|
||||||
st.CacheMap = make(map[string]string)
|
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"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Check creation and testing of state flags
|
// Check creation
|
||||||
func TestNewStateFlags(t *testing.T) {
|
func TestNewState(t *testing.T) {
|
||||||
st := NewState(5)
|
st := NewState(5)
|
||||||
if len(st.Flags) != 1 {
|
if len(st.Flags) != 1 {
|
||||||
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
||||||
@ -17,7 +17,73 @@ func TestNewStateFlags(t *testing.T) {
|
|||||||
st = NewState(17)
|
st = NewState(17)
|
||||||
if len(st.Flags) != 3 {
|
if len(st.Flags) != 3 {
|
||||||
t.Errorf("invalid state flag length: %v", len(st.Flags))
|
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