bump reva

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
Jörn Friedrich Dreyer
2025-09-12 12:18:47 +02:00
parent 9f096d4107
commit f8440edc9a
66 changed files with 3771 additions and 1136 deletions
+86 -41
View File
@@ -1,7 +1,6 @@
package encoding
import (
"fmt"
"math"
"reflect"
"sync"
@@ -13,6 +12,8 @@ import (
type structCache struct {
indexes []int
names []string
omits []bool
noOmit bool
common.Common
}
@@ -60,10 +61,16 @@ func (e *encoder) calcStructArray(rv reflect.Value) (int, error) {
cache, find := cachemap.Load(t)
var c *structCache
if !find {
c = &structCache{}
for i := 0; i < rv.NumField(); i++ {
num := rv.NumField()
c = &structCache{
indexes: make([]int, 0, num),
names: make([]string, 0, num),
omits: make([]bool, 0, num),
}
omitCount := 0
for i := 0; i < num; i++ {
field := t.Field(i)
if ok, name := e.CheckField(field); ok {
if ok, omit, name := e.CheckField(field); ok {
size, err := e.calcSize(rv.Field(i))
if err != nil {
return 0, err
@@ -71,8 +78,13 @@ func (e *encoder) calcStructArray(rv reflect.Value) (int, error) {
ret += size
c.indexes = append(c.indexes, i)
c.names = append(c.names, name)
c.omits = append(c.omits, omit)
if omit {
omitCount++
}
}
}
c.noOmit = omitCount == 0
cachemap.Store(t, c)
} else {
c = cache.(*structCache)
@@ -86,17 +98,11 @@ func (e *encoder) calcStructArray(rv reflect.Value) (int, error) {
}
// format size
l := len(c.indexes)
if l <= 0x0f {
// format code only
} else if l <= math.MaxUint16 {
ret += def.Byte2
} else if uint(l) <= math.MaxUint32 {
ret += def.Byte4
} else {
// not supported error
return 0, fmt.Errorf("array length %d is %w", l, def.ErrUnsupportedLength)
size, err := e.calcLength(len(c.indexes))
if err != nil {
return 0, err
}
ret += size
return ret, nil
}
@@ -105,48 +111,72 @@ func (e *encoder) calcStructMap(rv reflect.Value) (int, error) {
t := rv.Type()
cache, find := cachemap.Load(t)
var c *structCache
var l int
if !find {
c = &structCache{}
for i := 0; i < rv.NumField(); i++ {
if ok, name := e.CheckField(rv.Type().Field(i)); ok {
keySize := def.Byte1 + e.calcString(name)
valueSize, err := e.calcSize(rv.Field(i))
num := rv.NumField()
c = &structCache{
indexes: make([]int, 0, num),
names: make([]string, 0, num),
omits: make([]bool, 0, num),
}
omitCount := 0
for i := 0; i < num; i++ {
if ok, omit, name := e.CheckField(rv.Type().Field(i)); ok {
size, err := e.calcSizeWithOmitEmpty(rv.Field(i), name, omit)
if err != nil {
return 0, err
}
ret += keySize + valueSize
ret += size
c.indexes = append(c.indexes, i)
c.names = append(c.names, name)
c.omits = append(c.omits, omit)
if omit {
omitCount++
}
if size > 0 {
l++
}
}
}
c.noOmit = omitCount == 0
cachemap.Store(t, c)
} else {
c = cache.(*structCache)
for i := 0; i < len(c.indexes); i++ {
keySize := def.Byte1 + e.calcString(c.names[i])
valueSize, err := e.calcSize(rv.Field(c.indexes[i]))
size, err := e.calcSizeWithOmitEmpty(rv.Field(c.indexes[i]), c.names[i], c.omits[i])
if err != nil {
return 0, err
}
ret += keySize + valueSize
ret += size
if size > 0 {
l++
}
}
}
// format size
l := len(c.indexes)
if l <= 0x0f {
// format code only
} else if l <= math.MaxUint16 {
ret += def.Byte2
} else if uint(l) <= math.MaxUint32 {
ret += def.Byte4
} else {
// not supported error
return 0, fmt.Errorf("map length %d is %w", l, def.ErrUnsupportedLength)
size, err := e.calcLength(len(c.indexes))
if err != nil {
return 0, err
}
ret += size
return ret, nil
}
func (e *encoder) calcSizeWithOmitEmpty(rv reflect.Value, name string, omit bool) (int, error) {
keySize := 0
valueSize := 0
if !omit || !rv.IsZero() {
keySize = e.calcString(name)
vSize, err := e.calcSize(rv)
if err != nil {
return 0, err
}
valueSize = vSize
}
return keySize + valueSize, nil
}
func (e *encoder) getStructWriter(typ reflect.Type) structWriteFunc {
for i := range extCoders {
@@ -212,19 +242,34 @@ func (e *encoder) writeStructMap(rv reflect.Value, offset int) int {
// format size
num := len(c.indexes)
if num <= 0x0f {
offset = e.setByte1Int(def.FixMap+num, offset)
} else if num <= math.MaxUint16 {
l := 0
if c.noOmit {
l = num
} else {
for i := 0; i < num; i++ {
irv := rv.Field(c.indexes[i])
if !c.omits[i] || !irv.IsZero() {
l++
}
}
}
if l <= 0x0f {
offset = e.setByte1Int(def.FixMap+l, offset)
} else if l <= math.MaxUint16 {
offset = e.setByte1Int(def.Map16, offset)
offset = e.setByte2Int(num, offset)
} else if uint(num) <= math.MaxUint32 {
offset = e.setByte2Int(l, offset)
} else if uint(l) <= math.MaxUint32 {
offset = e.setByte1Int(def.Map32, offset)
offset = e.setByte4Int(num, offset)
offset = e.setByte4Int(l, offset)
}
for i := 0; i < num; i++ {
offset = e.writeString(c.names[i], offset)
offset = e.create(rv.Field(c.indexes[i]), offset)
irv := rv.Field(c.indexes[i])
if !c.omits[i] || !irv.IsZero() {
offset = e.writeString(c.names[i], offset)
offset = e.create(irv, offset)
}
}
return offset
}