-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathcallback.go
48 lines (42 loc) · 1.07 KB
/
callback.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
package socketio
import (
"reflect"
)
type callback struct {
fn reflect.Value
args []reflect.Type
}
func newCallback(fn interface{}) *callback {
v := reflect.ValueOf(fn)
if v.Kind() != reflect.Func {
panic("invalid callback function")
}
t := v.Type()
args := make([]reflect.Type, t.NumIn())
for i := 0; i < t.NumIn(); i++ {
switch t.In(i).Kind() {
case reflect.Invalid, reflect.Chan, reflect.Func, reflect.UnsafePointer:
panic("invalid callback argument " + t.In(i).String())
}
args[i] = t.In(i)
}
return &callback{fn: v, args: args}
}
func (e *callback) Call(so Socket, au ArgsUnmarshaler, data []byte, buffer [][]byte) ([]reflect.Value, error) {
in, err := au.UnmarshalArgs(e.args, data, buffer)
if err != nil {
return nil, err
}
soval := reflect.ValueOf(so)
for i, typ := range e.args {
if isTypeSocket(typ) {
in[i] = soval
}
}
if e.fn.Type().IsVariadic() {
return e.fn.CallSlice(in), nil
}
return e.fn.Call(in), nil
}
var socketType = reflect.TypeOf((*Socket)(nil)).Elem()
func isTypeSocket(t reflect.Type) bool { return t == socketType }