From a1b590f2e469191381b5eb8613b5618ffbcafcc4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Fri, 30 Sep 2011 22:58:49 +0200
Subject: Moved DiscoServiceWalker to Swiften.


diff --git a/Swift/Controllers/Chat/MUCSearchController.cpp b/Swift/Controllers/Chat/MUCSearchController.cpp
index 2cb89b4..5312fa7 100644
--- a/Swift/Controllers/Chat/MUCSearchController.cpp
+++ b/Swift/Controllers/Chat/MUCSearchController.cpp
@@ -17,7 +17,7 @@
 #include <Swiften/Base/String.h>
 #include <Swift/Controllers/UIEvents/UIEventStream.h>
 #include <Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h>
-#include <Swift/Controllers/DiscoServiceWalker.h>
+#include <Swiften/Disco/DiscoServiceWalker.h>
 #include <Swiften/Client/NickResolver.h>
 
 namespace Swift {
diff --git a/Swift/Controllers/Chat/UserSearchController.cpp b/Swift/Controllers/Chat/UserSearchController.cpp
index 5a76c5d..3e734df 100644
--- a/Swift/Controllers/Chat/UserSearchController.cpp
+++ b/Swift/Controllers/Chat/UserSearchController.cpp
@@ -12,7 +12,7 @@
 #include <Swiften/Base/foreach.h>
 #include <Swiften/Disco/GetDiscoInfoRequest.h>
 #include <Swiften/Disco/GetDiscoItemsRequest.h>
-#include <Swift/Controllers/DiscoServiceWalker.h>
+#include <Swiften/Disco/DiscoServiceWalker.h>
 #include <Swift/Controllers/UIEvents/UIEventStream.h>
 #include <Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h>
 #include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
diff --git a/Swift/Controllers/DiscoServiceWalker.cpp b/Swift/Controllers/DiscoServiceWalker.cpp
deleted file mode 100644
index 1ca4930..0000000
--- a/Swift/Controllers/DiscoServiceWalker.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include <Swift/Controllers/DiscoServiceWalker.h>
-#include <Swiften/Base/Log.h>
-#include <Swiften/Base/foreach.h>
-
-#include <boost/bind.hpp>
-
-namespace Swift {
-
-DiscoServiceWalker::DiscoServiceWalker(const JID& service, IQRouter* iqRouter, size_t maxSteps) : service_(service), iqRouter_(iqRouter), maxSteps_(maxSteps), active_(false) {
-
-}
-
-void DiscoServiceWalker::beginWalk() {
-	SWIFT_LOG(debug) << "Starting walk to " << service_ << std::endl;
-	assert(!active_);
-	assert(servicesBeingSearched_.empty());
-	active_ = true;
-	walkNode(service_);
-}
-
-void DiscoServiceWalker::endWalk() {
-	if (active_) {
-		SWIFT_LOG(debug) << "Ending walk to " << service_ << std::endl;
-		foreach (GetDiscoInfoRequest::ref request, pendingDiscoInfoRequests_) {
-			request->onResponse.disconnect(boost::bind(&DiscoServiceWalker::handleDiscoInfoResponse, this, _1, _2, request));
-		}
-		foreach (GetDiscoItemsRequest::ref request, pendingDiscoItemsRequests_) {
-			request->onResponse.disconnect(boost::bind(&DiscoServiceWalker::handleDiscoItemsResponse, this, _1, _2, request));
-		}
-		active_ = false;
-	}
-}
-
-void DiscoServiceWalker::walkNode(const JID& jid) {
-	SWIFT_LOG(debug) << "Walking node " << jid << std::endl;
-	servicesBeingSearched_.insert(jid);
-	searchedServices_.insert(jid);
-	GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(jid, iqRouter_);
-	discoInfoRequest->onResponse.connect(boost::bind(&DiscoServiceWalker::handleDiscoInfoResponse, this, _1, _2, discoInfoRequest));
-	pendingDiscoInfoRequests_.insert(discoInfoRequest);
-	discoInfoRequest->send();
-}
-
-void DiscoServiceWalker::handleReceivedDiscoItem(const JID& item) {
-	SWIFT_LOG(debug) << "Received disco item " << item << std::endl;
-
-	/* If we got canceled, don't do anything */
-	if (!active_) {
-		return;
-	}
-
-	if (std::find(searchedServices_.begin(), searchedServices_.end(), item) != searchedServices_.end()) {
-		/* Don't recurse infinitely */
-		return;
-	}
-	walkNode(item);
-}
-
-void DiscoServiceWalker::handleDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error, GetDiscoInfoRequest::ref request) {
-	/* If we got canceled, don't do anything */
-	if (!active_) {
-		return;
-	}
-
-	SWIFT_LOG(debug) << "Disco info response from " << request->getReceiver() << std::endl;
-
-	pendingDiscoInfoRequests_.erase(request);
-	if (error) {
-		handleDiscoError(request->getReceiver(), error);
-		return;
-	}
-
-	bool couldContainServices = false;
-	foreach (DiscoInfo::Identity identity, info->getIdentities()) {
-		if (identity.getCategory() == "server") {
-			couldContainServices = true;
-		}
-	}
-	bool completed = false;
-	if (couldContainServices) {
-		GetDiscoItemsRequest::ref discoItemsRequest = GetDiscoItemsRequest::create(request->getReceiver(), iqRouter_);
-		discoItemsRequest->onResponse.connect(boost::bind(&DiscoServiceWalker::handleDiscoItemsResponse, this, _1, _2, discoItemsRequest));
-		pendingDiscoItemsRequests_.insert(discoItemsRequest);
-		discoItemsRequest->send();
-	} else {
-		completed = true;
-	}
-	onServiceFound(request->getReceiver(), info);
-	if (completed) {
-		markNodeCompleted(request->getReceiver());
-	}
-}
-
-void DiscoServiceWalker::handleDiscoItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, GetDiscoItemsRequest::ref request) {
-	/* If we got canceled, don't do anything */
-	if (!active_) {
-		return;
-	}
-
-	SWIFT_LOG(debug) << "Received disco item from " << request->getReceiver() << std::endl;
-
-	pendingDiscoItemsRequests_.erase(request);
-	if (error) {
-		handleDiscoError(request->getReceiver(), error);
-		return;
-	}
-	foreach (DiscoItems::Item item, items->getItems()) {
-		if (item.getNode().empty()) {
-			/* Don't look at noded items. It's possible that this will exclude some services,
-			 * but I've never seen one in the wild, and it's an easy fix for not looping.
-			 */
-			handleReceivedDiscoItem(item.getJID());
-		}
-	}
-	markNodeCompleted(request->getReceiver());
-}
-
-void DiscoServiceWalker::handleDiscoError(const JID& jid, ErrorPayload::ref /*error*/) {
-	/* If we got canceled, don't do anything */
-	if (!active_) {
-		return;
-	}
-
-	SWIFT_LOG(debug) << "Disco error from " << jid << std::endl;
-
-	markNodeCompleted(jid);
-}
-
-void DiscoServiceWalker::markNodeCompleted(const JID& jid) {
-	// Check whether we weren't canceled in between a 'emit result' and this call
-	if (!active_) {
-		return;
-	}
-	SWIFT_LOG(debug) << "Node completed " << jid << std::endl;
-
-	servicesBeingSearched_.erase(jid);
-	/* All results are in */
-	if (servicesBeingSearched_.empty()) {
-		active_ = false;
-		onWalkComplete();
-	}
-	/* Check if we're on a rampage */
-	else if (searchedServices_.size() >= maxSteps_) {
-		active_ = false;
-		onWalkComplete();
-	}
-}
-
-}
diff --git a/Swift/Controllers/DiscoServiceWalker.h b/Swift/Controllers/DiscoServiceWalker.h
deleted file mode 100644
index 7982bbc..0000000
--- a/Swift/Controllers/DiscoServiceWalker.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <vector>
-#include <set>
-
-#include <boost/shared_ptr.hpp>
-#include <Swiften/Base/boost_bsignals.h>
-#include <string>
-#include <Swiften/JID/JID.h>
-#include <Swiften/Elements/DiscoInfo.h>
-#include <Swiften/Elements/DiscoItems.h>
-#include <Swiften/Elements/ErrorPayload.h>
-#include <Swiften/Disco/GetDiscoInfoRequest.h>
-#include <Swiften/Disco/GetDiscoItemsRequest.h>
-
-namespace Swift {
-	class IQRouter;
-	/**
-	 * Recursively walk service discovery trees to find all services offered.
-	 * This stops on any disco item that's not reporting itself as a server.
-	 */
-	class DiscoServiceWalker {
-		public:
-			DiscoServiceWalker(const JID& service, IQRouter* iqRouter, size_t maxSteps = 200);
-
-			/**
-			 * Start the walk.
-			 *
-			 * Call this exactly once.
-			 */
-			void beginWalk();
-
-			/**
-			 * End the walk.
-			 */
-			void endWalk();
-
-			bool isActive() const {
-				return active_;
-			}
-
-			/** Emitted for each service found. */
-			boost::signal<void(const JID&, boost::shared_ptr<DiscoInfo>)> onServiceFound;
-
-			/** Emitted when walking is complete.*/
-			boost::signal<void()> onWalkComplete;
-
-		private:
-			void handleReceivedDiscoItem(const JID& item);
-			void walkNode(const JID& jid);
-			void markNodeCompleted(const JID& jid);
-			void handleDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error, GetDiscoInfoRequest::ref request);
-			void handleDiscoItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, GetDiscoItemsRequest::ref request);
-			void handleDiscoError(const JID& jid, ErrorPayload::ref error);
-
-		private:
-			JID service_;
-			IQRouter* iqRouter_;
-			size_t maxSteps_;
-			bool active_;
-			std::set<JID> servicesBeingSearched_;
-			std::set<JID> searchedServices_;
-			std::set<GetDiscoInfoRequest::ref> pendingDiscoInfoRequests_;
-			std::set<GetDiscoItemsRequest::ref> pendingDiscoItemsRequests_;
-	};
-}
diff --git a/Swift/Controllers/FileTransfer/SOCKS5BytestreamProxyFinder.h b/Swift/Controllers/FileTransfer/SOCKS5BytestreamProxyFinder.h
index 1727a63..bffc7a1 100644
--- a/Swift/Controllers/FileTransfer/SOCKS5BytestreamProxyFinder.h
+++ b/Swift/Controllers/FileTransfer/SOCKS5BytestreamProxyFinder.h
@@ -8,7 +8,7 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include <Swift/Controllers/DiscoServiceWalker.h>
+#include <Swiften/Disco/DiscoServiceWalker.h>
 #include <Swiften/Network/HostAddressPort.h>
 #include <Swiften/Elements/S5BProxyRequest.h>
 
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index 289f055..03dc0b7 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -27,7 +27,6 @@ if env["SCONS_STAGE"] == "build" :
 			"Chat/MUCController.cpp",
 			"Chat/MUCSearchController.cpp",
 			"Chat/UserSearchController.cpp",
