diff -r 48be1ae93fd4 -r 122ab6208c3c structs.go --- a/structs.go Tue Dec 27 15:36:07 2011 -0700 +++ b/structs.go Tue Dec 27 20:42:44 2011 -0700 @@ -21,9 +21,10 @@ // entities. It looks like node@domain/resource. Node and resource are // sometimes optional. type JID struct { + // TODO Make this not a pointer. Node *string Domain string - Resource *string + Resource string } var _ fmt.Stringer = &JID{} var _ flag.Value = &JID{} @@ -61,6 +62,7 @@ type Features struct { Starttls *starttls Mechanisms mechs + Bind *Unrecognized } type starttls struct { @@ -79,8 +81,64 @@ Any *Unrecognized } +type Stanza interface { + XName() string + XTo() string + XFrom() string + XId() string + XType() string + XLang() string + XError() *Error + XChild() *Unrecognized +} + +type Message struct { + To string `xml:"attr"` + From string `xml:"attr"` + Id string `xml:"attr"` + Type string `xml:"attr"` + Lang string `xml:"attr"` + Error *Error + Any *Unrecognized +} +var _ xml.Marshaler = &Message{} +var _ Stanza = &Message{} + +type Presence struct { + To string `xml:"attr"` + From string `xml:"attr"` + Id string `xml:"attr"` + Type string `xml:"attr"` + Lang string `xml:"attr"` + Error *Error + Any *Unrecognized +} +var _ xml.Marshaler = &Presence{} +var _ Stanza = &Presence{} + +type Iq struct { + To string `xml:"attr"` + From string `xml:"attr"` + Id string `xml:"attr"` + Type string `xml:"attr"` + Lang string `xml:"attr"` + Error *Error + Any *Unrecognized +} +var _ xml.Marshaler = &Iq{} +var _ Stanza = &Iq{} + +type Error struct { + Type string `xml:"attr"` + Any *Unrecognized +} +var _ xml.Marshaler = &Error{} + +// TODO Rename this to something like Generic. type Unrecognized struct { XMLName xml.Name + Any *Unrecognized + Chardata string `xml:"chardata"` } var _ fmt.Stringer = &Unrecognized{} @@ -89,8 +147,8 @@ if jid.Node != nil { result = *jid.Node + "@" + result } - if jid.Resource != nil { - result = result + "/" + *jid.Resource + if jid.Resource != "" { + result = result + "/" + jid.Resource } return result } @@ -107,11 +165,7 @@ jid.Node = &parts[2] } jid.Domain = parts[3] - if parts[5] == "" { - jid.Resource = nil - } else { - jid.Resource = &parts[5] - } + jid.Resource = parts[5] return true } @@ -187,6 +241,164 @@ } func (u *Unrecognized) String() string { - return fmt.Sprintf("unrecognized{%s %s}", u.XMLName.Space, + var sub string + if u.Any != nil { + sub = u.Any.String() + } + return fmt.Sprintf("<%s %s>%s%s", u.XMLName.Space, + u.XMLName.Local, sub, u.Chardata, u.XMLName.Space, u.XMLName.Local) } + +func marshalXML(st Stanza) ([]byte, os.Error) { + buf := bytes.NewBuffer(nil) + buf.WriteString("<") + buf.WriteString(st.XName()) + if st.XTo() != "" { + writeField(buf, "to", st.XTo()) + } + if st.XFrom() != "" { + writeField(buf, "from", st.XFrom()) + } + if st.XId() != "" { + writeField(buf, "id", st.XId()) + } + if st.XType() != "" { + writeField(buf, "type", st.XType()) + } + if st.XLang() != "" { + 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()) + } + buf.WriteString("") + return buf.Bytes(), nil +} + +func (er *Error) MarshalXML() ([]byte, os.Error) { + buf := bytes.NewBuffer(nil) + buf.WriteString("") + if er.Any != nil { + xml.Marshal(buf, er.Any) + } + buf.WriteString("") + return buf.Bytes(), nil +} + +func (m *Message) XName() string { + return "message" +} + +func (m *Message) XTo() string { + return m.To +} + +func (m *Message) XFrom() string { + return m.From +} + +func (m *Message) XId() string { + return m.Id +} + +func (m *Message) XType() string { + return m.Type + } + +func (m *Message) XLang() string { + return m.Lang +} + +func (m *Message) XError() *Error { + return m.Error +} + +func (m *Message) XChild() *Unrecognized { + return m.Any +} + +func (m *Message) MarshalXML() ([]byte, os.Error) { + return marshalXML(m) +} + +func (p *Presence) XName() string { + return "presence" +} + +func (p *Presence) XTo() string { + return p.To +} + +func (p *Presence) XFrom() string { + return p.From +} + +func (p *Presence) XId() string { + return p.Id +} + +func (p *Presence) XType() string { + return p.Type + } + +func (p *Presence) XLang() string { + return p.Lang +} + +func (p *Presence) XError() *Error { + return p.Error +} + +func (p *Presence) XChild() *Unrecognized { + return p.Any +} + +func (p *Presence) MarshalXML() ([]byte, os.Error) { + return marshalXML(p) +} + +func (iq *Iq) XName() string { + return "iq" +} + +func (iq *Iq) XTo() string { + return iq.To +} + +func (iq *Iq) XFrom() string { + return iq.From +} + +func (iq *Iq) XId() string { + return iq.Id +} + +func (iq *Iq) XType() string { + return iq.Type + } + +func (iq *Iq) XLang() string { + return iq.Lang +} + +func (iq *Iq) XError() *Error { + return iq.Error +} + +func (iq *Iq) XChild() *Unrecognized { + return iq.Any +} + +func (iq *Iq) MarshalXML() ([]byte, os.Error) { + return marshalXML(iq) +}