diff --git a/registry.go b/registry.go index 2984ed9..f64e1fd 100644 --- a/registry.go +++ b/registry.go @@ -77,16 +77,16 @@ func (rr *rpcRegistry) Invoke(codec protocol.RegistryCodec) (result interface{}, // Decode the args. var in []reflect.Value - params := methodSpec.getInterfaces() + pValues, pInstances := methodSpec.getParamValues() - if nil != params && 0 < len(params) { - if errRead := codec.ReadParams(¶ms); errRead != nil { + if nil != pInstances && 0 < len(pInstances) { + if errRead := codec.ReadParams(&pInstances); errRead != nil { return nil, errRead } - pCount := len(params) + pCount := len(pInstances) in = make([]reflect.Value, pCount+1) for indexI := 0; indexI < pCount; indexI++ { - in[indexI+1] = reflect.ValueOf(params[indexI]) + in[indexI+1] = pValues[indexI] } } else { in = make([]reflect.Value, 1) diff --git a/service_map.go b/service_map.go index 963833e..2c2b329 100644 --- a/service_map.go +++ b/service_map.go @@ -26,28 +26,41 @@ type service struct { } type serviceMethod struct { - method reflect.Method // receiver method - paramTypes []reflect.Type // type of the request argument - paramValues []reflect.Value - returnType reflect.Type // type of the response argument - returnValue reflect.Value + method reflect.Method // receiver method + paramTypes []reflect.Type // type of the request argument + returnType reflect.Type // type of the response argument } -func (sm *serviceMethod) getInterfaces() (instances []interface{}) { - if nil == sm.paramValues || 0 == len(sm.paramValues) { - return nil +func (sm *serviceMethod) getParamValues() (values []reflect.Value, instances []interface{}) { + if nil == sm.paramTypes || 0 == len(sm.paramTypes) { + return nil, nil } - pCount := len(sm.paramValues) + pCount := len(sm.paramTypes) + values = make([]reflect.Value, pCount) instances = make([]interface{}, pCount) for indexI := 0; indexI < pCount; indexI++ { - instances[indexI] = sm.paramValues[indexI].Interface() + values[indexI] = getValue(sm.paramTypes[indexI]) + instances[indexI] = values[indexI].Interface() } return } +func getValue(t reflect.Type) reflect.Value { + rt := t + if rt.Kind() == reflect.Ptr { + rt = rt.Elem() + } + + rv := reflect.New(rt) + if rt.Kind() != reflect.Struct { + rv = reflect.Indirect(rv) + } + return rv +} + // ---------------------------------------------------------------------------- // serviceMap // ---------------------------------------------------------------------------- @@ -90,20 +103,19 @@ Loop: } var paramTypes []reflect.Type - var paramValues []reflect.Value var returnType reflect.Type - var returnValue reflect.Value pCount := mt.NumIn() - 1 if 0 < pCount { paramTypes = make([]reflect.Type, pCount) - paramValues = make([]reflect.Value, pCount) for indexI := 0; indexI < pCount; indexI++ { - if paramTypes[indexI], paramValues[indexI], err = validateType(mt.In(indexI + 1)); nil != err { + pt := mt.In(indexI + 1) + if err = validateType(mt.In(indexI + 1)); nil != err { return err } + paramTypes[indexI] = pt } } @@ -120,19 +132,19 @@ Loop: if t := mt.Out(1); t != typeOfError { continue Loop } - if returnType, returnValue, err = validateType(mt.Out(0)); nil != err { + rt := mt.Out(0) + if err = validateType(rt); nil != err { return err } + returnType = rt default: continue } s.methods[m.Name] = &serviceMethod{ - method: m, - paramTypes: paramTypes, - paramValues: paramValues, - returnType: returnType, - returnValue: returnValue, + method: m, + paramTypes: paramTypes, + returnType: returnType, } } if len(s.methods) == 0 { @@ -150,21 +162,11 @@ Loop: return nil } -func validateType(t reflect.Type) (rt reflect.Type, rv reflect.Value, err error) { +func validateType(t reflect.Type) error { if t.Kind() == reflect.Struct { - err = fmt.Errorf("Type is Struct. Pass by reference, i.e. *%s", t) - return + return fmt.Errorf("Type is Struct. Pass by reference, i.e. *%s", t) } - rt = t - if t.Kind() == reflect.Ptr { - rt = t.Elem() - } - - rv = reflect.New(rt) - if rt.Kind() != reflect.Struct { - rv = reflect.Indirect(rv) - } - return + return nil } // get returns a registered service given a method name.