structs.go
changeset 74 e619e18dcec3
parent 72 53f15893a1a7
child 75 03a923eb5c01
equal deleted inserted replaced
73:acca351fb8f0 74:e619e18dcec3
     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 	"io"
    15 	"io"
    14 	"os"
       
    15 	"regexp"
    16 	"regexp"
    16 	"strings"
    17 	"strings"
    17 	"xml"
       
    18 )
    18 )
    19 
    19 
    20 // JID represents an entity that can communicate with other
    20 // JID represents an entity that can communicate with other
    21 // entities. It looks like node@domain/resource. Node and resource are
    21 // entities. It looks like node@domain/resource. Node and resource are
    22 // sometimes optional.
    22 // sometimes optional.
   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())
   352 	buf.WriteString(st.GetName())
   352 	buf.WriteString(st.GetName())
   353 	buf.WriteString(">")
   353 	buf.WriteString(">")
   354 	return buf.Bytes(), nil
   354 	return buf.Bytes(), nil
   355 }
   355 }
   356 
   356 
   357 func (er *Error) String() string {
   357 func (er *Error) Error() string {
   358 	buf := bytes.NewBuffer(nil)
   358 	buf := bytes.NewBuffer(nil)
   359 	xml.Marshal(buf, er)
   359 	xml.Marshal(buf, er)
   360 	return buf.String()
   360 	return buf.String()
   361 }
   361 }
   362 
   362 
   398 
   398 
   399 func (m *Message) innerxml() string {
   399 func (m *Message) innerxml() string {
   400 	return m.Innerxml
   400 	return m.Innerxml
   401 }
   401 }
   402 
   402 
   403 func (m *Message) MarshalXML() ([]byte, os.Error) {
   403 func (m *Message) MarshalXML() ([]byte, error) {
   404 	return marshalXML(m)
   404 	return marshalXML(m)
   405 }
   405 }
   406 
   406 
   407 func (p *Presence) GetName() string {
   407 func (p *Presence) GetName() string {
   408 	return "presence"
   408 	return "presence"
   442 
   442 
   443 func (p *Presence) innerxml() string {
   443 func (p *Presence) innerxml() string {
   444 	return p.Innerxml
   444 	return p.Innerxml
   445 }
   445 }
   446 
   446 
   447 func (p *Presence) MarshalXML() ([]byte, os.Error) {
   447 func (p *Presence) MarshalXML() ([]byte, error) {
   448 	return marshalXML(p)
   448 	return marshalXML(p)
   449 }
   449 }
   450 
   450 
   451 func (iq *Iq) GetName() string {
   451 func (iq *Iq) GetName() string {
   452 	return "iq"
   452 	return "iq"
   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 	}