-
Notifications
You must be signed in to change notification settings - Fork 2
/
kodec.go
109 lines (97 loc) · 1.96 KB
/
kodec.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
* common codec library for chat application
*/
package kodec
import (
"fmt"
"github.com/golang/protobuf/proto"
)
const (
BAG_ID_MSG byte = iota //bag id in for message
BAG_ID_CMD
BAG_ID_ACK
)
func BuildAck(id string) *Ack {
m := &Ack{
Id: &id,
}
return m
}
func BuildCmd(tp Cmd_Type, desc string, tick int64) *Cmd {
m := &Cmd{
Tp: &tp,
Txt: proto.String(desc),
Ct: proto.Int64(tick),
}
return m
}
func BuildMeta(tp Meta_Type, txt string) *Meta {
m := &Meta{
Tp: &tp,
Txt: proto.String(txt),
}
return m
}
func BuildMessage(from int, to string, data []byte, tp Msg_Type, tick int64) *Msg {
m := &Msg{
From: proto.Int64(int64(from)),
To: proto.String(to),
Tp: &tp,
D: data,
Ct: proto.Int64(tick),
}
return m
}
func SetMessageId(m *Msg, id string) {
m.Id = proto.String(id)
}
func Boxing(m proto.Message) ([]byte, error) {
b, err := proto.Marshal(m)
if err != nil {
return nil, err
}
var bagId byte
switch m.(type) {
case *Msg:
bagId = BAG_ID_MSG
case *Cmd:
bagId = BAG_ID_CMD
case *Ack:
bagId = BAG_ID_ACK
default:
return nil, fmt.Errorf("unknown frame")
}
return append([]byte{bagId}, b...), nil
}
func Unboxing(data []byte) (interface{}, error) {
if len(data) < 1 {
return nil, fmt.Errorf("warning: bad frame")
}
bagId := data[0]
data = data[1:]
switch bagId {
case BAG_ID_MSG:
if len(data) < 1 {
return nil, fmt.Errorf("warning: bad message frame")
}
upMsg := new(Msg)
if err := proto.Unmarshal(data, upMsg); err != nil {
return nil, fmt.Errorf("parse msg err %v", err)
}
return upMsg, nil
case BAG_ID_ACK:
ack := new(Ack)
if err := proto.Unmarshal(data, ack); err != nil {
return nil, fmt.Errorf("parse ack err %v", err)
}
return ack, nil
case BAG_ID_CMD:
cmd := new(Cmd)
if err := proto.Unmarshal(data, cmd); err != nil {
return nil, fmt.Errorf("parse cmd err %v", err)
}
return cmd, nil
default:
return nil, fmt.Errorf("warning: unknown bag id: %v", bagId)
}
}