1 // Copyright (c) 2020 Cisco and/or its affiliates.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at:
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
26 "github.com/lunixbochs/struc"
28 "git.fd.io/govpp.git/api"
31 var DefaultCodec = &NewCodec{} // &MsgCodec{}
33 // Marshaler is the interface implemented by the binary API messages that can
34 // marshal itself into binary form for the wire.
35 type Marshaler interface {
37 Marshal([]byte) ([]byte, error)
40 // Unmarshaler is the interface implemented by the binary API messages that can
41 // unmarshal a binary representation of itself from the wire.
42 type Unmarshaler interface {
43 Unmarshal([]byte) error
46 type NewCodec struct{}
48 func (*NewCodec) EncodeMsg(msg api.Message, msgID uint16) (data []byte, err error) {
50 return nil, errors.New("nil message passed in")
52 marshaller, ok := msg.(Marshaler)
54 return nil, fmt.Errorf("message %s does not implement marshaller", msg.GetMessageName())
57 size := marshaller.Size()
58 offset := getOffset(msg)
59 //fmt.Printf("size=%d offset=%d\n", size, offset)
61 b := make([]byte, size+offset)
62 b[0] = byte(msgID >> 8)
65 //fmt.Printf("len(b)=%d cap(b)=%d\n", len(b), cap(b))
66 //b = append(b, byte(msgID>>8), byte(msgID))
68 //buf := new(bytes.Buffer)
72 //buf.WriteByte(byte(msgID >> 8))
73 //buf.WriteByte(byte(msgID))
75 data, err = marshaller.Marshal(b[offset:])
81 return b[0:len(b):len(b)], nil
84 func getOffset(msg api.Message) (offset int) {
85 switch msg.GetMessageType() {
86 case api.RequestMessage:
88 case api.ReplyMessage:
90 case api.EventMessage:
96 func (*NewCodec) DecodeMsg(data []byte, msg api.Message) (err error) {
98 return errors.New("nil message passed in")
100 marshaller, ok := msg.(Unmarshaler)
102 return fmt.Errorf("message %s does not implement marshaller", msg.GetMessageName())
105 offset := getOffset(msg)
107 err = marshaller.Unmarshal(data[offset:len(data)])
115 func (*NewCodec) DecodeMsgContext(data []byte, msg api.Message) (context uint32, err error) {
117 return 0, errors.New("nil message passed in")
120 switch msg.GetMessageType() {
121 case api.RequestMessage:
122 return order.Uint32(data[6:10]), nil
123 case api.ReplyMessage:
124 return order.Uint32(data[2:6]), nil
130 type OldCodec struct{}
132 func (c *OldCodec) Marshal(v interface{}) (b []byte, err error) {
133 buf := new(bytes.Buffer)
134 if err := struc.Pack(buf, v); err != nil {
137 return buf.Bytes(), nil
140 func (c *OldCodec) Unmarshal(data []byte, v interface{}) error {
141 buf := bytes.NewReader(data)
142 if err := struc.Unpack(buf, v); err != nil {
148 /*type CodecNew struct{}
150 func (c *CodecNew) Marshal(v interface{}) (b []byte, err error) {
151 buf := new(bytes.Buffer)
152 if err := binary.Write(buf, binary.BigEndian, v); err != nil {
155 return buf.Bytes(), nil
158 func EncodeBool(b bool) byte {
165 func MarshalValue(value interface{}) []byte {
166 switch value.(type) {
168 return []byte{byte(value.(int8))}
170 return []byte{byte(value.(uint8))}
175 var order = binary.BigEndian
182 func (b *Buffer) Bytes() []byte {
186 func (b *Buffer) EncodeUint8(v uint8) {
191 func (b *Buffer) EncodeUint16(v uint16) {
192 order.PutUint16(b.buf[b.pos:b.pos+2], v)
196 func (b *Buffer) EncodeUint32(v uint32) {
197 order.PutUint32(b.buf[b.pos:b.pos+4], v)
201 func (b *Buffer) EncodeUint64(v uint64) {
202 order.PutUint64(b.buf[b.pos:b.pos+8], v)
206 func (b *Buffer) EncodeFloat64(v float64) {
207 order.PutUint64(b.buf[b.pos:b.pos+8], math.Float64bits(v))
211 func (b *Buffer) EncodeBool(v bool) {
220 func (b *Buffer) EncodeString(v string) {
225 func DecodeString(b []byte) string {
226 sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
227 stringHeader := reflect.StringHeader{Data: sliceHeader.Data, Len: sliceHeader.Len}
228 return *(*string)(unsafe.Pointer(&stringHeader))