-
Notifications
You must be signed in to change notification settings - Fork 0
/
rpc_decode.go
84 lines (75 loc) · 2.11 KB
/
rpc_decode.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
package rpc
import (
"bytes"
"context"
"encoding/gob"
"errors"
reflect "reflect"
"github.com/fengqk/mars-base/base"
"github.com/golang/protobuf/proto"
)
// rpc UnmarshalHead
func UnmarshalHead(buff []byte) (*RpcPacket, RpcHead) {
nLen := base.Clamp(len(buff), 0, 256)
return Unmarshal(buff[:nLen])
}
func Unmarshal(buff []byte) (*RpcPacket, RpcHead) {
rpcPacket := &RpcPacket{}
proto.Unmarshal(buff, rpcPacket)
if rpcPacket.RpcHead == nil {
rpcPacket.RpcHead = &RpcHead{}
}
return rpcPacket, *(*RpcHead)(rpcPacket.RpcHead)
}
// rpc Unmarshal
// pFuncType for (this *X)func(conttext, params)
func UnmarshalBody(rpcPacket *RpcPacket, pFuncType reflect.Type) []interface{} {
nCurLen := pFuncType.NumIn()
params := make([]interface{}, nCurLen)
buf := bytes.NewBuffer(rpcPacket.RpcBody)
dec := gob.NewDecoder(buf)
for i := 1; i < nCurLen; i++ {
if i == 1 {
params[1] = context.WithValue(context.Background(), "rpcHead", *(*RpcHead)(rpcPacket.RpcHead))
continue
}
val := reflect.New(pFuncType.In(i))
if i < int(rpcPacket.ArgLen+2) {
dec.DecodeValue(val)
}
params[i] = val.Elem().Interface()
}
return params
}
func UnmarshalBodyCall(rpcPacket *RpcPacket, pFuncType reflect.Type) (error, []interface{}) {
strErr := ""
nCurLen := pFuncType.NumIn()
params := make([]interface{}, nCurLen)
buf := bytes.NewBuffer(rpcPacket.RpcBody)
dec := gob.NewDecoder(buf)
dec.Decode(&strErr)
if strErr != "" {
return errors.New(strErr), params
}
for i := 0; i < nCurLen; i++ {
if i == 0 {
params[0] = context.WithValue(context.Background(), "rpcHead", *(*RpcHead)(rpcPacket.RpcHead))
continue
}
val := reflect.New(pFuncType.In(i))
if i < int(rpcPacket.ArgLen+1) {
dec.DecodeValue(val)
}
params[i] = val.Elem().Interface()
}
return nil, params
}
// rpc UnmarshalPB
func unmarshalPB(bitstream *base.BitStream) (proto.Message, error) {
packetName := bitstream.ReadString()
nLen := bitstream.ReadInt(32)
packetBuf := bitstream.ReadBits(nLen << 3)
packet := reflect.New(proto.MessageType(packetName).Elem()).Interface().(proto.Message)
err := proto.Unmarshal(packetBuf, packet)
return packet, err
}