-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathconvert.go
103 lines (75 loc) · 2.01 KB
/
convert.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
package gosocketio
import (
"encoding/json"
"fmt"
"reflect"
"github.com/wedeploy/gosocketio/internal/protocol"
)
func (h *Handler) getFunctionCallArgs(msg *protocol.Message) (is []interface{}, err error) {
is = []interface{}{}
if len(h.args) == 0 {
is = append(is, &struct{}{})
return is, nil
}
var parts []json.RawMessage
if err := jsonUnmarshalUnpanic(msg.Data, &parts); err != nil {
return nil, err
}
funcArgs := h.Args()
if len(funcArgs) > len(parts) {
return is, ErrorInvalidInterface{
method: msg.Method,
reason: fmt.Sprintf("message has %d arguments, but listener requires at least %d", len(funcArgs), len(parts)),
}
}
handledArguments := len(parts)
// cap the number of handled parameters to what the function can handle
if len(funcArgs) < handledArguments && !h.Variadic {
handledArguments = len(funcArgs)
}
funcsArgsNum := len(funcArgs)
for c := 0; c < handledArguments; c++ {
if h.Variadic && c == funcsArgsNum-1 {
variadic := parts[funcsArgsNum-1:]
vis, err := getVariadicFunctionCallArgs(variadic, funcArgs[funcsArgsNum-1])
if err != nil {
return nil, err
}
is = append(is, vis...)
break
}
if err := jsonUnmarshalUnpanic(parts[c], &funcArgs[c]); err != nil {
return nil, err
}
is = append(is, funcArgs[c])
}
return is, nil
}
func getVariadicFunctionCallArgs(variadic []json.RawMessage, funcArg interface{}) (vis []interface{}, err error) {
var vp = []byte("[")
for l, value := range variadic {
vp = append(vp, value...)
if l != len(variadic)-1 {
vp = append(vp, ',')
}
}
vp = append(vp, ']')
if err := jsonUnmarshalUnpanic(vp, &funcArg); err != nil {
return nil, err
}
elems := reflect.ValueOf(funcArg).Elem()
lenFuncArg := elems.Len()
for c := 0; c < lenFuncArg; c++ {
addElem := elems.Index(c)
vis = append(vis, addElem)
}
return vis, nil
}
func jsonUnmarshalUnpanic(data []byte, v interface{}) (err error) {
defer func() {
if r := recover(); r != nil {
err = r.(error)
}
}()
return json.Unmarshal(data, v)
}