Просмотр исходного кода

Fix a couple of bugs reported by Roger.

Gustavo Niemeyer 13 лет назад
Родитель
Сommit
4d6bb54d8a
3 измененных файлов с 31 добавлено и 15 удалено
  1. 2 2
      encode.go
  2. 23 0
      encode_test.go
  3. 6 13
      goyaml.go

+ 2 - 2
encode.go

@@ -142,8 +142,8 @@ func (e *encoder) structv(tag string, in reflect.Value) {
 		panic(err)
 	}
 	e.mappingv(tag, func() {
-		for i, info := range fields.List {
-			value := in.Field(i)
+		for _, info := range fields.List {
+			value := in.Field(info.Num)
 			if info.OmitEmpty && isZero(value) {
 				continue
 			}

+ 23 - 0
encode_test.go

@@ -97,6 +97,13 @@ var marshalTests = []struct {
 				B string
 			} "a,flow"
 		}{struct{ B string }{"c"}}},
+
+	// Unexported field
+	{"a: 1\n",
+		&struct {
+			u int
+			A int
+		}{0, 1}},
 }
 
 func (s *S) TestMarshal(c *C) {
@@ -141,6 +148,22 @@ var getterTests = []struct {
 	{"_: !foo\n  a: B\n", "!foo", &marshalTaggedIfaceTest},
 }
 
+func (s *S) TestMarshalTypeCache(c *C) {
+	var data []byte
+	var err error
+	func() {
+		type T struct{ A int }
+		data, err = goyaml.Marshal(&T{})
+		c.Assert(err, IsNil)
+	}()
+	func() {
+		type T struct{ B int }
+		data, err = goyaml.Marshal(&T{})
+		c.Assert(err, IsNil)
+	}()
+	c.Assert(string(data), Equals, "b: 0\n")
+}
+
 type typeWithGetter struct {
 	tag   string
 	value interface{}

+ 6 - 13
goyaml.go

@@ -129,7 +129,7 @@ func Unmarshal(in []byte, out interface{}) (err error) {
 //     goyaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
 //
 func Marshal(in interface{}) (out []byte, err error) {
-	defer handleErr(&err)
+	//defer handleErr(&err)
 	e := newEncoder()
 	defer e.destroy()
 	e.marshal("", reflect.ValueOf(in))
@@ -155,7 +155,7 @@ type fieldInfo struct {
 	Flow      bool
 }
 
-var fieldMap = make(map[string]*structFields)
+var fieldMap = make(map[reflect.Type]*structFields)
 var fieldMapMutex sync.RWMutex
 
 type externalPanic string
@@ -165,12 +165,8 @@ func (e externalPanic) String() string {
 }
 
 func getStructFields(st reflect.Type) (*structFields, error) {
-	path := st.PkgPath()
-	name := st.Name()
-
-	fullName := path + "." + name
 	fieldMapMutex.RLock()
-	fields, found := fieldMap[fullName]
+	fields, found := fieldMap[st]
 	fieldMapMutex.RUnlock()
 	if found {
 		return fields, nil
@@ -243,12 +239,9 @@ func getStructFields(st reflect.Type) (*structFields, error) {
 
 	fields = &structFields{fieldsMap, fieldsList[:len(fieldsMap)]}
 
-	if fullName != "." {
-		fieldMapMutex.Lock()
-		fieldMap[fullName] = fields
-		fieldMapMutex.Unlock()
-	}
-
+	fieldMapMutex.Lock()
+	fieldMap[st] = fields
+	fieldMapMutex.Unlock()
 	return fields, nil
 }