Skip to content

Commit

Permalink
feat: add sizeof function
Browse files Browse the repository at this point in the history
  • Loading branch information
yang.yu committed Dec 12, 2023
1 parent e6baf3f commit 89161f4
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
72 changes: 72 additions & 0 deletions kaitai/sizefo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package kaitai

import (
"errors"
"reflect"
)

func SizeOf(msg interface{}) (uint64, error) {
v := reflect.ValueOf(msg)
return sizeof(v)
}

func sizeof(fieldValue reflect.Value) (uint64, error) {
switch fieldValue.Kind() {
case reflect.Uint8, reflect.Int8, reflect.Bool:
return 1, nil
case reflect.Uint16, reflect.Int16:
return 2, nil
case reflect.Uint32, reflect.Int32, reflect.Float32:
return 4, nil
case reflect.Uint64, reflect.Int64, reflect.Float64:
return 8, nil
case reflect.String:
return uint64(len(fieldValue.String())), nil
case reflect.Slice, reflect.Array:
arrLen := fieldValue.Len()
var result uint64
for i := 0; i < arrLen; i++ {
v := fieldValue.Index(i)
vl, err := sizeof(v)
if err != nil {
return 0, err
}
result += vl
}
return result, nil
case reflect.Struct:
numField := fieldValue.NumField()
valueType := fieldValue.Type()
var result uint64
for i := 0; i < numField; i++ {
fieldType := valueType.Field(i)
// skip stream and not exported field
if fieldType.Anonymous || fieldType.PkgPath != "" {
continue
}

v := fieldValue.Field(i)
vl, err := sizeof(v)
if err != nil {
return 0, err
}
result += vl
}
return result, nil
case reflect.Pointer:
// nil 0
if fieldValue.IsNil() {
return 0, nil
}
fieldValue = fieldValue.Elem()
return sizeof(fieldValue)
case reflect.Interface:
if fieldValue.IsNil() {
return 0, errors.New(fieldValue.Kind().String() + " interface nil")
}
fieldValue = fieldValue.Elem()
return sizeof(fieldValue)
default:
return 0, errors.New(`type "` + fieldValue.Kind().String() + `" not supported`)
}
}
53 changes: 53 additions & 0 deletions kaitai/sizeof_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package kaitai

import (
"testing"
)

func TestSizeOf(t *testing.T) {
type args struct {
*Stream
Uint8 uint8
Int8 int8
Bool bool
Uint16 uint16
Int16 int16
Uint32 uint32
Int32 int32
Float32 float32
Uint64 uint64
Int64 int64
Float64 float64
String string
Bytes []byte
Slice []string
Array [4]byte
Args *args
}
result := args{}
var initLength uint64 = 55

l, err := SizeOf(result)
if err != nil {
t.Fatal(err)
}
if l == initLength {
t.Fatal("wrong len")
}
result.String = "123"
if l == initLength+3 {
t.Fatal("wrong len")
}
result.Bytes = []byte("123")
if l == initLength+6 {
t.Fatal("wrong len")
}
result.Slice = []string{"1", "2"}
if l == initLength+8 {
t.Fatal("wrong len")
}
result.Args = &args{}
if l == 2*initLength+8 {
t.Fatal("wrong len")
}
}

0 comments on commit 89161f4

Please sign in to comment.