mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-22 19:29:39 +00:00
io: redo GetVarSize for Serializable things
Use writes to a fake io.Writer that counts the bytes. Allows us to kill Size() methods as useless and duplicating lots of functionality.
This commit is contained in:
parent
0da9fe6946
commit
56c72b5c67
2 changed files with 30 additions and 3 deletions
|
@ -17,6 +17,20 @@ var (
|
|||
i64 int64
|
||||
)
|
||||
|
||||
// This structure is used to calculate the wire size of the serializable
|
||||
// structure. It's an io.Writer that doesn't do any real writes, but instead
|
||||
// just counts the number of bytes to be written.
|
||||
type counterWriter struct {
|
||||
counter int
|
||||
}
|
||||
|
||||
// Write implements the io.Writer interface
|
||||
func (cw *counterWriter) Write(p []byte) (int, error) {
|
||||
n := len(p)
|
||||
cw.counter += n
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// GetVarIntSize returns the size in number of bytes of a variable integer
|
||||
// (reference: GetVarSize(int value), https://github.com/neo-project/neo/blob/master/neo/IO/Helper.cs)
|
||||
func GetVarIntSize(value int) int {
|
||||
|
@ -59,6 +73,18 @@ func GetVarSize(value interface{}) int {
|
|||
reflect.Uint32,
|
||||
reflect.Uint64:
|
||||
return GetVarIntSize(int(v.Uint()))
|
||||
case reflect.Ptr:
|
||||
vser, ok := v.Interface().(Serializable)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("unable to calculate GetVarSize for a non-Serializable pointer"))
|
||||
}
|
||||
cw := counterWriter{}
|
||||
w := NewBinWriterFromIO(&cw)
|
||||
err := vser.EncodeBinary(w)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error serializing %s: %s", reflect.TypeOf(value), err.Error()))
|
||||
}
|
||||
return cw.counter
|
||||
case reflect.Slice, reflect.Array:
|
||||
valueLength := v.Len()
|
||||
valueSize := 0
|
||||
|
@ -67,8 +93,7 @@ func GetVarSize(value interface{}) int {
|
|||
switch reflect.ValueOf(value).Index(0).Interface().(type) {
|
||||
case Serializable:
|
||||
for i := 0; i < valueLength; i++ {
|
||||
elem := v.Index(i).Interface().(Serializable)
|
||||
valueSize += elem.Size()
|
||||
valueSize += GetVarSize(v.Index(i).Interface())
|
||||
}
|
||||
case uint8, int8:
|
||||
valueSize = valueLength
|
||||
|
|
|
@ -10,13 +10,15 @@ import (
|
|||
|
||||
// Mock structure to test getting size of an array of serializable things
|
||||
type smthSerializable struct {
|
||||
some [42]byte
|
||||
}
|
||||
|
||||
func (*smthSerializable) DecodeBinary(*BinReader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*smthSerializable) EncodeBinary(*BinWriter) error {
|
||||
func (ss *smthSerializable) EncodeBinary(bw *BinWriter) error {
|
||||
bw.WriteLE(ss.some)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue