forked from ortuman/jackal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiq.go
125 lines (108 loc) · 2.81 KB
/
iq.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
* Copyright (c) 2018 Miguel Ángel Ortuño.
* See the LICENSE file for more information.
*/
package xml
import (
"errors"
"fmt"
)
const (
// GetType represents a 'get' IQ type.
GetType = "get"
// SetType represents a 'set' IQ type.
SetType = "set"
// ResultType represents a 'result' IQ type.
ResultType = "result"
)
// IQ type represents an <iq> element.
// All incoming <iq> elements providing from the
// stream will automatically be converted to IQ objects.
type IQ struct {
Element
to *JID
from *JID
}
// NewIQFromElement creates an IQ object from XElement.
func NewIQFromElement(e XElement, from *JID, to *JID) (*IQ, error) {
if e.Name() != "iq" {
return nil, fmt.Errorf("wrong IQ element name: %s", e.Name())
}
if len(e.ID()) == 0 {
return nil, errors.New(`IQ "id" attribute is required`)
}
iqType := e.Type()
if len(iqType) == 0 {
return nil, errors.New(`IQ "type" attribute is required`)
}
if !isIQType(iqType) {
return nil, fmt.Errorf(`invalid IQ "type" attribute: %s`, iqType)
}
if (iqType == GetType || iqType == SetType) && e.Elements().Count() != 1 {
return nil, errors.New(`an IQ stanza of type "get" or "set" must contain one and only one child element`)
}
if iqType == ResultType && e.Elements().Count() > 1 {
return nil, errors.New(`an IQ stanza of type "result" must include zero or one child elements`)
}
iq := &IQ{}
iq.copyFrom(e)
iq.SetToJID(to)
iq.SetFromJID(from)
return iq, nil
}
// NewIQType creates and returns a new IQ element.
func NewIQType(identifier string, iqType string) *IQ {
iq := &IQ{}
iq.SetName("iq")
iq.SetID(identifier)
iq.SetType(iqType)
return iq
}
// IsGet returns true if this is a 'get' type IQ.
func (iq *IQ) IsGet() bool {
return iq.Type() == GetType
}
// IsSet returns true if this is a 'set' type IQ.
func (iq *IQ) IsSet() bool {
return iq.Type() == SetType
}
// IsResult returns true if this is a 'result' type IQ.
func (iq *IQ) IsResult() bool {
return iq.Type() == ResultType
}
// ResultIQ returns the instance associated result IQ.
func (iq *IQ) ResultIQ() *IQ {
rs := &IQ{}
rs.SetName("iq")
rs.SetAttribute("xmlns", iq.Namespace())
rs.SetAttribute("type", ResultType)
rs.SetAttribute("id", iq.ID())
rs.SetAttribute("from", iq.To())
rs.SetAttribute("to", iq.From())
return rs
}
// ToJID returns iq 'from' JID value.
func (iq *IQ) ToJID() *JID {
return iq.to
}
// SetToJID sets the IQ 'to' JID value.
func (iq *IQ) SetToJID(to *JID) {
iq.to = to
iq.SetAttribute("to", to.String())
}
// FromJID returns presence 'from' JID value.
func (iq *IQ) FromJID() *JID {
return iq.from
}
// SetFromJID sets the IQ 'from' JID value.
func (iq *IQ) SetFromJID(from *JID) {
iq.from = from
iq.SetAttribute("from", from.String())
}
func isIQType(tp string) bool {
switch tp {
case ErrorType, GetType, SetType, ResultType:
return true
}
return false
}