--- a/structs.go Fri Dec 30 18:25:08 2011 -0700
+++ b/structs.go Fri Dec 30 21:49:00 2011 -0700
@@ -95,6 +95,11 @@
XError() *Error
// A (non-error) nested element, if any.
XChild() *Generic
+ innerxml() string
+}
+
+type ExtendedStanza interface {
+ InnerMarshal(io.Writer) os.Error
}
// message stanza
@@ -104,6 +109,7 @@
Id string `xml:"attr"`
Type string `xml:"attr"`
Lang string `xml:"attr"`
+ Innerxml string `xml:"innerxml"`
Error *Error
Subject *Generic
Body *Generic
@@ -112,6 +118,7 @@
}
var _ xml.Marshaler = &Message{}
var _ Stanza = &Message{}
+var _ ExtendedStanza = &Message{}
// presence stanza
type Presence struct {
@@ -120,6 +127,7 @@
Id string `xml:"attr"`
Type string `xml:"attr"`
Lang string `xml:"attr"`
+ Innerxml string `xml:"innerxml"`
Error *Error
Show *Generic
Status *Generic
@@ -128,6 +136,7 @@
}
var _ xml.Marshaler = &Presence{}
var _ Stanza = &Presence{}
+var _ ExtendedStanza = &Presence{}
// iq stanza
type Iq struct {
@@ -136,30 +145,13 @@
Id string `xml:"attr"`
Type string `xml:"attr"`
Lang string `xml:"attr"`
+ Innerxml string `xml:"innerxml"`
Error *Error
Any *Generic
- Query *RosterQuery
}
var _ xml.Marshaler = &Iq{}
var _ Stanza = &Iq{}
-// Roster query/result
-type RosterQuery struct {
- // Should always be query in the NsRoster namespace
- XMLName xml.Name
- Item []RosterItem
-}
-
-// See RFC 3921, Section 7.1.
-type RosterItem struct {
- // Should always be "item"
- XMLName xml.Name
- Jid string `xml:"attr"`
- Subscription string `xml:"attr"`
- Name string `xml:"attr"`
- Group []string
-}
-
// Describes an XMPP stanza error. See RFC 3920, Section 9.3.
type Error struct {
// The error type attribute.
@@ -282,8 +274,6 @@
u.XMLName.Local)
}
-// BUG(cjyar) This is fragile. We should find a way to use go's native
-// XML marshaling.
func marshalXML(st Stanza) ([]byte, os.Error) {
buf := bytes.NewBuffer(nil)
buf.WriteString("<")
@@ -304,15 +294,22 @@
writeField(buf, "xml:lang", st.XLang())
}
buf.WriteString(">")
- if st.XError() != nil {
- bytes, _ := st.XError().MarshalXML()
- buf.WriteString(string(bytes))
- }
- if st.XChild() != nil {
- xml.Marshal(buf, st.XChild())
- }
- if iq, ok := st.(*Iq) ; ok && iq.Query != nil {
- xml.Marshal(buf, iq.Query)
+ if ext, ok := st.(ExtendedStanza) ; ok {
+ if st.XError() != nil {
+ bytes, _ := st.XError().MarshalXML()
+ buf.WriteString(string(bytes))
+ }
+ err := ext.InnerMarshal(buf)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ inner := st.innerxml()
+ if inner == "" {
+ xml.Marshal(buf, st.XChild())
+ } else {
+ buf.WriteString(st.innerxml())
+ }
}
buf.WriteString("</")
buf.WriteString(st.XName())
@@ -369,10 +366,30 @@
return m.Any
}
+func (m *Message) innerxml() string {
+ return m.Innerxml
+}
+
func (m *Message) MarshalXML() ([]byte, os.Error) {
return marshalXML(m)
}
+func (m *Message) InnerMarshal(w io.Writer) os.Error {
+ err := xml.Marshal(w, m.Subject)
+ if err != nil {
+ return err
+ }
+ err = xml.Marshal(w, m.Body)
+ if err != nil {
+ return err
+ }
+ err = xml.Marshal(w, m.Thread)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
func (p *Presence) XName() string {
return "presence"
}
@@ -405,10 +422,30 @@
return p.Any
}
+func (p *Presence) innerxml() string {
+ return p.Innerxml
+}
+
func (p *Presence) MarshalXML() ([]byte, os.Error) {
return marshalXML(p)
}
+func (p *Presence) InnerMarshal(w io.Writer) os.Error {
+ err := xml.Marshal(w, p.Show)
+ if err != nil {
+ return err
+ }
+ err = xml.Marshal(w, p.Status)
+ if err != nil {
+ return err
+ }
+ err = xml.Marshal(w, p.Priority)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
func (iq *Iq) XName() string {
return "iq"
}
@@ -441,6 +478,10 @@
return iq.Any
}
+func (iq *Iq) innerxml() string {
+ return iq.Innerxml
+}
+
func (iq *Iq) MarshalXML() ([]byte, os.Error) {
return marshalXML(iq)
}