浏览代码

marshall: allow missing fields in UDT structs (#957)

Allow unmarshalling UDT's into structs which do not contain all the
fields in the UDT.

Tidy up unmarshallUDT a little.
Chris Bannister 8 年之前
父节点
当前提交
44be8dc52e
共有 1 个文件被更改,包括 16 次插入15 次删除
  1. 16 15
      marshal.go

+ 16 - 15
marshal.go

@@ -21,7 +21,8 @@ import (
 )
 
 var (
-	bigOne = big.NewInt(1)
+	bigOne     = big.NewInt(1)
+	emptyValue reflect.Value
 )
 
 var (
@@ -1927,8 +1928,16 @@ func unmarshalUDT(info TypeInfo, data []byte, value interface{}) error {
 		return unmarshalErrorf("cannot unmarshal %s into %T", info, value)
 	}
 
-	fields := make(map[string]reflect.Value)
+	if len(data) == 0 {
+		if k.CanSet() {
+			k.Set(reflect.Zero(k.Type()))
+		}
+
+		return nil
+	}
+
 	t := k.Type()
+	fields := make(map[string]reflect.Value, t.NumField())
 	for i := 0; i < t.NumField(); i++ {
 		sf := t.Field(i)
 
@@ -1937,14 +1946,6 @@ func unmarshalUDT(info TypeInfo, data []byte, value interface{}) error {
 		}
 	}
 
-	if len(data) == 0 {
-		if k.CanSet() {
-			k.Set(reflect.Zero(k.Type()))
-		}
-
-		return nil
-	}
-
 	udt := info.(UDTTypeInfo)
 	for _, e := range udt.Elements {
 		if len(data) < 4 {
@@ -1955,11 +1956,15 @@ func unmarshalUDT(info TypeInfo, data []byte, value interface{}) error {
 		size := readInt(data[:4])
 		data = data[4:]
 
-		var err error
 		if size >= 0 {
 			f, ok := fields[e.Name]
 			if !ok {
 				f = k.FieldByName(e.Name)
+				if f == emptyValue {
+					// skip fields which exist in the UDT but not in
+					// the struct passed in
+					continue
+				}
 			}
 
 			if !f.IsValid() || !f.CanAddr() {
@@ -1972,10 +1977,6 @@ func unmarshalUDT(info TypeInfo, data []byte, value interface{}) error {
 			}
 			data = data[size:]
 		}
-
-		if err != nil {
-			return err
-		}
 	}
 
 	return nil