summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2009-07-26 08:21:20 (GMT)
committerRemko Tronçon <git@el-tramo.be>2009-07-26 14:52:17 (GMT)
commit26d623d3cfd8937fb52acf76ef33d230f5010538 (patch)
treeade8246f719fa4dee9de1daaa2ba3f7b6c324e53
parent2833b8f09c9aef09004662a2a89eefbaee1e4247 (diff)
downloadswift-contrib-26d623d3cfd8937fb52acf76ef33d230f5010538.zip
swift-contrib-26d623d3cfd8937fb52acf76ef33d230f5010538.tar.bz2
Implement fake DNSSD querier.
-rw-r--r--Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h13
-rw-r--r--Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp7
-rw-r--r--Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h14
-rw-r--r--Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h9
-rw-r--r--Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h9
-rw-r--r--Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h1
-rw-r--r--Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h1
-rw-r--r--Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h22
-rw-r--r--Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp92
-rw-r--r--Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h61
-rw-r--r--Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp20
-rw-r--r--Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h25
-rw-r--r--Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h31
-rw-r--r--Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h25
-rw-r--r--Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h25
-rw-r--r--Swiften/LinkLocal/DNSSD/Fake/Makefile.inc3
-rw-r--r--Swiften/LinkLocal/DNSSD/Makefile.inc2
-rw-r--r--Swiften/LinkLocal/LinkLocalServiceBrowser.cpp66
-rw-r--r--Swiften/LinkLocal/LinkLocalServiceBrowser.h16
-rw-r--r--Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp162
-rw-r--r--Swiften/LinkLocal/UnitTest/Makefile.inc1
-rw-r--r--Swiften/LinkLocal/UnitTest/MockDNSSDService.h97
22 files changed, 551 insertions, 151 deletions
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h
index 62d8606..8e3181e 100644
--- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h
@@ -14,14 +14,17 @@ namespace Swift {
&sdRef, 0, 0, "_presence._tcp", 0,
&BonjourBrowseQuery::handleServiceDiscoveredStatic, this);
if (result != kDNSServiceErr_NoError) {
- std::cout << "Error" << std::endl;
- // TODO
+ sdRef = NULL;
}
}
void startBrowsing() {
- assert(sdRef);
- run();
+ if (!sdRef) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onError)), shared_from_this());
+ }
+ else {
+ run();
+ }
}
void stopBrowsing() {
@@ -35,7 +38,7 @@ namespace Swift {
void handleServiceDiscovered(DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain) {
if (errorCode != kDNSServiceErr_NoError) {
- return;
+ MainEventLoop::postEvent(boost::bind(boost::ref(onError)), shared_from_this());
}
else {
DNSSDServiceID service(name, type, domain, interfaceIndex);
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp
index c065d4d..70fbc7c 100644
--- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp
@@ -22,7 +22,7 @@ BonjourQuerier::BonjourQuerier() : stopRequested(false), thread(0) {
}
BonjourQuerier::~BonjourQuerier() {
- stop();
+ assert(!thread);
}
boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() {
@@ -64,18 +64,19 @@ void BonjourQuerier::interruptSelect() {
}
void BonjourQuerier::start() {
- stop();
+ assert(!thread);
thread = new boost::thread(boost::bind(&BonjourQuerier::run, shared_from_this()));
}
void BonjourQuerier::stop() {
if (thread) {
stopRequested = true;
- runningQueries.clear(); // TODO: Is this the right thing to do?
+ assert(runningQueries.empty());
runningQueriesAvailableEvent.notify_one();
interruptSelect();
thread->join();
delete thread;
+ thread = NULL;
stopRequested = false;
}
}
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h
index 9c4db13..41e5831 100644
--- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h
@@ -18,13 +18,21 @@ namespace Swift {
txtRecord.getSize(), txtRecord.getData(),
&BonjourRegisterQuery::handleServiceRegisteredStatic, this);
if (result != kDNSServiceErr_NoError) {
- // TODO
- std::cerr << "Error creating service registration" << std::endl;
+ sdRef = NULL;
}
}
void registerService() {
- run();
+ if (sdRef) {
+ run();
+ }
+ else {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this());
+ }
+ }
+
+ void unregisterService() {
+ stop();
}
void updateServiceInfo(const LinkLocalServiceInfo& info) {
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h
index 58c6588..6e2a852 100644
--- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h
@@ -19,13 +19,18 @@ namespace Swift {
hostname.getUTF8Data(),
&BonjourResolveHostnameQuery::handleHostnameResolvedStatic, this);
if (result != kDNSServiceErr_NoError) {
- MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this());
+ sdRef = NULL;
}
}
//void DNSSDResolveHostnameQuery::run() {
void run() {
- BonjourQuery::run();
+ if (sdRef) {
+ BonjourQuery::run();
+ }
+ else {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this());
+ }
}
private:
diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h
index 1ebd487..8b3f7ec 100644
--- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h
+++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h
@@ -18,12 +18,17 @@ namespace Swift {
service.getDomain().getUTF8Data(),
&BonjourResolveServiceQuery::handleServiceResolvedStatic, this);
if (result != kDNSServiceErr_NoError) {
- MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this());
+ sdRef = NULL;
}
}
void start() {
- run();
+ if (sdRef) {
+ run();
+ }
+ else {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this());
+ }
}
void stop() {
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h
index 86967ed..9b30858 100644
--- a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h
+++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h
@@ -14,5 +14,6 @@ namespace Swift {
boost::signal<void (const DNSSDServiceID&)> onServiceAdded;
boost::signal<void (const DNSSDServiceID&)> onServiceRemoved;
+ boost::signal<void ()> onError;
};
}
diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h
index a643880..627cc6b 100644
--- a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h
+++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h
@@ -13,6 +13,7 @@ namespace Swift {
virtual ~DNSSDRegisterQuery();
virtual void registerService() = 0;
+ virtual void unregisterService() = 0;
virtual void updateServiceInfo(const LinkLocalServiceInfo& info) = 0;
boost::signal<void (boost::optional<DNSSDServiceID>)> onRegisterFinished;
diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h
new file mode 100644
index 0000000..5a0b93b
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h"
+
+namespace Swift {
+ class FakeDNSSDQuerier;
+
+ class FakeDNSSDBrowseQuery : public DNSSDBrowseQuery, public FakeDNSSDQuery {
+ public:
+ FakeDNSSDBrowseQuery(boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier) {
+ }
+
+ void startBrowsing() {
+ run();
+ }
+
+ void stopBrowsing() {
+ finish();
+ }
+ };
+}
diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp
new file mode 100644
index 0000000..222500a
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp
@@ -0,0 +1,92 @@
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h"
+
+#include <boost/bind.hpp>
+
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h"
+#include "Swiften/EventLoop/MainEventLoop.h"
+
+namespace Swift {
+
+FakeDNSSDQuerier::FakeDNSSDQuerier() {
+}
+
+boost::shared_ptr<DNSSDBrowseQuery> FakeDNSSDQuerier::createBrowseQuery() {
+ return boost::shared_ptr<DNSSDBrowseQuery>(new FakeDNSSDBrowseQuery(shared_from_this()));
+}
+
+boost::shared_ptr<DNSSDRegisterQuery> FakeDNSSDQuerier::createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info) {
+ return boost::shared_ptr<DNSSDRegisterQuery>(new FakeDNSSDRegisterQuery(name, port, info, shared_from_this()));
+}
+
+boost::shared_ptr<DNSSDResolveServiceQuery> FakeDNSSDQuerier::createResolveServiceQuery(const DNSSDServiceID& service) {
+ return boost::shared_ptr<DNSSDResolveServiceQuery>(new FakeDNSSDResolveServiceQuery(service, shared_from_this()));
+}
+
+boost::shared_ptr<DNSSDResolveHostnameQuery> FakeDNSSDQuerier::createResolveHostnameQuery(const String& hostname, int interfaceIndex) {
+ return boost::shared_ptr<DNSSDResolveHostnameQuery>(new FakeDNSSDResolveHostnameQuery(hostname, interfaceIndex, shared_from_this()));
+}
+
+void FakeDNSSDQuerier::addRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query) {
+ runningQueries.push_back(query);
+ if (boost::shared_ptr<FakeDNSSDBrowseQuery> browseQuery = boost::dynamic_pointer_cast<FakeDNSSDBrowseQuery>(query)) {
+ foreach(const DNSSDServiceID& service, services) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(browseQuery->onServiceAdded), service), shared_from_this());
+ }
+ }
+ else if (boost::shared_ptr<FakeDNSSDResolveServiceQuery> resolveQuery = boost::dynamic_pointer_cast<FakeDNSSDResolveServiceQuery>(query)) {
+ for(ServiceInfoMap::const_iterator i = serviceInfo.begin(); i != serviceInfo.end(); ++i) {
+ if (i->first == resolveQuery->service) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(resolveQuery->onServiceResolved), i->second), shared_from_this());
+ }
+ }
+ }
+}
+
+void FakeDNSSDQuerier::removeRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query) {
+ runningQueries.erase(std::remove(
+ runningQueries.begin(), runningQueries.end(), query), runningQueries.end());
+}
+
+void FakeDNSSDQuerier::addService(const DNSSDServiceID& id) {
+ services.insert(id);
+ foreach(const boost::shared_ptr<FakeDNSSDBrowseQuery>& query, getQueries<FakeDNSSDBrowseQuery>()) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(query->onServiceAdded), id), shared_from_this());
+ }
+}
+
+void FakeDNSSDQuerier::removeService(const DNSSDServiceID& id) {
+ services.erase(id);
+ serviceInfo.erase(id);
+ foreach(const boost::shared_ptr<FakeDNSSDBrowseQuery>& query, getQueries<FakeDNSSDBrowseQuery>()) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(query->onServiceRemoved), id), shared_from_this());
+ }
+}
+
+void FakeDNSSDQuerier::setServiceInfo(const DNSSDServiceID& id, const DNSSDResolveServiceQuery::Result& info) {
+ std::pair<ServiceInfoMap::iterator, bool> r = serviceInfo.insert(std::make_pair(id, info));
+ if (!r.second) {
+ r.first->second = info;
+ }
+ foreach(const boost::shared_ptr<FakeDNSSDResolveServiceQuery>& query, getQueries<FakeDNSSDResolveServiceQuery>()) {
+ if (query->service == id) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(query->onServiceResolved), info), shared_from_this());
+ }
+ }
+}
+
+void FakeDNSSDQuerier::setBrowseError() {
+ foreach(const boost::shared_ptr<FakeDNSSDBrowseQuery>& query, getQueries<FakeDNSSDBrowseQuery>()) {
+ MainEventLoop::postEvent(boost::ref(query->onError), shared_from_this());
+ }
+}
+
+void FakeDNSSDQuerier::setRegisterError() {
+ foreach(const boost::shared_ptr<FakeDNSSDRegisterQuery>& query, getQueries<FakeDNSSDRegisterQuery>()) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(query->onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this());
+ }
+}
+
+}
diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h
new file mode 100644
index 0000000..6c5f343
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h
@@ -0,0 +1,61 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <list>
+#include <set>
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/EventLoop/EventOwner.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h"
+
+namespace Swift {
+ class LinkLocalServiceInfo;
+ class FakeDNSSDQuery;
+ class FakeDNSSDBrowseQuery;
+
+ class FakeDNSSDQuerier :
+ public DNSSDQuerier,
+ public EventOwner,
+ public boost::enable_shared_from_this<FakeDNSSDQuerier> {
+ public:
+ FakeDNSSDQuerier();
+
+ boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery();
+ boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery(
+ const String& name, int port, const LinkLocalServiceInfo& info);
+ boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery(
+ const DNSSDServiceID&);
+ boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery(
+ const String& hostname, int interfaceIndex);
+
+ void addRunningQuery(boost::shared_ptr<FakeDNSSDQuery>);
+ void removeRunningQuery(boost::shared_ptr<FakeDNSSDQuery>);
+
+ void addService(const DNSSDServiceID& id);
+ void removeService(const DNSSDServiceID& id);
+ void setServiceInfo(const DNSSDServiceID& id, const DNSSDResolveServiceQuery::Result& info);
+
+ void setBrowseError();
+ void setRegisterError();
+
+ private:
+ template<typename T>
+ std::vector< boost::shared_ptr<T> > getQueries() const {
+ std::vector< boost::shared_ptr<T> > result;
+ foreach(const boost::shared_ptr<FakeDNSSDQuery>& query, runningQueries) {
+ if (boost::shared_ptr<T> resultQuery = boost::dynamic_pointer_cast<T>(query)) {
+ result.push_back(resultQuery);
+ }
+ }
+ return result;
+ }
+
+ private:
+ std::list< boost::shared_ptr<FakeDNSSDQuery> > runningQueries;
+ std::set<DNSSDServiceID> services;
+ typedef std::map<DNSSDServiceID,DNSSDResolveServiceQuery::Result> ServiceInfoMap;
+ ServiceInfoMap serviceInfo;
+ };
+}
diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp
new file mode 100644
index 0000000..ced7850
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp
@@ -0,0 +1,20 @@
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h"
+
+namespace Swift {
+
+FakeDNSSDQuery::FakeDNSSDQuery(boost::shared_ptr<FakeDNSSDQuerier> querier) : querier(querier) {
+}
+
+FakeDNSSDQuery::~FakeDNSSDQuery() {
+}
+
+void FakeDNSSDQuery::run() {
+ querier->addRunningQuery(shared_from_this());
+}
+
+void FakeDNSSDQuery::finish() {
+ querier->removeRunningQuery(shared_from_this());
+}
+
+}
diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h
new file mode 100644
index 0000000..9fca1d4
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include "Swiften/EventLoop/EventOwner.h"
+
+namespace Swift {
+ class FakeDNSSDQuerier;
+
+ class FakeDNSSDQuery :
+ public EventOwner,
+ public boost::enable_shared_from_this<FakeDNSSDQuery> {
+ public:
+ FakeDNSSDQuery(boost::shared_ptr<FakeDNSSDQuerier>);
+ virtual ~FakeDNSSDQuery();
+
+ protected:
+ void run();
+ void finish();
+
+ protected:
+ boost::shared_ptr<FakeDNSSDQuerier> querier;
+ };
+}
diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h
new file mode 100644
index 0000000..b4646fd
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h"
+#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
+#include "Swiften/Base/String.h"
+
+namespace Swift {
+ class FakeDNSSDQuerier;
+
+ class FakeDNSSDRegisterQuery : public DNSSDRegisterQuery, public FakeDNSSDQuery {
+ public:
+ FakeDNSSDRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier), name(name), port(port), info(info) {
+ }
+
+ void registerService() {
+ run();
+ }
+
+ void updateServiceInfo(const LinkLocalServiceInfo&) {
+ }
+
+ void unregisterService() {
+ finish();
+ }
+
+ String name;
+ int port;
+ LinkLocalServiceInfo info;
+ };
+}
diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h
new file mode 100644
index 0000000..2ff84d3
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "Swiften/Base/String.h"
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h"
+#include "Swiften/Network/HostAddress.h"
+
+#include <netinet/in.h>
+
+namespace Swift {
+ class FakeDNSSDQuerier;
+
+ class FakeDNSSDResolveHostnameQuery : public DNSSDResolveHostnameQuery, public FakeDNSSDQuery {
+ public:
+ FakeDNSSDResolveHostnameQuery(const String& hostname, int interfaceIndex, boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier), hostname(hostname), interfaceIndex(interfaceIndex) {
+ }
+
+ void run() {
+ FakeDNSSDQuery::run();
+ }
+
+ String hostname;
+ int interfaceIndex;
+ };
+}
diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h
new file mode 100644
index 0000000..60d35e5
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h"
+#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
+
+namespace Swift {
+ class FakeDNSSDQuerier;
+
+ class FakeDNSSDResolveServiceQuery : public DNSSDResolveServiceQuery, public FakeDNSSDQuery {
+ public:
+ FakeDNSSDResolveServiceQuery(const DNSSDServiceID& service, boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier), service(service) {
+ }
+
+ void start() {
+ run();
+ }
+
+ void stop() {
+ finish();
+ }
+
+ DNSSDServiceID service;
+ };
+}
diff --git a/Swiften/LinkLocal/DNSSD/Fake/Makefile.inc b/Swiften/LinkLocal/DNSSD/Fake/Makefile.inc
new file mode 100644
index 0000000..316d061
--- /dev/null
+++ b/Swiften/LinkLocal/DNSSD/Fake/Makefile.inc
@@ -0,0 +1,3 @@
+SWIFTEN_SOURCES += \
+ Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp \
+ Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp
diff --git a/Swiften/LinkLocal/DNSSD/Makefile.inc b/Swiften/LinkLocal/DNSSD/Makefile.inc
index 8612fee..3d2c969 100644
--- a/Swiften/LinkLocal/DNSSD/Makefile.inc
+++ b/Swiften/LinkLocal/DNSSD/Makefile.inc
@@ -11,3 +11,5 @@ include Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc
endif
ifeq ($(HAVE_AVAHI),yes)
endif
+
+include Swiften/LinkLocal/DNSSD/Fake/Makefile.inc
diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp
index 4e9c2de..aed917a 100644
--- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp
+++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp
@@ -7,17 +7,66 @@
namespace Swift {
-LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier) : querier(querier) {
+LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier) : querier(querier), haveError(false) {
+}
+
+LinkLocalServiceBrowser::~LinkLocalServiceBrowser() {
+ assert(!isRunning());
+}
+
+
+void LinkLocalServiceBrowser::start() {
+ assert(!isRunning());
+ haveError = false;
browseQuery = querier->createBrowseQuery();
browseQuery->onServiceAdded.connect(
boost::bind(&LinkLocalServiceBrowser::handleServiceAdded, this, _1));
browseQuery->onServiceRemoved.connect(
boost::bind(&LinkLocalServiceBrowser::handleServiceRemoved, this, _1));
+ browseQuery->onError.connect(
+ boost::bind(&LinkLocalServiceBrowser::handleBrowseError, this));
browseQuery->startBrowsing();
}
-LinkLocalServiceBrowser::~LinkLocalServiceBrowser() {
+void LinkLocalServiceBrowser::stop() {
+ assert(isRunning());
+ if (isRegistered()) {
+ unregisterService();
+ }
+ for (ResolveQueryMap::const_iterator i = resolveQueries.begin(); i != resolveQueries.end(); ++i) {
+ i->second->stop();
+ }
+ resolveQueries.clear();
+ services.clear();
browseQuery->stopBrowsing();
+ browseQuery.reset();
+ onStopped(haveError);
+}
+
+bool LinkLocalServiceBrowser::isRunning() const {
+ return browseQuery;
+}
+
+bool LinkLocalServiceBrowser::hasError() const {
+ return haveError;
+}
+
+bool LinkLocalServiceBrowser::isRegistered() const {
+ return registerQuery;
+}
+
+void LinkLocalServiceBrowser::registerService(const String& name, int port, const LinkLocalServiceInfo& info) {
+ assert(!registerQuery);
+ registerQuery = querier->createRegisterQuery(name, port, info);
+ registerQuery->onRegisterFinished.connect(
+ boost::bind(&LinkLocalServiceBrowser::handleRegisterFinished, this, _1));
+ registerQuery->registerService();
+}
+
+void LinkLocalServiceBrowser::unregisterService() {
+ assert(registerQuery);
+ registerQuery->unregisterService();
+ registerQuery.reset();
}
std::vector<LinkLocalService> LinkLocalServiceBrowser::getServices() const {
@@ -44,6 +93,7 @@ void LinkLocalServiceBrowser::handleServiceRemoved(const DNSSDServiceID& service
assert(i != resolveQueries.end());
i->second->stop();
resolveQueries.erase(i);
+ services.erase(service);
onServiceRemoved(service);
}
@@ -60,4 +110,16 @@ void LinkLocalServiceBrowser::handleServiceResolved(const DNSSDServiceID& servic
}
}
+void LinkLocalServiceBrowser::handleRegisterFinished(const boost::optional<DNSSDServiceID>& result) {
+ if (!result) {
+ haveError = true;
+ stop();
+ }
+}
+
+void LinkLocalServiceBrowser::handleBrowseError() {
+ haveError = true;
+ stop();
+}
+
}
diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h
index 7ec796a..33c9858 100644
--- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h
+++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h
@@ -9,8 +9,10 @@
#include "Swiften/Base/String.h"
#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h"
#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h"
#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h"
#include "Swiften/LinkLocal/LinkLocalService.h"
+#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
namespace Swift {
class LinkLocalServiceBrowser {
@@ -18,23 +20,37 @@ namespace Swift {
LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier);
~LinkLocalServiceBrowser();
+ void start();
+ void stop();
+ bool isRunning() const;
+ bool hasError() const;
+
+ void registerService(const String& name, int port, const LinkLocalServiceInfo& info = LinkLocalServiceInfo());
+ void unregisterService();
+ bool isRegistered() const;
+
std::vector<LinkLocalService> getServices() const;
boost::signal<void (const DNSSDServiceID&)> onServiceAdded;
boost::signal<void (const DNSSDServiceID&)> onServiceChanged;
boost::signal<void (const DNSSDServiceID&)> onServiceRemoved;
+ boost::signal<void (bool)> onStopped;
private:
void handleServiceAdded(const DNSSDServiceID&);
void handleServiceRemoved(const DNSSDServiceID&);
void handleServiceResolved(const DNSSDServiceID& service, const boost::optional<DNSSDResolveServiceQuery::Result>& result);
+ void handleRegisterFinished(const boost::optional<DNSSDServiceID>&);
+ void handleBrowseError();
private:
boost::shared_ptr<DNSSDQuerier> querier;
boost::shared_ptr<DNSSDBrowseQuery> browseQuery;
+ boost::shared_ptr<DNSSDRegisterQuery> registerQuery;
typedef std::map<DNSSDServiceID, boost::shared_ptr<DNSSDResolveServiceQuery> > ResolveQueryMap;
ResolveQueryMap resolveQueries;
typedef std::map<DNSSDServiceID, DNSSDResolveServiceQuery::Result> ServiceMap;
ServiceMap services;
+ bool haveError;
};
}
diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp
index 34f797c..7e2dd26 100644
--- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp
+++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp
@@ -5,20 +5,26 @@
#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h"
#include "Swiften/LinkLocal/LinkLocalService.h"
-#include "Swiften/LinkLocal/UnitTest/MockDNSSDService.h"
-#include "Swiften/LinkLocal/DNSSDService.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h"
#include "Swiften/EventLoop/DummyEventLoop.h"
-// Test canCreate() == false
-
using namespace Swift;
class LinkLocalServiceBrowserTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(LinkLocalServiceBrowserTest);
+ CPPUNIT_TEST(testConstructor);
+ CPPUNIT_TEST(testStart);
CPPUNIT_TEST(testServiceAdded);
CPPUNIT_TEST(testServiceAdded_NoServiceInfo);
CPPUNIT_TEST(testServiceChanged);
CPPUNIT_TEST(testServiceRemoved);
+ CPPUNIT_TEST(testError_BrowseErrorAfterStart);
+ CPPUNIT_TEST(testError_BrowseErrorAfterResolve);
+ CPPUNIT_TEST(testRegisterService);
+ CPPUNIT_TEST(testRegisterService_Error);
+ CPPUNIT_TEST(testRegisterService_Reregister);
CPPUNIT_TEST_SUITE_END();
public:
@@ -26,10 +32,10 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture {
void setUp() {
eventLoop = new DummyEventLoop();
- dnsSDServiceFactory = new MockDNSSDServiceFactory();
- testServiceID = new LinkLocalServiceID("foo", "bar.local");
- testServiceInfo = new DNSSDService::ResolveResult("xmpp.bar.local", 1234, LinkLocalServiceInfo());
- testServiceInfo2 = new DNSSDService::ResolveResult("xmpp.foo.local", 2345, LinkLocalServiceInfo());
+ querier = boost::shared_ptr<FakeDNSSDQuerier>(new FakeDNSSDQuerier());
+ testServiceID = new DNSSDServiceID("foo", "bar.local");
+ testServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.bar.local", "xmpp.bar.local", 1234, LinkLocalServiceInfo());
+ testServiceInfo2 = new DNSSDResolveServiceQuery::Result("_presence.tcp.bar.local", "xmpp.foo.local", 2345, LinkLocalServiceInfo());
}
void tearDown() {
@@ -40,15 +46,33 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture {
delete testServiceInfo2;
delete testServiceInfo;
delete testServiceID;
- delete dnsSDServiceFactory;
delete eventLoop;
}
+ void testConstructor() {
+ boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
+
+ CPPUNIT_ASSERT(!testling->isRunning());
+ CPPUNIT_ASSERT(!testling->hasError());
+ }
+
+ void testStart() {
+ boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
+ testling->start();
+
+ CPPUNIT_ASSERT(testling->isRunning());
+ CPPUNIT_ASSERT(!testling->hasError());
+
+ testling->stop();
+ }
+
void testServiceAdded() {
boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
+ testling->start();
+ eventLoop->processEvents();
- dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo);
- dnsSDService()->addService(*testServiceID);
+ querier->setServiceInfo(*testServiceID,*testServiceInfo);
+ querier->addService(*testServiceID);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size()));
@@ -60,26 +84,33 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT(*testServiceID == services[0].getID());
CPPUNIT_ASSERT(testServiceInfo->port == services[0].getPort());
CPPUNIT_ASSERT(testServiceInfo->host == services[0].getHostname());
+
+ testling->stop();
}
void testServiceAdded_NoServiceInfo() {
boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
+ testling->start();
+ eventLoop->processEvents();
- dnsSDService()->addService(*testServiceID);
+ querier->addService(*testServiceID);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(addedServices.size()));
std::vector<LinkLocalService> services = testling->getServices();
CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(services.size()));
+
+ testling->stop();
}
void testServiceChanged() {
boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
- dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo);
- dnsSDService()->addService(*testServiceID);
+ testling->start();
+ querier->setServiceInfo(*testServiceID,*testServiceInfo);
+ querier->addService(*testServiceID);
eventLoop->processEvents();
- dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo2);
+ querier->setServiceInfo(*testServiceID,*testServiceInfo2);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size()));
@@ -91,31 +122,93 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT(*testServiceID == services[0].getID());
CPPUNIT_ASSERT(testServiceInfo2->port == services[0].getPort());
CPPUNIT_ASSERT(testServiceInfo2->host == services[0].getHostname());
+
+ testling->stop();
}
void testServiceRemoved() {
boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
- dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo);
- dnsSDService()->addService(*testServiceID);
+ testling->start();
+ querier->setServiceInfo(*testServiceID,*testServiceInfo);
+ querier->addService(*testServiceID);
eventLoop->processEvents();
- dnsSDService()->removeService(*testServiceID);
+ querier->removeService(*testServiceID);
eventLoop->processEvents();
- dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo2);
+ querier->setServiceInfo(*testServiceID,*testServiceInfo2);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size()));
CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size()));
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(removedServices.size()));
CPPUNIT_ASSERT(removedServices[0] == *testServiceID);
- std::vector<LinkLocalService> services = testling->getServices();
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(services.size()));
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(testling->getServices().size()));
+
+ testling->stop();
+ }
+
+ void testError_BrowseErrorAfterStart() {
+ boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
+ testling->start();
+
+ querier->setBrowseError();
+ eventLoop->processEvents();
+
+ CPPUNIT_ASSERT(!testling->isRunning());
+ CPPUNIT_ASSERT(testling->hasError());
+ }
+
+ void testError_BrowseErrorAfterResolve() {
+ boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
+ testling->start();
+ querier->setServiceInfo(*testServiceID,*testServiceInfo);
+ querier->addService(*testServiceID);
+ eventLoop->processEvents();
+
+ querier->setBrowseError();
+ eventLoop->processEvents();
+ querier->setServiceInfo(*testServiceID,*testServiceInfo2);
+ eventLoop->processEvents();
+
+ CPPUNIT_ASSERT(!testling->isRunning());
+ CPPUNIT_ASSERT(testling->hasError());
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(testling->getServices().size()));
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size()));
+ }
+
+ void testRegisterService() {
+ boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
+ testling->start();
+ eventLoop->processEvents();
+
+ testling->stop();
+ }
+
+ void testRegisterService_Error() {
+ boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
+ testling->start();
+ testling->registerService("", 1234);
+ eventLoop->processEvents();
+
+ querier->setRegisterError();
+ eventLoop->processEvents();
+
+ CPPUNIT_ASSERT(!testling->isRunning());
+ CPPUNIT_ASSERT(testling->hasError());
+ }
+
+ void testRegisterService_Reregister() {
+ boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling();
+ testling->start();
+ eventLoop->processEvents();
+
+ testling->stop();
}
private:
boost::shared_ptr<LinkLocalServiceBrowser> createTestling() {
boost::shared_ptr<LinkLocalServiceBrowser> testling(
- new LinkLocalServiceBrowser(dnsSDServiceFactory));
+ new LinkLocalServiceBrowser(querier));
testling->onServiceAdded.connect(boost::bind(
&LinkLocalServiceBrowserTest::handleServiceAdded, this, _1));
testling->onServiceChanged.connect(boost::bind(
@@ -125,32 +218,27 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture {
return testling;
}
- void handleServiceAdded(const LinkLocalServiceID& service) {
+ void handleServiceAdded(const DNSSDServiceID& service) {
addedServices.push_back(service);
}
- void handleServiceRemoved(const LinkLocalServiceID& service) {
+ void handleServiceRemoved(const DNSSDServiceID& service) {
removedServices.push_back(service);
}
- void handleServiceChanged(const LinkLocalServiceID& service) {
+ void handleServiceChanged(const DNSSDServiceID& service) {
changedServices.push_back(service);
}
- boost::shared_ptr<MockDNSSDService> dnsSDService() const {
- CPPUNIT_ASSERT(dnsSDServiceFactory->services.size() > 0);
- return dnsSDServiceFactory->services[0];
- }
-
private:
DummyEventLoop* eventLoop;
- MockDNSSDServiceFactory* dnsSDServiceFactory;
- std::vector<LinkLocalServiceID> addedServices;
- std::vector<LinkLocalServiceID> changedServices;
- std::vector<LinkLocalServiceID> removedServices;
- LinkLocalServiceID* testServiceID;
- DNSSDService::ResolveResult* testServiceInfo;
- DNSSDService::ResolveResult* testServiceInfo2;
+ boost::shared_ptr<FakeDNSSDQuerier> querier;
+ std::vector<DNSSDServiceID> addedServices;
+ std::vector<DNSSDServiceID> changedServices;
+ std::vector<DNSSDServiceID> removedServices;
+ DNSSDServiceID* testServiceID;
+ DNSSDResolveServiceQuery::Result* testServiceInfo;
+ DNSSDResolveServiceQuery::Result* testServiceInfo2;
};
CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalServiceBrowserTest);
diff --git a/Swiften/LinkLocal/UnitTest/Makefile.inc b/Swiften/LinkLocal/UnitTest/Makefile.inc
index abc1180..9640fa7 100644
--- a/Swiften/LinkLocal/UnitTest/Makefile.inc
+++ b/Swiften/LinkLocal/UnitTest/Makefile.inc
@@ -1,2 +1,3 @@
UNITTEST_SOURCES += \
+ Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp \
Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp
diff --git a/Swiften/LinkLocal/UnitTest/MockDNSSDService.h b/Swiften/LinkLocal/UnitTest/MockDNSSDService.h
deleted file mode 100644
index 69ac06d..0000000
--- a/Swiften/LinkLocal/UnitTest/MockDNSSDService.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <map>
-#include <boost/bind.hpp>
-
-#include "Swiften/EventLoop/MainEventLoop.h"
-#include "Swiften/LinkLocal/DNSSDService.h"
-#include "Swiften/LinkLocal/DNSSDServiceFactory.h"
-
-namespace Swift {
- class MockDNSSDService : public DNSSDService {
- public:
- MockDNSSDService() {
- }
-
- void start() {
- }
-
- void stop() {
- }
-
- virtual void registerService(const String&, int, const LinkLocalServiceInfo&) {
- assert(false);
- }
-
- virtual void updateService(const LinkLocalServiceInfo&) {
- assert(false);
- }
-
- virtual void unregisterService() {
- assert(false);
- }
-
- virtual void startResolvingService(const LinkLocalServiceID& id) {
- resolvingServices.push_back(id);
- broadcastServiceInfo(id);
- }
-
- virtual void stopResolvingService(const LinkLocalServiceID& id) {
- resolvingServices.erase(std::remove(resolvingServices.begin(), resolvingServices.end(), id), resolvingServices.end());
- }
-
- virtual void resolveHostname(const String&, int) {
- assert(false);
- }
-
- void addService(const LinkLocalServiceID& id) {
- MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), id));
- }
-
- void removeService(const LinkLocalServiceID& id) {
- serviceInfo.erase(id);
- MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), id));
- }
-
- void setServiceInfo(const LinkLocalServiceID& id, const DNSSDService::ResolveResult& info) {
- std::pair<ServiceInfoMap::iterator, bool> r = serviceInfo.insert(std::make_pair(id, info));
- if (!r.second) {
- r.first->second = info;
- }
- broadcastServiceInfo(id);
- }
-
- private:
- void broadcastServiceInfo(const LinkLocalServiceID& id) {
- if (std::find(resolvingServices.begin(), resolvingServices.end(), id) != resolvingServices.end()) {
- ServiceInfoMap::const_iterator i = serviceInfo.find(id);
- if (i != serviceInfo.end()) {
- MainEventLoop::postEvent(
- boost::bind(boost::ref(onServiceResolved), id, i->second));
- }
- }
- }
-
- private:
- typedef std::map<LinkLocalServiceID,DNSSDService::ResolveResult> ServiceInfoMap;
- ServiceInfoMap serviceInfo;
- std::vector<LinkLocalServiceID> resolvingServices;
- };
-
- class MockDNSSDServiceFactory : public DNSSDServiceFactory {
- public:
- boost::shared_ptr<DNSSDService> createDNSSDService() {
- boost::shared_ptr<MockDNSSDService> result(new MockDNSSDService());
- services.push_back(result);
- return result;
- }
-
- bool canCreate() const {
- return true;
- }
-
- std::vector<boost::shared_ptr<MockDNSSDService> > services;
- };
-
-}