c6d33a366581204491b6c3ed101b73defd085691
[govpp.git] / codec / marshaler.go
1 //  Copyright (c) 2020 Cisco and/or its affiliates.
2 //
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:
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14
15 package codec
16
17 import (
18         "bytes"
19         "encoding/binary"
20         "errors"
21         "fmt"
22         "math"
23         "reflect"
24         "unsafe"
25
26         "github.com/lunixbochs/struc"
27
28         "git.fd.io/govpp.git/api"
29 )
30
31 var DefaultCodec = &NewCodec{} // &MsgCodec{}
32
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 {
36         Size() int
37         Marshal([]byte) ([]byte, error)
38 }
39
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
44 }
45
46 type NewCodec struct{}
47
48 func (*NewCodec) EncodeMsg(msg api.Message, msgID uint16) (data []byte, err error) {
49         if msg == nil {
50                 return nil, errors.New("nil message passed in")
51         }
52         marshaller, ok := msg.(Marshaler)
53         if !ok {
54                 return nil, fmt.Errorf("message %s does not implement marshaller", msg.GetMessageName())
55         }
56
57         size := marshaller.Size()
58         offset := getOffset(msg)
59         //fmt.Printf("size=%d offset=%d\n", size, offset)
60
61         b := make([]byte, size+offset)
62         b[0] = byte(msgID >> 8)
63         b[1] = byte(msgID)
64
65         //fmt.Printf("len(b)=%d cap(b)=%d\n", len(b), cap(b))
66         //b = append(b, byte(msgID>>8), byte(msgID))
67
68         //buf := new(bytes.Buffer)
69         //buf.Grow(size)
70
71         // encode msg ID
72         //buf.WriteByte(byte(msgID >> 8))
73         //buf.WriteByte(byte(msgID))
74
75         data, err = marshaller.Marshal(b[offset:])
76         if err != nil {
77                 return nil, err
78         }
79         //buf.Write(b)
80
81         return b[0:len(b):len(b)], nil
82 }
83
84 func getOffset(msg api.Message) (offset int) {
85         switch msg.GetMessageType() {
86         case api.RequestMessage:
87                 return 10
88         case api.ReplyMessage:
89                 return 6
90         case api.EventMessage:
91                 return 6
92         }
93         return 2
94 }
95
96 func (*NewCodec) DecodeMsg(data []byte, msg api.Message) (err error) {
97         if msg == nil {
98                 return errors.New("nil message passed in")
99         }
100         marshaller, ok := msg.(Unmarshaler)
101         if !ok {
102                 return fmt.Errorf("message %s does not implement marshaller", msg.GetMessageName())
103         }
104
105         offset := getOffset(msg)
106
107         err = marshaller.Unmarshal(data[offset:len(data)])
108         if err != nil {
109                 return err
110         }
111
112         return nil
113 }
114
115 func (*NewCodec) DecodeMsgContext(data []byte, msg api.Message) (context uint32, err error) {
116         if msg == nil {
117                 return 0, errors.New("nil message passed in")
118         }
119
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
125         }
126
127         return 0, nil
128 }
129
130 type OldCodec struct{}
131
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 {
135                 return nil, err
136         }
137         return buf.Bytes(), nil
138 }
139
140 func (c *OldCodec) Unmarshal(data []byte, v interface{}) error {
141         buf := bytes.NewReader(data)
142         if err := struc.Unpack(buf, v); err != nil {
143                 return err
144         }
145         return nil
146 }
147
148 /*type CodecNew struct{}
149
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 {
153                 return nil, err
154         }
155         return buf.Bytes(), nil
156 }*/
157
158 func EncodeBool(b bool) byte {
159         if b {
160                 return 1
161         }
162         return 0
163 }
164
165 func MarshalValue(value interface{}) []byte {
166         switch value.(type) {
167         case int8:
168                 return []byte{byte(value.(int8))}
169         case uint8:
170                 return []byte{byte(value.(uint8))}
171         }
172         return nil
173 }
174
175 var order = binary.BigEndian
176
177 type Buffer struct {
178         pos int
179         buf []byte
180 }
181
182 func (b *Buffer) Bytes() []byte {
183         return b.buf[:b.pos]
184 }
185
186 func (b *Buffer) EncodeUint8(v uint8) {
187         b.buf[b.pos] = v
188         b.pos += 1
189 }
190
191 func (b *Buffer) EncodeUint16(v uint16) {
192         order.PutUint16(b.buf[b.pos:b.pos+2], v)
193         b.pos += 2
194 }
195
196 func (b *Buffer) EncodeUint32(v uint32) {
197         order.PutUint32(b.buf[b.pos:b.pos+4], v)
198         b.pos += 4
199 }
200
201 func (b *Buffer) EncodeUint64(v uint64) {
202         order.PutUint64(b.buf[b.pos:b.pos+8], v)
203         b.pos += 8
204 }
205
206 func (b *Buffer) EncodeFloat64(v float64) {
207         order.PutUint64(b.buf[b.pos:b.pos+8], math.Float64bits(v))
208         b.pos += 8
209 }
210
211 func (b *Buffer) EncodeBool(v bool) {
212         if v {
213                 b.buf[b.pos] = 1
214         } else {
215                 b.buf[b.pos] = 0
216         }
217         b.pos += 1
218 }
219
220 func (b *Buffer) EncodeString(v string) {
221
222         b.pos += 1
223 }
224
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))
229 }