diff --git a/binapigen/binapigen.go b/binapigen/binapigen.go index 68d4afb2..5a8d8e60 100644 --- a/binapigen/binapigen.go +++ b/binapigen/binapigen.go @@ -21,6 +21,8 @@ import ( "strconv" "strings" + "go.fd.io/govpp/binapi/ethernet_types" + "go.fd.io/govpp/binapi/ip_types" "go.fd.io/govpp/binapigen/vppapi" ) @@ -448,6 +450,96 @@ type Field struct { FieldSizeFrom *Field } +func convertDefaultValue(val interface{}, typ *Field) { + var err error + switch typ.Type { + case "bool": + switch v := val.(type) { + case bool: + typ.DefaultValue = v + case string: + typ.DefaultValue, err = strconv.ParseBool(v) + if err != nil { + panic(err) + } + case float64: + typ.DefaultValue = v != 0 + default: + panic("bool default unknown value") + } + case "int64": + switch v := val.(type) { + case int64: + typ.DefaultValue = v + case uint64: + typ.DefaultValue = v + case string: + typ.DefaultValue, err = strconv.ParseInt(v, 10, 64) + if err != nil { + panic(err) + } + default: + panic("int64 default unknown value") + } + case "uint64": + switch v := val.(type) { + case int64: + typ.DefaultValue = v + case uint64: + typ.DefaultValue = v + case string: + typ.DefaultValue, err = strconv.ParseInt(v, 10, 64) + if err != nil { + panic(err) + } + default: + panic("uint64 default unknown value") + } + case "vl_api_address_t": + switch v := val.(type) { + case string: + typ.DefaultValue, err = ip_types.ParseAddress(v) + if err != nil { + panic(err) + } + default: + panic("vl_api_address_t default unknown value") + } + case "vl_api_ip4_address_t": + switch v := val.(type) { + case string: + typ.DefaultValue, err = ip_types.ParseIP4Address(v) + if err != nil { + panic(err) + } + default: + panic("vl_api_ip4_address_t default unknown value") + } + case "vl_api_ip6_address_t": + switch v := val.(type) { + case string: + typ.DefaultValue, err = ip_types.ParseIP6Address(v) + if err != nil { + panic(err) + } + default: + panic("vl_api_ip6_address_t default unknown value") + } + case "vl_api_mac_address_t": + switch v := val.(type) { + case string: + typ.DefaultValue, err = ethernet_types.ParseMacAddress(v) + if err != nil { + panic(err) + } + default: + panic("vl_api_mac_address_t default unknown value") + } + default: + typ.DefaultValue = val + } +} + func newField(gen *Generator, file *File, parent interface{}, apitype vppapi.Field, index int) *Field { typ := &Field{ Field: apitype, @@ -466,7 +558,7 @@ func newField(gen *Generator, file *File, parent interface{}, apitype vppapi.Fie } if apitype.Meta != nil { if val, ok := apitype.Meta[optFieldDefault]; ok { - typ.DefaultValue = val + convertDefaultValue(val, typ) } } return typ diff --git a/binapigen/generate_api.go b/binapigen/generate_api.go index 21dc2eb7..cd57ff49 100644 --- a/binapigen/generate_api.go +++ b/binapigen/generate_api.go @@ -15,6 +15,7 @@ package binapigen import ( + "bytes" "fmt" "path" "strconv" @@ -470,9 +471,52 @@ func genMessage(g *GenFile, msg *Message) { g.P() } +func genMessageResetBody(_ *GenFile, msg *Message) (string, string) { + if msg == nil || msg.Fields == nil || len(msg.Fields) == 0 { + return "", "" + } + res := bytes.Buffer{} + unmarshalText := bytes.Buffer{} + for _, field := range msg.Fields { + if field.DefaultValue == nil { + continue + } + val := field.Meta[optFieldDefault] + switch field.Type { + case "vl_api_ip4_address_t": + fallthrough + case "vl_api_ip6_address_t": + fallthrough + case "vl_api_mac_address_t": + fallthrough + case "vl_api_address_t": + unmarshalText.WriteString(fmt.Sprintf("\n//%s default %s", field.GoName, val.(string))) + unmarshalText.WriteString(fmt.Sprintf("\nm.%s.UnmarshalText([]byte(\"%s\"))", field.GoName, val.(string))) + continue + } + + res.WriteString(field.GoName) + res.WriteString(":") + switch v := val.(type) { + case float64: + res.WriteString(strconv.FormatFloat(v, 'f', -1, 64)) + case string: + + res.WriteString(v) + case bool: + res.WriteString(strconv.FormatBool(v)) + default: + panic("unknown field type") + } + res.WriteString(",") + } + return res.String(), unmarshalText.String() +} + func genMessageBaseMethods(g *GenFile, msg *Message) { + body, initBody := genMessageResetBody(g, msg) // Reset method - g.P("func (m *", msg.GoName, ") Reset() { *m = ", msg.GoName, "{} }") + g.P("func (m *", msg.GoName, ") Reset() { *m = ", msg.GoName, "{", body, "}", initBody, " }") // GetXXX methods genMessageMethods(g, msg) diff --git a/binapigen/types.go b/binapigen/types.go index 483e8209..8715cd63 100644 --- a/binapigen/types.go +++ b/binapigen/types.go @@ -78,7 +78,7 @@ var BaseTypesGo = map[string]string{ func fieldActualType(field *Field) (actual string) { switch { - case field.TypeAlias != nil: + case field.TypeAlias != nil && field.TypeAlias.Length == 0: actual = field.TypeAlias.Type case field.TypeEnum != nil: actual = field.TypeEnum.Type