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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/libjingle_xmpp/xmpp/chatroommoduleimpl.cc
diff --git a/third_party/libjingle_xmpp/xmpp/chatroommoduleimpl.cc b/third_party/libjingle_xmpp/xmpp/chatroommoduleimpl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..78be440290f2322fb76cb0cdd443f5f0ba885b27
--- /dev/null
+++ b/third_party/libjingle_xmpp/xmpp/chatroommoduleimpl.cc
@@ -0,0 +1,731 @@
+// Copyright 2004 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+#include "third_party/libjingle_xmpp/xmpp/chatroommodule.h"
+#include "third_party/libjingle_xmpp/xmpp/constants.h"
+#include "third_party/libjingle_xmpp/xmpp/moduleimpl.h"
+#include "webrtc/base/arraysize.h"
+#include "webrtc/base/common.h"
+
+namespace buzz {
+
+// forward declarations
+class XmppChatroomImpl;
+class XmppChatroomMemberImpl;
+
+//! Module that encapsulates multiple chatrooms.
+//! Each chatroom is represented by an XmppChatroomImpl instance
+class XmppChatroomModuleImpl : public XmppChatroomModule,
+ public XmppModuleImpl, public XmppIqHandler {
+public:
+ IMPLEMENT_XMPPMODULE
+
+ // Creates a chatroom with specified Jid
+ XmppChatroomModuleImpl();
+ ~XmppChatroomModuleImpl();
+
+ // XmppChatroomModule
+ virtual XmppReturnStatus set_chatroom_handler(XmppChatroomHandler* handler);
+ virtual XmppChatroomHandler* chatroom_handler();
+ virtual XmppReturnStatus set_chatroom_jid(const Jid& chatroom_jid);
+ virtual const Jid& chatroom_jid() const;
+ virtual XmppReturnStatus set_nickname(const std::string& nickname);
+ virtual const std::string& nickname() const;
+ virtual const Jid member_jid() const;
+ virtual XmppReturnStatus RequestEnterChatroom(const std::string& password,
+ const std::string& client_version,
+ const std::string& locale);
+ virtual XmppReturnStatus RequestExitChatroom();
+ virtual XmppReturnStatus RequestConnectionStatusChange(
+ XmppPresenceConnectionStatus connection_status);
+ virtual size_t GetChatroomMemberCount();
+ virtual XmppReturnStatus CreateMemberEnumerator(XmppChatroomMemberEnumerator** enumerator);
+ virtual const std::string subject();
+ virtual XmppChatroomState state() { return chatroom_state_; }
+ virtual XmppReturnStatus SendMessage(const XmlElement& message);
+
+ // XmppModule
+ virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) {RTC_UNUSED2(cookie, pelStanza);}
+ virtual bool HandleStanza(const XmlElement *);
+
+private:
+ friend class XmppChatroomMemberEnumeratorImpl;
+
+ XmppReturnStatus ServerChangeMyPresence(const XmlElement& presence);
+ XmppReturnStatus ClientChangeMyPresence(XmppChatroomState new_state);
+ XmppReturnStatus ChangePresence(XmppChatroomState new_state, const XmlElement* presence, bool isServer);
+ XmppReturnStatus ServerChangedOtherPresence(const XmlElement& presence_element);
+ XmppChatroomEnteredStatus GetEnterFailureFromXml(const XmlElement* presence);
+ XmppChatroomExitedStatus GetExitFailureFromXml(const XmlElement* presence);
+
+ bool CheckEnterChatroomStateOk();
+
+ void FireEnteredStatus(const XmlElement* presence,
+ XmppChatroomEnteredStatus status);
+ void FireExitStatus(XmppChatroomExitedStatus status);
+ void FireMessageReceived(const XmlElement& message);
+ void FireMemberEntered(const XmppChatroomMember* entered_member);
+ void FireMemberChanged(const XmppChatroomMember* changed_member);
+ void FireMemberExited(const XmppChatroomMember* exited_member);
+
+
+ typedef std::map<Jid, XmppChatroomMemberImpl*> JidMemberMap;
+
+ XmppChatroomHandler* chatroom_handler_;
+ Jid chatroom_jid_;
+ std::string nickname_;
+ XmppChatroomState chatroom_state_;
+ JidMemberMap chatroom_jid_members_;
+ int chatroom_jid_members_version_;
+};
+
+
+class XmppChatroomMemberImpl : public XmppChatroomMember {
+public:
+ ~XmppChatroomMemberImpl() {}
+ XmppReturnStatus SetPresence(const XmppPresence* presence);
+
+ // XmppChatroomMember
+ const Jid member_jid() const;
+ const Jid full_jid() const;
+ const std::string name() const;
+ const XmppPresence* presence() const;
+
+private:
+ std::unique_ptr<XmppPresence> presence_;
+};
+
+class XmppChatroomMemberEnumeratorImpl :
+ public XmppChatroomMemberEnumerator {
+public:
+ XmppChatroomMemberEnumeratorImpl(XmppChatroomModuleImpl::JidMemberMap* chatroom_jid_members,
+ int* map_version);
+
+ // XmppChatroomMemberEnumerator
+ virtual XmppChatroomMember* current();
+ virtual bool Next();
+ virtual bool Prev();
+ virtual bool IsValid();
+ virtual bool IsBeforeBeginning();
+ virtual bool IsAfterEnd();
+
+private:
+ XmppChatroomModuleImpl::JidMemberMap* map_;
+ int map_version_created_;
+ int* map_version_;
+ XmppChatroomModuleImpl::JidMemberMap::iterator iterator_;
+ bool before_beginning_;
+};
+
+
+// XmppChatroomModuleImpl ------------------------------------------------
+XmppChatroomModule *
+XmppChatroomModule::Create() {
+ return new XmppChatroomModuleImpl();
+}
+
+XmppChatroomModuleImpl::XmppChatroomModuleImpl() :
+ chatroom_handler_(NULL),
+ chatroom_jid_(STR_EMPTY),
+ chatroom_state_(XMPP_CHATROOM_STATE_NOT_IN_ROOM),
+ chatroom_jid_members_version_(0) {
+}
+
+XmppChatroomModuleImpl::~XmppChatroomModuleImpl() {
+ JidMemberMap::iterator iterator = chatroom_jid_members_.begin();
+ while (iterator != chatroom_jid_members_.end()) {
+ delete iterator->second;
+ iterator++;
+ }
+}
+
+
+bool
+XmppChatroomModuleImpl::HandleStanza(const XmlElement* stanza) {
+ ASSERT(engine() != NULL);
+
+ // we handle stanzas that are for one of our chatrooms
+ Jid from_jid = Jid(stanza->Attr(QN_FROM));
+ // see if it's one of our chatrooms
+ if (chatroom_jid_ != from_jid.BareJid()) {
+ return false; // not one of our chatrooms
+ } else {
+ // handle presence stanza
+ if (stanza->Name() == QN_PRESENCE) {
+ if (from_jid == member_jid()) {
+ ServerChangeMyPresence(*stanza);
+ } else {
+ ServerChangedOtherPresence(*stanza);
+ }
+ } else if (stanza->Name() == QN_MESSAGE) {
+ FireMessageReceived(*stanza);
+ }
+ return true;
+ }
+}
+
+
+XmppReturnStatus
+XmppChatroomModuleImpl::set_chatroom_handler(XmppChatroomHandler* handler) {
+ // Calling with NULL removes the handler.
+ chatroom_handler_ = handler;
+ return XMPP_RETURN_OK;
+}
+
+
+XmppChatroomHandler*
+XmppChatroomModuleImpl::chatroom_handler() {
+ return chatroom_handler_;
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::set_chatroom_jid(const Jid& chatroom_jid) {
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM) {
+ return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call, diff error code?
+ }
+ if (chatroom_jid != chatroom_jid.BareJid()) {
+ // chatroom_jid must be a bare jid
+ return XMPP_RETURN_BADARGUMENT;
+ }
+
+ chatroom_jid_ = chatroom_jid;
+ return XMPP_RETURN_OK;
+}
+
+const Jid&
+XmppChatroomModuleImpl::chatroom_jid() const {
+ return chatroom_jid_;
+}
+
+ XmppReturnStatus
+ XmppChatroomModuleImpl::set_nickname(const std::string& nickname) {
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM) {
+ return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call, diff error code?
+ }
+ nickname_ = nickname;
+ return XMPP_RETURN_OK;
+ }
+
+ const std::string&
+ XmppChatroomModuleImpl::nickname() const {
+ return nickname_;
+ }
+
+const Jid
+XmppChatroomModuleImpl::member_jid() const {
+ return Jid(chatroom_jid_.node(), chatroom_jid_.domain(), nickname_);
+}
+
+
+bool
+XmppChatroomModuleImpl::CheckEnterChatroomStateOk() {
+ if (chatroom_jid_.IsValid() == false) {
+ ASSERT(0);
+ return false;
+ }
+ if (nickname_ == STR_EMPTY) {
+ ASSERT(0);
+ return false;
+ }
+ return true;
+}
+
+std::string GetAttrValueFor(XmppPresenceConnectionStatus connection_status) {
+ switch (connection_status) {
+ default:
+ case XMPP_CONNECTION_STATUS_UNKNOWN:
+ return "";
+ case XMPP_CONNECTION_STATUS_CONNECTING:
+ return STR_PSTN_CONFERENCE_STATUS_CONNECTING;
+ case XMPP_CONNECTION_STATUS_CONNECTED:
+ return STR_PSTN_CONFERENCE_STATUS_CONNECTED;
+ }
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::RequestEnterChatroom(
+ const std::string& password,
+ const std::string& client_version,
+ const std::string& locale) {
+ RTC_UNUSED(password);
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM)
+ return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call, diff error code?
+
+ if (CheckEnterChatroomStateOk() == false) {
+ return XMPP_RETURN_BADSTATE;
+ }
+
+ // entering a chatroom is a presence request to the server
+ XmlElement element(QN_PRESENCE);
+ element.AddAttr(QN_TO, member_jid().Str());
+
+ XmlElement* muc_x = new XmlElement(QN_MUC_X);
+ element.AddElement(muc_x);
+
+ if (!client_version.empty()) {
+ XmlElement* client_version_element = new XmlElement(QN_CLIENT_VERSION,
+ false);
+ client_version_element->SetBodyText(client_version);
+ muc_x->AddElement(client_version_element);
+ }
+
+ if (!locale.empty()) {
+ XmlElement* locale_element = new XmlElement(QN_LOCALE, false);
+
+ locale_element->SetBodyText(locale);
+ muc_x->AddElement(locale_element);
+ }
+
+ XmppReturnStatus status = engine()->SendStanza(&element);
+ if (status == XMPP_RETURN_OK) {
+ return ClientChangeMyPresence(XMPP_CHATROOM_STATE_REQUESTED_ENTER);
+ }
+ return status;
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::RequestExitChatroom() {
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ // exiting a chatroom is a presence request to the server
+ XmlElement element(QN_PRESENCE);
+ element.AddAttr(QN_TO, member_jid().Str());
+ element.AddAttr(QN_TYPE, "unavailable");
+ XmppReturnStatus status = engine()->SendStanza(&element);
+ if (status == XMPP_RETURN_OK &&
+ chatroom_state_ == XMPP_CHATROOM_STATE_IN_ROOM) {
+ return ClientChangeMyPresence(XMPP_CHATROOM_STATE_REQUESTED_EXIT);
+ }
+ return status;
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::RequestConnectionStatusChange(
+ XmppPresenceConnectionStatus connection_status) {
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_IN_ROOM) {
+ // $TODO - this isn't a bad state, it's a bad call, diff error code?
+ return XMPP_RETURN_BADSTATE;
+ }
+
+ if (CheckEnterChatroomStateOk() == false) {
+ return XMPP_RETURN_BADSTATE;
+ }
+
+ // entering a chatroom is a presence request to the server
+ XmlElement element(QN_PRESENCE);
+ element.AddAttr(QN_TO, member_jid().Str());
+ element.AddElement(new XmlElement(QN_MUC_X));
+ if (connection_status != XMPP_CONNECTION_STATUS_UNKNOWN) {
+ XmlElement* con_status_element =
+ new XmlElement(QN_GOOGLE_PSTN_CONFERENCE_STATUS);
+ con_status_element->AddAttr(QN_STATUS, GetAttrValueFor(connection_status));
+ element.AddElement(con_status_element);
+ }
+ XmppReturnStatus status = engine()->SendStanza(&element);
+
+ return status;
+}
+
+size_t
+XmppChatroomModuleImpl::GetChatroomMemberCount() {
+ return chatroom_jid_members_.size();
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::CreateMemberEnumerator(XmppChatroomMemberEnumerator** enumerator) {
+ *enumerator = new XmppChatroomMemberEnumeratorImpl(&chatroom_jid_members_, &chatroom_jid_members_version_);
+ return XMPP_RETURN_OK;
+}
+
+const std::string
+XmppChatroomModuleImpl::subject() {
+ return ""; //NYI
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::SendMessage(const XmlElement& message) {
+ XmppReturnStatus xmpp_status = XMPP_RETURN_OK;
+
+ // can only send a message if we're in the room
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_IN_ROOM) {
+ return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call, diff error code?
+ }
+
+ if (message.Name() != QN_MESSAGE) {
+ IFR(XMPP_RETURN_BADARGUMENT);
+ }
+
+ const std::string& type = message.Attr(QN_TYPE);
+ if (type != "groupchat") {
+ IFR(XMPP_RETURN_BADARGUMENT);
+ }
+
+ if (message.HasAttr(QN_FROM)) {
+ IFR(XMPP_RETURN_BADARGUMENT);
+ }
+
+ if (message.Attr(QN_TO) != chatroom_jid_.Str()) {
+ IFR(XMPP_RETURN_BADARGUMENT);
+ }
+
+ IFR(engine()->SendStanza(&message));
+
+ return xmpp_status;
+}
+
+enum TransitionType {
+ TRANSITION_TYPE_NONE = 0,
+ TRANSITION_TYPE_ENTER_SUCCESS = 1,
+ TRANSITION_TYPE_ENTER_FAILURE = 2,
+ TRANSITION_TYPE_EXIT_VOLUNTARILY = 3,
+ TRANSITION_TYPE_EXIT_INVOLUNTARILY = 4,
+};
+
+struct StateTransitionDescription {
+ XmppChatroomState old_state;
+ XmppChatroomState new_state;
+ bool is_valid_server_transition;
+ bool is_valid_client_transition;
+ TransitionType transition_type;
+};
+
+StateTransitionDescription Transitions[] = {
+ { XMPP_CHATROOM_STATE_NOT_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_ENTER, false, true, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_NOT_IN_ROOM, XMPP_CHATROOM_STATE_IN_ROOM, false, false, TRANSITION_TYPE_ENTER_SUCCESS, },
+ { XMPP_CHATROOM_STATE_NOT_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_EXIT, false, false, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_NOT_IN_ROOM, true, false, TRANSITION_TYPE_ENTER_FAILURE, },
+ { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_IN_ROOM, true, false, TRANSITION_TYPE_ENTER_SUCCESS, },
+ { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_REQUESTED_EXIT, false, false, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_IN_ROOM, XMPP_CHATROOM_STATE_NOT_IN_ROOM, true, false, TRANSITION_TYPE_EXIT_INVOLUNTARILY, },
+ { XMPP_CHATROOM_STATE_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_ENTER, false, false, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_EXIT, false, true, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_REQUESTED_EXIT, XMPP_CHATROOM_STATE_NOT_IN_ROOM, true, false, TRANSITION_TYPE_EXIT_VOLUNTARILY, },
+ { XMPP_CHATROOM_STATE_REQUESTED_EXIT, XMPP_CHATROOM_STATE_REQUESTED_ENTER, false, false, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_REQUESTED_EXIT, XMPP_CHATROOM_STATE_IN_ROOM, false, false, TRANSITION_TYPE_NONE, },
+};
+
+
+
+void
+XmppChatroomModuleImpl::FireEnteredStatus(const XmlElement* presence,
+ XmppChatroomEnteredStatus status) {
+ if (chatroom_handler_) {
+ std::unique_ptr<XmppPresence> xmpp_presence(XmppPresence::Create());
+ xmpp_presence->set_raw_xml(presence);
+ chatroom_handler_->ChatroomEnteredStatus(this, xmpp_presence.get(), status);
+ }
+}
+
+void
+XmppChatroomModuleImpl::FireExitStatus(XmppChatroomExitedStatus status) {
+ if (chatroom_handler_)
+ chatroom_handler_->ChatroomExitedStatus(this, status);
+}
+
+void
+XmppChatroomModuleImpl::FireMessageReceived(const XmlElement& message) {
+ if (chatroom_handler_)
+ chatroom_handler_->MessageReceived(this, message);
+}
+
+void
+XmppChatroomModuleImpl::FireMemberEntered(const XmppChatroomMember* entered_member) {
+ if (chatroom_handler_)
+ chatroom_handler_->MemberEntered(this, entered_member);
+}
+
+void
+XmppChatroomModuleImpl::FireMemberChanged(
+ const XmppChatroomMember* changed_member) {
+ if (chatroom_handler_)
+ chatroom_handler_->MemberChanged(this, changed_member);
+}
+
+void
+XmppChatroomModuleImpl::FireMemberExited(const XmppChatroomMember* exited_member) {
+ if (chatroom_handler_)
+ chatroom_handler_->MemberExited(this, exited_member);
+}
+
+
+XmppReturnStatus
+XmppChatroomModuleImpl::ServerChangedOtherPresence(const XmlElement&
+ presence_element) {
+ XmppReturnStatus xmpp_status = XMPP_RETURN_OK;
+ std::unique_ptr<XmppPresence> presence(XmppPresence::Create());
+ IFR(presence->set_raw_xml(&presence_element));
+
+ JidMemberMap::iterator pos = chatroom_jid_members_.find(presence->jid());
+
+ if (pos == chatroom_jid_members_.end()) {
+ if (presence->available() == XMPP_PRESENCE_AVAILABLE) {
+ XmppChatroomMemberImpl* member = new XmppChatroomMemberImpl();
+ member->SetPresence(presence.get());
+ chatroom_jid_members_.insert(std::make_pair(member->member_jid(), member));
+ chatroom_jid_members_version_++;
+ FireMemberEntered(member);
+ }
+ } else {
+ XmppChatroomMemberImpl* member = pos->second;
+ if (presence->available() == XMPP_PRESENCE_AVAILABLE) {
+ member->SetPresence(presence.get());
+ chatroom_jid_members_version_++;
+ FireMemberChanged(member);
+ }
+ else if (presence->available() == XMPP_PRESENCE_UNAVAILABLE) {
+ member->SetPresence(presence.get());
+ chatroom_jid_members_.erase(pos);
+ chatroom_jid_members_version_++;
+ FireMemberExited(member);
+ delete member;
+ }
+ }
+
+ return xmpp_status;
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::ClientChangeMyPresence(XmppChatroomState new_state) {
+ return ChangePresence(new_state, NULL, false);
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::ServerChangeMyPresence(const XmlElement& presence) {
+ XmppChatroomState new_state;
+
+ if (presence.HasAttr(QN_TYPE) == false) {
+ new_state = XMPP_CHATROOM_STATE_IN_ROOM;
+ } else {
+ new_state = XMPP_CHATROOM_STATE_NOT_IN_ROOM;
+ }
+ return ChangePresence(new_state, &presence, true);
+
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::ChangePresence(XmppChatroomState new_state,
+ const XmlElement* presence,
+ bool isServer) {
+ RTC_UNUSED(presence);
+
+ XmppChatroomState old_state = chatroom_state_;
+
+ // do nothing if state hasn't changed
+ if (old_state == new_state)
+ return XMPP_RETURN_OK;
+
+ // find the right transition description
+ StateTransitionDescription* transition_desc = NULL;
+ for (size_t i = 0; i < arraysize(Transitions); i++) {
+ if (Transitions[i].old_state == old_state &&
+ Transitions[i].new_state == new_state) {
+ transition_desc = &Transitions[i];
+ break;
+ }
+ }
+
+ if (transition_desc == NULL) {
+ ASSERT(0);
+ return XMPP_RETURN_BADSTATE;
+ }
+
+ // we assert for any invalid transition states, and we'll
+ if (isServer) {
+ // $TODO send original stanza back to server and log an error?
+ // Disable the assert because of b/6133072
+ // ASSERT(transition_desc->is_valid_server_transition);
+ if (!transition_desc->is_valid_server_transition) {
+ return XMPP_RETURN_BADSTATE;
+ }
+ } else {
+ if (transition_desc->is_valid_client_transition == false) {
+ ASSERT(0);
+ return XMPP_RETURN_BADARGUMENT;
+ }
+ }
+
+ // set the new state and then fire any notifications to the handler
+ chatroom_state_ = new_state;
+
+ switch (transition_desc->transition_type) {
+ case TRANSITION_TYPE_ENTER_SUCCESS:
+ FireEnteredStatus(presence, XMPP_CHATROOM_ENTERED_SUCCESS);
+ break;
+ case TRANSITION_TYPE_ENTER_FAILURE:
+ FireEnteredStatus(presence, GetEnterFailureFromXml(presence));
+ break;
+ case TRANSITION_TYPE_EXIT_INVOLUNTARILY:
+ FireExitStatus(GetExitFailureFromXml(presence));
+ break;
+ case TRANSITION_TYPE_EXIT_VOLUNTARILY:
+ FireExitStatus(XMPP_CHATROOM_EXITED_REQUESTED);
+ break;
+ case TRANSITION_TYPE_NONE:
+ break;
+ }
+
+ return XMPP_RETURN_OK;
+}
+
+XmppChatroomEnteredStatus
+XmppChatroomModuleImpl::GetEnterFailureFromXml(const XmlElement* presence) {
+ XmppChatroomEnteredStatus status = XMPP_CHATROOM_ENTERED_FAILURE_UNSPECIFIED;
+ const XmlElement* error = presence->FirstNamed(QN_ERROR);
+ if (error != NULL && error->HasAttr(QN_CODE)) {
+ int code = atoi(error->Attr(QN_CODE).c_str());
+ switch (code) {
+ case 401: status = XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_REQUIRED; break;
+ case 403: {
+ status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BANNED;
+ if (error->FirstNamed(QN_GOOGLE_SESSION_BLOCKED)) {
+ status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKED;
+ } else if (error->FirstNamed(QN_GOOGLE_SESSION_BLOCKING)) {
+ status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKING;
+ }
+ break;
+ }
+ case 405: status = XMPP_CHATROOM_ENTERED_FAILURE_ROOM_LOCKED; break;
+ case 406: status = XMPP_CHATROOM_ENTERED_FAILURE_OUTDATED_CLIENT; break;
+ case 407: status = XMPP_CHATROOM_ENTERED_FAILURE_NOT_A_MEMBER; break;
+ case 409: status = XMPP_CHATROOM_ENTERED_FAILURE_NICKNAME_CONFLICT; break;
+ // http://xmpp.org/extensions/xep-0045.html#enter-maxusers
+ case 503: status = XMPP_CHATROOM_ENTERED_FAILURE_MAX_USERS; break;
+ }
+ }
+ return status;
+}
+
+XmppChatroomExitedStatus
+XmppChatroomModuleImpl::GetExitFailureFromXml(const XmlElement* presence) {
+ XmppChatroomExitedStatus status = XMPP_CHATROOM_EXITED_UNSPECIFIED;
+ const XmlElement* muc_user = presence->FirstNamed(QN_MUC_USER_X);
+ if (muc_user != NULL) {
+ const XmlElement* user_status = muc_user->FirstNamed(QN_MUC_USER_STATUS);
+ if (user_status != NULL && user_status->HasAttr(QN_CODE)) {
+ int code = atoi(user_status->Attr(QN_CODE).c_str());
+ switch (code) {
+ case 307: status = XMPP_CHATROOM_EXITED_KICKED; break;
+ case 322: status = XMPP_CHATROOM_EXITED_NOT_A_MEMBER; break;
+ case 332: status = XMPP_CHATROOM_EXITED_SYSTEM_SHUTDOWN; break;
+ }
+ }
+ }
+ return status;
+}
+
+XmppReturnStatus
+XmppChatroomMemberImpl::SetPresence(const XmppPresence* presence) {
+ ASSERT(presence != NULL);
+
+ // copy presence
+ presence_.reset(XmppPresence::Create());
+ presence_->set_raw_xml(presence->raw_xml());
+ return XMPP_RETURN_OK;
+}
+
+const Jid
+XmppChatroomMemberImpl::member_jid() const {
+ return presence_->jid();
+}
+
+const Jid
+XmppChatroomMemberImpl::full_jid() const {
+ return Jid("");
+}
+
+const std::string
+XmppChatroomMemberImpl::name() const {
+ return member_jid().resource();
+}
+
+const XmppPresence*
+XmppChatroomMemberImpl::presence() const {
+ return presence_.get();
+}
+
+
+// XmppChatroomMemberEnumeratorImpl --------------------------------------
+XmppChatroomMemberEnumeratorImpl::XmppChatroomMemberEnumeratorImpl(
+ XmppChatroomModuleImpl::JidMemberMap* map, int* map_version) {
+ map_ = map;
+ map_version_ = map_version;
+ map_version_created_ = *map_version_;
+ iterator_ = map->begin();
+ before_beginning_ = true;
+}
+
+XmppChatroomMember*
+XmppChatroomMemberEnumeratorImpl::current() {
+ if (IsValid() == false) {
+ return NULL;
+ } else if (IsBeforeBeginning() || IsAfterEnd()) {
+ return NULL;
+ } else {
+ return iterator_->second;
+ }
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::Prev() {
+ if (IsValid() == false) {
+ return false;
+ } else if (IsBeforeBeginning()) {
+ return false;
+ } else if (iterator_ == map_->begin()) {
+ before_beginning_ = true;
+ return false;
+ } else {
+ iterator_--;
+ return current() != NULL;
+ }
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::Next() {
+ if (IsValid() == false) {
+ return false;
+ } else if (IsBeforeBeginning()) {
+ before_beginning_ = false;
+ iterator_ = map_->begin();
+ return current() != NULL;
+ } else if (IsAfterEnd()) {
+ return false;
+ } else {
+ iterator_++;
+ return current() != NULL;
+ }
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::IsValid() {
+ return map_version_created_ == *map_version_;
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::IsBeforeBeginning() {
+ return before_beginning_;
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::IsAfterEnd() {
+ return (iterator_ == map_->end());
+}
+
+
+
+} // namespace buzz

Powered by Google App Engine
This is Rietveld 408576698