From 27401b6ea459921a6152ab1744da1618358465f4 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 10 Jul 2022 13:18:30 -0600 Subject: Rename the module, mv pkg lib --- lib/binstruct/size.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 lib/binstruct/size.go (limited to 'lib/binstruct/size.go') diff --git a/lib/binstruct/size.go b/lib/binstruct/size.go new file mode 100644 index 0000000..6563455 --- /dev/null +++ b/lib/binstruct/size.go @@ -0,0 +1,57 @@ +package binstruct + +import ( + "fmt" + "reflect" +) + +type StaticSizer interface { + BinaryStaticSize() int +} + +func StaticSize(obj any) int { + sz, err := staticSize(reflect.TypeOf(obj)) + if err != nil { + panic(err) + } + return sz +} + +var ( + staticSizerType = reflect.TypeOf((*StaticSizer)(nil)).Elem() + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() + unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() +) + +func staticSize(typ reflect.Type) (int, error) { + if typ.Implements(staticSizerType) { + return reflect.New(typ).Elem().Interface().(StaticSizer).BinaryStaticSize(), nil + } + switch typ.Kind() { + case reflect.Uint8, reflect.Int8: + return 1, nil + case reflect.Uint16, reflect.Int16: + return 2, nil + case reflect.Uint32, reflect.Int32: + return 4, nil + case reflect.Uint64, reflect.Int64: + return 8, nil + case reflect.Ptr: + return staticSize(typ.Elem()) + case reflect.Array: + elemSize, err := staticSize(typ.Elem()) + if err != nil { + return 0, err + } + return elemSize * typ.Len(), nil + case reflect.Struct: + if !(typ.Implements(marshalerType) || typ.Implements(unmarshalerType)) { + return getStructHandler(typ).Size, nil + } + return 0, fmt.Errorf("type=%v (kind=%v) does not implement binfmt.StaticSizer but does implement binfmt.Marshaler or binfmt.Unmarshaler", + typ, typ.Kind()) + default: + return 0, fmt.Errorf("type=%v does not implement binfmt.StaticSizer and kind=%v is not a supported statically-sized kind", + typ, typ.Kind()) + } +} -- cgit v1.2.3-54-g00ecf