diff --git a/empty_struct_test.go b/empty_struct_test.go new file mode 100644 index 00000000..28b94cd6 --- /dev/null +++ b/empty_struct_test.go @@ -0,0 +1,69 @@ +package main + +import "testing" + +func TestEmptyStructCollections(t *testing.T) { + filename, err := generate(t, emptyStructCollections) + if err != nil { + t.Fatalf("generate failed: %v", err) + } + goExec(t, filename, false) + goExec(t, filename, true) +} + +var emptyStructCollections = `package main + +import ( + "bytes" + "fmt" + "reflect" + + "github.com/tinylib/msgp/msgp" +) + +type Empty struct{} +type ZeroArray [0]Empty +type NestedArray [2][1]Empty + +type Collection struct { + Named []Empty + Anonymous []struct{} + Array [2]Empty +} + +func main() { + input := Collection{ + Named: []Empty{{}, {}}, + Anonymous: []struct{}{{}, {}, {}}, + } + data, err := input.MarshalMsg(nil) + if err != nil { + panic(err) + } + if size := input.Msgsize(); size < len(data) { + panic(fmt.Sprintf("Msgsize %d is smaller than encoded length %d", size, len(data))) + } + var decoded Collection + if rest, err := decoded.UnmarshalMsg(data); err != nil || len(rest) != 0 { + panic(fmt.Sprintf("UnmarshalMsg: rest %x, error %v", rest, err)) + } + if !reflect.DeepEqual(input, decoded) { + panic(fmt.Sprintf("UnmarshalMsg got %#v, want %#v", decoded, input)) + } + + var stream bytes.Buffer + if err := msgp.Encode(&stream, &input); err != nil { + panic(err) + } + if !bytes.Equal(stream.Bytes(), data) { + panic("stream encoding differs from MarshalMsg") + } + var streamed Collection + if err := msgp.Decode(&stream, &streamed); err != nil { + panic(err) + } + if !reflect.DeepEqual(input, streamed) { + panic(fmt.Sprintf("DecodeMsg got %#v, want %#v", streamed, input)) + } +} +` diff --git a/gen/size.go b/gen/size.go index 5b9639ae..09dcb16c 100644 --- a/gen/size.go +++ b/gen/size.go @@ -324,6 +324,9 @@ func fixedsizeExpr(e Elem) (string, bool) { strbody = msgp.AppendString(strbody[:0], f.FieldTag) hdrlen += len(strbody) } + if str == "" { + return strconv.Itoa(hdrlen), true + } return fmt.Sprintf("%d + %s", hdrlen, str), true } return "", false