浏览代码

marshal: fix nil colleciton handling

Nil collections should be marshalled to an empty collection, ie
a collection with 0 elements, it can not be encoded with -1 length
which indicates a null value.
Chris Bannister 10 年之前
父节点
当前提交
65ce6c1437
共有 2 个文件被更改,包括 14 次插入13 次删除
  1. 10 9
      marshal.go
  2. 4 4
      marshal_test.go

+ 10 - 9
marshal.go

@@ -43,9 +43,6 @@ type Unmarshaler interface {
 // Marshal returns the CQL encoding of the value for the Cassandra
 // internal type described by the info parameter.
 func Marshal(info TypeInfo, value interface{}) ([]byte, error) {
-	if value == nil {
-		return nil, nil
-	}
 	if info.Version() < protoVersion1 {
 		panic("protocol version not set")
 	}
@@ -290,7 +287,16 @@ func marshalInt(info TypeInfo, value interface{}) ([]byte, error) {
 		}
 		return encInt(int32(i)), nil
 	}
+
+	if value == nil {
+		return nil, nil
+	}
+
 	rv := reflect.ValueOf(value)
+	if rv.IsNil() {
+		return nil, nil
+	}
+
 	switch rv.Type().Kind() {
 	case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8:
 		v := rv.Int()
@@ -881,9 +887,6 @@ func marshalList(info TypeInfo, value interface{}) ([]byte, error) {
 	k := t.Kind()
 	switch k {
 	case reflect.Slice, reflect.Array:
-		if k == reflect.Slice && rv.IsNil() {
-			return nil, nil
-		}
 		buf := &bytes.Buffer{}
 		n := rv.Len()
 
@@ -989,9 +992,7 @@ func marshalMap(info TypeInfo, value interface{}) ([]byte, error) {
 	if t.Kind() != reflect.Map {
 		return nil, marshalErrorf("can not marshal %T into %s", value, info)
 	}
-	if rv.IsNil() {
-		return nil, nil
-	}
+
 	buf := &bytes.Buffer{}
 	n := rv.Len()
 

+ 4 - 4
marshal_test.go

@@ -257,8 +257,8 @@ var marshalTests = []struct {
 			NativeType: NativeType{proto: 2, typ: TypeSet},
 			Elem:       NativeType{proto: 2, typ: TypeInt},
 		},
-		[]byte(nil),
-		[]int(nil),
+		[]byte{0, 0}, // encoding of a list should always include the size of the collection
+		[]int{},
 	},
 	{
 		CollectionType{
@@ -275,8 +275,8 @@ var marshalTests = []struct {
 			Key:        NativeType{proto: 2, typ: TypeVarchar},
 			Elem:       NativeType{proto: 2, typ: TypeInt},
 		},
-		[]byte(nil),
-		map[string]int(nil),
+		[]byte{0, 0},
+		map[string]int{},
 	},
 	{
 		CollectionType{