New upstream version 3.1.1
aviau
6 years ago
8 | 8 |
- [CustomEncoder](https://godoc.org/github.com/vmihailenco/msgpack#example-CustomEncoder)/CustomDecoder interfaces for custom encoding.
|
9 | 9 |
- [Extensions](https://godoc.org/github.com/vmihailenco/msgpack#example-RegisterExt) to encode type information.
|
10 | 10 |
- Renaming fields via `msgpack:"my_field_name"`.
|
11 | |
- Omitting empty fields via `msgpack:",omitempty"`.
|
|
11 |
- Omitting individual empty fields via `msgpack:",omitempty"` tag or all [empty fields in a struct](https://godoc.org/github.com/vmihailenco/msgpack#example-Marshal--OmitEmpty).
|
12 | 12 |
- [Map keys sorting](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.SortMapKeys).
|
13 | 13 |
- Encoding/decoding all [structs as arrays](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.StructAsArray) or [individual structs](https://godoc.org/github.com/vmihailenco/msgpack#example-Marshal--AsArray).
|
14 | 14 |
- Simple but very fast and efficient [queries](https://godoc.org/github.com/vmihailenco/msgpack#example-Decoder-Query).
|
158 | 158 |
fmt.Println(v)
|
159 | 159 |
// Output: [foo bar]
|
160 | 160 |
}
|
|
161 |
|
|
162 |
func ExampleMarshal_omitEmpty() {
|
|
163 |
type Item struct {
|
|
164 |
Foo string
|
|
165 |
Bar string
|
|
166 |
}
|
|
167 |
|
|
168 |
item := &Item{
|
|
169 |
Foo: "hello",
|
|
170 |
}
|
|
171 |
b, err := msgpack.Marshal(item)
|
|
172 |
if err != nil {
|
|
173 |
panic(err)
|
|
174 |
}
|
|
175 |
fmt.Printf("item: %q\n", b)
|
|
176 |
|
|
177 |
type ItemOmitEmpty struct {
|
|
178 |
_msgpack struct{} `msgpack:",omitempty"`
|
|
179 |
Foo string
|
|
180 |
Bar string
|
|
181 |
}
|
|
182 |
|
|
183 |
itemOmitEmpty := &ItemOmitEmpty{
|
|
184 |
Foo: "hello",
|
|
185 |
}
|
|
186 |
b, err = msgpack.Marshal(itemOmitEmpty)
|
|
187 |
if err != nil {
|
|
188 |
panic(err)
|
|
189 |
}
|
|
190 |
fmt.Printf("item2: %q\n", b)
|
|
191 |
|
|
192 |
// Output: item: "\x82\xa3Foo\xa5hello\xa3Bar\xa0"
|
|
193 |
// item2: "\x81\xa3Foo\xa5hello"
|
|
194 |
}
|
|
0 |
package msgpack
|
|
1 |
|
|
2 |
import (
|
|
3 |
"strings"
|
|
4 |
)
|
|
5 |
|
|
6 |
type tagOptions string
|
|
7 |
|
|
8 |
func (o tagOptions) Get(name string) (string, bool) {
|
|
9 |
s := string(o)
|
|
10 |
for len(s) > 0 {
|
|
11 |
var next string
|
|
12 |
idx := strings.IndexByte(s, ',')
|
|
13 |
if idx >= 0 {
|
|
14 |
s, next = s[:idx], s[idx+1:]
|
|
15 |
}
|
|
16 |
if strings.HasPrefix(s, name) {
|
|
17 |
return s[len(name):], true
|
|
18 |
}
|
|
19 |
s = next
|
|
20 |
}
|
|
21 |
return "", false
|
|
22 |
}
|
|
23 |
|
|
24 |
func (o tagOptions) Contains(name string) bool {
|
|
25 |
_, ok := o.Get(name)
|
|
26 |
return ok
|
|
27 |
}
|
|
28 |
|
|
29 |
func parseTag(tag string) (string, tagOptions) {
|
|
30 |
if idx := strings.IndexByte(tag, ','); idx != -1 {
|
|
31 |
name := tag[:idx]
|
|
32 |
if strings.IndexByte(name, ':') == -1 {
|
|
33 |
return name, tagOptions(tag[idx+1:])
|
|
34 |
}
|
|
35 |
}
|
|
36 |
|
|
37 |
if strings.IndexByte(tag, ':') == -1 {
|
|
38 |
return tag, ""
|
|
39 |
}
|
|
40 |
return "", tagOptions(tag)
|
|
41 |
}
|
0 | |
// Copyright 2011 The Go Authors. All rights reserved.
|
1 | |
// Use of this source code is governed by a BSD-style
|
2 | |
// license that can be found in the LICENSE file.
|
3 | |
|
4 | |
package msgpack
|
5 | |
|
6 | |
import (
|
7 | |
"strings"
|
8 | |
)
|
9 | |
|
10 | |
// tagOptions is the string following a comma in a struct field's "json"
|
11 | |
// tag, or the empty string. It does not include the leading comma.
|
12 | |
type tagOptions string
|
13 | |
|
14 | |
// parseTag splits a struct field's json tag into its name and
|
15 | |
// comma-separated options.
|
16 | |
func parseTag(tag string) (string, tagOptions) {
|
17 | |
if idx := strings.Index(tag, ","); idx != -1 {
|
18 | |
return tag[:idx], tagOptions(tag[idx+1:])
|
19 | |
}
|
20 | |
return tag, tagOptions("")
|
21 | |
}
|
22 | |
|
23 | |
// Contains reports whether a comma-separated list of options
|
24 | |
// contains a particular substr flag. substr must be surrounded by a
|
25 | |
// string boundary or commas.
|
26 | |
func (o tagOptions) Contains(optionName string) bool {
|
27 | |
if len(o) == 0 {
|
28 | |
return false
|
29 | |
}
|
30 | |
s := string(o)
|
31 | |
for s != "" {
|
32 | |
var next string
|
33 | |
i := strings.IndexRune(s, ',')
|
34 | |
if i >= 0 {
|
35 | |
s, next = s[:i], s[i+1:]
|
36 | |
}
|
37 | |
if s == optionName {
|
38 | |
return true
|
39 | |
}
|
40 | |
s = next
|
41 | |
}
|
42 | |
return false
|
43 | |
}
|
190 | 190 |
}
|
191 | 191 |
|
192 | 192 |
func inlineFields(fs *fields, typ reflect.Type, f *field) bool {
|
193 | |
if typ.Kind() == reflect.Ptr {
|
194 | |
typ = typ.Elem()
|
195 | |
}
|
196 | |
if typ.Kind() != reflect.Struct {
|
|
193 |
var encoder encoderFunc
|
|
194 |
var decoder decoderFunc
|
|
195 |
|
|
196 |
if typ.Kind() == reflect.Struct {
|
|
197 |
encoder = f.encoder
|
|
198 |
decoder = f.decoder
|
|
199 |
} else {
|
|
200 |
for typ.Kind() == reflect.Ptr {
|
|
201 |
typ = typ.Elem()
|
|
202 |
encoder = getEncoder(typ)
|
|
203 |
decoder = getDecoder(typ)
|
|
204 |
}
|
|
205 |
if typ.Kind() != reflect.Struct {
|
|
206 |
return false
|
|
207 |
}
|
|
208 |
}
|
|
209 |
|
|
210 |
if reflect.ValueOf(encoder).Pointer() != encodeStructValuePtr {
|
197 | 211 |
return false
|
198 | 212 |
}
|
199 | |
|
200 | |
if reflect.ValueOf(f.encoder).Pointer() != encodeStructValuePtr {
|
201 | |
return false
|
202 | |
}
|
203 | |
if reflect.ValueOf(f.decoder).Pointer() != decodeStructValuePtr {
|
|
213 |
if reflect.ValueOf(decoder).Pointer() != decodeStructValuePtr {
|
204 | 214 |
return false
|
205 | 215 |
}
|
206 | 216 |
|
99 | 99 |
OmitEmptyTest
|
100 | 100 |
}
|
101 | 101 |
|
|
102 |
type InlinePtrTest struct {
|
|
103 |
*OmitEmptyTest
|
|
104 |
}
|
|
105 |
|
102 | 106 |
type AsArrayTest struct {
|
103 | 107 |
_msgpack struct{} `msgpack:",asArray"`
|
104 | 108 |
|
|
147 | 151 |
{&OmitEmptyTest{Foo: "hello"}, "81a3466f6fa568656c6c6f"},
|
148 | 152 |
|
149 | 153 |
{&InlineTest{OmitEmptyTest: OmitEmptyTest{Bar: "world"}}, "81a3426172a5776f726c64"},
|
|
154 |
{&InlinePtrTest{OmitEmptyTest: &OmitEmptyTest{Bar: "world"}}, "81a3426172a5776f726c64"},
|
150 | 155 |
|
151 | 156 |
{&AsArrayTest{}, "92a0a0"},
|
152 | 157 |
}
|