Add frame exit
This commit is contained in:
parent
2034c393f9
commit
ad518b92d8
@ -2,18 +2,18 @@ package state
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type State struct {
|
type State struct {
|
||||||
Flags []byte
|
Flags []byte
|
||||||
OutputSize uint16
|
|
||||||
CacheSize uint32
|
CacheSize uint32
|
||||||
CacheUseSize uint32
|
CacheUseSize uint32
|
||||||
Cache []map[string]string
|
Cache []map[string]string
|
||||||
ExecPath []string
|
ExecPath []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewState(bitSize uint64, outputSize uint16) State {
|
func NewState(bitSize uint64) State {
|
||||||
if bitSize == 0 {
|
if bitSize == 0 {
|
||||||
panic("bitsize cannot be 0")
|
panic("bitsize cannot be 0")
|
||||||
}
|
}
|
||||||
@ -24,7 +24,6 @@ func NewState(bitSize uint64, outputSize uint16) State {
|
|||||||
|
|
||||||
return State{
|
return State{
|
||||||
Flags: make([]byte, bitSize / 8),
|
Flags: make([]byte, bitSize / 8),
|
||||||
OutputSize: outputSize,
|
|
||||||
CacheSize: 0,
|
CacheSize: 0,
|
||||||
CacheUseSize: 0,
|
CacheUseSize: 0,
|
||||||
}
|
}
|
||||||
@ -45,7 +44,7 @@ func(st *State) Add(k string, v string) error {
|
|||||||
if sz == 0 {
|
if sz == 0 {
|
||||||
return fmt.Errorf("Cache capacity exceeded %v of %v", st.CacheUseSize + sz, st.CacheSize)
|
return fmt.Errorf("Cache capacity exceeded %v of %v", st.CacheUseSize + sz, st.CacheSize)
|
||||||
}
|
}
|
||||||
fmt.Printf("len %v %v\n", sz, st.CacheUseSize)
|
log.Printf("add key %s value size %v", k, sz)
|
||||||
st.Cache[len(st.Cache)-1][k] = v
|
st.Cache[len(st.Cache)-1][k] = v
|
||||||
st.CacheUseSize += sz
|
st.CacheUseSize += sz
|
||||||
return nil
|
return nil
|
||||||
@ -55,7 +54,20 @@ func(st *State) Get() (map[string]string, error) {
|
|||||||
return st.Cache[len(st.Cache)-1], nil
|
return st.Cache[len(st.Cache)-1], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *State) Exit() {
|
func (st *State) Exit() error {
|
||||||
|
l := len(st.Cache)
|
||||||
|
if l == 0 {
|
||||||
|
return fmt.Errorf("exit called beyond top frame")
|
||||||
|
}
|
||||||
|
l -= 1
|
||||||
|
m := st.Cache[l]
|
||||||
|
for k, v := range m {
|
||||||
|
sz := len(v)
|
||||||
|
st.CacheUseSize -= uint32(sz)
|
||||||
|
log.Printf("free frame %v key %v value size %v", l, k, sz)
|
||||||
|
}
|
||||||
|
st.Cache = st.Cache[:l]
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func(st *State) checkCapacity(v string) uint32 {
|
func(st *State) checkCapacity(v string) uint32 {
|
||||||
|
@ -5,15 +5,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNewStateFlags(t *testing.T) {
|
func TestNewStateFlags(t *testing.T) {
|
||||||
st := NewState(5, 0)
|
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))
|
||||||
}
|
}
|
||||||
st = NewState(8, 0)
|
st = NewState(8)
|
||||||
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))
|
||||||
}
|
}
|
||||||
st = NewState(17, 0)
|
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))
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ func TestNewStateFlags(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNewStateCache(t *testing.T) {
|
func TestNewStateCache(t *testing.T) {
|
||||||
st := NewState(17, 0)
|
st := NewState(17)
|
||||||
if st.CacheSize != 0 {
|
if st.CacheSize != 0 {
|
||||||
t.Errorf("cache size not 0")
|
t.Errorf("cache size not 0")
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ func TestNewStateCache(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStateCacheUse(t *testing.T) {
|
func TestStateCacheUse(t *testing.T) {
|
||||||
st := NewState(17, 0)
|
st := NewState(17)
|
||||||
st = st.WithCacheSize(10)
|
st = st.WithCacheSize(10)
|
||||||
st.Enter("foo")
|
st.Enter("foo")
|
||||||
err := st.Add("bar", "baz")
|
err := st.Add("bar", "baz")
|
||||||
@ -49,3 +49,27 @@ func TestStateCacheUse(t *testing.T) {
|
|||||||
t.Errorf("expected capacity error")
|
t.Errorf("expected capacity error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStateEnterExit(t *testing.T) {
|
||||||
|
st := NewState(17)
|
||||||
|
st.Enter("one")
|
||||||
|
err := st.Add("foo", "bar")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
err = st.Add("baz", "xyzzy")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if st.CacheUseSize != 8 {
|
||||||
|
t.Errorf("expected cache use size 8 got %v", st.CacheUseSize)
|
||||||
|
}
|
||||||
|
err = st.Exit()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
err = st.Exit()
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expected out of top frame error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -61,7 +61,7 @@ func (r *TestResource) FuncFor(sym string) (resource.EntryFunc, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRun(t *testing.T) {
|
func TestRun(t *testing.T) {
|
||||||
st := state.NewState(5, 255)
|
st := state.NewState(5)
|
||||||
rs := TestResource{}
|
rs := TestResource{}
|
||||||
b := []byte{0x00, 0x02}
|
b := []byte{0x00, 0x02}
|
||||||
r, err := Run(b, st, &rs, context.TODO())
|
r, err := Run(b, st, &rs, context.TODO())
|
||||||
@ -78,7 +78,7 @@ func TestRun(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRunMap(t *testing.T) {
|
func TestRunMap(t *testing.T) {
|
||||||
st := state.NewState(5, 255)
|
st := state.NewState(5)
|
||||||
st.Enter("barbarbar")
|
st.Enter("barbarbar")
|
||||||
rs := TestResource{}
|
rs := TestResource{}
|
||||||
sym := "one"
|
sym := "one"
|
||||||
|
Loading…
Reference in New Issue
Block a user