29 var _ fmt.Stringer = &JID{} |
29 var _ fmt.Stringer = &JID{} |
30 var _ flag.Value = &JID{} |
30 var _ flag.Value = &JID{} |
31 |
31 |
32 // XMPP's <stream:stream> XML element |
32 // XMPP's <stream:stream> XML element |
33 type stream struct { |
33 type stream struct { |
34 To string `xml:"attr"` |
34 To string `xml:"to,attr"` |
35 From string `xml:"attr"` |
35 From string `xml:"from,attr"` |
36 Id string `xml:"attr"` |
36 Id string `xml:"id,attr"` |
37 Lang string `xml:"attr"` |
37 Lang string `xml:"lang,attr"` |
38 Version string `xml:"attr"` |
38 Version string `xml:"version,attr"` |
39 } |
39 } |
40 |
40 |
41 var _ xml.Marshaler = &stream{} |
41 var _ xml.Marshaler = &stream{} |
42 var _ fmt.Stringer = &stream{} |
42 var _ fmt.Stringer = &stream{} |
43 |
43 |
44 // <stream:error> |
44 // <stream:error> |
45 type streamError struct { |
45 type streamError struct { |
46 Any Generic |
46 Any Generic `xml:",any"` |
47 Text *errText |
47 Text *errText `xml:"text"` |
48 } |
48 } |
49 |
49 |
50 var _ xml.Marshaler = &streamError{} |
50 var _ xml.Marshaler = &streamError{} |
51 |
51 |
52 type errText struct { |
52 type errText struct { |
53 Lang string `xml:"attr"` |
53 Lang string `xml:"lang,attr"` |
54 Text string `xml:"chardata"` |
54 Text string `xml:",chardata"` |
55 } |
55 } |
56 |
56 |
57 var _ xml.Marshaler = &errText{} |
57 var _ xml.Marshaler = &errText{} |
58 |
58 |
59 type Features struct { |
59 type Features struct { |
60 Starttls *starttls |
60 Starttls *starttls `xml:"starttls"` |
61 Mechanisms mechs |
61 Mechanisms mechs `xml:"mechanisms"` |
62 Bind *bindIq |
62 Bind *bindIq `xml:"bind"` |
63 Session *Generic |
63 Session *Generic `xml:"session"` |
64 Any *Generic |
64 Any *Generic `xml:",any"` |
65 } |
65 } |
66 |
66 |
67 type starttls struct { |
67 type starttls struct { |
68 XMLName xml.Name |
68 XMLName xml.Name |
69 Required *string |
69 Required *string `xml:"required"` |
70 } |
70 } |
71 |
71 |
72 type mechs struct { |
72 type mechs struct { |
73 Mechanism []string |
73 Mechanism []string `xml:"mechanism"` |
74 } |
74 } |
75 |
75 |
76 type auth struct { |
76 type auth struct { |
77 XMLName xml.Name |
77 XMLName xml.Name |
78 Chardata string `xml:"chardata"` |
78 Chardata string `xml:",chardata"` |
79 Mechanism string `xml:"attr"` |
79 Mechanism string `xml:"mechanism,attr"` |
80 Any *Generic |
80 Any *Generic `xml:",any"` |
81 } |
81 } |
82 |
82 |
83 // One of the three core XMPP stanza types: iq, message, presence. See |
83 // One of the three core XMPP stanza types: iq, message, presence. See |
84 // RFC3920, section 9. |
84 // RFC3920, section 9. |
85 type Stanza interface { |
85 type Stanza interface { |
104 innerxml() string |
104 innerxml() string |
105 } |
105 } |
106 |
106 |
107 // message stanza |
107 // message stanza |
108 type Message struct { |
108 type Message struct { |
109 To string `xml:"attr"` |
109 To string `xml:"to,attr"` |
110 From string `xml:"attr"` |
110 From string `xml:"from,attr"` |
111 Id string `xml:"attr"` |
111 Id string `xml:"id,attr"` |
112 Type string `xml:"attr"` |
112 Type string `xml:"type,attr"` |
113 Lang string `xml:"attr"` |
113 Lang string `xml:"lang,attr"` |
114 Innerxml string `xml:"innerxml"` |
114 Innerxml string `xml:",innerxml"` |
115 Error *Error |
115 Error *Error `xml:"error"` |
116 Subject *Generic |
116 Subject *Generic `xml:"subject"` |
117 Body *Generic |
117 Body *Generic `xml:"body"` |
118 Thread *Generic |
118 Thread *Generic `xml:"thread"` |
119 Nested []interface{} |
119 Nested []interface{} |
120 } |
120 } |
121 |
121 |
122 var _ xml.Marshaler = &Message{} |
122 var _ xml.Marshaler = &Message{} |
123 var _ Stanza = &Message{} |
123 var _ Stanza = &Message{} |
124 |
124 |
125 // presence stanza |
125 // presence stanza |
126 type Presence struct { |
126 type Presence struct { |
127 To string `xml:"attr"` |
127 To string `xml:"to,attr"` |
128 From string `xml:"attr"` |
128 From string `xml:"from,attr"` |
129 Id string `xml:"attr"` |
129 Id string `xml:"id,attr"` |
130 Type string `xml:"attr"` |
130 Type string `xml:"type,attr"` |
131 Lang string `xml:"attr"` |
131 Lang string `xml:"lang,attr"` |
132 Innerxml string `xml:"innerxml"` |
132 Innerxml string `xml:",innerxml"` |
133 Error *Error |
133 Error *Error `xml:"error"` |
134 Show *Generic |
134 Show *Generic `xml:"show"` |
135 Status *Generic |
135 Status *Generic `xml:"status"` |
136 Priority *Generic |
136 Priority *Generic `xml:"priority"` |
137 Nested []interface{} |
137 Nested []interface{} |
138 } |
138 } |
139 |
139 |
140 var _ xml.Marshaler = &Presence{} |
140 var _ xml.Marshaler = &Presence{} |
141 var _ Stanza = &Presence{} |
141 var _ Stanza = &Presence{} |
142 |
142 |
143 // iq stanza |
143 // iq stanza |
144 type Iq struct { |
144 type Iq struct { |
145 To string `xml:"attr"` |
145 To string `xml:"to,attr"` |
146 From string `xml:"attr"` |
146 From string `xml:"from,attr"` |
147 Id string `xml:"attr"` |
147 Id string `xml:"id,attr"` |
148 Type string `xml:"attr"` |
148 Type string `xml:"type,attr"` |
149 Lang string `xml:"attr"` |
149 Lang string `xml:"lang,attr"` |
150 Innerxml string `xml:"innerxml"` |
150 Innerxml string `xml:",innerxml"` |
151 Error *Error |
151 Error *Error `xml:"error"` |
152 Nested []interface{} |
152 Nested []interface{} |
153 } |
153 } |
154 |
154 |
155 var _ xml.Marshaler = &Iq{} |
155 var _ xml.Marshaler = &Iq{} |
156 var _ Stanza = &Iq{} |
156 var _ Stanza = &Iq{} |
157 |
157 |
158 // Describes an XMPP stanza error. See RFC 3920, Section 9.3. |
158 // Describes an XMPP stanza error. See RFC 3920, Section 9.3. |
159 type Error struct { |
159 type Error struct { |
160 XMLName xml.Name `xml:"error"` |
160 XMLName xml.Name `xml:"error"` |
161 // The error type attribute. |
161 // The error type attribute. |
162 Type string `xml:"attr"` |
162 Type string `xml:"type,attr"` |
163 // Any nested element, if present. |
163 // Any nested element, if present. |
164 Any *Generic |
164 Any *Generic `xml:",any"` |
165 } |
165 } |
166 |
166 |
167 var _ 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/>. |
193 return result |
193 return result |
194 } |
194 } |
195 |
195 |
196 // Set implements flag.Value. It returns true if it successfully |
196 // Set implements flag.Value. It returns true if it successfully |
197 // parses the string. |
197 // parses the string. |
198 func (jid *JID) Set(val string) bool { |
198 func (jid *JID) Set(val string) error { |
199 r := regexp.MustCompile("^(([^@/]+)@)?([^@/]+)(/([^@/]+))?$") |
199 r := regexp.MustCompile("^(([^@/]+)@)?([^@/]+)(/([^@/]+))?$") |
200 parts := r.FindStringSubmatch(val) |
200 parts := r.FindStringSubmatch(val) |
201 if parts == nil { |
201 if parts == nil { |
202 return false |
202 return errors.New("Can't parse as JID: " + val) |
203 } |
203 } |
204 jid.Node = parts[2] |
204 jid.Node = parts[2] |
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 nil |
208 } |
208 } |
209 |
209 |
210 func (s *stream) MarshalXML() ([]byte, 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") |