/* * Copyright (c) 2010 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" #include #include #include #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/EventLoop.h" namespace Swift { FakeDNSSDQuerier::FakeDNSSDQuerier(const std::string& domain, EventLoop* eventLoop) : domain(domain), eventLoop(eventLoop) { } FakeDNSSDQuerier::~FakeDNSSDQuerier() { if (!runningQueries.empty()) { std::cerr << "FakeDNSSDQuerier: Running queries not empty at destruction time" << std::endl; } } boost::shared_ptr FakeDNSSDQuerier::createBrowseQuery() { return boost::shared_ptr(new FakeDNSSDBrowseQuery(shared_from_this())); } boost::shared_ptr FakeDNSSDQuerier::createRegisterQuery(const std::string& name, int port, const ByteArray& info) { return boost::shared_ptr(new FakeDNSSDRegisterQuery(name, port, info, shared_from_this())); } boost::shared_ptr FakeDNSSDQuerier::createResolveServiceQuery(const DNSSDServiceID& service) { return boost::shared_ptr(new FakeDNSSDResolveServiceQuery(service, shared_from_this())); } boost::shared_ptr FakeDNSSDQuerier::createResolveHostnameQuery(const std::string& hostname, int interfaceIndex) { return boost::shared_ptr(new FakeDNSSDResolveHostnameQuery(hostname, interfaceIndex, shared_from_this())); } void FakeDNSSDQuerier::addRunningQuery(boost::shared_ptr query) { runningQueries.push_back(query); allQueriesEverRun.push_back(query); if (boost::shared_ptr browseQuery = boost::dynamic_pointer_cast(query)) { foreach(const DNSSDServiceID& service, services) { eventLoop->postEvent(boost::bind(boost::ref(browseQuery->onServiceAdded), service), shared_from_this()); } } else if (boost::shared_ptr resolveQuery = boost::dynamic_pointer_cast(query)) { for(ServiceInfoMap::const_iterator i = serviceInfo.begin(); i != serviceInfo.end(); ++i) { if (i->first == resolveQuery->service) { eventLoop->postEvent(boost::bind(boost::ref(resolveQuery->onServiceResolved), i->second), shared_from_this()); } } } else if (boost::shared_ptr registerQuery = boost::dynamic_pointer_cast(query)) { DNSSDServiceID service(registerQuery->name, domain); eventLoop->postEvent(boost::bind(boost::ref(registerQuery->onRegisterFinished), service), shared_from_this()); } else if (boost::shared_ptr resolveHostnameQuery = boost::dynamic_pointer_cast(query)) { std::map >::const_iterator i = addresses.find(resolveHostnameQuery->hostname); if (i != addresses.end()) { eventLoop->postEvent( boost::bind( boost::ref(resolveHostnameQuery->onHostnameResolved), i->second), shared_from_this()); } } } void FakeDNSSDQuerier::removeRunningQuery(boost::shared_ptr 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& query, getQueries()) { eventLoop->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& query, getQueries()) { eventLoop->postEvent(boost::bind(boost::ref(query->onServiceRemoved), id), shared_from_this()); } } void FakeDNSSDQuerier::setServiceInfo(const DNSSDServiceID& id, const DNSSDResolveServiceQuery::Result& info) { std::pair r = serviceInfo.insert(std::make_pair(id, info)); if (!r.second) { r.first->second = info; } foreach(const boost::shared_ptr& query, getQueries()) { if (query->service == id) { eventLoop->postEvent(boost::bind(boost::ref(query->onServiceResolved), info), shared_from_this()); } } } bool FakeDNSSDQuerier::isServiceRegistered(const std::string& name, int port, const ByteArray& info) { foreach(const boost::shared_ptr& query, getQueries()) { if (query->name == name && query->port == port && query->info == info) { return true; } } return false; } void FakeDNSSDQuerier::setBrowseError() { foreach(const boost::shared_ptr& query, getQueries()) { eventLoop->postEvent(boost::ref(query->onError), shared_from_this()); } } void FakeDNSSDQuerier::setRegisterError() { foreach(const boost::shared_ptr& query, getQueries()) { eventLoop->postEvent(boost::bind(boost::ref(query->onRegisterFinished), boost::optional()), shared_from_this()); } } void FakeDNSSDQuerier::setAddress(const std::string& hostname, boost::optional address) { addresses[hostname] = address; foreach(const boost::shared_ptr& query, getQueries()) { if (query->hostname == hostname) { eventLoop->postEvent(boost::bind( boost::ref(query->onHostnameResolved), address), shared_from_this()); } } } }