diff --git a/_generated/convert.go b/_generated/convert.go index 964cff7d..9f0d92bb 100644 --- a/_generated/convert.go +++ b/_generated/convert.go @@ -81,3 +81,26 @@ type ConvertErrVal string type ConvertErr struct { Err ConvertErrVal } + +//msgp:shim ConvertIntVal as:int64 using:fromConvertIntVal/toConvertIntVal mode:convert +//msgp:ignore ConvertIntVal + +func fromConvertIntVal(v ConvertIntVal) (int64, error) { + return int64(v), nil +} + +func toConvertIntVal(i int64) (ConvertIntVal, error) { + return ConvertIntVal(i), nil +} + +type ConvertIntVal int64 + +// ConvertInt exercises a fixed-size (int64) convert shim. +type ConvertInt struct { + Int ConvertIntVal + Ptr *ConvertIntVal + Map map[string]ConvertIntVal + MapP map[string]*ConvertIntVal + Arr []ConvertIntVal + ArrP []*ConvertIntVal +} diff --git a/_generated/convert_test.go b/_generated/convert_test.go index 7b67305e..6440f745 100644 --- a/_generated/convert_test.go +++ b/_generated/convert_test.go @@ -2,6 +2,7 @@ package _generated import ( "bytes" + "reflect" "testing" "github.com/tinylib/msgp/msgp" @@ -58,3 +59,30 @@ func TestConvertToMarshalError(t *testing.T) { t.Fatalf("expected conversion error, found %v", err.Error()) } } + +func TestConvertInt(t *testing.T) { + // A fixed-size convert shim must report an accurate constant Msgsize. + v := ConvertIntVal(7) + in := ConvertInt{ + Int: 42, + Ptr: &v, + Map: map[string]ConvertIntVal{"a": 1}, + MapP: map[string]*ConvertIntVal{"b": &v}, + Arr: []ConvertIntVal{1, 2}, + ArrP: []*ConvertIntVal{&v}, + } + b, err := in.MarshalMsg(nil) + if err != nil { + t.Fatal(err) + } + if in.Msgsize() < len(b) { + t.Fatalf("Msgsize %d under-reports marshaled size %d", in.Msgsize(), len(b)) + } + var out ConvertInt + if _, err = out.UnmarshalMsg(b); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(out, in) { + t.Fatalf("round-trip mismatch: %v != %v", out, in) + } +} diff --git a/gen/size.go b/gen/size.go index 3efab37d..5b9639ae 100644 --- a/gen/size.go +++ b/gen/size.go @@ -228,6 +228,12 @@ func (s *sizeGen) gBase(b *BaseElem) { return } if b.Convert && b.ShimMode == Convert { + if fixedSize(b.Value) { + // A fixed-size base has a constant wire size, so there is no need + // for a temporary holding the converted value. + s.addConstant(basesizeExpr(b.Value, "", b.BaseName())) + return + } s.state = add vname := randIdent() s.p.printf("\nvar %s %s", vname, b.BaseType()) @@ -237,7 +243,6 @@ func (s *sizeGen) gBase(b *BaseElem) { s.p.printf("\ns += %s", basesizeExpr(b.Value, vname, b.BaseName())) s.state = expr - } else { vname := b.Varname() if b.Convert {