Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Struct fields numeric labels #160

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
493757e
add ability to use numeric labels in map
Jul 14, 2016
fd9ac4f
readme fixes
Jul 14, 2016
d57ab0a
bugfix
Jul 14, 2016
97823d4
fix tests
Jul 14, 2016
0108cd3
bugfix with empty field tag
Jul 15, 2016
9452270
add generated files to clean task
Jul 15, 2016
6da8d3d
declare vars out of the loop
Jul 15, 2016
77232d3
use declareOnce pattern
Jul 15, 2016
79ca299
optimize gen for single typed labels
Jul 15, 2016
84311a7
add tests for numeric labels
Jul 15, 2016
97f80c9
code style
Jul 15, 2016
f7c196e
comment
Jul 15, 2016
af829af
use different syntax, refactoring
Jul 22, 2016
b2cdf6e
update readme
Jul 22, 2016
91edff8
use different literals in readme example
Jul 22, 2016
62450e6
add different number literals test
Jul 22, 2016
56a4935
bug fix with single numeric field
Jul 22, 2016
26008c6
change panic message
Jul 23, 2016
0c1cb94
apply review comments
Aug 2, 2016
7a547e1
common internal log package
Aug 2, 2016
5fd38c2
use common log package
Aug 2, 2016
efbe90c
fix import
Aug 2, 2016
f1ccc2a
ignore idea files
Sep 14, 2016
de20c15
map keys are not just strings now
Sep 14, 2016
dff3b85
apply gofmt to sources
Sep 14, 2016
ff02952
eol
Sep 14, 2016
af68dbd
fix possible shadowing bytes value in a map
Sep 15, 2016
61bf3ee
read map of interfaces
Oct 18, 2016
24d54ba
remove redundant errcheck
Oct 18, 2016
9b93c50
signature fix
Oct 18, 2016
66e724c
map of interface to inteface
Nov 19, 2016
8eedca8
fix tests, use map of interface instead
Nov 19, 2016
1f2d896
Add (*Reader).CopyNext(w) (int64, error) (#167)
pwaller Dec 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# normal `go install`.

# generated integration test files
GGEN = ./_generated/generated.go ./_generated/generated_test.go
GGEN = ./_generated/generated.go ./_generated/generated_test.go ./_generated/issue94_gen.go ./_generated/issue94_gen_test.go
# generated unit test files
MGEN = ./msgp/defgen_test.go

Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ type Person struct {
unexported bool // this field is also ignored
}
```
If you need to have numeric labels for a struct fields, you could set it in `msg:"(int/uint)value"` notation:
```go
type Person struct {
Name string `msg:"(int)0x01"`
Address string `msg:"(int)0x02"`
Age int `msg:"(int)0x03"`
}
```
> Note that field labels with `uint` value will be serialized as `msgp.fixint` in case when label value is <= (1<<7)-1

By default, the code generator will satisfy `msgp.Sizer`, `msgp.Encodable`, `msgp.Decodable`,
`msgp.Marshaler`, and `msgp.Unmarshaler`. Carefully-designed applications can use these methods to do
Expand Down
11 changes: 11 additions & 0 deletions _generated/def.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ type TestType struct {
Slice2 []string
}

type TestNumericLabels struct {
One string `msg:"(int)0x01"`
Two string `msg:"(uint)0xffffffffffffffff"`
}

type TestOnlyIntLabels struct {
A string `msg:"(int)0xfa"`
B string `msg:"(int)0xfb"`
C string `msg:"(int)0xfc"`
}

//msgp:tuple Object
type Object struct {
ObjectNo string `msg:"objno"`
Expand Down
59 changes: 25 additions & 34 deletions gen/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,24 @@ import (

func decode(w io.Writer) *decodeGen {
return &decodeGen{
p: printer{w: w},
hasfield: false,
p: printer{w: w},
}
}

type decodeGen struct {
passes
p printer
hasfield bool
fields
p printer
}

func (d *decodeGen) Method() Method { return Decode }

func (d *decodeGen) needsField() {
if d.hasfield {
return
}
d.p.print("\nvar field []byte; _ = field")
d.hasfield = true
}

func (d *decodeGen) Execute(p Elem) error {
p = d.applyall(p)
if p == nil {
return nil
}
d.hasfield = false
d.fields.drop()
if !d.p.ok() {
return d.p.err
}
Expand Down Expand Up @@ -63,14 +54,32 @@ func (d *decodeGen) gStruct(s *Struct) {
return
}

func (d *decodeGen) assignAndCheck(name string, typ string) {
func (d *decodeGen) assignAndCheck(name string, base string) {
if !d.p.ok() {
return
}
d.p.printf("\n%s, err = dc.Read%s()", name, typ)
if base == mapKey {
d.p.printf("\n%s, err = dc.ReadMapKeyPtr()", name)
} else {
d.p.printf("\n%s, err = dc.Read%s()", name, base)
}

d.p.print(errcheck)
}

func (u *decodeGen) nextTypeAndCheck(name string) {
if !u.p.ok() {
return
}
u.p.printf("\n%s, err = dc.NextType()", name)
u.p.print(errcheck)
}

func (u *decodeGen) skipAndCheck() {
u.p.print("\nerr = dc.Skip()")
u.p.print(errcheck)
}

func (d *decodeGen) structAsTuple(s *Struct) {
nfields := len(s.Fields)

Expand All @@ -87,25 +96,7 @@ func (d *decodeGen) structAsTuple(s *Struct) {
}

func (d *decodeGen) structAsMap(s *Struct) {
d.needsField()
sz := randIdent()
d.p.declare(sz, u32)
d.assignAndCheck(sz, mapHeader)

d.p.printf("\nfor %s > 0 {\n%s--", sz, sz)
d.assignAndCheck("field", mapKey)
d.p.print("\nswitch msgp.UnsafeString(field) {")
for i := range s.Fields {
d.p.printf("\ncase \"%s\":", s.Fields[i].FieldTag)
next(d, s.Fields[i].FieldElem)
if !d.p.ok() {
return
}
}
d.p.print("\ndefault:\nerr = dc.Skip()")
d.p.print(errcheck)
d.p.closeblock() // close switch
d.p.closeblock() // close for loop
genStructFieldsParser(d, d.p, s.Fields)
}

func (d *decodeGen) gBase(b *BaseElem) {
Expand Down
6 changes: 3 additions & 3 deletions gen/elem.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,9 @@ func (s *Struct) Complexity() int {
}

type StructField struct {
FieldTag string // the string inside the `msg:""` tag
FieldName string // the name of the struct field
FieldElem Elem // the field type
FieldTag interface{} // the label of the struct field in msgpack
FieldName string // the name of the struct field
FieldElem Elem // the field type
}

// BaseElem is an element that
Expand Down
17 changes: 3 additions & 14 deletions gen/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package gen

import (
"fmt"
"github.com/tinylib/msgp/msgp"
"io"

"github.com/tinylib/msgp/msgp"
)

func encode(w io.Writer) *encodeGen {
Expand Down Expand Up @@ -101,19 +102,7 @@ func (e *encodeGen) appendraw(bts []byte) {
}

func (e *encodeGen) structmap(s *Struct) {
nfields := len(s.Fields)
data := msgp.AppendMapHeader(nil, uint32(nfields))
e.p.printf("\n// map header, size %d", nfields)
e.Fuse(data)
for i := range s.Fields {
if !e.p.ok() {
return
}
data = msgp.AppendString(nil, s.Fields[i].FieldTag)
e.p.printf("\n// write %q", s.Fields[i].FieldTag)
e.Fuse(data)
next(e, s.Fields[i].FieldElem)
}
genStructFieldsSerializer(e, e.p, s.Fields)
}

func (e *encodeGen) gMap(m *Map) {
Expand Down
19 changes: 3 additions & 16 deletions gen/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package gen

import (
"fmt"
"github.com/tinylib/msgp/msgp"
"io"

"github.com/tinylib/msgp/msgp"
)

func marshal(w io.Writer) *marshalGen {
Expand Down Expand Up @@ -96,21 +97,7 @@ func (m *marshalGen) tuple(s *Struct) {
}

func (m *marshalGen) mapstruct(s *Struct) {
data := make([]byte, 0, 64)
data = msgp.AppendMapHeader(data, uint32(len(s.Fields)))
m.p.printf("\n// map header, size %d", len(s.Fields))
m.Fuse(data)
for i := range s.Fields {
if !m.p.ok() {
return
}
data = msgp.AppendString(nil, s.Fields[i].FieldTag)

m.p.printf("\n// string %q", s.Fields[i].FieldTag)
m.Fuse(data)

next(m, s.Fields[i].FieldElem)
}
genStructFieldsSerializer(m, m.p, s.Fields)
}

// append raw data
Expand Down
11 changes: 8 additions & 3 deletions gen/size.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package gen

import (
"fmt"
"github.com/tinylib/msgp/msgp"
"io"
"strconv"

"github.com/tinylib/msgp/msgp"
)

type sizeState uint8
Expand Down Expand Up @@ -107,7 +108,7 @@ func (s *sizeGen) gStruct(st *Struct) {
s.addConstant(strconv.Itoa(len(data)))
for i := range st.Fields {
data = data[:0]
data = msgp.AppendString(data, st.Fields[i].FieldTag)
data, s.p.err = msgp.AppendIntf(data, st.Fields[i].FieldTag)
s.addConstant(strconv.Itoa(len(data)))
next(s, st.Fields[i].FieldElem)
}
Expand Down Expand Up @@ -238,8 +239,12 @@ func fixedsizeExpr(e Elem) (string, bool) {
mhdr := msgp.AppendMapHeader(nil, uint32(len(e.Fields)))
hdrlen += len(mhdr)
var strbody []byte
var err error
for _, f := range e.Fields {
strbody = msgp.AppendString(strbody[:0], f.FieldTag)
strbody, err = msgp.AppendIntf(strbody[:0], f.FieldTag)
if err != nil {
return "", false
}
hdrlen += len(strbody)
}
return fmt.Sprintf("%d + %s", hdrlen, str), true
Expand Down
Loading