Commit 2427123d authored by Russ Cox's avatar Russ Cox

encoding/xml: split attribute marshaling into its own method

No functional changes here. Just makes next CL easier to read.

Change-Id: Icf7b2281b4da6cb59ff4edff05943b2ee288576a
Reviewed-on: https://go-review.googlesource.com/30945
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 26c7b4fb
...@@ -494,7 +494,6 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat ...@@ -494,7 +494,6 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
continue continue
} }
fv := finfo.value(val) fv := finfo.value(val)
name := Name{Space: finfo.xmlns, Local: finfo.name}
if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) { if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
continue continue
...@@ -504,19 +503,54 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat ...@@ -504,19 +503,54 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
continue continue
} }
if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) { name := Name{Space: finfo.xmlns, Local: finfo.name}
attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name) if err := p.marshalAttr(&start, name, fv); err != nil {
return err
}
}
if err := p.writeStart(&start); err != nil {
return err
}
if val.Kind() == reflect.Struct {
err = p.marshalStruct(tinfo, val)
} else {
s, b, err1 := p.marshalSimple(typ, val)
if err1 != nil {
err = err1
} else if b != nil {
EscapeText(p, b)
} else {
p.EscapeString(s)
}
}
if err != nil {
return err
}
if err := p.writeEnd(start.Name); err != nil {
return err
}
return p.cachedWriteError()
}
// marshalAttr marshals an attribute with the given name and value, adding to start.Attr.
func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value) error {
if val.CanInterface() && val.Type().Implements(marshalerAttrType) {
attr, err := val.Interface().(MarshalerAttr).MarshalXMLAttr(name)
if err != nil { if err != nil {
return err return err
} }
if attr.Name.Local != "" { if attr.Name.Local != "" {
start.Attr = append(start.Attr, attr) start.Attr = append(start.Attr, attr)
} }
continue return nil
} }
if fv.CanAddr() { if val.CanAddr() {
pv := fv.Addr() pv := val.Addr()
if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) { if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name) attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
if err != nil { if err != nil {
...@@ -525,41 +559,41 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat ...@@ -525,41 +559,41 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
if attr.Name.Local != "" { if attr.Name.Local != "" {
start.Attr = append(start.Attr, attr) start.Attr = append(start.Attr, attr)
} }
continue return nil
} }
} }
if fv.CanInterface() && fv.Type().Implements(textMarshalerType) { if val.CanInterface() && val.Type().Implements(textMarshalerType) {
text, err := fv.Interface().(encoding.TextMarshaler).MarshalText() text, err := val.Interface().(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
return err return err
} }
start.Attr = append(start.Attr, Attr{name, string(text)}) start.Attr = append(start.Attr, Attr{name, string(text)})
continue return nil
} }
if fv.CanAddr() { if val.CanAddr() {
pv := fv.Addr() pv := val.Addr()
if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
text, err := pv.Interface().(encoding.TextMarshaler).MarshalText() text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
return err return err
} }
start.Attr = append(start.Attr, Attr{name, string(text)}) start.Attr = append(start.Attr, Attr{name, string(text)})
continue return nil
} }
} }
// Dereference or skip nil pointer, interface values. // Dereference or skip nil pointer, interface values.
switch fv.Kind() { switch val.Kind() {
case reflect.Ptr, reflect.Interface: case reflect.Ptr, reflect.Interface:
if fv.IsNil() { if val.IsNil() {
continue return nil
} }
fv = fv.Elem() val = val.Elem()
} }
s, b, err := p.marshalSimple(fv.Type(), fv) s, b, err := p.marshalSimple(val.Type(), val)
if err != nil { if err != nil {
return err return err
} }
...@@ -567,33 +601,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat ...@@ -567,33 +601,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
s = string(b) s = string(b)
} }
start.Attr = append(start.Attr, Attr{name, s}) start.Attr = append(start.Attr, Attr{name, s})
} return nil
if err := p.writeStart(&start); err != nil {
return err
}
if val.Kind() == reflect.Struct {
err = p.marshalStruct(tinfo, val)
} else {
s, b, err1 := p.marshalSimple(typ, val)
if err1 != nil {
err = err1
} else if b != nil {
EscapeText(p, b)
} else {
p.EscapeString(s)
}
}
if err != nil {
return err
}
if err := p.writeEnd(start.Name); err != nil {
return err
}
return p.cachedWriteError()
} }
// defaultStart returns the default start element to use, // defaultStart returns the default start element to use,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment