Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions syntax/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type decOpts struct {
min uint // minimum size in bytes
max uint // maximum size in bytes
varint bool // whether to decode as a varint
none bool // whether to decode at all
}

type decodeState struct {
Expand Down Expand Up @@ -287,6 +288,10 @@ func newSliceDecoder(t reflect.Type) decoderFunc {

//////////

func noopDecoder(d *decodeState, v reflect.Value, opts decOpts) int {
return 0
}

type structDecoder struct {
fieldOpts []decOpts
fieldDecs []decoderFunc
Expand Down Expand Up @@ -318,6 +323,12 @@ func newStructDecoder(t reflect.Type) decoderFunc {
max: tagOpts["max"],
min: tagOpts["min"],
varint: tagOpts[varintOption] > 0,
none: tagOpts[noneOption] > 0,
}

if sd.fieldOpts[i].none {
sd.fieldDecs[i] = noopDecoder
continue
}

sd.fieldDecs[i] = typeDecoder(f.Type)
Expand Down
22 changes: 22 additions & 0 deletions syntax/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,28 @@ func TestDecodeUnsupported(t *testing.T) {
}
}

func TestDecodeNone(t *testing.T) {
template := struct {
A uint16
B uint16 `tls:"none"`
C uint16
}{}
encoding := unhex("AAAACCCC")

template.B = 0xBBBB
n, err := Unmarshal(encoding, &template)
if n != len(encoding) {
t.Fatalf("Failed to use all of the encoded value")
}
if err != nil {
t.Fatalf("Error in unmarshal: %v", err)
}
if template.B != 0xBBBB {
t.Fatalf("Overwrote value of unencoded field")
}

}

func TestDecodeErrors(t *testing.T) {
vector0x20 := append([]byte{0x20}, buffer(0x20)...)
errorCases := map[string]struct {
Expand Down
10 changes: 10 additions & 0 deletions syntax/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type encOpts struct {
min uint // minimum size in bytes
max uint // maximum size in bytes
varint bool // whether to encode as a varint
none bool // whether to encode at all
}

type encodeState struct {
Expand Down Expand Up @@ -220,6 +221,8 @@ func newSliceEncoder(t reflect.Type) encoderFunc {

//////////

func noopEncoder(e *encodeState, v reflect.Value, opts encOpts) {}

type structEncoder struct {
fieldOpts []encOpts
fieldEncs []encoderFunc
Expand Down Expand Up @@ -248,7 +251,14 @@ func newStructEncoder(t reflect.Type) encoderFunc {
max: tagOpts["max"],
min: tagOpts["min"],
varint: tagOpts[varintOption] > 0,
none: tagOpts[noneOption] > 0,
}

if se.fieldOpts[i].none {
se.fieldEncs[i] = noopEncoder
continue
}

se.fieldEncs[i] = typeEncoder(f.Type)
}

Expand Down
12 changes: 12 additions & 0 deletions syntax/success_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,18 @@ func TestSuccessCases(t *testing.T) {
value: struct{ V *uint16 }{V: &dummyUint16},
encoding: unhex("B0A0"),
},
"struct-none": {
value: struct {
A uint16
B uint16 `tls:"none"`
C uint16
}{
A: 0xAAAA,
B: 0x0000, // must be zero value in order for tests to pass
C: 0xCCCC,
},
encoding: unhex("AAAACCCC"),
},

// Marshaler
"marshaler": {
Expand Down
6 changes: 6 additions & 0 deletions syntax/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
type tagOptions map[string]uint

var (
noneOption = "none"
varintOption = "varint"

headOptionNone = "none"
Expand All @@ -24,6 +25,11 @@ var (
func parseTag(tag string) tagOptions {
opts := tagOptions{}
for _, token := range strings.Split(tag, ",") {
if token == noneOption {
opts[noneOption] = 1
continue
}

if token == varintOption {
opts[varintOption] = 1
continue
Expand Down