~ubuntu-branches/ubuntu/trusty/jreen/trusty

« back to all changes in this revision

Viewing changes to src/bindfeature.cpp

  • Committer: Package Import Robot
  • Author(s): Prasad Murthy
  • Date: 2013-03-08 00:00:33 UTC
  • Revision ID: package-import@ubuntu.com-20130308000033-x8thp6syo1kkh63s
Tags: upstream-1.1.1
Import upstream version 1.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Jreen
 
4
**
 
5
** Copyright © 2011 Ruslan Nigmatullin <euroelessar@yandex.ru>
 
6
**
 
7
*****************************************************************************
 
8
**
 
9
** $JREEN_BEGIN_LICENSE$
 
10
** This program is free software: you can redistribute it and/or modify
 
11
** it under the terms of the GNU General Public License as published by
 
12
** the Free Software Foundation, either version 2 of the License, or
 
13
** (at your option) any later version.
 
14
**
 
15
** This program is distributed in the hope that it will be useful,
 
16
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
18
** See the GNU General Public License for more details.
 
19
**
 
20
** You should have received a copy of the GNU General Public License
 
21
** along with this program.  If not, see http://www.gnu.org/licenses/.
 
22
** $JREEN_END_LICENSE$
 
23
**
 
24
****************************************************************************/
 
25
 
 
26
#include "bindfeature_p.h"
 
27
#include "client.h"
 
28
#include "iq_p.h"
 
29
#include <QXmlStreamWriter>
 
30
#include <QStringList>
 
31
#include "logger.h"
 
32
 
 
33
#define NS_BIND QLatin1String("urn:ietf:params:xml:ns:xmpp-bind")
 
34
 
 
35
namespace Jreen
 
36
{
 
37
class BindQuery : public Payload
 
38
{
 
39
        J_PAYLOAD(Jreen::BindQuery)
 
40
        public:
 
41
                BindQuery(const JID &jid, const QString &resource, bool bind = true) 
 
42
          : m_jid(jid), m_resource(resource), m_bind(bind) {}
 
43
        JID jid() { return m_jid; }
 
44
        QString resource() { return m_resource; }
 
45
        bool isBind() { return m_bind; }
 
46
private:
 
47
        JID m_jid;
 
48
        QString m_resource;
 
49
        bool m_bind;
 
50
};
 
51
 
 
52
class JREEN_AUTOTEST_EXPORT BindQueryFactory : public PayloadFactory<BindQuery>
 
53
{
 
54
public:
 
55
        BindQueryFactory() : m_bind(true), m_depth(0), m_state(AtStart) {}
 
56
        QStringList features() const { return QStringList(); }
 
57
        bool canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes);
 
58
        void handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes);
 
59
        void handleEndElement(const QStringRef &name, const QStringRef &uri);
 
60
        void handleCharacterData(const QStringRef &text);
 
61
        void serialize(Payload *extension, QXmlStreamWriter *writer);
 
62
        Payload::Ptr createPayload();
 
63
private:
 
64
        enum State { AtStart, AtResource, AtJid };
 
65
        bool m_bind;
 
66
        QString m_resource;
 
67
        JID m_jid;
 
68
        int m_depth;
 
69
        State m_state;
 
70
};
 
71
 
 
72
bool BindQueryFactory::canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
 
73
{
 
74
        Q_UNUSED(attributes);
 
75
        return (name == QLatin1String("bind") || name == QLatin1String("unbind")) && uri == NS_BIND;
 
76
}
 
77
 
 
78
void BindQueryFactory::handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
 
79
{
 
80
        Q_UNUSED(uri);
 
81
        Q_UNUSED(attributes);
 
82
        m_depth++;
 
83
        if (m_depth == 1) {
 
84
                m_state = AtStart;
 
85
                m_bind = name == QLatin1String("bind");
 
86
                m_jid.clear();
 
87
                m_resource.clear();
 
88
        } else if (m_depth == 2) {
 
89
                if (name == QLatin1String("jid"))
 
90
                        m_state = AtJid;
 
91
                else if (name == QLatin1String("resource"))
 
92
                        m_state = AtResource;
 
93
                else
 
94
                        m_state = AtStart;
 
95
        }
 
96
}
 
