// MsgPackEncode encode a reflect.Value value in enc. func MsgPackEncode(enc *msgpack.Encoder, arg reflect.Value) error { var err error if arg.Kind() == reflect.Func { err = enc.Encode(Func) if err != nil { return e.Forward(err) } return nil } if !arg.IsValid() { err = enc.Encode(NotValid) if err != nil { return e.Forward(err) } return nil } err = enc.Encode(Valid) if err != nil { return e.Forward(err) } if (arg.Kind() == reflect.Interface || arg.Kind() == reflect.Map || arg.Kind() == reflect.Ptr || arg.Kind() == reflect.Slice) && arg.IsNil() { err = enc.Encode(ArgNil) if err != nil { return e.Forward(err) } t, err := TypeOf(arg) // Hum, arg.IsValid(). Why not? if err != nil { err = enc.Encode(ZeroArg) if err != nil { return e.Forward(err) } return nil } err = enc.Encode(NoZeroArg) if err != nil { return e.Forward(err) } err = enc.Encode(types.NameOf(t)) if err != nil { return e.Forward(err) } return nil } err = enc.Encode(NotNil) if err != nil { return e.Forward(err) } if zero.IsZero(arg) { err = enc.Encode(ZeroArg) if err != nil { return e.Forward(err) } err = enc.Encode(NameOf(arg)) if err != nil { return e.Forward(err) } return nil } err = enc.Encode(NoZeroArg) if err != nil { return e.Forward(err) } switch v := arg.Interface().(type) { case *e.Error: err := enc.Encode(ArgNormal) if err != nil { return e.Forward(err) } err = enc.Encode(NameOf(arg)) if err != nil { return e.Forward(err) } err = enc.EncodeValue(Strip(arg)) if err != nil { return e.Forward(err) } case error: err := enc.Encode(ArgError) if err != nil { return e.Forward(err) } err = enc.Encode(v.Error()) if err != nil { return e.Forward(err) } default: err := enc.Encode(ArgNormal) if err != nil { return e.Forward(err) } err = enc.Encode(NameOf(arg)) if err != nil { return e.Forward(err) } err = enc.EncodeValue(Strip(arg)) if err != nil { return e.Forward(err) } } return nil }
func TestReqCall(t *testing.T) { var nilstruct *reqCall var err error str := "string" //var inil interface{} = nilstruct var istr interface{} = str var ipstr interface{} = &str emptySlice := make([]int, 0) types.Insert(make([]int, 0)) s := &strct{} types.Insert(s) tests := []*reqCall{ {"", nil}, {"oi", []reflect.Value{}}, {"oi", []reflect.Value{reflect.ValueOf(nilstruct)}}, {"oi", []reflect.Value{reflect.ValueOf(err)}}, {"oi", []reflect.Value{reflect.ValueOf(e.New("oi"))}}, {"oi", []reflect.Value{reflect.ValueOf(errors.New("oi"))}}, {"oi", []reflect.Value{reflect.ValueOf(1)}}, {"oi", []reflect.Value{reflect.ValueOf("string")}}, //{"oi", []reflect.Value{reflect.ValueOf(&str)}}, //{"oi", []reflect.Value{reflect.ValueOf(inil)}}, {"oi", []reflect.Value{reflect.ValueOf(istr)}}, {"oi", []reflect.Value{reflect.ValueOf(ipstr)}}, {"oi", []reflect.Value{reflect.ValueOf(s)}}, {"oi", []reflect.Value{reflect.ValueOf(emptySlice)}}, } for i, test := range tests { buf := bytes.NewBuffer([]byte{}) enc := msgpack.NewEncoder(buf) dec := msgpack.NewDecoder(buf) err := enc.Encode(test) if err != nil { t.Fatal(i, e.Trace(e.Forward(err))) } var req reqCall err = dec.Decode(&req) if err != nil { t.Fatal(i, e.Trace(e.Forward(err))) } if req.Method != test.Method { t.Fatal("method not equal") } if len(req.Args) != len(test.Args) { t.Fatal("num of args not equal") } for ii, arg := range req.Args { if zero.IsZero(arg) != zero.IsZero(test.Args[ii]) { t.Fatal("arg differ", i, ii, zero.IsZero(arg), zero.IsZero(test.Args[ii])) } if zero.IsZero(arg) { continue } if arg.IsValid() != test.Args[ii].IsValid() { t.Fatal("valid differ") } if !arg.IsValid() { continue } if test.Args[ii].Kind() == reflect.Interface || test.Args[ii].Kind() == reflect.Map || test.Args[ii].Kind() == reflect.Ptr || test.Args[ii].Kind() == reflect.Slice { if arg.IsNil() != test.Args[ii].IsNil() { t.Fatal("arg differ", i, arg.IsNil(), test.Args[ii].IsNil()) } if arg.IsNil() { continue } } if _, ok := arg.Interface().(*e.Error); !ok && !reflect.DeepEqual(arg.Interface(), test.Args[ii].Interface()) { t.Fatalf("Fail to encode and decode %v %#v %#v", i, arg.Interface(), test.Args[ii].Interface()) } } } }
func TestRespCall(t *testing.T) { tests := []*respCall{ {nil, nil}, {e.New("oi"), nil}, {errors.New("oi"), nil}, {nil, []reflect.Value{reflect.ValueOf(error(nil))}}, {nil, []reflect.Value{reflect.ValueOf("db/blog/blog")}}, } for i, test := range tests { buf := bytes.NewBuffer([]byte{}) enc := msgpack.NewEncoder(buf) dec := msgpack.NewDecoder(buf) err := enc.Encode(test) if err != nil { t.Fatal(i, e.Trace(e.Forward(err))) } var resp respCall err = dec.Decode(&resp) if err != nil { t.Fatal(i, e.Trace(e.Forward(err))) } if resp.Err == nil && test.Err == nil { continue } fmt.Println(i) fmt.Printf("%#v\n", resp) if resp.Err.Error() != test.Err.Error() { t.Fatal("method not equal") } if len(resp.Vals) != len(test.Vals) { t.Fatal("num of args not equal") } for ii, arg := range resp.Vals { if zero.IsZero(arg) != zero.IsZero(test.Vals[ii]) { t.Fatal("arg differ", zero.IsZero(arg), zero.IsZero(test.Vals[ii])) } if zero.IsZero(arg) { continue } if arg.IsValid() != test.Vals[ii].IsValid() { t.Fatal("valid differ") } if !arg.IsValid() { continue } if test.Vals[ii].Kind() == reflect.Interface || test.Vals[ii].Kind() == reflect.Map || test.Vals[ii].Kind() == reflect.Ptr || test.Vals[ii].Kind() == reflect.Slice { if arg.IsNil() != test.Vals[ii].IsNil() { t.Fatal("arg differ") } if arg.IsNil() { continue } } if !reflect.DeepEqual(arg.Interface(), test.Vals[ii].Interface()) { t.Fatalf("Fail to encode and decode %v %#v %#v", i, arg.Interface(), test.Vals[ii].Interface()) } } } }