From 58da9ac6e691a8c660eb8ca838a154e11da0db68 Mon Sep 17 00:00:00 2001 From: Ondrej Fabry Date: Wed, 22 Jul 2020 04:40:55 +0200 Subject: Fix binapigen decoding and minor improvements - fixed allocating byte slices before copying decoded data - simplified encoding functions - several minor improvements Change-Id: I6669424b89eb86333805cb1b57e4551169980cc2 Signed-off-by: Ondrej Fabry --- codec/codec.go | 70 +++++++++++++------ codec/marshaler_test.go | 175 +----------------------------------------------- codec/msg_codec.go | 10 +++ 3 files changed, 59 insertions(+), 196 deletions(-) (limited to 'codec') diff --git a/codec/codec.go b/codec/codec.go index 4178e12..3ae578b 100644 --- a/codec/codec.go +++ b/codec/codec.go @@ -18,8 +18,6 @@ import ( "bytes" "encoding/binary" "math" - "reflect" - "unsafe" ) // Buffer provides buffer for encoding and decoding data on wire. @@ -28,12 +26,14 @@ type Buffer struct { pos int } +// NewBuffer creates new buffer using b as data. func NewBuffer(b []byte) *Buffer { return &Buffer{ buf: b, } } +// Bytes returns buffer data up to current position. func (b *Buffer) Bytes() []byte { return b.buf[:b.pos] } @@ -68,12 +68,12 @@ func (b *Buffer) DecodeBool() bool { } func (b *Buffer) EncodeUint8(v uint8) { - b.buf[b.pos] = v + b.buf[b.pos] = byte(v) b.pos += 1 } func (b *Buffer) DecodeUint8() uint8 { - v := b.buf[b.pos] + v := uint8(b.buf[b.pos]) b.pos += 1 return v } @@ -111,6 +111,50 @@ func (b *Buffer) DecodeUint64() uint64 { return v } +func (b *Buffer) EncodeInt8(v int8) { + b.buf[b.pos] = byte(v) + b.pos += 1 +} + +func (b *Buffer) DecodeInt8() int8 { + v := int8(b.buf[b.pos]) + b.pos += 1 + return v +} + +func (b *Buffer) EncodeInt16(v int16) { + binary.BigEndian.PutUint16(b.buf[b.pos:b.pos+2], uint16(v)) + b.pos += 2 +} + +func (b *Buffer) DecodeInt16() int16 { + v := int16(binary.BigEndian.Uint16(b.buf[b.pos : b.pos+2])) + b.pos += 2 + return v +} + +func (b *Buffer) EncodeInt32(v int32) { + binary.BigEndian.PutUint32(b.buf[b.pos:b.pos+4], uint32(v)) + b.pos += 4 +} + +func (b *Buffer) DecodeInt32() int32 { + v := int32(binary.BigEndian.Uint32(b.buf[b.pos : b.pos+4])) + b.pos += 4 + return v +} + +func (b *Buffer) EncodeInt64(v int64) { + binary.BigEndian.PutUint64(b.buf[b.pos:b.pos+8], uint64(v)) + b.pos += 8 +} + +func (b *Buffer) DecodeInt64() int64 { + v := int64(binary.BigEndian.Uint64(b.buf[b.pos : b.pos+8])) + b.pos += 8 + return v +} + func (b *Buffer) EncodeFloat64(v float64) { binary.BigEndian.PutUint64(b.buf[b.pos:b.pos+8], math.Float64bits(v)) b.pos += 8 @@ -145,21 +189,3 @@ func (b *Buffer) DecodeString(length int) string { b.pos += length return string(v) } - -func BytesToString(b []byte) string { - sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b)) - stringHeader := reflect.StringHeader{Data: sliceHeader.Data, Len: sliceHeader.Len} - return *(*string)(unsafe.Pointer(&stringHeader)) -} - -func DecodeString(b []byte) string { - return string(b) -} - -func DecodeStringZero(b []byte) string { - nul := bytes.Index(b, []byte{0x00}) - if nul >= 0 { - b = b[:nul] - } - return string(b) -} diff --git a/codec/marshaler_test.go b/codec/marshaler_test.go index b3b20b0..985dd31 100644 --- a/codec/marshaler_test.go +++ b/codec/marshaler_test.go @@ -23,8 +23,7 @@ import ( "git.fd.io/govpp.git/binapi/ip_types" "git.fd.io/govpp.git/binapi/sr" "git.fd.io/govpp.git/codec" - "git.fd.io/govpp.git/internal/testbinapi/binapi2001/interfaces" - "git.fd.io/govpp.git/internal/testbinapi/binapi2001/ip" + interfaces "git.fd.io/govpp.git/internal/testbinapi/binapi2001/interface" ) // CliInband represents VPP binary API message 'cli_inband'. @@ -167,175 +166,3 @@ func TestNewCodecEncodeDecode2(t *testing.T) { t.Fatalf("newData differs from oldData") } } - -func TestNewCodecEncode(t *testing.T) { - m := NewIPRouteLookupReply() - /*m := &sr.SrPoliciesDetails{ - Bsid: sr.IP6Address{00, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, - IsSpray: true, - IsEncap: false, - FibTable: 33, - NumSidLists: 1, - SidLists: []sr.Srv6SidList{ - { - Weight: 555, - NumSids: 2, - Sids: [16]sr.IP6Address{ - {99}, - {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - }, - }, - }, - }*/ - - var err error - var oldData, newData []byte - { - w := codec.Wrapper{m} - size := m.Size() - t.Logf("wrapper size: %d", size) - oldData, err = w.Marshal(nil) - if err != nil { - t.Fatalf("expected nil error, got: %v", err) - } - } - { - size := m.Size() - t.Logf("size: %d", size) - newData, err = m.Marshal(nil) - if err != nil { - t.Fatalf("expected nil error, got: %v", err) - } - } - t.Logf("Data:\nOLD[%d]: % 03x\nNEW[%d]: % 03x", len(oldData), oldData, len(newData), newData) - - if !bytes.Equal(oldData, newData) { - t.Fatalf("newData differs from oldData") - } -} - -func TestNewCodecDecode(t *testing.T) { - data := []byte{ - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, - 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x08, 0x09, 0x0a, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x09, 0x00, - 0x00, 0x00, 0x08, 0x07, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - } - - var err error - var oldData, newData ip.IPRouteAddDel - { - w := codec.Wrapper{&oldData} - err = w.Unmarshal(data) - if err != nil { - t.Errorf("expected nil error, got: %v", err) - } - } - { - err = newData.Unmarshal(data) - if err != nil { - t.Errorf("expected nil error, got: %v", err) - } - } - t.Logf("Data:\nOLD: %+v\nNEW: %+v", oldData, newData) - - if !reflect.DeepEqual(oldData, newData) { - t.Fatalf("newData differs from oldData") - } -} - -func NewIPRouteLookupReply() *ip.IPRouteAddDel { - return &ip.IPRouteAddDel{ - Route: ip.IPRoute{ - TableID: 3, - StatsIndex: 5, - Prefix: ip.Prefix{ - Address: ip.Address{ - Af: ip.ADDRESS_IP6, - Un: ip.AddressUnion{}, - }, - Len: 24, - }, - NPaths: 2, - Paths: []ip.FibPath{ - { - SwIfIndex: 5, - TableID: 6, - RpfID: 8, - Weight: 9, - Preference: 10, - Type: 11, - Flags: 1, - Proto: 2, - Nh: ip.FibPathNh{ - Address: ip.AddressUnion{}, - ViaLabel: 3, - ObjID: 1, - ClassifyTableIndex: 2, - }, - NLabels: 1, - LabelStack: [16]ip.FibMplsLabel{ - { - IsUniform: 9, - Label: 8, - TTL: 7, - Exp: 6, - }, - }, - }, - { - SwIfIndex: 7, - TableID: 6, - RpfID: 8, - Weight: 9, - Preference: 10, - Type: 11, - Flags: 1, - Proto: 1, - Nh: ip.FibPathNh{ - Address: ip.AddressUnion{}, - ViaLabel: 3, - ObjID: 1, - ClassifyTableIndex: 2, - }, - NLabels: 2, - LabelStack: [16]ip.FibMplsLabel{ - { - IsUniform: 9, - Label: 8, - TTL: 7, - Exp: 6, - }, - { - IsUniform: 10, - Label: 8, - TTL: 7, - Exp: 6, - }, - }, - }, - }, - }, - } -} diff --git a/codec/msg_codec.go b/codec/msg_codec.go index 68cf3b1..6534e7d 100644 --- a/codec/msg_codec.go +++ b/codec/msg_codec.go @@ -24,6 +24,16 @@ import ( var DefaultCodec = new(MsgCodec) +func EncodeMsg(msg api.Message, msgID uint16) (data []byte, err error) { + return DefaultCodec.EncodeMsg(msg, msgID) +} +func DecodeMsg(data []byte, msg api.Message) (err error) { + return DefaultCodec.DecodeMsg(data, msg) +} +func DecodeMsgContext(data []byte, msg api.Message) (context uint32, err error) { + return DefaultCodec.DecodeMsgContext(data, msg) +} + // MsgCodec provides encoding and decoding functionality of `api.Message` structs into/from // binary format as accepted by VPP. type MsgCodec struct{} -- cgit