-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathproto.go
123 lines (97 loc) · 2.25 KB
/
proto.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package marionette_client
import (
"encoding/json"
"errors"
"fmt"
"log"
"strconv"
)
func NewDecoderEncoder(protoVersion int32) (DecoderEncoder, error) {
if protoVersion == MARIONETTE_PROTOCOL_V3 {
return ProtoV3DecoderEncoder{}, nil
}
m := fmt.Sprintf("No DecoderEncoder found for the specified version : %v", protoVersion)
return nil, errors.New(m)
}
type Decoder interface {
Decode(buf []byte, r *Response) error
}
type Encoder interface {
Encode(t Transporter, command string, values interface{}) ([]byte, error)
}
type DecoderEncoder interface {
Decoder
Encoder
}
type ProtoV3DecoderEncoder struct{}
func (e ProtoV3DecoderEncoder) Encode(t Transporter, command string, values interface{}) ([]byte, error) {
message := make([]interface{}, 4)
message[0] = 0
message[1] = t.MessageID()
message[2] = command
message[3] = values
b, err := json.Marshal(message)
if err != nil {
return nil, err
}
if RunningInDebugMode {
fmt.Println(string(b))
}
return []byte(strconv.Itoa(len(b)) + ":" + string(b)), nil
}
func (e ProtoV3DecoderEncoder) Decode(buf []byte, r *Response) error {
var v []interface{}
if err := json.Unmarshal(buf, &v); err != nil {
return err
}
//Debug only
if RunningInDebugMode {
if len(buf) >= 512 {
log.Println(string(buf)[0:256] + " - END - " + string(buf)[len(buf)-256:])
} else {
log.Println(string(buf))
}
}
//Debug only end
r.MessageID = int32(v[1].(float64))
r.Size = int32(len(buf))
// error found on response?
if v[2] != nil {
re := &DriverError{}
for key, value := range v[2].(map[string]interface{}) {
if key == "error" {
re.ErrorType = value.(string)
}
if key == "message" {
re.Message = value.(string)
}
if key == "stacktrace" && value != nil {
theTrace := value.(string)
re.Stacktrace = &theTrace
}
}
return re
}
// It's a JSON Object
result, found := v[3].(map[string]interface{})
if found {
resultBytes, err := json.Marshal(result)
if err != nil {
return err
}
r.Value = string(resultBytes)
}
if !found {
// JSON Array
result, found := v[3].([]interface{})
if found {
resultBytes, err := json.Marshal(result)
if err != nil {
return err
}
r.Value = string(resultBytes)
}
//TODO: return error?
}
return nil
}