structs.go
changeset 36 9fe022261dcc
parent 34 7b1f924c75e2
child 37 fbda8e925fdf
equal deleted inserted replaced
35:569833f08780 36:9fe022261dcc
    93 	XLang() string
    93 	XLang() string
    94 	// A nested error element, if any.
    94 	// A nested error element, if any.
    95 	XError() *Error
    95 	XError() *Error
    96 	// A (non-error) nested element, if any.
    96 	// A (non-error) nested element, if any.
    97 	XChild() *Generic
    97 	XChild() *Generic
       
    98 	innerxml() string
       
    99 }
       
   100 
       
   101 type ExtendedStanza interface {
       
   102 	InnerMarshal(io.Writer) os.Error
    98 }
   103 }
    99 
   104 
   100 // message stanza
   105 // message stanza
   101 type Message struct {
   106 type Message struct {
   102 	To string `xml:"attr"`
   107 	To string `xml:"attr"`
   103 	From string `xml:"attr"`
   108 	From string `xml:"attr"`
   104 	Id string `xml:"attr"`
   109 	Id string `xml:"attr"`
   105 	Type string `xml:"attr"`
   110 	Type string `xml:"attr"`
   106 	Lang string `xml:"attr"`
   111 	Lang string `xml:"attr"`
       
   112 	Innerxml string `xml:"innerxml"`
   107 	Error *Error
   113 	Error *Error
   108 	Subject *Generic
   114 	Subject *Generic
   109 	Body *Generic
   115 	Body *Generic
   110 	Thread *Generic
   116 	Thread *Generic
   111 	Any *Generic
   117 	Any *Generic
   112 }
   118 }
   113 var _ xml.Marshaler = &Message{}
   119 var _ xml.Marshaler = &Message{}
   114 var _ Stanza = &Message{}
   120 var _ Stanza = &Message{}
       
   121 var _ ExtendedStanza = &Message{}
   115 
   122 
   116 // presence stanza
   123 // presence stanza
   117 type Presence struct {
   124 type Presence struct {
   118 	To string `xml:"attr"`
   125 	To string `xml:"attr"`
   119 	From string `xml:"attr"`
   126 	From string `xml:"attr"`
   120 	Id string `xml:"attr"`
   127 	Id string `xml:"attr"`
   121 	Type string `xml:"attr"`
   128 	Type string `xml:"attr"`
   122 	Lang string `xml:"attr"`
   129 	Lang string `xml:"attr"`
       
   130 	Innerxml string `xml:"innerxml"`
   123 	Error *Error
   131 	Error *Error
   124 	Show *Generic
   132 	Show *Generic
   125 	Status *Generic
   133 	Status *Generic
   126 	Priority *Generic
   134 	Priority *Generic
   127 	Any *Generic
   135 	Any *Generic
   128 }
   136 }
   129 var _ xml.Marshaler = &Presence{}
   137 var _ xml.Marshaler = &Presence{}
   130 var _ Stanza = &Presence{}
   138 var _ Stanza = &Presence{}
       
   139 var _ ExtendedStanza = &Presence{}
   131 
   140 
   132 // iq stanza
   141 // iq stanza
   133 type Iq struct {
   142 type Iq struct {
   134 	To string `xml:"attr"`
   143 	To string `xml:"attr"`
   135 	From string `xml:"attr"`
   144 	From string `xml:"attr"`
   136 	Id string `xml:"attr"`
   145 	Id string `xml:"attr"`
   137 	Type string `xml:"attr"`
   146 	Type string `xml:"attr"`
   138 	Lang string `xml:"attr"`
   147 	Lang string `xml:"attr"`
       
   148 	Innerxml string `xml:"innerxml"`
   139 	Error *Error
   149 	Error *Error
   140 	Any *Generic
   150 	Any *Generic
   141 	Query *RosterQuery
       
   142 }
   151 }
   143 var _ xml.Marshaler = &Iq{}
   152 var _ xml.Marshaler = &Iq{}
   144 var _ Stanza = &Iq{}
   153 var _ Stanza = &Iq{}
   145 
       
   146 // Roster query/result
       
   147 type RosterQuery struct {
       
   148 	// Should always be query in the NsRoster namespace
       
   149 	XMLName xml.Name
       
   150 	Item []RosterItem
       
   151 }
       
   152 
       
   153 // See RFC 3921, Section 7.1.
       
   154 type RosterItem struct {
       
   155 	// Should always be "item"
       
   156 	XMLName xml.Name
       
   157 	Jid string `xml:"attr"`
       
   158 	Subscription string `xml:"attr"`
       
   159 	Name string `xml:"attr"`
       
   160 	Group []string
       
   161 }
       
   162 
   154 
   163 // Describes an XMPP stanza error. See RFC 3920, Section 9.3.
   155 // Describes an XMPP stanza error. See RFC 3920, Section 9.3.
   164 type Error struct {
   156 type Error struct {
   165 	// The error type attribute.
   157 	// The error type attribute.
   166 	Type string `xml:"attr"`
   158 	Type string `xml:"attr"`
   280 	return fmt.Sprintf("<%s %s>%s%s</%s %s>", u.XMLName.Space,
   272 	return fmt.Sprintf("<%s %s>%s%s</%s %s>", u.XMLName.Space,
   281 		u.XMLName.Local, sub, u.Chardata, u.XMLName.Space,
   273 		u.XMLName.Local, sub, u.Chardata, u.XMLName.Space,
   282 		u.XMLName.Local)
   274 		u.XMLName.Local)
   283 }
   275 }
   284 
   276 
   285 // BUG(cjyar) This is fragile. We should find a way to use go's native
       
   286 // XML marshaling.
       
   287 func marshalXML(st Stanza) ([]byte, os.Error) {
   277 func marshalXML(st Stanza) ([]byte, os.Error) {
   288 	buf := bytes.NewBuffer(nil)
   278 	buf := bytes.NewBuffer(nil)
   289 	buf.WriteString("<")
   279 	buf.WriteString("<")
   290 	buf.WriteString(st.XName())
   280 	buf.WriteString(st.XName())
   291 	if st.XTo() != "" {
   281 	if st.XTo() != "" {
   302 	}
   292 	}
   303 	if st.XLang() != "" {
   293 	if st.XLang() != "" {
   304 		writeField(buf, "xml:lang", st.XLang())
   294 		writeField(buf, "xml:lang", st.XLang())
   305 	}
   295 	}
   306 	buf.WriteString(">")
   296 	buf.WriteString(">")
   307 	if st.XError() != nil {
   297 	if ext, ok := st.(ExtendedStanza) ; ok {
   308 		bytes, _ := st.XError().MarshalXML()
   298 		if st.XError() != nil {
   309 		buf.WriteString(string(bytes))
   299 			bytes, _ := st.XError().MarshalXML()
   310 	}
   300 			buf.WriteString(string(bytes))
   311 	if st.XChild() != nil {
   301 		}
   312 		xml.Marshal(buf, st.XChild())
   302 		err := ext.InnerMarshal(buf)
   313 	}
   303 		if err != nil {
   314 	if iq, ok := st.(*Iq) ; ok && iq.Query != nil {
   304 			return nil, err
   315 		xml.Marshal(buf, iq.Query)
   305 		}
       
   306 	} else {
       
   307 		inner := st.innerxml()
       
   308 		if inner == "" {
       
   309 			xml.Marshal(buf, st.XChild())
       
   310 		} else {
       
   311 			buf.WriteString(st.innerxml())
       
   312 		}
   316 	}
   313 	}
   317 	buf.WriteString("</")
   314 	buf.WriteString("</")
   318 	buf.WriteString(st.XName())
   315 	buf.WriteString(st.XName())
   319 	buf.WriteString(">")
   316 	buf.WriteString(">")
   320 	return buf.Bytes(), nil
   317 	return buf.Bytes(), nil
   367 
   364 
   368 func (m *Message) XChild() *Generic {
   365 func (m *Message) XChild() *Generic {
   369 	return m.Any
   366 	return m.Any
   370 }
   367 }
   371 
   368 
       
   369 func (m *Message) innerxml() string {
       
   370 	return m.Innerxml
       
   371 }
       
   372 
   372 func (m *Message) MarshalXML() ([]byte, os.Error) {
   373 func (m *Message) MarshalXML() ([]byte, os.Error) {
   373 	return marshalXML(m)
   374 	return marshalXML(m)
   374 }
   375 }
   375 
   376 
       
   377 func (m *Message) InnerMarshal(w io.Writer) os.Error {
       
   378 	err := xml.Marshal(w, m.Subject)
       
   379 	if err != nil {
       
   380 		return err
       
   381 	}
       
   382 	err = xml.Marshal(w, m.Body)
       
   383 	if err != nil {
       
   384 		return err
       
   385 	}
       
   386 	err = xml.Marshal(w, m.Thread)
       
   387 	if err != nil {
       
   388 		return err
       
   389 	}
       
   390 	return nil
       
   391 }
       
   392 
   376 func (p *Presence) XName() string {
   393 func (p *Presence) XName() string {
   377 	return "presence"
   394 	return "presence"
   378 }
   395 }
   379 
   396 
   380 func (p *Presence) XTo() string {
   397 func (p *Presence) XTo() string {
   403 
   420 
   404 func (p *Presence) XChild() *Generic {
   421 func (p *Presence) XChild() *Generic {
   405 	return p.Any
   422 	return p.Any
   406 }
   423 }
   407 
   424 
       
   425 func (p *Presence) innerxml() string {
       
   426 	return p.Innerxml
       
   427 }
       
   428 
   408 func (p *Presence) MarshalXML() ([]byte, os.Error) {
   429 func (p *Presence) MarshalXML() ([]byte, os.Error) {
   409 	return marshalXML(p)
   430 	return marshalXML(p)
   410 }
   431 }
   411 
   432 
       
   433 func (p *Presence) InnerMarshal(w io.Writer) os.Error {
       
   434 	err := xml.Marshal(w, p.Show)
       
   435 	if err != nil {
       
   436 		return err
       
   437 	}
       
   438 	err = xml.Marshal(w, p.Status)
       
   439 	if err != nil {
       
   440 		return err
       
   441 	}
       
   442 	err = xml.Marshal(w, p.Priority)
       
   443 	if err != nil {
       
   444 		return err
       
   445 	}
       
   446 	return nil
       
   447 }
       
   448 
   412 func (iq *Iq) XName() string {
   449 func (iq *Iq) XName() string {
   413 	return "iq"
   450 	return "iq"
   414 }
   451 }
   415 
   452 
   416 func (iq *Iq) XTo() string {
   453 func (iq *Iq) XTo() string {
   437 	return iq.Error
   474 	return iq.Error
   438 }
   475 }
   439 
   476 
   440 func (iq *Iq) XChild() *Generic {
   477 func (iq *Iq) XChild() *Generic {
   441 	return iq.Any
   478 	return iq.Any
       
   479 }
       
   480 
       
   481 func (iq *Iq) innerxml() string {
       
   482 	return iq.Innerxml
   442 }
   483 }
   443 
   484 
   444 func (iq *Iq) MarshalXML() ([]byte, os.Error) {
   485 func (iq *Iq) MarshalXML() ([]byte, os.Error) {
   445 	return marshalXML(iq)
   486 	return marshalXML(iq)
   446 }
   487 }