97
 
 
98
void BindQueryFactory::handleEndElement(const QStringRef &name, const QStringRef &uri)
 
99
{
 
100
        Q_UNUSED(name);
 
101
        Q_UNUSED(uri);
 
102
        m_depth--;
 
103
        if (m_depth == 1)
 
104
                m_state = AtStart;
 
105
}
 
106
 
 
107
void BindQueryFactory::handleCharacterData(const QStringRef &text)
 
108
{
 
109
        if (m_depth == 2 && m_state == AtResource)
 
110
                m_resource = text.toString();
 
111
        else if (m_depth == 2 && m_state == AtJid)
 
112
                m_jid = text.toString();
 
113
}
 
114
 
 
115
void BindQueryFactory::serialize(Payload *extension, QXmlStreamWriter *writer)
 
116
{
 
117
        BindQuery *query = se_cast<BindQuery*>(extension);
 
118
        writer->writeStartElement(QLatin1String(query->isBind() ? "bind" : "unbind"));
 
119
        writer->writeDefaultNamespace(NS_BIND);
 
120
        if (query->jid().isValid())
 
121
                writer->writeTextElement(QLatin1String("jid"), query->jid());
 
122
        else if (!query->resource().isEmpty())
 
123
                writer->writeTextElement(QLatin1String("resource"), query->resource());
 
124
        writer->writeEndElement();
 
125
}
 
126
 
 
127
Payload::Ptr BindQueryFactory::createPayload()
 
128
{
 
129
        return Payload::Ptr(new BindQuery(m_jid, m_resource, m_bind));
 
130
}
 
131
 
 
132
BindFeature::BindFeature() : StreamFeature(Custom)
 
133
{
 
134
        m_hasFeature = false;
 
135
}
 
136
 
 
137
void BindFeature::setStreamInfo(StreamInfo *info)
 
138
{
 
139
        StreamFeature::setStreamInfo(info);
 
140
        info->client()->registerPayload(new BindQueryFactory);
 
141
}
 
142
 
 
143
void BindFeature::reset()
 
144
{
 
145
        m_hasFeature = false;
 
146
}
 
147
 
 
148
bool BindFeature::canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
 
149
{
 
150
        Q_UNUSED(attributes);
 
151
        Logger::debug() << Q_FUNC_INFO;
 
152
        return name == QLatin1String("bind") && uri == NS_BIND;
 
153
}
 
154
 
 
155
void BindFeature::handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
 
156
{
 
157
        Q_UNUSED(name);
 
158
        Q_UNUSED(uri);
 
159
        Q_UNUSED(attributes);
 
160
        Logger::debug() << Q_FUNC_INFO;
 
161
        m_hasFeature = true;
 
162
}
 
163
 
 
164
void BindFeature::handleEndElement(const QStringRef &name, const QStringRef &uri)
 
165
{
 
166
        Q_UNUSED(name);
 
167
        Q_UNUSED(uri);
 
168
}
 
169
 
 
170
void BindFeature::handleCharacterData(const QStringRef &text)
 
171
{
 
172
        Q_UNUSED(text);
 
173
}
 
174
 
 
175
bool BindFeature::isActivatable()
 
176
{
 
177
        return m_hasFeature;
 
178
}
 
179
 
 
180
bool BindFeature::activate()
 
181
{
 
182
        IQ::Ptr iq(new ConnectionIQ(IQ::Set, JID()));
 
183
        iq->addExtension(new BindQuery(JID(), m_info->jid().resource()));
 
184
        m_info->client()->send(*iq.data(), this, SLOT(onIQResult(Jreen::IQ,int)), 0);
 
185
        return true;
 
186
}
 
187
 
 
188
void BindFeature::onIQResult(const IQ &iq, int context)
 
189
{
 
190
        Q_ASSERT(context == 0);
 
191
        BindQuery::Ptr query = iq.payload<BindQuery>();
 
192
        if (query && iq.subtype() == IQ::Result) {
 
193
                m_info->setJID(query->jid());
 
194
                m_info->completed(StreamInfo::ActivateNext);
 
195
        }
 
196
}
 
197
}