]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/xml: allow attributes stored in pointers to be marshaled.
authorDmitriy Shelenin <deemok@googlemail.com>
Thu, 8 Aug 2013 17:40:51 +0000 (10:40 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 8 Aug 2013 17:40:51 +0000 (10:40 -0700)
Fixes #5334.

R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/8653047

src/pkg/encoding/xml/marshal.go
src/pkg/encoding/xml/marshal_test.go

index 47b00176342facfab24d4b53416f961bb9420081..fae0f6a7322e05518116045e925019fd98fa5264 100644 (file)
@@ -271,7 +271,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error {
                        continue
                }
                fv := finfo.value(val)
-               if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
+               if (finfo.flags&fOmitEmpty != 0 || fv.Kind() == reflect.Ptr) && isEmptyValue(fv) {
                        continue
                }
                p.WriteByte(' ')
@@ -285,6 +285,11 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error {
                }
                p.WriteString(finfo.name)
                p.WriteString(`="`)
+               // Handle pointer values by following the pointer,
+               // Pointer is known to be non-nil because we called isEmptyValue above.
+               if fv.Kind() == reflect.Ptr {
+                       fv = fv.Elem()
+               }
                if err := p.marshalSimple(fv.Type(), fv); err != nil {
                        return err
                }
@@ -363,6 +368,10 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
                        continue
                }
                vf := finfo.value(val)
+               // Handle pointer values by following the pointer
+               if vf.Kind() == reflect.Ptr && !isEmptyValue(vf) {
+                       vf = vf.Elem()
+               }
                switch finfo.flags & fMode {
                case fCharData:
                        var scratch [64]byte
index ca14a1e53db14ae3f13f389424ce2e1a723c4602..fa2ba52a8fb7a5d9343041da9a51f2d610d376a9 100644 (file)
@@ -276,6 +276,25 @@ type Strings struct {
        X []string `xml:"A>B,omitempty"`
 }
 
+type PointerFieldsTest struct {
+       XMLName  Name    `xml:"dummy"`
+       Name     *string `xml:"name,attr"`
+       Age      *uint   `xml:"age,attr"`
+       Empty    *string `xml:"empty,attr"`
+       Contents *string `xml:",chardata"`
+}
+
+type ChardataEmptyTest struct {
+       XMLName  Name    `xml:"test"`
+       Contents *string `xml:",chardata"`
+}
+
+var (
+       nameAttr     = "Sarah"
+       ageAttr      = uint(12)
+       contentsAttr = "lorem ipsum"
+)
+
 // Unless explicitly stated as such (or *Plain), all of the
 // tests below are two-way tests. When introducing new tests,
 // please try to make them two-way as well to ensure that
@@ -673,6 +692,20 @@ var marshalTests = []struct {
                ExpectXML: `<OmitAttrTest></OmitAttrTest>`,
        },
 
+       // pointer fields
+       {
+               Value:       &PointerFieldsTest{Name: &nameAttr, Age: &ageAttr, Contents: &contentsAttr},
+               ExpectXML:   `<dummy name="Sarah" age="12">lorem ipsum</dummy>`,
+               MarshalOnly: true,
+       },
+
+       // empty chardata pointer field
+       {
+               Value:       &ChardataEmptyTest{},
+               ExpectXML:   `<test></test>`,
+               MarshalOnly: true,
+       },
+
        // omitempty on fields
        {
                Value: &OmitFieldTest{