Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(761)

Side by Side Diff: webrtc/libjingle/xmpp/chatroommoduleimpl.cc

Issue 2617443003: Remove webrtc/libjingle/{xmllite,xmpp} (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/libjingle/xmpp/chatroommodule.h ('k') | webrtc/libjingle/xmpp/constants.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <algorithm>
12 #include <iostream>
13 #include <map>
14 #include <memory>
15 #include <sstream>
16 #include <string>
17 #include <vector>
18 #include "webrtc/libjingle/xmpp/chatroommodule.h"
19 #include "webrtc/libjingle/xmpp/constants.h"
20 #include "webrtc/libjingle/xmpp/moduleimpl.h"
21 #include "webrtc/base/arraysize.h"
22 #include "webrtc/base/common.h"
23
24 namespace buzz {
25
26 // forward declarations
27 class XmppChatroomImpl;
28 class XmppChatroomMemberImpl;
29
30 //! Module that encapsulates multiple chatrooms.
31 //! Each chatroom is represented by an XmppChatroomImpl instance
32 class XmppChatroomModuleImpl : public XmppChatroomModule,
33 public XmppModuleImpl, public XmppIqHandler {
34 public:
35 IMPLEMENT_XMPPMODULE
36
37 // Creates a chatroom with specified Jid
38 XmppChatroomModuleImpl();
39 ~XmppChatroomModuleImpl();
40
41 // XmppChatroomModule
42 virtual XmppReturnStatus set_chatroom_handler(XmppChatroomHandler* handler);
43 virtual XmppChatroomHandler* chatroom_handler();
44 virtual XmppReturnStatus set_chatroom_jid(const Jid& chatroom_jid);
45 virtual const Jid& chatroom_jid() const;
46 virtual XmppReturnStatus set_nickname(const std::string& nickname);
47 virtual const std::string& nickname() const;
48 virtual const Jid member_jid() const;
49 virtual XmppReturnStatus RequestEnterChatroom(const std::string& password,
50 const std::string& client_version,
51 const std::string& locale);
52 virtual XmppReturnStatus RequestExitChatroom();
53 virtual XmppReturnStatus RequestConnectionStatusChange(
54 XmppPresenceConnectionStatus connection_status);
55 virtual size_t GetChatroomMemberCount();
56 virtual XmppReturnStatus CreateMemberEnumerator(XmppChatroomMemberEnumerator** enumerator);
57 virtual const std::string subject();
58 virtual XmppChatroomState state() { return chatroom_state_; }
59 virtual XmppReturnStatus SendMessage(const XmlElement& message);
60
61 // XmppModule
62 virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) {RT C_UNUSED2(cookie, pelStanza);}
63 virtual bool HandleStanza(const XmlElement *);
64
65 private:
66 friend class XmppChatroomMemberEnumeratorImpl;
67
68 XmppReturnStatus ServerChangeMyPresence(const XmlElement& presence);
69 XmppReturnStatus ClientChangeMyPresence(XmppChatroomState new_state);
70 XmppReturnStatus ChangePresence(XmppChatroomState new_state, const XmlElement* presence, bool isServer);
71 XmppReturnStatus ServerChangedOtherPresence(const XmlElement& presence_element );
72 XmppChatroomEnteredStatus GetEnterFailureFromXml(const XmlElement* presence);
73 XmppChatroomExitedStatus GetExitFailureFromXml(const XmlElement* presence);
74
75 bool CheckEnterChatroomStateOk();
76
77 void FireEnteredStatus(const XmlElement* presence,
78 XmppChatroomEnteredStatus status);
79 void FireExitStatus(XmppChatroomExitedStatus status);
80 void FireMessageReceived(const XmlElement& message);
81 void FireMemberEntered(const XmppChatroomMember* entered_member);
82 void FireMemberChanged(const XmppChatroomMember* changed_member);
83 void FireMemberExited(const XmppChatroomMember* exited_member);
84
85
86 typedef std::map<Jid, XmppChatroomMemberImpl*> JidMemberMap;
87
88 XmppChatroomHandler* chatroom_handler_;
89 Jid chatroom_jid_;
90 std::string nickname_;
91 XmppChatroomState chatroom_state_;
92 JidMemberMap chatroom_jid_members_;
93 int chatroom_jid_members_version_;
94 };
95
96
97 class XmppChatroomMemberImpl : public XmppChatroomMember {
98 public:
99 ~XmppChatroomMemberImpl() {}
100 XmppReturnStatus SetPresence(const XmppPresence* presence);
101
102 // XmppChatroomMember
103 const Jid member_jid() const;
104 const Jid full_jid() const;
105 const std::string name() const;
106 const XmppPresence* presence() const;
107
108 private:
109 std::unique_ptr<XmppPresence> presence_;
110 };
111
112 class XmppChatroomMemberEnumeratorImpl :
113 public XmppChatroomMemberEnumerator {
114 public:
115 XmppChatroomMemberEnumeratorImpl(XmppChatroomModuleImpl::JidMemberMap* chatroo m_jid_members,
116 int* map_version);
117
118 // XmppChatroomMemberEnumerator
119 virtual XmppChatroomMember* current();
120 virtual bool Next();
121 virtual bool Prev();
122 virtual bool IsValid();
123 virtual bool IsBeforeBeginning();
124 virtual bool IsAfterEnd();
125
126 private:
127 XmppChatroomModuleImpl::JidMemberMap* map_;
128 int map_version_created_;
129 int* map_version_;
130 XmppChatroomModuleImpl::JidMemberMap::iterator iterator_;
131 bool before_beginning_;
132 };
133
134
135 // XmppChatroomModuleImpl ------------------------------------------------
136 XmppChatroomModule *
137 XmppChatroomModule::Create() {
138 return new XmppChatroomModuleImpl();
139 }
140
141 XmppChatroomModuleImpl::XmppChatroomModuleImpl() :
142 chatroom_handler_(NULL),
143 chatroom_jid_(STR_EMPTY),
144 chatroom_state_(XMPP_CHATROOM_STATE_NOT_IN_ROOM),
145 chatroom_jid_members_version_(0) {
146 }
147
148 XmppChatroomModuleImpl::~XmppChatroomModuleImpl() {
149 JidMemberMap::iterator iterator = chatroom_jid_members_.begin();
150 while (iterator != chatroom_jid_members_.end()) {
151 delete iterator->second;
152 iterator++;
153 }
154 }
155
156
157 bool
158 XmppChatroomModuleImpl::HandleStanza(const XmlElement* stanza) {
159 ASSERT(engine() != NULL);
160
161 // we handle stanzas that are for one of our chatrooms
162 Jid from_jid = Jid(stanza->Attr(QN_FROM));
163 // see if it's one of our chatrooms
164 if (chatroom_jid_ != from_jid.BareJid()) {
165 return false; // not one of our chatrooms
166 } else {
167 // handle presence stanza
168 if (stanza->Name() == QN_PRESENCE) {
169 if (from_jid == member_jid()) {
170 ServerChangeMyPresence(*stanza);
171 } else {
172 ServerChangedOtherPresence(*stanza);
173 }
174 } else if (stanza->Name() == QN_MESSAGE) {
175 FireMessageReceived(*stanza);
176 }
177 return true;
178 }
179 }
180
181
182 XmppReturnStatus
183 XmppChatroomModuleImpl::set_chatroom_handler(XmppChatroomHandler* handler) {
184 // Calling with NULL removes the handler.
185 chatroom_handler_ = handler;
186 return XMPP_RETURN_OK;
187 }
188
189
190 XmppChatroomHandler*
191 XmppChatroomModuleImpl::chatroom_handler() {
192 return chatroom_handler_;
193 }
194
195 XmppReturnStatus
196 XmppChatroomModuleImpl::set_chatroom_jid(const Jid& chatroom_jid) {
197 if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM) {
198 return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad c all, diff error code?
199 }
200 if (chatroom_jid != chatroom_jid.BareJid()) {
201 // chatroom_jid must be a bare jid
202 return XMPP_RETURN_BADARGUMENT;
203 }
204
205 chatroom_jid_ = chatroom_jid;
206 return XMPP_RETURN_OK;
207 }
208
209 const Jid&
210 XmppChatroomModuleImpl::chatroom_jid() const {
211 return chatroom_jid_;
212 }
213
214 XmppReturnStatus
215 XmppChatroomModuleImpl::set_nickname(const std::string& nickname) {
216 if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM) {
217 return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad c all, diff error code?
218 }
219 nickname_ = nickname;
220 return XMPP_RETURN_OK;
221 }
222
223 const std::string&
224 XmppChatroomModuleImpl::nickname() const {
225 return nickname_;
226 }
227
228 const Jid
229 XmppChatroomModuleImpl::member_jid() const {
230 return Jid(chatroom_jid_.node(), chatroom_jid_.domain(), nickname_);
231 }
232
233
234 bool
235 XmppChatroomModuleImpl::CheckEnterChatroomStateOk() {
236 if (chatroom_jid_.IsValid() == false) {
237 ASSERT(0);
238 return false;
239 }
240 if (nickname_ == STR_EMPTY) {
241 ASSERT(0);
242 return false;
243 }
244 return true;
245 }
246
247 std::string GetAttrValueFor(XmppPresenceConnectionStatus connection_status) {
248 switch (connection_status) {
249 default:
250 case XMPP_CONNECTION_STATUS_UNKNOWN:
251 return "";
252 case XMPP_CONNECTION_STATUS_CONNECTING:
253 return STR_PSTN_CONFERENCE_STATUS_CONNECTING;
254 case XMPP_CONNECTION_STATUS_CONNECTED:
255 return STR_PSTN_CONFERENCE_STATUS_CONNECTED;
256 }
257 }
258
259 XmppReturnStatus
260 XmppChatroomModuleImpl::RequestEnterChatroom(
261 const std::string& password,
262 const std::string& client_version,
263 const std::string& locale) {
264 RTC_UNUSED(password);
265 if (!engine())
266 return XMPP_RETURN_BADSTATE;
267
268 if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM)
269 return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad c all, diff error code?
270
271 if (CheckEnterChatroomStateOk() == false) {
272 return XMPP_RETURN_BADSTATE;
273 }
274
275 // entering a chatroom is a presence request to the server
276 XmlElement element(QN_PRESENCE);
277 element.AddAttr(QN_TO, member_jid().Str());
278
279 XmlElement* muc_x = new XmlElement(QN_MUC_X);
280 element.AddElement(muc_x);
281
282 if (!client_version.empty()) {
283 XmlElement* client_version_element = new XmlElement(QN_CLIENT_VERSION,
284 false);
285 client_version_element->SetBodyText(client_version);
286 muc_x->AddElement(client_version_element);
287 }
288
289 if (!locale.empty()) {
290 XmlElement* locale_element = new XmlElement(QN_LOCALE, false);
291
292 locale_element->SetBodyText(locale);
293 muc_x->AddElement(locale_element);
294 }
295
296 XmppReturnStatus status = engine()->SendStanza(&element);
297 if (status == XMPP_RETURN_OK) {
298 return ClientChangeMyPresence(XMPP_CHATROOM_STATE_REQUESTED_ENTER);
299 }
300 return status;
301 }
302
303 XmppReturnStatus
304 XmppChatroomModuleImpl::RequestExitChatroom() {
305 if (!engine())
306 return XMPP_RETURN_BADSTATE;
307
308 // exiting a chatroom is a presence request to the server
309 XmlElement element(QN_PRESENCE);
310 element.AddAttr(QN_TO, member_jid().Str());
311 element.AddAttr(QN_TYPE, "unavailable");
312 XmppReturnStatus status = engine()->SendStanza(&element);
313 if (status == XMPP_RETURN_OK &&
314 chatroom_state_ == XMPP_CHATROOM_STATE_IN_ROOM) {
315 return ClientChangeMyPresence(XMPP_CHATROOM_STATE_REQUESTED_EXIT);
316 }
317 return status;
318 }
319
320 XmppReturnStatus
321 XmppChatroomModuleImpl::RequestConnectionStatusChange(
322 XmppPresenceConnectionStatus connection_status) {
323 if (!engine())
324 return XMPP_RETURN_BADSTATE;
325
326 if (chatroom_state_ != XMPP_CHATROOM_STATE_IN_ROOM) {
327 // $TODO - this isn't a bad state, it's a bad call, diff error code?
328 return XMPP_RETURN_BADSTATE;
329 }
330
331 if (CheckEnterChatroomStateOk() == false) {
332 return XMPP_RETURN_BADSTATE;
333 }
334
335 // entering a chatroom is a presence request to the server
336 XmlElement element(QN_PRESENCE);
337 element.AddAttr(QN_TO, member_jid().Str());
338 element.AddElement(new XmlElement(QN_MUC_X));
339 if (connection_status != XMPP_CONNECTION_STATUS_UNKNOWN) {
340 XmlElement* con_status_element =
341 new XmlElement(QN_GOOGLE_PSTN_CONFERENCE_STATUS);
342 con_status_element->AddAttr(QN_STATUS, GetAttrValueFor(connection_status));
343 element.AddElement(con_status_element);
344 }
345 XmppReturnStatus status = engine()->SendStanza(&element);
346
347 return status;
348 }
349
350 size_t
351 XmppChatroomModuleImpl::GetChatroomMemberCount() {
352 return chatroom_jid_members_.size();
353 }
354
355 XmppReturnStatus
356 XmppChatroomModuleImpl::CreateMemberEnumerator(XmppChatroomMemberEnumerator** en umerator) {
357 *enumerator = new XmppChatroomMemberEnumeratorImpl(&chatroom_jid_members_, &ch atroom_jid_members_version_);
358 return XMPP_RETURN_OK;
359 }
360
361 const std::string
362 XmppChatroomModuleImpl::subject() {
363 return ""; //NYI
364 }
365
366 XmppReturnStatus
367 XmppChatroomModuleImpl::SendMessage(const XmlElement& message) {
368 XmppReturnStatus xmpp_status = XMPP_RETURN_OK;
369
370 // can only send a message if we're in the room
371 if (chatroom_state_ != XMPP_CHATROOM_STATE_IN_ROOM) {
372 return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad c all, diff error code?
373 }
374
375 if (message.Name() != QN_MESSAGE) {
376 IFR(XMPP_RETURN_BADARGUMENT);
377 }
378
379 const std::string& type = message.Attr(QN_TYPE);
380 if (type != "groupchat") {
381 IFR(XMPP_RETURN_BADARGUMENT);
382 }
383
384 if (message.HasAttr(QN_FROM)) {
385 IFR(XMPP_RETURN_BADARGUMENT);
386 }
387
388 if (message.Attr(QN_TO) != chatroom_jid_.Str()) {
389 IFR(XMPP_RETURN_BADARGUMENT);
390 }
391
392 IFR(engine()->SendStanza(&message));
393
394 return xmpp_status;
395 }
396
397 enum TransitionType {
398 TRANSITION_TYPE_NONE = 0,
399 TRANSITION_TYPE_ENTER_SUCCESS = 1,
400 TRANSITION_TYPE_ENTER_FAILURE = 2,
401 TRANSITION_TYPE_EXIT_VOLUNTARILY = 3,
402 TRANSITION_TYPE_EXIT_INVOLUNTARILY = 4,
403 };
404
405 struct StateTransitionDescription {
406 XmppChatroomState old_state;
407 XmppChatroomState new_state;
408 bool is_valid_server_transition;
409 bool is_valid_client_transition;
410 TransitionType transition_type;
411 };
412
413 StateTransitionDescription Transitions[] = {
414 { XMPP_CHATROOM_STATE_NOT_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_ENTER, fa lse, true, TRANSITION_TYPE_NONE, },
415 { XMPP_CHATROOM_STATE_NOT_IN_ROOM, XMPP_CHATROOM_STATE_IN_ROOM, fa lse, false, TRANSITION_TYPE_ENTER_SUCCESS, },
416 { XMPP_CHATROOM_STATE_NOT_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_EXIT, fa lse, false, TRANSITION_TYPE_NONE, },
417 { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_NOT_IN_ROOM, tr ue, false, TRANSITION_TYPE_ENTER_FAILURE, },
418 { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_IN_ROOM, tr ue, false, TRANSITION_TYPE_ENTER_SUCCESS, },
419 { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_REQUESTED_EXIT, fa lse, false, TRANSITION_TYPE_NONE, },
420 { XMPP_CHATROOM_STATE_IN_ROOM, XMPP_CHATROOM_STATE_NOT_IN_ROOM, tr ue, false, TRANSITION_TYPE_EXIT_INVOLUNTARILY, },
421 { XMPP_CHATROOM_STATE_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_ENTER, fa lse, false, TRANSITION_TYPE_NONE, },
422 { XMPP_CHATROOM_STATE_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_EXIT, fa lse, true, TRANSITION_TYPE_NONE, },
423 { XMPP_CHATROOM_STATE_REQUESTED_EXIT, XMPP_CHATROOM_STATE_NOT_IN_ROOM, tr ue, false, TRANSITION_TYPE_EXIT_VOLUNTARILY, },
424 { XMPP_CHATROOM_STATE_REQUESTED_EXIT, XMPP_CHATROOM_STATE_REQUESTED_ENTER, fa lse, false, TRANSITION_TYPE_NONE, },
425 { XMPP_CHATROOM_STATE_REQUESTED_EXIT, XMPP_CHATROOM_STATE_IN_ROOM, fa lse, false, TRANSITION_TYPE_NONE, },
426 };
427
428
429
430 void
431 XmppChatroomModuleImpl::FireEnteredStatus(const XmlElement* presence,
432 XmppChatroomEnteredStatus status) {
433 if (chatroom_handler_) {
434 std::unique_ptr<XmppPresence> xmpp_presence(XmppPresence::Create());
435 xmpp_presence->set_raw_xml(presence);
436 chatroom_handler_->ChatroomEnteredStatus(this, xmpp_presence.get(), status);
437 }
438 }
439
440 void
441 XmppChatroomModuleImpl::FireExitStatus(XmppChatroomExitedStatus status) {
442 if (chatroom_handler_)
443 chatroom_handler_->ChatroomExitedStatus(this, status);
444 }
445
446 void
447 XmppChatroomModuleImpl::FireMessageReceived(const XmlElement& message) {
448 if (chatroom_handler_)
449 chatroom_handler_->MessageReceived(this, message);
450 }
451
452 void
453 XmppChatroomModuleImpl::FireMemberEntered(const XmppChatroomMember* entered_memb er) {
454 if (chatroom_handler_)
455 chatroom_handler_->MemberEntered(this, entered_member);
456 }
457
458 void
459 XmppChatroomModuleImpl::FireMemberChanged(
460 const XmppChatroomMember* changed_member) {
461 if (chatroom_handler_)
462 chatroom_handler_->MemberChanged(this, changed_member);
463 }
464
465 void
466 XmppChatroomModuleImpl::FireMemberExited(const XmppChatroomMember* exited_member ) {
467 if (chatroom_handler_)
468 chatroom_handler_->MemberExited(this, exited_member);
469 }
470
471
472 XmppReturnStatus
473 XmppChatroomModuleImpl::ServerChangedOtherPresence(const XmlElement&
474 presence_element) {
475 XmppReturnStatus xmpp_status = XMPP_RETURN_OK;
476 std::unique_ptr<XmppPresence> presence(XmppPresence::Create());
477 IFR(presence->set_raw_xml(&presence_element));
478
479 JidMemberMap::iterator pos = chatroom_jid_members_.find(presence->jid());
480
481 if (pos == chatroom_jid_members_.end()) {
482 if (presence->available() == XMPP_PRESENCE_AVAILABLE) {
483 XmppChatroomMemberImpl* member = new XmppChatroomMemberImpl();
484 member->SetPresence(presence.get());
485 chatroom_jid_members_.insert(std::make_pair(member->member_jid(), member)) ;
486 chatroom_jid_members_version_++;
487 FireMemberEntered(member);
488 }
489 } else {
490 XmppChatroomMemberImpl* member = pos->second;
491 if (presence->available() == XMPP_PRESENCE_AVAILABLE) {
492 member->SetPresence(presence.get());
493 chatroom_jid_members_version_++;
494 FireMemberChanged(member);
495 }
496 else if (presence->available() == XMPP_PRESENCE_UNAVAILABLE) {
497 member->SetPresence(presence.get());
498 chatroom_jid_members_.erase(pos);
499 chatroom_jid_members_version_++;
500 FireMemberExited(member);
501 delete member;
502 }
503 }
504
505 return xmpp_status;
506 }
507
508 XmppReturnStatus
509 XmppChatroomModuleImpl::ClientChangeMyPresence(XmppChatroomState new_state) {
510 return ChangePresence(new_state, NULL, false);
511 }
512
513 XmppReturnStatus
514 XmppChatroomModuleImpl::ServerChangeMyPresence(const XmlElement& presence) {
515 XmppChatroomState new_state;
516
517 if (presence.HasAttr(QN_TYPE) == false) {
518 new_state = XMPP_CHATROOM_STATE_IN_ROOM;
519 } else {
520 new_state = XMPP_CHATROOM_STATE_NOT_IN_ROOM;
521 }
522 return ChangePresence(new_state, &presence, true);
523
524 }
525
526 XmppReturnStatus
527 XmppChatroomModuleImpl::ChangePresence(XmppChatroomState new_state,
528 const XmlElement* presence,
529 bool isServer) {
530 RTC_UNUSED(presence);
531
532 XmppChatroomState old_state = chatroom_state_;
533
534 // do nothing if state hasn't changed
535 if (old_state == new_state)
536 return XMPP_RETURN_OK;
537
538 // find the right transition description
539 StateTransitionDescription* transition_desc = NULL;
540 for (size_t i = 0; i < arraysize(Transitions); i++) {
541 if (Transitions[i].old_state == old_state &&
542 Transitions[i].new_state == new_state) {
543 transition_desc = &Transitions[i];
544 break;
545 }
546 }
547
548 if (transition_desc == NULL) {
549 ASSERT(0);
550 return XMPP_RETURN_BADSTATE;
551 }
552
553 // we assert for any invalid transition states, and we'll
554 if (isServer) {
555 // $TODO send original stanza back to server and log an error?
556 // Disable the assert because of b/6133072
557 // ASSERT(transition_desc->is_valid_server_transition);
558 if (!transition_desc->is_valid_server_transition) {
559 return XMPP_RETURN_BADSTATE;
560 }
561 } else {
562 if (transition_desc->is_valid_client_transition == false) {
563 ASSERT(0);
564 return XMPP_RETURN_BADARGUMENT;
565 }
566 }
567
568 // set the new state and then fire any notifications to the handler
569 chatroom_state_ = new_state;
570
571 switch (transition_desc->transition_type) {
572 case TRANSITION_TYPE_ENTER_SUCCESS:
573 FireEnteredStatus(presence, XMPP_CHATROOM_ENTERED_SUCCESS);
574 break;
575 case TRANSITION_TYPE_ENTER_FAILURE:
576 FireEnteredStatus(presence, GetEnterFailureFromXml(presence));
577 break;
578 case TRANSITION_TYPE_EXIT_INVOLUNTARILY:
579 FireExitStatus(GetExitFailureFromXml(presence));
580 break;
581 case TRANSITION_TYPE_EXIT_VOLUNTARILY:
582 FireExitStatus(XMPP_CHATROOM_EXITED_REQUESTED);
583 break;
584 case TRANSITION_TYPE_NONE:
585 break;
586 }
587
588 return XMPP_RETURN_OK;
589 }
590
591 XmppChatroomEnteredStatus
592 XmppChatroomModuleImpl::GetEnterFailureFromXml(const XmlElement* presence) {
593 XmppChatroomEnteredStatus status = XMPP_CHATROOM_ENTERED_FAILURE_UNSPECIFIED;
594 const XmlElement* error = presence->FirstNamed(QN_ERROR);
595 if (error != NULL && error->HasAttr(QN_CODE)) {
596 int code = atoi(error->Attr(QN_CODE).c_str());
597 switch (code) {
598 case 401: status = XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_REQUIRED; break;
599 case 403: {
600 status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BANNED;
601 if (error->FirstNamed(QN_GOOGLE_SESSION_BLOCKED)) {
602 status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKED;
603 } else if (error->FirstNamed(QN_GOOGLE_SESSION_BLOCKING)) {
604 status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKING;
605 }
606 break;
607 }
608 case 405: status = XMPP_CHATROOM_ENTERED_FAILURE_ROOM_LOCKED; break;
609 case 406: status = XMPP_CHATROOM_ENTERED_FAILURE_OUTDATED_CLIENT; break;
610 case 407: status = XMPP_CHATROOM_ENTERED_FAILURE_NOT_A_MEMBER; break;
611 case 409: status = XMPP_CHATROOM_ENTERED_FAILURE_NICKNAME_CONFLICT; break;
612 // http://xmpp.org/extensions/xep-0045.html#enter-maxusers
613 case 503: status = XMPP_CHATROOM_ENTERED_FAILURE_MAX_USERS; break;
614 }
615 }
616 return status;
617 }
618
619 XmppChatroomExitedStatus
620 XmppChatroomModuleImpl::GetExitFailureFromXml(const XmlElement* presence) {
621 XmppChatroomExitedStatus status = XMPP_CHATROOM_EXITED_UNSPECIFIED;
622 const XmlElement* muc_user = presence->FirstNamed(QN_MUC_USER_X);
623 if (muc_user != NULL) {
624 const XmlElement* user_status = muc_user->FirstNamed(QN_MUC_USER_STATUS);
625 if (user_status != NULL && user_status->HasAttr(QN_CODE)) {
626 int code = atoi(user_status->Attr(QN_CODE).c_str());
627 switch (code) {
628 case 307: status = XMPP_CHATROOM_EXITED_KICKED; break;
629 case 322: status = XMPP_CHATROOM_EXITED_NOT_A_MEMBER; break;
630 case 332: status = XMPP_CHATROOM_EXITED_SYSTEM_SHUTDOWN; break;
631 }
632 }
633 }
634 return status;
635 }
636
637 XmppReturnStatus
638 XmppChatroomMemberImpl::SetPresence(const XmppPresence* presence) {
639 ASSERT(presence != NULL);
640
641 // copy presence
642 presence_.reset(XmppPresence::Create());
643 presence_->set_raw_xml(presence->raw_xml());
644 return XMPP_RETURN_OK;
645 }
646
647 const Jid
648 XmppChatroomMemberImpl::member_jid() const {
649 return presence_->jid();
650 }
651
652 const Jid
653 XmppChatroomMemberImpl::full_jid() const {
654 return Jid("");
655 }
656
657 const std::string
658 XmppChatroomMemberImpl::name() const {
659 return member_jid().resource();
660 }
661
662 const XmppPresence*
663 XmppChatroomMemberImpl::presence() const {
664 return presence_.get();
665 }
666
667
668 // XmppChatroomMemberEnumeratorImpl --------------------------------------
669 XmppChatroomMemberEnumeratorImpl::XmppChatroomMemberEnumeratorImpl(
670 XmppChatroomModuleImpl::JidMemberMap* map, int* map_version) {
671 map_ = map;
672 map_version_ = map_version;
673 map_version_created_ = *map_version_;
674 iterator_ = map->begin();
675 before_beginning_ = true;
676 }
677
678 XmppChatroomMember*
679 XmppChatroomMemberEnumeratorImpl::current() {
680 if (IsValid() == false) {
681 return NULL;
682 } else if (IsBeforeBeginning() || IsAfterEnd()) {
683 return NULL;
684 } else {
685 return iterator_->second;
686 }
687 }
688
689 bool
690 XmppChatroomMemberEnumeratorImpl::Prev() {
691 if (IsValid() == false) {
692 return false;
693 } else if (IsBeforeBeginning()) {
694 return false;
695 } else if (iterator_ == map_->begin()) {
696 before_beginning_ = true;
697 return false;
698 } else {
699 iterator_--;
700 return current() != NULL;
701 }
702 }
703
704 bool
705 XmppChatroomMemberEnumeratorImpl::Next() {
706 if (IsValid() == false) {
707 return false;
708 } else if (IsBeforeBeginning()) {
709 before_beginning_ = false;
710 iterator_ = map_->begin();
711 return current() != NULL;
712 } else if (IsAfterEnd()) {
713 return false;
714 } else {
715 iterator_++;
716 return current() != NULL;
717 }
718 }
719
720 bool
721 XmppChatroomMemberEnumeratorImpl::IsValid() {
722 return map_version_created_ == *map_version_;
723 }
724
725 bool
726 XmppChatroomMemberEnumeratorImpl::IsBeforeBeginning() {
727 return before_beginning_;
728 }
729
730 bool
731 XmppChatroomMemberEnumeratorImpl::IsAfterEnd() {
732 return (iterator_ == map_->end());
733 }
734
735
736
737 } // namespace buzz
OLDNEW
« no previous file with comments | « webrtc/libjingle/xmpp/chatroommodule.h ('k') | webrtc/libjingle/xmpp/constants.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698