structs.go
changeset 98 c9cc4eda6dce
parent 88 d2ec96c80efe
child 100 24231ff0016c
equal deleted inserted replaced
88:d2ec96c80efe 98:c9cc4eda6dce
     6 
     6 
     7 // This file contains data structures.
     7 // This file contains data structures.
     8 
     8 
     9 import (
     9 import (
    10 	"bytes"
    10 	"bytes"
       
    11 	"encoding/xml"
       
    12 	"errors"
    11 	"flag"
    13 	"flag"
    12 	"fmt"
    14 	"fmt"
    13 	"go-idn.googlecode.com/hg/src/stringprep"
    15 	// BUG(cjyar): We should use stringprep
    14 	"io"
    16 	// "code.google.com/p/go-idn/src/stringprep"
    15 	"os"
       
    16 	"regexp"
    17 	"regexp"
    17 	"strings"
    18 	"strings"
    18 	"xml"
       
    19 )
    19 )
    20 
    20 
    21 // JID represents an entity that can communicate with other
    21 // JID represents an entity that can communicate with other
    22 // entities. It looks like node@domain/resource. Node and resource are
    22 // entities. It looks like node@domain/resource. Node and resource are
    23 // sometimes optional.
    23 // sometimes optional.
    30 var _ fmt.Stringer = &JID{}
    30 var _ fmt.Stringer = &JID{}
    31 var _ flag.Value = &JID{}
    31 var _ flag.Value = &JID{}
    32 
    32 
    33 // XMPP's <stream:stream> XML element
    33 // XMPP's <stream:stream> XML element
    34 type stream struct {
    34 type stream struct {
    35 	To      string `xml:"attr"`
    35 	XMLName xml.Name `xml:"stream=http://etherx.jabber.org/streams stream"`
    36 	From    string `xml:"attr"`
    36 	To      string   `xml:"to,attr"`
    37 	Id      string `xml:"attr"`
    37 	From    string   `xml:"from,attr"`
    38 	Lang    string `xml:"attr"`
    38 	Id      string   `xml:"id,attr"`
    39 	Version string `xml:"attr"`
    39 	Lang    string   `xml:"http://www.w3.org/XML/1998/namespace lang,attr"`
    40 }
    40 	Version string   `xml:"version,attr"`
    41 
    41 }
    42 var _ xml.Marshaler = &stream{}
       
    43 var _ fmt.Stringer = &stream{}
    42 var _ fmt.Stringer = &stream{}
    44 
    43 
    45 // <stream:error>
    44 // <stream:error>
    46 type streamError struct {
    45 type streamError struct {
    47 	Any  Generic
    46 	XMLName xml.Name `xml:"http://etherx.jabber.org/streams error"`
       
    47 	Any  Generic     `xml:",any"`
    48 	Text *errText
    48 	Text *errText
    49 }
    49 }
    50 
    50 
    51 var _ xml.Marshaler = &streamError{}
       
    52 
       
    53 type errText struct {
    51 type errText struct {
    54 	Lang string `xml:"attr"`
    52 	XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams text"`
    55 	Text string `xml:"chardata"`
    53 	Lang    string   `xml:"http://www.w3.org/XML/1998/namespace lang,attr"`
    56 }
    54 	Text string      `xml:",chardata"`
    57 
    55 }
    58 var _ xml.Marshaler = &errText{}
       
    59 
    56 
    60 type Features struct {
    57 type Features struct {
    61 	Starttls   *starttls
    58 	Starttls   *starttls
    62 	Mechanisms mechs
    59 	Mechanisms mechs
    63 	Bind       *bindIq
    60 	Bind       *bindIq
    82 }
    79 }
    83 
    80 
    84 // One of the three core XMPP stanza types: iq, message, presence. See
    81 // One of the three core XMPP stanza types: iq, message, presence. See
    85 // RFC3920, section 9.
    82 // RFC3920, section 9.
    86 type Stanza interface {
    83 type Stanza interface {
    87 	// Returns "iq", "message", or "presence".
    84 	// // Returns "iq", "message", or "presence".
    88 	GetName() string
    85 	// GetName() string
    89 	// The to attribute.
    86 	// // The to attribute.
    90 	GetTo() string
    87 	// GetTo() string
    91 	// The from attribute.
    88 	// // The from attribute.
    92 	GetFrom() string
    89 	// GetFrom() string
    93 	// The id attribute.
    90 	// The id attribute. TODO maybe remove this.
    94 	GetId() string
    91 	GetId() string
    95 	// The type attribute.
    92 	// // The type attribute.
    96 	GetType() string
    93 	// GetType() string
    97 	// The xml:lang attribute.
    94 	// // The xml:lang attribute.
    98 	GetLang() string
    95 	// GetLang() string
    99 	// A nested error element, if any.
    96 	// // A nested error element, if any.
   100 	GetError() *Error
    97 	// GetError() *Error
   101 	// Zero or more (non-error) nested elements. These will be in
    98 	// // Zero or more (non-error) nested elements. These will be in
   102 	// namespaces managed by extensions.
    99 	// // namespaces managed by extensions.
   103 	GetNested() []interface{}
   100 	// GetNested() []interface{}
   104 	addNested(interface{})
   101 	addNested(interface{})
   105 	innerxml() string
   102 	innerxml() string
   106 }
   103 }
   107 
   104 
   108 // message stanza
   105 // message stanza
   109 type Message struct {
   106 type Message struct {
   110 	To       string `xml:"attr"`
   107 	XMLName  xml.Name `xml:"message"`
   111 	From     string `xml:"attr"`
   108 	To       string   `xml:"to,attr,omitempty"`
   112 	Id       string `xml:"attr"`
   109 	From     string   `xml:"from,attr,omitempty"`
   113 	Type     string `xml:"attr"`
   110 	Id       string   `xml:"id,attr,omitempty"`
   114 	Lang     string `xml:"attr"`
   111 	Type     string   `xml:"type,attr,omitempty"`
   115 	Innerxml string `xml:"innerxml"`
   112 	Lang     string   `xml:"http://www.w3.org/XML/1998/namespace lang,attr,omitempty"`
       
   113 	Innerxml string   `xml:",innerxml"`
   116 	Error    *Error
   114 	Error    *Error
   117 	Subject  *Generic
   115 	Subject  *Generic `xml:"subject"`
   118 	Body     *Generic
   116 	Body     *Generic `xml:"body"`
   119 	Thread   *Generic
   117 	Thread   *Generic `xml:"thread"`
   120 	Nested   []interface{}
   118 	Nested   []interface{}
   121 }
   119 }
   122 
       
   123 var _ xml.Marshaler = &Message{}
       
   124 var _ Stanza = &Message{}
   120 var _ Stanza = &Message{}
   125 
   121 
   126 // presence stanza
   122 // presence stanza
   127 type Presence struct {
   123 type Presence struct {
   128 	To       string `xml:"attr"`
   124 	XMLName  xml.Name `xml:"presence"`
   129 	From     string `xml:"attr"`
   125 	To       string   `xml:"to,attr,omitempty"`
   130 	Id       string `xml:"attr"`
   126 	From     string   `xml:"from,attr,omitempty"`
   131 	Type     string `xml:"attr"`
   127 	Id       string   `xml:"id,attr,omitempty"`
   132 	Lang     string `xml:"attr"`
   128 	Type     string   `xml:"type,attr,omitempty"`
   133 	Innerxml string `xml:"innerxml"`
   129 	Lang     string   `xml:"http://www.w3.org/XML/1998/namespace lang,attr,omitempty"`
       
   130 	Innerxml string   `xml:",innerxml"`
   134 	Error    *Error
   131 	Error    *Error
   135 	Show     *Generic
   132 	Show     *Generic `xml:"show"`
   136 	Status   *Generic
   133 	Status   *Generic `xml:"status"`
   137 	Priority *Generic
   134 	Priority *Generic `xml:"priority"`
   138 	Nested   []interface{}
   135 	Nested   []interface{}
   139 }
   136 }
   140 
       
   141 var _ xml.Marshaler = &Presence{}
       
   142 var _ Stanza = &Presence{}
   137 var _ Stanza = &Presence{}
   143 
   138 
   144 // iq stanza
   139 // iq stanza
   145 type Iq struct {
   140 type Iq struct {
   146 	To       string `xml:"attr"`
   141 	XMLName  xml.Name `xml:"iq"`
   147 	From     string `xml:"attr"`
   142 	To       string   `xml:"to,attr,omitempty"`
   148 	Id       string `xml:"attr"`
   143 	From     string   `xml:"from,attr,omitempty"`
   149 	Type     string `xml:"attr"`
   144 	Id       string   `xml:"id,attr,omitempty"`
   150 	Lang     string `xml:"attr"`
   145 	Type     string   `xml:"type,attr,omitempty"`
   151 	Innerxml string `xml:"innerxml"`
   146 	Lang     string   `xml:"http://www.w3.org/XML/1998/namespace lang,attr,omitempty"`
       
   147 	Innerxml string   `xml:",innerxml"`
   152 	Error    *Error
   148 	Error    *Error
   153 	Nested   []interface{}
   149 	Nested   []interface{}
   154 }
   150 }
   155 
       
   156 var _ xml.Marshaler = &Iq{}
       
   157 var _ Stanza = &Iq{}
   151 var _ Stanza = &Iq{}
   158 
   152 
   159 // Describes an XMPP stanza error. See RFC 3920, Section 9.3.
   153 // Describes an XMPP stanza error. See RFC 3920, Section 9.3.
   160 type Error struct {
   154 type Error struct {
   161 	XMLName xml.Name `xml:"error"`
   155 	XMLName xml.Name `xml:"error"`
   162 	// The error type attribute.
   156 	// The error type attribute.
   163 	Type string `xml:"attr"`
   157 	Type string `xml:"type,attr"`
   164 	// Any nested element, if present.
   158 	// Any nested element, if present.
   165 	Any *Generic
   159 	Any *Generic
   166 }
   160 }
   167 
   161 var _ error = &Error{}
   168 var _ os.Error = &Error{}
       
   169 
   162 
   170 // Used for resource binding as a nested element inside <iq/>.
   163 // Used for resource binding as a nested element inside <iq/>.
   171 type bindIq struct {
   164 type bindIq struct {
   172 	XMLName  xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
   165 	XMLName  xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
   173 	Resource *string  `xml:"resource"`
   166 	Resource *string  `xml:"resource"`
   175 }
   168 }
   176 
   169 
   177 // Holds an XML element not described by the more specific types.
   170 // Holds an XML element not described by the more specific types.
   178 type Generic struct {
   171 type Generic struct {
   179 	XMLName  xml.Name
   172 	XMLName  xml.Name
   180 	Any      *Generic
   173 	Any      *Generic `xml:",any"`
   181 	Chardata string `xml:"chardata"`
   174 	Chardata string `xml:",chardata"`
   182 }
   175 }
   183 
       
   184 var _ fmt.Stringer = &Generic{}
   176 var _ fmt.Stringer = &Generic{}
   185 
   177 
   186 func (jid *JID) String() string {
   178 func (jid *JID) String() string {
   187 	result := jid.Domain
   179 	result := jid.Domain
   188 	if jid.Node != "" {
   180 	if jid.Node != "" {
   194 	return result
   186 	return result
   195 }
   187 }
   196 
   188 
   197 // Set implements flag.Value. It returns true if it successfully
   189 // Set implements flag.Value. It returns true if it successfully
   198 // parses the string.
   190 // parses the string.
   199 func (jid *JID) Set(val string) bool {
   191 func (jid *JID) Set(val string) error {
   200 	r := regexp.MustCompile("^(([^@/]+)@)?([^@/]+)(/([^@/]+))?$")
   192 	r := regexp.MustCompile("^(([^@/]+)@)?([^@/]+)(/([^@/]+))?$")
   201 	parts := r.FindStringSubmatch(val)
   193 	parts := r.FindStringSubmatch(val)
   202 	if parts == nil {
   194 	if parts == nil {
   203 		return false
   195 		return fmt.Errorf("%s doesn't match user@domain/resource", val)
   204 	}
   196 	}
   205 	jid.Node = stringprep.Nodeprep(parts[2])
   197 	// jid.Node = stringprep.Nodeprep(parts[2])
   206 	jid.Domain = stringprep.Nodeprep(parts[3])
   198 	// jid.Domain = stringprep.Nodeprep(parts[3])
   207 	jid.Resource = stringprep.Resourceprep(parts[5])
   199 	// jid.Resource = stringprep.Resourceprep(parts[5])
   208 	return true
   200 	jid.Node = parts[2]
   209 }
   201 	jid.Domain = parts[3]
   210 
   202 	jid.Resource = parts[5]
   211 func (s *stream) MarshalXML() ([]byte, os.Error) {
   203 	return nil
   212 	buf := bytes.NewBuffer(nil)
   204 }
   213 	buf.WriteString("<stream:stream")
   205 
   214 	writeField(buf, "xmlns", "jabber:client")
   206 func (s *stream) String() string {
   215 	writeField(buf, "xmlns:stream", NsStream)
   207 	var buf bytes.Buffer
   216 	writeField(buf, "to", s.To)
   208 	buf.WriteString(`<stream:stream xmlns="`)
   217 	writeField(buf, "from", s.From)
   209 	buf.WriteString(NsClient)
   218 	writeField(buf, "id", s.Id)
   210 	buf.WriteString(`" xmlns:stream="`)
   219 	writeField(buf, "xml:lang", s.Lang)
   211 	buf.WriteString(NsStream)
   220 	writeField(buf, "version", s.Version)
   212 	buf.WriteString(`"`)
       
   213 	if s.To != "" {
       
   214 		buf.WriteString(` to="`)
       
   215 		xml.Escape(&buf, []byte(s.To))
       
   216 		buf.WriteString(`"`)
       
   217 	}
       
   218 	if s.From != "" {
       
   219 		buf.WriteString(` from="`)
       
   220 		xml.Escape(&buf, []byte(s.From))
       
   221 		buf.WriteString(`"`)
       
   222 	}
       
   223 	if s.Id != "" {
       
   224 		buf.WriteString(` id="`)
       
   225 		xml.Escape(&buf, []byte(s.Id))
       
   226 		buf.WriteString(`"`)
       
   227 	}
       
   228 	if s.Lang != "" {
       
   229 		buf.WriteString(` xml:lang="`)
       
   230 		xml.Escape(&buf, []byte(s.Lang))
       
   231 		buf.WriteString(`"`)
       
   232 	}
       
   233 	if s.Version != "" {
       
   234 		buf.WriteString(` version="`)
       
   235 		xml.Escape(&buf, []byte(s.Version))
       
   236 		buf.WriteString(`"`)
       
   237 	}
   221 	buf.WriteString(">")
   238 	buf.WriteString(">")
   222 	// We never write </stream:stream>
   239 	return buf.String()
   223 	return buf.Bytes(), nil
   240 }
   224 }
   241 
   225 
   242 func parseStream(se xml.StartElement) (*stream, error) {
   226 func (s *stream) String() string {
       
   227 	result, _ := s.MarshalXML()
       
   228 	return string(result)
       
   229 }
       
   230 
       
   231 func parseStream(se xml.StartElement) (*stream, os.Error) {
       
   232 	s := &stream{}
   243 	s := &stream{}
   233 	for _, attr := range se.Attr {
   244 	for _, attr := range se.Attr {
   234 		switch strings.ToLower(attr.Name.Local) {
   245 		switch strings.ToLower(attr.Name.Local) {
   235 		case "to":
   246 		case "to":
   236 			s.To = attr.Value
   247 			s.To = attr.Value
   245 		}
   256 		}
   246 	}
   257 	}
   247 	return s, nil
   258 	return s, nil
   248 }
   259 }
   249 
   260 
   250 func (s *streamError) MarshalXML() ([]byte, os.Error) {
       
   251 	buf := bytes.NewBuffer(nil)
       
   252 	buf.WriteString("<stream:error>")
       
   253 	xml.Marshal(buf, s.Any)
       
   254 	if s.Text != nil {
       
   255 		xml.Marshal(buf, s.Text)
       
   256 	}
       
   257 	buf.WriteString("</stream:error>")
       
   258 	return buf.Bytes(), nil
       
   259 }
       
   260 
       
   261 func (e *errText) MarshalXML() ([]byte, os.Error) {
       
   262 	buf := bytes.NewBuffer(nil)
       
   263 	buf.WriteString("<text")
       
   264 	writeField(buf, "xmlns", NsStreams)
       
   265 	writeField(buf, "xml:lang", e.Lang)
       
   266 	buf.WriteString(">")
       
   267 	xml.Escape(buf, []byte(e.Text))
       
   268 	buf.WriteString("</text>")
       
   269 	return buf.Bytes(), nil
       
   270 }
       
   271 
       
   272 func writeField(w io.Writer, field, value string) {
       
   273 	if value != "" {
       
   274 		io.WriteString(w, " ")
       
   275 		io.WriteString(w, field)
       
   276 		io.WriteString(w, `="`)
       
   277 		xml.Escape(w, []byte(value))
       
   278 		io.WriteString(w, `"`)
       
   279 	}
       
   280 }
       
   281 
       
   282 func (u *Generic) String() string {
   261 func (u *Generic) String() string {
   283 	if u == nil {
   262 	if u == nil {
   284 		return "nil"
   263 		return "nil"
   285 	}
   264 	}
   286 	var sub string
   265 	var sub string
   290 	return fmt.Sprintf("<%s %s>%s%s</%s %s>", u.XMLName.Space,
   269 	return fmt.Sprintf("<%s %s>%s%s</%s %s>", u.XMLName.Space,
   291 		u.XMLName.Local, sub, u.Chardata, u.XMLName.Space,
   270 		u.XMLName.Local, sub, u.Chardata, u.XMLName.Space,
   292 		u.XMLName.Local)
   271 		u.XMLName.Local)
   293 }
   272 }
   294 
   273 
   295 func marshalXML(st Stanza) ([]byte, os.Error) {
   274 func (er *Error) Error() string {
   296 	buf := bytes.NewBuffer(nil)
   275 	buf, err := xml.Marshal(er)
   297 	buf.WriteString("<")
   276 	if err != nil {
   298 	buf.WriteString(st.GetName())
   277 		if Log != nil {
   299 	if st.GetTo() != "" {
   278 			Log.Err("double bad error couldn't marshal error")
   300 		writeField(buf, "to", st.GetTo())
       
   301 	}
       
   302 	if st.GetFrom() != "" {
       
   303 		writeField(buf, "from", st.GetFrom())
       
   304 	}
       
   305 	if st.GetId() != "" {
       
   306 		writeField(buf, "id", st.GetId())
       
   307 	}
       
   308 	if st.GetType() != "" {
       
   309 		writeField(buf, "type", st.GetType())
       
   310 	}
       
   311 	if st.GetLang() != "" {
       
   312 		writeField(buf, "xml:lang", st.GetLang())
       
   313 	}
       
   314 	buf.WriteString(">")
       
   315 
       
   316 	if m, ok := st.(*Message); ok {
       
   317 		err := xml.Marshal(buf, m.Subject)
       
   318 		if err != nil {
       
   319 			return nil, err
       
   320 		}
   279 		}
   321 		err = xml.Marshal(buf, m.Body)
   280 		return "unreadable error"
   322 		if err != nil {
   281 	}
   323 			return nil, err
   282 	return string(buf)
   324 		}
       
   325 		err = xml.Marshal(buf, m.Thread)
       
   326 		if err != nil {
       
   327 			return nil, err
       
   328 		}
       
   329 	}
       
   330 	if p, ok := st.(*Presence); ok {
       
   331 		err := xml.Marshal(buf, p.Show)
       
   332 		if err != nil {
       
   333 			return nil, err
       
   334 		}
       
   335 		err = xml.Marshal(buf, p.Status)
       
   336 		if err != nil {
       
   337 			return nil, err
       
   338 		}
       
   339 		err = xml.Marshal(buf, p.Priority)
       
   340 		if err != nil {
       
   341 			return nil, err
       
   342 		}
       
   343 	}
       
   344 	if nested := st.GetNested(); nested != nil {
       
   345 		for _, n := range nested {
       
   346 			xml.Marshal(buf, n)
       
   347 		}
       
   348 	} else if st.innerxml() != "" {
       
   349 		buf.WriteString(st.innerxml())
       
   350 	}
       
   351 
       
   352 	buf.WriteString("</")
       
   353 	buf.WriteString(st.GetName())
       
   354 	buf.WriteString(">")
       
   355 	return buf.Bytes(), nil
       
   356 }
       
   357 
       
   358 func (er *Error) String() string {
       
   359 	buf := bytes.NewBuffer(nil)
       
   360 	xml.Marshal(buf, er)
       
   361 	return buf.String()
       
   362 }
       
   363 
       
   364 func (m *Message) GetName() string {
       
   365 	return "message"
       
   366 }
       
   367 
       
   368 func (m *Message) GetTo() string {
       
   369 	return m.To
       
   370 }
       
   371 
       
   372 func (m *Message) GetFrom() string {
       
   373 	return m.From
       
   374 }
   283 }
   375 
   284 
   376 func (m *Message) GetId() string {
   285 func (m *Message) GetId() string {
   377 	return m.Id
   286 	return m.Id
   378 }
   287 }
   379 
   288 
   380 func (m *Message) GetType() string {
       
   381 	return m.Type
       
   382 }
       
   383 
       
   384 func (m *Message) GetLang() string {
       
   385 	return m.Lang
       
   386 }
       
   387 
       
   388 func (m *Message) GetError() *Error {
       
   389 	return m.Error
       
   390 }
       
   391 
       
   392 func (m *Message) GetNested() []interface{} {
       
   393 	return m.Nested
       
   394 }
       
   395 
       
   396 func (m *Message) addNested(n interface{}) {
   289 func (m *Message) addNested(n interface{}) {
   397 	m.Nested = append(m.Nested, n)
   290 	m.Nested = append(m.Nested, n)
   398 }
   291 }
   399 
   292 
   400 func (m *Message) innerxml() string {
   293 func (m *Message) innerxml() string {
   401 	return m.Innerxml
   294 	return m.Innerxml
   402 }
   295 }
   403 
   296 
   404 func (m *Message) MarshalXML() ([]byte, os.Error) {
       
   405 	return marshalXML(m)
       
   406 }
       
   407 
       
   408 func (p *Presence) GetName() string {
       
   409 	return "presence"
       
   410 }
       
   411 
       
   412 func (p *Presence) GetTo() string {
       
   413 	return p.To
       
   414 }
       
   415 
       
   416 func (p *Presence) GetFrom() string {
       
   417 	return p.From
       
   418 }
       
   419 
       
   420 func (p *Presence) GetId() string {
   297 func (p *Presence) GetId() string {
   421 	return p.Id
   298 	return p.Id
   422 }
   299 }
   423 
   300 
   424 func (p *Presence) GetType() string {
       
   425 	return p.Type
       
   426 }
       
   427 
       
   428 func (p *Presence) GetLang() string {
       
   429 	return p.Lang
       
   430 }
       
   431 
       
   432 func (p *Presence) GetError() *Error {
       
   433 	return p.Error
       
   434 }
       
   435 
       
   436 func (p *Presence) GetNested() []interface{} {
       
   437 	return p.Nested
       
   438 }
       
   439 
       
   440 func (p *Presence) addNested(n interface{}) {
   301 func (p *Presence) addNested(n interface{}) {
   441 	p.Nested = append(p.Nested, n)
   302 	p.Nested = append(p.Nested, n)
   442 }
   303 }
   443 
   304 
   444 func (p *Presence) innerxml() string {
   305 func (p *Presence) innerxml() string {
   445 	return p.Innerxml
   306 	return p.Innerxml
   446 }
   307 }
   447 
   308 
   448 func (p *Presence) MarshalXML() ([]byte, os.Error) {
       
   449 	return marshalXML(p)
       
   450 }
       
   451 
       
   452 func (iq *Iq) GetName() string {
       
   453 	return "iq"
       
   454 }
       
   455 
       
   456 func (iq *Iq) GetTo() string {
       
   457 	return iq.To
       
   458 }
       
   459 
       
   460 func (iq *Iq) GetFrom() string {
       
   461 	return iq.From
       
   462 }
       
   463 
       
   464 func (iq *Iq) GetId() string {
   309 func (iq *Iq) GetId() string {
   465 	return iq.Id
   310 	return iq.Id
   466 }
   311 }
   467 
   312 
   468 func (iq *Iq) GetType() string {
       
   469 	return iq.Type
       
   470 }
       
   471 
       
   472 func (iq *Iq) GetLang() string {
       
   473 	return iq.Lang
       
   474 }
       
   475 
       
   476 func (iq *Iq) GetError() *Error {
       
   477 	return iq.Error
       
   478 }
       
   479 
       
   480 func (iq *Iq) GetNested() []interface{} {
       
   481 	return iq.Nested
       
   482 }
       
   483 
       
   484 func (iq *Iq) addNested(n interface{}) {
   313 func (iq *Iq) addNested(n interface{}) {
   485 	iq.Nested = append(iq.Nested, n)
   314 	iq.Nested = append(iq.Nested, n)
   486 }
   315 }
   487 
   316 
   488 func (iq *Iq) innerxml() string {
   317 func (iq *Iq) innerxml() string {
   489 	return iq.Innerxml
   318 	return iq.Innerxml
   490 }
   319 }
   491 
   320 
   492 func (iq *Iq) MarshalXML() ([]byte, os.Error) {
       
   493 	return marshalXML(iq)
       
   494 }
       
   495 
   321 
   496 // Parse a string into a struct implementing Stanza -- this will be
   322 // Parse a string into a struct implementing Stanza -- this will be
   497 // either an Iq, a Message, or a Presence.
   323 // either an Iq, a Message, or a Presence.
   498 func ParseStanza(str string) (Stanza, os.Error) {
   324 func ParseStanza(str string) (Stanza, error) {
   499 	r := strings.NewReader(str)
   325 	r := strings.NewReader(str)
   500 	p := xml.NewParser(r)
   326 	p := xml.NewDecoder(r)
   501 	tok, err := p.Token()
   327 	tok, err := p.Token()
   502 	if err != nil {
   328 	if err != nil {
   503 		return nil, err
   329 		return nil, err
   504 	}
   330 	}
   505 	se, ok := tok.(xml.StartElement)
   331 	se, ok := tok.(xml.StartElement)
   506 	if !ok {
   332 	if !ok {
   507 		return nil, os.NewError("Not a start element")
   333 		return nil, errors.New("Not a start element")
   508 	}
   334 	}
   509 	var stan Stanza
   335 	var stan Stanza
   510 	switch se.Name.Local {
   336 	switch se.Name.Local {
   511 	case "iq":
   337 	case "iq":
   512 		stan = &Iq{}
   338 		stan = &Iq{}
   513 	case "message":
   339 	case "message":
   514 		stan = &Message{}
   340 		stan = &Message{}
   515 	case "presence":
   341 	case "presence":
   516 		stan = &Presence{}
   342 		stan = &Presence{}
   517 	default:
   343 	default:
   518 		return nil, os.NewError("Not iq, message, or presence")
   344 		return nil, errors.New("Not iq, message, or presence")
   519 	}
   345 	}
   520 	err = p.Unmarshal(stan, &se)
   346 	err = p.DecodeElement(stan, &se)
   521 	if err != nil {
   347 	if err != nil {
   522 		return nil, err
   348 		return nil, err
   523 	}
   349 	}
   524 	return stan, nil
   350 	return stan, nil
   525 }
   351 }