2023-04-06 16:21:26 +02:00
|
|
|
package resource
|
|
|
|
|
|
|
|
import (
|
2023-04-07 12:31:30 +02:00
|
|
|
"bytes"
|
2023-04-06 16:21:26 +02:00
|
|
|
"fmt"
|
|
|
|
"log"
|
2023-04-07 12:31:30 +02:00
|
|
|
"strings"
|
2023-04-06 16:21:26 +02:00
|
|
|
|
|
|
|
"git.defalsify.org/festive/state"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Sizer struct {
|
|
|
|
outputSize uint32
|
|
|
|
menuSize uint16
|
|
|
|
memberSizes map[string]uint16
|
|
|
|
totalMemberSize uint32
|
2023-04-07 12:31:30 +02:00
|
|
|
crsrs []uint32
|
2023-04-06 16:21:26 +02:00
|
|
|
sink string
|
|
|
|
}
|
|
|
|
|
|
|
|
func SizerFromState(st *state.State) (Sizer, error){
|
|
|
|
sz := Sizer{
|
|
|
|
outputSize: st.GetOutputSize(),
|
|
|
|
menuSize: st.GetMenuSize(),
|
|
|
|
memberSizes: make(map[string]uint16),
|
|
|
|
}
|
2023-04-07 12:31:30 +02:00
|
|
|
|
2023-04-06 16:21:26 +02:00
|
|
|
sizes, err := st.Sizes()
|
|
|
|
if err != nil {
|
|
|
|
return sz, err
|
|
|
|
}
|
|
|
|
for k, v := range sizes {
|
|
|
|
if v == 0 {
|
|
|
|
sz.sink = k
|
|
|
|
}
|
|
|
|
sz.memberSizes[k] = v
|
|
|
|
sz.totalMemberSize += uint32(v)
|
|
|
|
}
|
|
|
|
return sz, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func(szr *Sizer) Check(s string) (uint32, bool) {
|
|
|
|
l := uint32(len(s))
|
2023-04-07 10:30:23 +02:00
|
|
|
if szr.outputSize > 0 {
|
|
|
|
if l > szr.outputSize {
|
|
|
|
log.Printf("sizer check fails with length %v: %s", l, szr)
|
|
|
|
return 0, false
|
|
|
|
}
|
|
|
|
l = szr.outputSize - l
|
2023-04-06 16:21:26 +02:00
|
|
|
}
|
|
|
|
return l, true
|
|
|
|
}
|
|
|
|
|
|
|
|
func(szr *Sizer) String() string {
|
|
|
|
var diff uint32
|
|
|
|
if szr.outputSize > 0 {
|
|
|
|
diff = szr.outputSize - szr.totalMemberSize - uint32(szr.menuSize)
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("output: %v, member: %v, menu: %v, diff: %v", szr.outputSize, szr.totalMemberSize, szr.menuSize, diff)
|
|
|
|
}
|
2023-04-07 10:30:23 +02:00
|
|
|
|
|
|
|
func(szr *Sizer) Size(s string) (uint16, error) {
|
|
|
|
r, ok := szr.memberSizes[s]
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("unknown member: %s", s)
|
|
|
|
}
|
|
|
|
return r, nil
|
|
|
|
}
|
2023-04-07 12:31:30 +02:00
|
|
|
|
|
|
|
func(szr *Sizer) AddCursor(c uint32) {
|
|
|
|
log.Printf("added cursor: %v", c)
|
|
|
|
szr.crsrs = append(szr.crsrs, c)
|
|
|
|
}
|
|
|
|
|
|
|
|
func(szr *Sizer) GetAt(values map[string]string, idx uint16) (map[string]string, error) {
|
|
|
|
if szr.sink == "" {
|
|
|
|
return values, nil
|
|
|
|
}
|
|
|
|
outValues := make(map[string]string)
|
|
|
|
for k, v := range values {
|
|
|
|
if szr.sink == k {
|
|
|
|
if idx >= uint16(len(szr.crsrs)) {
|
|
|
|
return nil, fmt.Errorf("no more values in index")
|
|
|
|
}
|
|
|
|
c := szr.crsrs[idx]
|
|
|
|
v = v[c:]
|
|
|
|
nl := strings.Index(v, "\n")
|
|
|
|
log.Printf("k %v v %v c %v nl %v", k, v, c, nl)
|
|
|
|
if nl > 0 {
|
|
|
|
v = v[:nl]
|
|
|
|
}
|
|
|
|
b := bytes.ReplaceAll([]byte(v), []byte{0x00}, []byte{0x0a})
|
|
|
|
v = string(b)
|
|
|
|
}
|
|
|
|
outValues[k] = v
|
|
|
|
}
|
|
|
|
return outValues, nil
|
|
|
|
}
|