-			"DiscoServiceWalker.cpp",
 			"MainController.cpp",
 			"ProfileController.cpp",
 			"ContactEditController.cpp",
diff --git a/Swiften/Disco/DiscoServiceWalker.cpp b/Swiften/Disco/DiscoServiceWalker.cpp
new file mode 100644
index 0000000..c8c3e1b
--- /dev/null
+++ b/Swiften/Disco/DiscoServiceWalker.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Disco/DiscoServiceWalker.h>
+
+#include <Swiften/Base/Log.h>
+#include <Swiften/Base/foreach.h>
+
+#include <boost/bind.hpp>
+
+namespace Swift {
+
+DiscoServiceWalker::DiscoServiceWalker(const JID& service, IQRouter* iqRouter, size_t maxSteps) : service_(service), iqRouter_(iqRouter), maxSteps_(maxSteps), active_(false) {
+
+}
+
+void DiscoServiceWalker::beginWalk() {
+	SWIFT_LOG(debug) << "Starting walk to " << service_ << std::endl;
+	assert(!active_);
+	assert(servicesBeingSearched_.empty());
+	active_ = true;
+	walkNode(service_);
+}
+
+void DiscoServiceWalker::endWalk() {
+	if (active_) {
+		SWIFT_LOG(debug) << "Ending walk to " << service_ << std::endl;
+		foreach (GetDiscoInfoRequest::ref request, pendingDiscoInfoRequests_) {
+			request->onResponse.disconnect(boost::bind(&DiscoServiceWalker::handleDiscoInfoResponse, this, _1, _2, request));
+		}
+		foreach (GetDiscoItemsRequest::ref request, pendingDiscoItemsRequests_) {
+			request->onResponse.disconnect(boost::bind(&DiscoServiceWalker::handleDiscoItemsResponse, this, _1, _2, request));
+		}
+		active_ = false;
+	}
+}
+
+void DiscoServiceWalker::walkNode(const JID& jid) {
+	SWIFT_LOG(debug) << "Walking node " << jid << std::endl;
+	servicesBeingSearched_.insert(jid);
+	searchedServices_.insert(jid);
+	GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(jid, iqRouter_);
+	discoInfoRequest->onResponse.connect(boost::bind(&DiscoServiceWalker::handleDiscoInfoResponse, this, _1, _2, discoInfoRequest));
+	pendingDiscoInfoRequests_.insert(discoInfoRequest);
+	discoInfoRequest->send();
+}
+
+void DiscoServiceWalker::handleDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error, GetDiscoInfoRequest::ref request) {
+	/* If we got canceled, don't do anything */
+	if (!active_) {
+		return;
+	}
+
+	SWIFT_LOG(debug) << "Disco info response from " << request->getReceiver() << std::endl;
+
+	pendingDiscoInfoRequests_.erase(request);
+	if (error) {
+		handleDiscoError(request->getReceiver(), error);
+		return;
+	}
+
+	bool couldContainServices = false;
+	foreach (DiscoInfo::Identity identity, info->getIdentities()) {
+		if (identity.getCategory() == "server") {
+			couldContainServices = true;
+		}
+	}
+	bool completed = false;
+	if (couldContainServices) {
+		GetDiscoItemsRequest::ref discoItemsRequest = GetDiscoItemsRequest::create(request->getReceiver(), iqRouter_);
+		discoItemsRequest->onResponse.connect(boost::bind(&DiscoServiceWalker::handleDiscoItemsResponse, this, _1, _2, discoItemsRequest));
+		pendingDiscoItemsRequests_.insert(discoItemsRequest);
+		discoItemsRequest->send();
+	} else {
+		completed = true;
+	}
+	onServiceFound(request->getReceiver(), info);
+	if (completed) {
+		markNodeCompleted(request->getReceiver());
+	}
+}
+
+void DiscoServiceWalker::handleDiscoItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, GetDiscoItemsRequest::ref request) {
+	/* If we got canceled, don't do anything */
+	if (!active_) {
+		return;
+	}
+
+	SWIFT_LOG(debug) << "Received disco items from " << request->getReceiver() << std::endl;
+	pendingDiscoItemsRequests_.erase(request);
+	if (error) {
+		handleDiscoError(request->getReceiver(), error);
+		return;
+	}
+	foreach (DiscoItems::Item item, items->getItems()) {
+		if (item.getNode().empty()) {
+			/* Don't look at noded items. It's possible that this will exclude some services,
+			 * but I've never seen one in the wild, and it's an easy fix for not looping.
+			 */
+			if (std::find(searchedServices_.begin(), searchedServices_.end(), item.getJID()) == searchedServices_.end()) { /* Don't recurse infinitely */
+				SWIFT_LOG(debug) << "Received disco item " << item.getJID() << std::endl;
+				walkNode(item.getJID());
+			}
+		}
+	}
+	markNodeCompleted(request->getReceiver());
+}
+
+void DiscoServiceWalker::handleDiscoError(const JID& jid, ErrorPayload::ref /*error*/) {
+	SWIFT_LOG(debug) << "Disco error from " << jid << std::endl;
+	markNodeCompleted(jid);
+}
+
+void DiscoServiceWalker::markNodeCompleted(const JID& jid) {
+	SWIFT_LOG(debug) << "Node completed " << jid << std::endl;
+	servicesBeingSearched_.erase(jid);
+	/* All results are in */
+	if (servicesBeingSearched_.empty()) {
+		active_ = false;
+		onWalkComplete();
+	}
+	/* Check if we're on a rampage */
+	else if (searchedServices_.size() >= maxSteps_) {
+		active_ = false;
+		onWalkComplete();
+	}
+}
+
+}
diff --git a/Swiften/Disco/DiscoServiceWalker.h b/Swiften/Disco/DiscoServiceWalker.h
new file mode 100644
index 0000000..fd749fc
--- /dev/null
+++ b/Swiften/Disco/DiscoServiceWalker.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+#include <set>
+
+#include <boost/shared_ptr.hpp>
+#include <Swiften/Base/boost_bsignals.h>
+#include <string>
+#include <Swiften/JID/JID.h>
+#include <Swiften/Elements/DiscoInfo.h>
+#include <Swiften/Elements/DiscoItems.h>
+#include <Swiften/Elements/ErrorPayload.h>
+#include <Swiften/Disco/GetDiscoInfoRequest.h>
+#include <Swiften/Disco/GetDiscoItemsRequest.h>
+
+namespace Swift {
+	class IQRouter;
+	/**
+	 * Recursively walk service discovery trees to find all services offered.
+	 * This stops on any disco item that's not reporting itself as a server.
+	 */
+	class DiscoServiceWalker {
+		public:
+			DiscoServiceWalker(const JID& service, IQRouter* iqRouter, size_t maxSteps = 200);
+
+			/**
+			 * Start the walk.
+			 *
+			 * Call this exactly once.
+			 */
+			void beginWalk();
+
+			/**
+			 * End the walk.
+			 */
+			void endWalk();
+
+			bool isActive() const {
+				return active_;
+			}
+
+			/** Emitted for each service found. */
+			boost::signal<void(const JID&, boost::shared_ptr<DiscoInfo>)> onServiceFound;
+
+			/** Emitted when walking is complete.*/
+			boost::signal<void()> onWalkComplete;
+
+		private:
+			void walkNode(const JID& jid);
+			void markNodeCompleted(const JID& jid);
+			void handleDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error, GetDiscoInfoRequest::ref request);
+			void handleDiscoItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, GetDiscoItemsRequest::ref request);
+			void handleDiscoError(const JID& jid, ErrorPayload::ref error);
+
+		private:
+			JID service_;
+			IQRouter* iqRouter_;
+			size_t maxSteps_;
+			bool active_;
+			std::set<JID> servicesBeingSearched_;
+			std::set<JID> searchedServices_;
+			std::set<GetDiscoInfoRequest::ref> pendingDiscoInfoRequests_;
+			std::set<GetDiscoItemsRequest::ref> pendingDiscoItemsRequests_;
+	};
+}
diff --git a/Swiften/Disco/SConscript b/Swiften/Disco/SConscript
index 434018a..c821b42 100644
--- a/Swiften/Disco/SConscript
+++ b/Swiften/Disco/SConscript
@@ -10,5 +10,6 @@ objects = swiften_env.SwiftenObject([
 			"ClientDiscoManager.cpp",
 			"DiscoInfoResponder.cpp",
 			"JIDDiscoInfoResponder.cpp",
+			"DiscoServiceWalker.cpp",
 		])
 swiften_env.Append(SWIFTEN_OBJECTS = [objects])
-- 
cgit v0.10.2-6-g49f6