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

Side by Side Diff: third_party/libjingle_xmpp/xmpp/chatroommoduleimpl.cc

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

Powered by Google App Engine
This is Rietveld 408576698