1 /* Copyright (C) 2018 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "precompiled.h"
19 
20 #include "glooxwrapper.h"
21 
22 #include <gloox/connectionlistener.h>
23 #include <gloox/error.h>
24 #include <gloox/glooxversion.h>
25 #include <gloox/messagehandler.h>
26 
27 #if OS_WIN
28 const std::string gloox::EmptyString = "";
29 #endif
30 
glooxwrapper_alloc(size_t size)31 void* glooxwrapper::glooxwrapper_alloc(size_t size)
32 {
33 	void* p = malloc(size);
34 	if (p == NULL)
35 		throw std::bad_alloc();
36 	return p;
37 }
38 
glooxwrapper_free(void * p)39 void glooxwrapper::glooxwrapper_free(void* p)
40 {
41 	free(p);
42 }
43 
44 
45 namespace glooxwrapper
46 {
47 
48 class ConnectionListenerWrapper : public gloox::ConnectionListener
49 {
50 	glooxwrapper::ConnectionListener* m_Wrapped;
51 public:
ConnectionListenerWrapper(glooxwrapper::ConnectionListener * wrapped)52 	ConnectionListenerWrapper(glooxwrapper::ConnectionListener* wrapped) : m_Wrapped(wrapped) {}
53 
onConnect()54 	virtual void onConnect()
55 	{
56 		m_Wrapped->onConnect();
57 	}
58 
onDisconnect(gloox::ConnectionError e)59 	virtual void onDisconnect(gloox::ConnectionError e)
60 	{
61 		m_Wrapped->onDisconnect(e);
62 	}
63 
onTLSConnect(const gloox::CertInfo & info)64 	virtual bool onTLSConnect(const gloox::CertInfo& info)
65 	{
66 		glooxwrapper::CertInfo infoWrapped;
67 #define COPY(n) infoWrapped.n = info.n
68 		COPY(status);
69 		COPY(chain);
70 		COPY(issuer);
71 		COPY(server);
72 		COPY(date_from);
73 		COPY(date_to);
74 		COPY(protocol);
75 		COPY(cipher);
76 		COPY(mac);
77 		COPY(compression);
78 #undef COPY
79 		return m_Wrapped->onTLSConnect(infoWrapped);
80 	}
81 };
82 
83 class IqHandlerWrapper : public gloox::IqHandler
84 {
85 	glooxwrapper::IqHandler* m_Wrapped;
86 public:
IqHandlerWrapper(glooxwrapper::IqHandler * wrapped)87 	IqHandlerWrapper(glooxwrapper::IqHandler* wrapped) : m_Wrapped(wrapped) {}
88 
handleIq(const gloox::IQ & iq)89 	virtual bool handleIq(const gloox::IQ& iq)
90 	{
91 		glooxwrapper::IQ iqWrapper(iq);
92 		return m_Wrapped->handleIq(iqWrapper);
93 	}
94 
handleIqID(const gloox::IQ & iq,int context)95 	virtual void handleIqID(const gloox::IQ& iq, int context)
96 	{
97 		glooxwrapper::IQ iqWrapper(iq);
98 		m_Wrapped->handleIqID(iqWrapper, context);
99 	}
100 };
101 
102 class MessageHandlerWrapper : public gloox::MessageHandler
103 {
104 	glooxwrapper::MessageHandler* m_Wrapped;
105 public:
MessageHandlerWrapper(glooxwrapper::MessageHandler * wrapped)106 	MessageHandlerWrapper(glooxwrapper::MessageHandler* wrapped) : m_Wrapped(wrapped) {}
107 
handleMessage(const gloox::Message & msg,gloox::MessageSession * UNUSED (session))108 	virtual void handleMessage(const gloox::Message& msg, gloox::MessageSession* UNUSED(session))
109 	{
110 		/* MessageSession not supported */
111 		glooxwrapper::Message msgWrapper(const_cast<gloox::Message*>(&msg), false);
112 		m_Wrapped->handleMessage(msgWrapper, NULL);
113 	}
114 };
115 
116 class MUCRoomHandlerWrapper : public gloox::MUCRoomHandler
117 {
118 	glooxwrapper::MUCRoomHandler* m_Wrapped;
119 public:
MUCRoomHandlerWrapper(glooxwrapper::MUCRoomHandler * wrapped)120 	MUCRoomHandlerWrapper(glooxwrapper::MUCRoomHandler* wrapped) : m_Wrapped(wrapped) {}
121 
~MUCRoomHandlerWrapper()122 	virtual ~MUCRoomHandlerWrapper() {}
123 
handleMUCParticipantPresence(gloox::MUCRoom * UNUSED (room),const gloox::MUCRoomParticipant participant,const gloox::Presence & presence)124 	virtual void handleMUCParticipantPresence(gloox::MUCRoom* UNUSED(room), const gloox::MUCRoomParticipant participant, const gloox::Presence& presence)
125 	{
126 		glooxwrapper::MUCRoomParticipant part;
127 		glooxwrapper::JID nick(*participant.nick);
128 		glooxwrapper::JID jid(*participant.jid);
129 		glooxwrapper::JID actor(*participant.actor);
130 		glooxwrapper::JID alternate(*participant.alternate);
131 		part.nick = participant.nick ? &nick : NULL;
132 		part.affiliation = participant.affiliation;
133 		part.role = participant.role;
134 		part.jid = participant.jid ? &jid : NULL;
135 		part.flags = participant.flags;
136 		part.reason = participant.reason;
137 		part.actor = participant.actor ? &actor : NULL;
138 		part.newNick = participant.newNick;
139 		part.status = participant.status;
140 		part.alternate = participant.alternate ? &alternate : NULL;
141 
142 		/* MUCRoom not supported */
143 		m_Wrapped->handleMUCParticipantPresence(NULL, part, glooxwrapper::Presence(presence.presence()));
144 
145 		/* gloox 1.0 leaks some JIDs (fixed in 1.0.1), so clean them up */
146 #if GLOOXVERSION == 0x10000
147 		delete participant.jid;
148 		delete participant.actor;
149 		delete participant.alternate;
150 #endif
151 	}
152 
handleMUCMessage(gloox::MUCRoom * UNUSED (room),const gloox::Message & msg,bool priv)153 	virtual void handleMUCMessage(gloox::MUCRoom* UNUSED(room), const gloox::Message& msg, bool priv)
154 	{
155 		glooxwrapper::Message msgWrapper(const_cast<gloox::Message*>(&msg), false);
156 
157 		/* MUCRoom not supported */
158 		m_Wrapped->handleMUCMessage(NULL, msgWrapper, priv);
159 	}
160 
handleMUCRoomCreation(gloox::MUCRoom * UNUSED (room))161 	virtual bool handleMUCRoomCreation(gloox::MUCRoom* UNUSED(room))
162 	{
163 		/* Not supported */
164 		return false;
165 	}
166 
handleMUCSubject(gloox::MUCRoom * UNUSED (room),const std::string & nick,const std::string & subject)167 	virtual void handleMUCSubject(gloox::MUCRoom* UNUSED(room), const std::string& nick, const std::string& subject)
168 	{
169 		/* MUCRoom not supported */
170 		m_Wrapped->handleMUCSubject(NULL, nick, subject);
171 	}
172 
handleMUCInviteDecline(gloox::MUCRoom * UNUSED (room),const gloox::JID & UNUSED (invitee),const std::string & UNUSED (reason))173 	virtual void handleMUCInviteDecline(gloox::MUCRoom* UNUSED(room), const gloox::JID& UNUSED(invitee), const std::string& UNUSED(reason))
174 	{
175 		/* Not supported */
176 	}
177 
handleMUCError(gloox::MUCRoom * UNUSED (room),gloox::StanzaError error)178 	virtual void handleMUCError(gloox::MUCRoom* UNUSED(room), gloox::StanzaError error)
179 	{
180 		/* MUCRoom not supported */
181 		m_Wrapped->handleMUCError(NULL, error);
182 	}
183 
handleMUCInfo(gloox::MUCRoom * UNUSED (room),int UNUSED (features),const std::string & UNUSED (name),const gloox::DataForm * UNUSED (infoForm))184 	virtual void handleMUCInfo(gloox::MUCRoom* UNUSED(room), int UNUSED(features), const std::string& UNUSED(name), const gloox::DataForm* UNUSED(infoForm))
185 	{
186 		/* Not supported */
187 	}
188 
handleMUCItems(gloox::MUCRoom * UNUSED (room),const gloox::Disco::ItemList & UNUSED (items))189 	virtual void handleMUCItems(gloox::MUCRoom* UNUSED(room), const gloox::Disco::ItemList& UNUSED(items))
190 	{
191 		/* Not supported */
192 	}
193 };
194 
195 class RegistrationHandlerWrapper : public gloox::RegistrationHandler
196 {
197 	glooxwrapper::RegistrationHandler* m_Wrapped;
198 public:
RegistrationHandlerWrapper(glooxwrapper::RegistrationHandler * wrapped)199 	RegistrationHandlerWrapper(glooxwrapper::RegistrationHandler* wrapped) : m_Wrapped(wrapped) {}
200 
handleRegistrationFields(const gloox::JID & from,int fields,std::string instructions)201 	virtual void handleRegistrationFields(const gloox::JID& from, int fields, std::string instructions)
202 	{
203 		glooxwrapper::JID fromWrapped(from);
204 		m_Wrapped->handleRegistrationFields(fromWrapped, fields, instructions);
205 	}
206 
handleAlreadyRegistered(const gloox::JID & from)207 	virtual void handleAlreadyRegistered(const gloox::JID& from)
208 	{
209 		glooxwrapper::JID fromWrapped(from);
210 		m_Wrapped->handleAlreadyRegistered(fromWrapped);
211 	}
212 
handleRegistrationResult(const gloox::JID & from,gloox::RegistrationResult regResult)213 	virtual void handleRegistrationResult(const gloox::JID& from, gloox::RegistrationResult regResult)
214 	{
215 		glooxwrapper::JID fromWrapped(from);
216 		m_Wrapped->handleRegistrationResult(fromWrapped, regResult);
217 	}
218 
handleDataForm(const gloox::JID & UNUSED (from),const gloox::DataForm & UNUSED (form))219 	virtual void handleDataForm(const gloox::JID& UNUSED(from), const gloox::DataForm& UNUSED(form))
220 	{
221 		/* DataForm not supported */
222 	}
223 
handleOOB(const gloox::JID & UNUSED (from),const gloox::OOB & UNUSED (oob))224 	virtual void handleOOB(const gloox::JID& UNUSED(from), const gloox::OOB& UNUSED(oob))
225 	{
226 		/* OOB not supported */
227 	}
228 };
229 
230 class StanzaExtensionWrapper : public gloox::StanzaExtension
231 {
232 public:
233 	const glooxwrapper::StanzaExtension* m_Wrapped;
234 	bool m_Owned;
235 	std::string m_FilterString;
236 
StanzaExtensionWrapper(const glooxwrapper::StanzaExtension * wrapped,bool owned)237 	StanzaExtensionWrapper(const glooxwrapper::StanzaExtension* wrapped, bool owned) :
238 	gloox::StanzaExtension(wrapped->extensionType()), m_Wrapped(wrapped), m_Owned(owned)
239 	{
240 		m_FilterString = m_Wrapped->filterString().to_string();
241 	}
242 
~StanzaExtensionWrapper()243 	~StanzaExtensionWrapper()
244 	{
245 		if (m_Owned)
246 			delete m_Wrapped;
247 	}
248 
filterString() const249 	virtual const std::string& filterString() const
250 	{
251 		return m_FilterString;
252 	}
253 
newInstance(const gloox::Tag * tag) const254 	virtual gloox::StanzaExtension* newInstance(const gloox::Tag* tag) const
255 	{
256 		glooxwrapper::Tag* tagWrapper = glooxwrapper::Tag::allocate(const_cast<gloox::Tag*>(tag), false);
257 		gloox::StanzaExtension* ret = new StanzaExtensionWrapper(m_Wrapped->newInstance(tagWrapper), true);
258 		glooxwrapper::Tag::free(tagWrapper);
259 		return ret;
260 	}
261 
tag() const262 	virtual gloox::Tag* tag() const
263 	{
264 		glooxwrapper::Tag* wrapper = m_Wrapped->tag();
265 		gloox::Tag* ret = wrapper->stealWrapped();
266 		glooxwrapper::Tag::free(wrapper);
267 		return ret;
268 	}
269 
clone() const270 	virtual gloox::StanzaExtension* clone() const
271 	{
272 		return new StanzaExtensionWrapper(m_Wrapped->clone(), true);
273 	}
274 };
275 
276 class SessionHandlerWrapper : public gloox::Jingle::SessionHandler
277 {
278 public:
279 	glooxwrapper::Jingle::SessionHandler* m_Wrapped;
280 	bool m_Owned;
281 
SessionHandlerWrapper(glooxwrapper::Jingle::SessionHandler * wrapped,bool owned)282 	SessionHandlerWrapper(glooxwrapper::Jingle::SessionHandler* wrapped, bool owned)
283 		: m_Wrapped(wrapped), m_Owned(owned) {}
284 
handleSessionAction(gloox::Jingle::Action action,gloox::Jingle::Session * session,const gloox::Jingle::Session::Jingle * jingle)285 	virtual void handleSessionAction(gloox::Jingle::Action action, gloox::Jingle::Session* session, const gloox::Jingle::Session::Jingle* jingle)
286 	{
287 		m_Wrapped->handleSessionAction(action, new glooxwrapper::Jingle::Session(session, false), new glooxwrapper::Jingle::Session::Jingle(jingle, false));
288 	}
289 
handleSessionActionError(gloox::Jingle::Action UNUSED (action),gloox::Jingle::Session * UNUSED (session),const gloox::Error * UNUSED (error))290 	virtual void handleSessionActionError(gloox::Jingle::Action UNUSED(action), gloox::Jingle::Session* UNUSED(session), const gloox::Error* UNUSED(error))
291 	{
292 	}
293 
handleIncomingSession(gloox::Jingle::Session * UNUSED (session))294 	virtual void handleIncomingSession(gloox::Jingle::Session* UNUSED(session))
295 	{
296 	}
297 };
298 
299 class ClientImpl
300 {
301 public:
302 	// List of registered callback wrappers, to get deleted when Client is deleted
303 	std::list<shared_ptr<gloox::ConnectionListener> > m_ConnectionListeners;
304 	std::list<shared_ptr<gloox::MessageHandler> > m_MessageHandlers;
305 	std::list<shared_ptr<gloox::IqHandler> > m_IqHandlers;
306 };
307 
308 static const std::string XMLNS = "xmlns";
309 static const std::string XMLNS_JINGLE_0AD_GAME = "urn:xmpp:jingle:apps:0ad-game:1";
310 
311 } // namespace glooxwrapper
312 
313 
Client(const string & server)314 glooxwrapper::Client::Client(const string& server)
315 {
316 	m_Wrapped = new gloox::Client(server.to_string());
317 	m_DiscoWrapper = new glooxwrapper::Disco(m_Wrapped->disco());
318 	m_Impl = new ClientImpl;
319 }
320 
Client(const JID & jid,const string & password,int port)321 glooxwrapper::Client::Client(const JID& jid, const string& password, int port)
322 {
323 	m_Wrapped = new gloox::Client(jid.getWrapped(), password.to_string(), port);
324 	m_DiscoWrapper = new glooxwrapper::Disco(m_Wrapped->disco());
325 	m_Impl = new ClientImpl;
326 }
327 
~Client()328 glooxwrapper::Client::~Client()
329 {
330 	delete m_Wrapped;
331 	delete m_DiscoWrapper;
332 	delete m_Impl;
333 }
334 
connect(bool block)335 bool glooxwrapper::Client::connect(bool block)
336 {
337 	return m_Wrapped->connect(block);
338 }
339 
recv(int timeout)340 gloox::ConnectionError glooxwrapper::Client::recv(int timeout)
341 {
342 	return m_Wrapped->recv(timeout);
343 }
344 
getID() const345 const glooxwrapper::string glooxwrapper::Client::getID() const
346 {
347 	return m_Wrapped->getID();
348 }
349 
send(const IQ & iq)350 void glooxwrapper::Client::send(const IQ& iq)
351 {
352 	m_Wrapped->send(iq.getWrapped());
353 }
354 
setTls(gloox::TLSPolicy tls)355 void glooxwrapper::Client::setTls(gloox::TLSPolicy tls)
356 {
357 	m_Wrapped->setTls(tls);
358 }
359 
setCompression(bool compression)360 void glooxwrapper::Client::setCompression(bool compression)
361 {
362 	m_Wrapped->setCompression(compression);
363 }
364 
setSASLMechanisms(int mechanisms)365 void glooxwrapper::Client::setSASLMechanisms(int mechanisms)
366 {
367 	m_Wrapped->setSASLMechanisms(mechanisms);
368 }
369 
disconnect()370 void glooxwrapper::Client::disconnect()
371 {
372 	m_Wrapped->disconnect();
373 }
374 
registerStanzaExtension(glooxwrapper::StanzaExtension * ext)375 void glooxwrapper::Client::registerStanzaExtension(glooxwrapper::StanzaExtension* ext)
376 {
377 	gloox::StanzaExtension* stanza = new StanzaExtensionWrapper(ext, true);
378 	m_Wrapped->registerStanzaExtension(stanza);
379 }
380 
registerConnectionListener(glooxwrapper::ConnectionListener * hnd)381 void glooxwrapper::Client::registerConnectionListener(glooxwrapper::ConnectionListener* hnd)
382 {
383 	gloox::ConnectionListener* listener = new ConnectionListenerWrapper(hnd);
384 	m_Wrapped->registerConnectionListener(listener);
385 	m_Impl->m_ConnectionListeners.push_back(shared_ptr<gloox::ConnectionListener>(listener));
386 }
387 
registerMessageHandler(glooxwrapper::MessageHandler * hnd)388 void glooxwrapper::Client::registerMessageHandler(glooxwrapper::MessageHandler* hnd)
389 {
390 	gloox::MessageHandler* handler = new MessageHandlerWrapper(hnd);
391 	m_Wrapped->registerMessageHandler(handler);
392 	m_Impl->m_MessageHandlers.push_back(shared_ptr<gloox::MessageHandler>(handler));
393 }
394 
registerIqHandler(glooxwrapper::IqHandler * ih,int exttype)395 void glooxwrapper::Client::registerIqHandler(glooxwrapper::IqHandler* ih, int exttype)
396 {
397 	gloox::IqHandler* handler = new IqHandlerWrapper(ih);
398 	m_Wrapped->registerIqHandler(handler, exttype);
399 	m_Impl->m_IqHandlers.push_back(shared_ptr<gloox::IqHandler>(handler));
400 }
401 
removePresenceExtension(int type)402 bool glooxwrapper::Client::removePresenceExtension(int type)
403 {
404 	return m_Wrapped->removePresenceExtension(type);
405 }
406 
setPresence(gloox::Presence::PresenceType pres,int priority,const string & status)407 void glooxwrapper::Client::setPresence(gloox::Presence::PresenceType pres, int priority, const string& status)
408 {
409 	m_Wrapped->setPresence(pres, priority, status.to_string());
410 }
411 
412 
DelayedDelivery(const gloox::DelayedDelivery * wrapped)413 glooxwrapper::DelayedDelivery::DelayedDelivery(const gloox::DelayedDelivery* wrapped)
414 {
415 	m_Wrapped = wrapped;
416 }
417 
stamp() const418 const glooxwrapper::string glooxwrapper::DelayedDelivery::stamp() const
419 {
420 	return m_Wrapped->stamp();
421 }
422 
423 
Disco(gloox::Disco * wrapped)424 glooxwrapper::Disco::Disco(gloox::Disco* wrapped)
425 {
426 	m_Wrapped = wrapped;
427 }
428 
setVersion(const string & name,const string & version,const string & os)429 void glooxwrapper::Disco::setVersion(const string& name, const string& version, const string& os)
430 {
431 	m_Wrapped->setVersion(name.to_string(), version.to_string(), os.to_string());
432 }
433 
setIdentity(const string & category,const string & type,const string & name)434 void glooxwrapper::Disco::setIdentity(const string& category, const string& type, const string& name)
435 {
436 	m_Wrapped->setIdentity(category.to_string(), type.to_string(), name.to_string());
437 }
438 
439 
IQ(gloox::IQ::IqType type,const JID & to,const string & id)440 glooxwrapper::IQ::IQ(gloox::IQ::IqType type, const JID& to, const string& id)
441 {
442 	m_Wrapped = new gloox::IQ(type, to.getWrapped(), id.to_string());
443 	m_Owned = true;
444 }
445 
~IQ()446 glooxwrapper::IQ::~IQ()
447 {
448 	if (m_Owned)
449 		delete m_Wrapped;
450 }
451 
addExtension(const glooxwrapper::StanzaExtension * se)452 void glooxwrapper::IQ::addExtension(const glooxwrapper::StanzaExtension* se)
453 {
454 	m_Wrapped->addExtension(new StanzaExtensionWrapper(se, true));
455 }
456 
findExtension(int type) const457 const glooxwrapper::StanzaExtension* glooxwrapper::IQ::findExtension(int type) const
458 {
459 	const gloox::StanzaExtension* ext = m_Wrapped->findExtension(type);
460 	if (!ext)
461 		return NULL;
462 	return static_cast<const StanzaExtensionWrapper*>(ext)->m_Wrapped;
463 }
464 
error_error() const465 gloox::StanzaError glooxwrapper::IQ::error_error() const
466 {
467 	const gloox::Error* error = m_Wrapped->error();
468 	if (!error)
469 		return gloox::StanzaErrorInternalServerError;
470 	return error->error();
471 }
472 
tag() const473 glooxwrapper::Tag* glooxwrapper::IQ::tag() const
474 {
475 	return Tag::allocate(m_Wrapped->tag(), true);
476 }
477 
subtype() const478 gloox::IQ::IqType glooxwrapper::IQ::subtype() const
479 {
480 	return m_Wrapped->subtype();
481 }
482 
id() const483 const glooxwrapper::string glooxwrapper::IQ::id() const
484 {
485 	return m_Wrapped->id();
486 }
487 
from() const488 const gloox::JID& glooxwrapper::IQ::from() const
489 {
490 	return m_Wrapped->from();
491 }
492 
JID()493 glooxwrapper::JID::JID()
494 {
495 	m_Wrapped = new gloox::JID();
496 	m_Owned = true;
497 }
498 
JID(const glooxwrapper::string & jid)499 glooxwrapper::JID::JID(const glooxwrapper::string& jid)
500 {
501 	m_Wrapped = new gloox::JID(jid.to_string());
502 	m_Owned = true;
503 }
504 
init(const char * data,size_t len)505 void glooxwrapper::JID::init(const char* data, size_t len)
506 {
507 	m_Wrapped = new gloox::JID(std::string(data, data+len));
508 	m_Owned = true;
509 }
510 
~JID()511 glooxwrapper::JID::~JID()
512 {
513 	if (m_Owned)
514 		delete m_Wrapped;
515 }
516 
username() const517 glooxwrapper::string glooxwrapper::JID::username() const
518 {
519 	return m_Wrapped->username();
520 }
521 
resource() const522 glooxwrapper::string glooxwrapper::JID::resource() const
523 {
524 	return m_Wrapped->resource();
525 };
526 
527 
Message(gloox::Message * wrapped,bool owned)528 glooxwrapper::Message::Message(gloox::Message* wrapped, bool owned)
529 	: m_Wrapped(wrapped), m_Owned(owned)
530 {
531 	m_From = new glooxwrapper::JID(m_Wrapped->from());
532 }
533 
~Message()534 glooxwrapper::Message::~Message()
535 {
536 	if (m_Owned)
537 		delete m_Wrapped;
538 	delete m_From;
539 }
540 
subtype() const541 gloox::Message::MessageType glooxwrapper::Message::subtype() const
542 {
543 	return m_Wrapped->subtype();
544 }
545 
from() const546 const glooxwrapper::JID& glooxwrapper::Message::from() const
547 {
548 	return *m_From;
549 }
550 
body() const551 glooxwrapper::string glooxwrapper::Message::body() const
552 {
553 	return m_Wrapped->body();
554 }
555 
subject(const string & lang) const556 glooxwrapper::string glooxwrapper::Message::subject(const string& lang) const
557 {
558 	return m_Wrapped->subject(lang.to_string());
559 }
560 
thread() const561 glooxwrapper::string glooxwrapper::Message::thread() const
562 {
563 	return m_Wrapped->thread();
564 }
565 
when() const566 const glooxwrapper::DelayedDelivery* glooxwrapper::Message::when() const
567 {
568 	const gloox::DelayedDelivery* wrapped = m_Wrapped->when();
569 	if (wrapped == 0)
570 		return 0;
571 	return new glooxwrapper::DelayedDelivery(wrapped);
572 }
573 
574 
MUCRoom(Client * parent,const JID & nick,MUCRoomHandler * mrh,MUCRoomConfigHandler * UNUSED (mrch))575 glooxwrapper::MUCRoom::MUCRoom(Client* parent, const JID& nick, MUCRoomHandler* mrh, MUCRoomConfigHandler* UNUSED(mrch))
576 {
577 	m_HandlerWrapper = new MUCRoomHandlerWrapper(mrh);
578 	m_Wrapped = new gloox::MUCRoom(parent ? parent->getWrapped() : NULL, nick.getWrapped(), m_HandlerWrapper);
579 }
580 
~MUCRoom()581 glooxwrapper::MUCRoom::~MUCRoom()
582 {
583 	delete m_Wrapped;
584 	delete m_HandlerWrapper;
585 }
586 
nick() const587 const glooxwrapper::string glooxwrapper::MUCRoom::nick() const
588 {
589 	return m_Wrapped->nick();
590 }
591 
join(gloox::Presence::PresenceType type,const string & status,int priority)592 void glooxwrapper::MUCRoom::join(gloox::Presence::PresenceType type, const string& status, int priority)
593 {
594 	m_Wrapped->join(type, status.to_string(), priority);
595 }
596 
leave(const string & msg)597 void glooxwrapper::MUCRoom::leave(const string& msg)
598 {
599 	m_Wrapped->leave(msg.to_string());
600 }
601 
send(const string & message)602 void glooxwrapper::MUCRoom::send(const string& message)
603 {
604 	m_Wrapped->send(message.to_string());
605 }
606 
setNick(const string & nick)607 void glooxwrapper::MUCRoom::setNick(const string& nick)
608 {
609 	m_Wrapped->setNick(nick.to_string());
610 }
611 
setPresence(gloox::Presence::PresenceType presence,const string & msg)612 void glooxwrapper::MUCRoom::setPresence(gloox::Presence::PresenceType presence, const string& msg)
613 {
614 	m_Wrapped->setPresence(presence, msg.to_string());
615 }
616 
setRequestHistory(int value,gloox::MUCRoom::HistoryRequestType type)617 void glooxwrapper::MUCRoom::setRequestHistory(int value, gloox::MUCRoom::HistoryRequestType type)
618 {
619 	m_Wrapped->setRequestHistory(value, type);
620 }
621 
kick(const string & nick,const string & reason)622 void glooxwrapper::MUCRoom::kick(const string& nick, const string& reason)
623 {
624 	m_Wrapped->kick(nick.to_string(), reason.to_string());
625 }
626 
ban(const string & nick,const string & reason)627 void glooxwrapper::MUCRoom::ban(const string& nick, const string& reason)
628 {
629 	m_Wrapped->ban(nick.to_string(), reason.to_string());
630 }
631 
632 
Registration(Client * parent)633 glooxwrapper::Registration::Registration(Client* parent)
634 {
635 	m_Wrapped = new gloox::Registration(parent->getWrapped());
636 }
637 
~Registration()638 glooxwrapper::Registration::~Registration()
639 {
640 	delete m_Wrapped;
641 }
642 
fetchRegistrationFields()643 void glooxwrapper::Registration::fetchRegistrationFields()
644 {
645 	m_Wrapped->fetchRegistrationFields();
646 }
647 
createAccount(int fields,const glooxwrapper::RegistrationFields & values)648 bool glooxwrapper::Registration::createAccount(int fields, const glooxwrapper::RegistrationFields& values)
649 {
650 	gloox::RegistrationFields valuesUnwrapped;
651 #define COPY(n) valuesUnwrapped.n = values.n.to_string()
652 	COPY(username);
653 	COPY(nick);
654 	COPY(password);
655 	COPY(name);
656 	COPY(first);
657 	COPY(last);
658 	COPY(email);
659 	COPY(address);
660 	COPY(city);
661 	COPY(state);
662 	COPY(zip);
663 	COPY(phone);
664 	COPY(url);
665 	COPY(date);
666 	COPY(misc);
667 	COPY(text);
668 #undef COPY
669 	return m_Wrapped->createAccount(fields, valuesUnwrapped);
670 }
671 
registerRegistrationHandler(RegistrationHandler * rh)672 void glooxwrapper::Registration::registerRegistrationHandler(RegistrationHandler* rh)
673 {
674 	gloox::RegistrationHandler* handler = new RegistrationHandlerWrapper(rh);
675 	m_Wrapped->registerRegistrationHandler(handler);
676 	m_RegistrationHandlers.push_back(shared_ptr<gloox::RegistrationHandler>(handler));
677 }
678 
679 
Tag(const string & name)680 glooxwrapper::Tag::Tag(const string& name)
681 {
682 	m_Wrapped = new gloox::Tag(name.to_string());
683 	m_Owned = true;
684 }
685 
Tag(const string & name,const string & cdata)686 glooxwrapper::Tag::Tag(const string& name, const string& cdata)
687 {
688 	m_Wrapped = new gloox::Tag(name.to_string(), cdata.to_string());
689 	m_Owned = true;
690 }
691 
~Tag()692 glooxwrapper::Tag::~Tag()
693 {
694 	if (m_Owned)
695 		delete m_Wrapped;
696 }
697 
allocate(const string & name)698 glooxwrapper::Tag* glooxwrapper::Tag::allocate(const string& name)
699 {
700 	return new glooxwrapper::Tag(name);
701 }
702 
allocate(const string & name,const string & cdata)703 glooxwrapper::Tag* glooxwrapper::Tag::allocate(const string& name, const string& cdata)
704 {
705 	return new glooxwrapper::Tag(name, cdata);
706 }
707 
allocate(gloox::Tag * wrapped,bool owned)708 glooxwrapper::Tag* glooxwrapper::Tag::allocate(gloox::Tag* wrapped, bool owned)
709 {
710 	return new glooxwrapper::Tag(wrapped, owned);
711 }
712 
free(const glooxwrapper::Tag * tag)713 void glooxwrapper::Tag::free(const glooxwrapper::Tag* tag)
714 {
715 	delete tag;
716 }
717 
addAttribute(const string & name,const string & value)718 bool glooxwrapper::Tag::addAttribute(const string& name, const string& value)
719 {
720 	return m_Wrapped->addAttribute(name.to_string(), value.to_string());
721 }
722 
findAttribute(const string & name) const723 glooxwrapper::string glooxwrapper::Tag::findAttribute(const string& name) const
724 {
725 	return m_Wrapped->findAttribute(name.to_string());
726 }
727 
clone() const728 glooxwrapper::Tag* glooxwrapper::Tag::clone() const
729 {
730 	return new glooxwrapper::Tag(m_Wrapped->clone(), true);
731 }
732 
xmlns() const733 glooxwrapper::string glooxwrapper::Tag::xmlns() const
734 {
735 	return m_Wrapped->xmlns();
736 }
737 
setXmlns(const string & xmlns)738 bool glooxwrapper::Tag::setXmlns(const string& xmlns)
739 {
740 	return m_Wrapped->setXmlns(xmlns.to_string());
741 }
742 
xml() const743 glooxwrapper::string glooxwrapper::Tag::xml() const
744 {
745 	return m_Wrapped->xml();
746 }
747 
addChild(Tag * child)748 void glooxwrapper::Tag::addChild(Tag* child)
749 {
750 	m_Wrapped->addChild(child->stealWrapped());
751 	Tag::free(child);
752 }
753 
name() const754 glooxwrapper::string glooxwrapper::Tag::name() const
755 {
756 	return m_Wrapped->name();
757 }
758 
cdata() const759 glooxwrapper::string glooxwrapper::Tag::cdata() const
760 {
761 	return m_Wrapped->cdata();
762 }
763 
findTag_clone(const string & expression) const764 const glooxwrapper::Tag* glooxwrapper::Tag::findTag_clone(const string& expression) const
765 {
766 	const gloox::Tag* tag = m_Wrapped->findTag(expression.to_string());
767 	if (!tag)
768 		return NULL;
769 	return new glooxwrapper::Tag(const_cast<gloox::Tag*>(tag), false);
770 }
771 
findTagList_clone(const string & expression) const772 glooxwrapper::ConstTagList glooxwrapper::Tag::findTagList_clone(const string& expression) const
773 {
774 	glooxwrapper::ConstTagList tagListWrapper;
775 	for (const gloox::Tag* const& t : m_Wrapped->findTagList(expression.to_string()))
776 		tagListWrapper.push_back(new glooxwrapper::Tag(const_cast<gloox::Tag*>(t), false));
777 	return tagListWrapper;
778 }
779 
~Plugin()780 glooxwrapper::Jingle::Plugin::~Plugin()
781 {
782 	if (m_Owned)
783 		delete m_Wrapped;
784 }
785 
findPlugin(int type) const786 const glooxwrapper::Jingle::Plugin glooxwrapper::Jingle::Plugin::findPlugin(int type) const
787 {
788 	return glooxwrapper::Jingle::Plugin(m_Wrapped->findPlugin(type), false);
789 }
790 
Content(const string & name,const PluginList & plugins)791 glooxwrapper::Jingle::Content::Content(const string& name, const PluginList& plugins)
792 	: glooxwrapper::Jingle::Plugin(NULL, false)
793 {
794 	gloox::Jingle::PluginList glooxPluginList;
795 	for (const glooxwrapper::Jingle::Plugin* const& plugin: plugins)
796 		glooxPluginList.push_back(plugin->getWrapped());
797 
798 	m_Wrapped = new gloox::Jingle::Content(name.to_string(), glooxPluginList);
799 	m_Owned = true;
800 }
801 
Content()802 glooxwrapper::Jingle::Content::Content()
803 	: glooxwrapper::Jingle::Plugin(NULL, false)
804 {
805 	m_Wrapped = new gloox::Jingle::Content();
806 	m_Owned = true;
807 }
808 
plugins() const809 const glooxwrapper::Jingle::PluginList glooxwrapper::Jingle::Session::Jingle::plugins() const
810 {
811 	glooxwrapper::Jingle::PluginList pluginListWrapper;
812 	for (const gloox::Jingle::Plugin* const& plugin : m_Wrapped->plugins())
813 		pluginListWrapper.push_back(new glooxwrapper::Jingle::Plugin(const_cast<gloox::Jingle::Plugin*>(plugin), false));
814 	return pluginListWrapper;
815 }
816 
getCandidate() const817 glooxwrapper::Jingle::ICEUDP::Candidate glooxwrapper::Jingle::Session::Jingle::getCandidate() const
818 {
819 	const gloox::Jingle::Content* content = static_cast<const gloox::Jingle::Content*>(m_Wrapped->plugins().front());
820 	if (!content)
821 		return glooxwrapper::Jingle::ICEUDP::Candidate();
822 
823 	const gloox::Jingle::ICEUDP* iceUDP = static_cast<const gloox::Jingle::ICEUDP*>(content->findPlugin(gloox::Jingle::PluginICEUDP));
824 	if (!iceUDP)
825 		return glooxwrapper::Jingle::ICEUDP::Candidate();
826 
827 	gloox::Jingle::ICEUDP::Candidate glooxCandidate = iceUDP->candidates().front();
828 	return glooxwrapper::Jingle::ICEUDP::Candidate{glooxCandidate.ip, glooxCandidate.port};
829 }
830 
sessionInitiate(char * ipStr,u16 port)831 bool glooxwrapper::Jingle::Session::sessionInitiate(char* ipStr, u16 port)
832 {
833 	gloox::Jingle::ICEUDP::CandidateList* candidateList = new gloox::Jingle::ICEUDP::CandidateList();
834 
835 	candidateList->push_back(gloox::Jingle::ICEUDP::Candidate
836 	{
837 		"1", // component_id,
838 		"1", // foundation
839 		"0", // andidate_generation
840 		"1", // candidate_id
841 		ipStr,
842 		"0", // network
843 		port,
844 		0, // priotiry
845 		"udp",
846 		"", // base_ip
847 		0, // base_port
848 		gloox::Jingle::ICEUDP::ServerReflexive
849 	});
850 
851 	gloox::Jingle::PluginList* pluginList = new gloox::Jingle::PluginList();
852 	pluginList->push_back(new gloox::Jingle::ICEUDP(/*local_pwd*/"", /*local_ufrag*/"", *candidateList));
853 	return m_Wrapped->sessionInitiate(new gloox::Jingle::Content(std::string("game-data"), *pluginList));
854 }
855 
ICEUDP(glooxwrapper::Jingle::ICEUDP::CandidateList & candidates)856 glooxwrapper::Jingle::ICEUDP::ICEUDP(glooxwrapper::Jingle::ICEUDP::CandidateList& candidates)
857 	: glooxwrapper::Jingle::Plugin(NULL, false)
858 {
859 	gloox::Jingle::ICEUDP::CandidateList glooxCandidates;
860 	for (const glooxwrapper::Jingle::ICEUDP::Candidate& candidate : candidates)
861 		glooxCandidates.push_back(gloox::Jingle::ICEUDP::Candidate
862 			{
863 				"1", // component_id,
864 				"1", // foundation
865 				"0", // candidate_generation
866 				"1", // candidate_id
867 				candidate.ip.to_string(),
868 				"0", // network
869 				candidate.port,
870 				0, // priority
871 				"udp",
872 				"", // base_ip
873 				0, // base_port
874 				gloox::Jingle::ICEUDP::ServerReflexive
875 			});
876 
877 	m_Wrapped = new gloox::Jingle::ICEUDP(/*local_pwd*/"", /*local_ufrag*/"", glooxCandidates);
878 	m_Owned = true;
879 }
880 
ICEUDP()881 glooxwrapper::Jingle::ICEUDP::ICEUDP()
882 	: glooxwrapper::Jingle::Plugin(NULL, false)
883 {
884 	m_Wrapped = new gloox::Jingle::ICEUDP();
885 	m_Owned = true;
886 }
887 
candidates() const888 const glooxwrapper::Jingle::ICEUDP::CandidateList glooxwrapper::Jingle::ICEUDP::candidates() const
889 {
890 	glooxwrapper::Jingle::ICEUDP::CandidateList candidateListWrapper;
891 	for (const gloox::Jingle::ICEUDP::Candidate& candidate : static_cast<const gloox::Jingle::ICEUDP*>(m_Wrapped)->candidates())
892 		candidateListWrapper.push_back(glooxwrapper::Jingle::ICEUDP::Candidate{candidate.ip, candidate.port});
893 	return candidateListWrapper;
894 }
895 
SessionManager(Client * parent,Jingle::SessionHandler * sh)896 glooxwrapper::SessionManager::SessionManager(Client* parent, Jingle::SessionHandler* sh)
897 {
898 	m_HandlerWrapper = new SessionHandlerWrapper(sh, false);
899 	m_Wrapped = new gloox::Jingle::SessionManager(parent->getWrapped(), m_HandlerWrapper);
900 }
901 
~SessionManager()902 glooxwrapper::SessionManager::~SessionManager()
903 {
904 	delete m_Wrapped;
905 	delete m_HandlerWrapper;
906 }
907 
registerPlugins()908 void glooxwrapper::SessionManager::registerPlugins()
909 {
910 	m_Wrapped->registerPlugin(new gloox::Jingle::Content());
911 	m_Wrapped->registerPlugin(new gloox::Jingle::ICEUDP());
912 }
913 
createSession(const JID & callee)914 glooxwrapper::Jingle::Session glooxwrapper::SessionManager::createSession(const JID& callee)
915 {
916 	gloox::Jingle::Session* glooxSession = m_Wrapped->createSession(callee.getWrapped(), m_HandlerWrapper);
917 	return glooxwrapper::Jingle::Session(glooxSession, false);
918 }
919