162 Type string `xml:"attr"` |
162 Type string `xml:"attr"` |
163 // Any nested element, if present. |
163 // Any nested element, if present. |
164 Any *Generic |
164 Any *Generic |
165 } |
165 } |
166 |
166 |
167 var _ os.Error = &Error{} |
167 var _ error = &Error{} |
168 |
168 |
169 // Used for resource binding as a nested element inside <iq/>. |
169 // Used for resource binding as a nested element inside <iq/>. |
170 type bindIq struct { |
170 type bindIq struct { |
171 XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"` |
171 XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"` |
172 Resource *string `xml:"resource"` |
172 Resource *string `xml:"resource"` |
205 jid.Domain = parts[3] |
205 jid.Domain = parts[3] |
206 jid.Resource = parts[5] |
206 jid.Resource = parts[5] |
207 return true |
207 return true |
208 } |
208 } |
209 |
209 |
210 func (s *stream) MarshalXML() ([]byte, os.Error) { |
210 func (s *stream) MarshalXML() ([]byte, error) { |
211 buf := bytes.NewBuffer(nil) |
211 buf := bytes.NewBuffer(nil) |
212 buf.WriteString("<stream:stream") |
212 buf.WriteString("<stream:stream") |
213 writeField(buf, "xmlns", "jabber:client") |
213 writeField(buf, "xmlns", "jabber:client") |
214 writeField(buf, "xmlns:stream", NsStream) |
214 writeField(buf, "xmlns:stream", NsStream) |
215 writeField(buf, "to", s.To) |
215 writeField(buf, "to", s.To) |
225 func (s *stream) String() string { |
225 func (s *stream) String() string { |
226 result, _ := s.MarshalXML() |
226 result, _ := s.MarshalXML() |
227 return string(result) |
227 return string(result) |
228 } |
228 } |
229 |
229 |
230 func parseStream(se xml.StartElement) (*stream, os.Error) { |
230 func parseStream(se xml.StartElement) (*stream, error) { |
231 s := &stream{} |
231 s := &stream{} |
232 for _, attr := range se.Attr { |
232 for _, attr := range se.Attr { |
233 switch strings.ToLower(attr.Name.Local) { |
233 switch strings.ToLower(attr.Name.Local) { |
234 case "to": |
234 case "to": |
235 s.To = attr.Value |
235 s.To = attr.Value |
244 } |
244 } |
245 } |
245 } |
246 return s, nil |
246 return s, nil |
247 } |
247 } |
248 |
248 |
249 func (s *streamError) MarshalXML() ([]byte, os.Error) { |
249 func (s *streamError) MarshalXML() ([]byte, error) { |
250 buf := bytes.NewBuffer(nil) |
250 buf := bytes.NewBuffer(nil) |
251 buf.WriteString("<stream:error>") |
251 buf.WriteString("<stream:error>") |
252 xml.Marshal(buf, s.Any) |
252 xml.Marshal(buf, s.Any) |
253 if s.Text != nil { |
253 if s.Text != nil { |
254 xml.Marshal(buf, s.Text) |
254 xml.Marshal(buf, s.Text) |
255 } |
255 } |
256 buf.WriteString("</stream:error>") |
256 buf.WriteString("</stream:error>") |
257 return buf.Bytes(), nil |
257 return buf.Bytes(), nil |
258 } |
258 } |
259 |
259 |
260 func (e *errText) MarshalXML() ([]byte, os.Error) { |
260 func (e *errText) MarshalXML() ([]byte, error) { |
261 buf := bytes.NewBuffer(nil) |
261 buf := bytes.NewBuffer(nil) |
262 buf.WriteString("<text") |
262 buf.WriteString("<text") |
263 writeField(buf, "xmlns", NsStreams) |
263 writeField(buf, "xmlns", NsStreams) |
264 writeField(buf, "xml:lang", e.Lang) |
264 writeField(buf, "xml:lang", e.Lang) |
265 buf.WriteString(">") |
265 buf.WriteString(">") |
289 return fmt.Sprintf("<%s %s>%s%s</%s %s>", u.XMLName.Space, |
289 return fmt.Sprintf("<%s %s>%s%s</%s %s>", u.XMLName.Space, |
290 u.XMLName.Local, sub, u.Chardata, u.XMLName.Space, |
290 u.XMLName.Local, sub, u.Chardata, u.XMLName.Space, |
291 u.XMLName.Local) |
291 u.XMLName.Local) |
292 } |
292 } |
293 |
293 |
294 func marshalXML(st Stanza) ([]byte, os.Error) { |
294 func marshalXML(st Stanza) ([]byte, error) { |
295 buf := bytes.NewBuffer(nil) |
295 buf := bytes.NewBuffer(nil) |
296 buf.WriteString("<") |
296 buf.WriteString("<") |
297 buf.WriteString(st.GetName()) |
297 buf.WriteString(st.GetName()) |
298 if st.GetTo() != "" { |
298 if st.GetTo() != "" { |
299 writeField(buf, "to", st.GetTo()) |
299 writeField(buf, "to", st.GetTo()) |
486 |
486 |
487 func (iq *Iq) innerxml() string { |
487 func (iq *Iq) innerxml() string { |
488 return iq.Innerxml |
488 return iq.Innerxml |
489 } |
489 } |
490 |
490 |
491 func (iq *Iq) MarshalXML() ([]byte, os.Error) { |
491 func (iq *Iq) MarshalXML() ([]byte, error) { |
492 return marshalXML(iq) |
492 return marshalXML(iq) |
493 } |
493 } |
494 |
494 |
495 // Parse a string into a struct implementing Stanza -- this will be |
495 // Parse a string into a struct implementing Stanza -- this will be |
496 // either an Iq, a Message, or a Presence. |
496 // either an Iq, a Message, or a Presence. |
497 func ParseStanza(str string) (Stanza, os.Error) { |
497 func ParseStanza(str string) (Stanza, error) { |
498 r := strings.NewReader(str) |
498 r := strings.NewReader(str) |
499 p := xml.NewParser(r) |
499 p := xml.NewParser(r) |
500 tok, err := p.Token() |
500 tok, err := p.Token() |
501 if err != nil { |
501 if err != nil { |
502 return nil, err |
502 return nil, err |
503 } |
503 } |
504 se, ok := tok.(xml.StartElement) |
504 se, ok := tok.(xml.StartElement) |
505 if !ok { |
505 if !ok { |
506 return nil, os.NewError("Not a start element") |
506 return nil, errors.New("Not a start element") |
507 } |
507 } |
508 var stan Stanza |
508 var stan Stanza |
509 switch se.Name.Local { |
509 switch se.Name.Local { |
510 case "iq": |
510 case "iq": |
511 stan = &Iq{} |
511 stan = &Iq{} |
512 case "message": |
512 case "message": |
513 stan = &Message{} |
513 stan = &Message{} |
514 case "presence": |
514 case "presence": |
515 stan = &Presence{} |
515 stan = &Presence{} |
516 default: |
516 default: |
517 return nil, os.NewError("Not iq, message, or presence") |
517 return nil, errors.New("Not iq, message, or presence") |
518 } |
518 } |
519 err = p.Unmarshal(stan, &se) |
519 err = p.Unmarshal(stan, &se) |
520 if err != nil { |
520 if err != nil { |
521 return nil, err |
521 return nil, err |
522 } |
522 } |