예제 #1
0
// 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
}
예제 #2
0
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())
			}
		}
	}
}
예제 #3
0
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())
			}
		}
	}
}