dnssd Library API Documentation

servicebrowser.cpp

00001 /* This file is part of the KDE project 00002 * 00003 * Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 * Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #include <qstringlist.h> 00022 #include "domainbrowser.h" 00023 #include "query.h" 00024 #include "servicebrowser.h" 00025 #include <config.h> 00026 #ifdef HAVE_DNSSD 00027 #include <dns_sd.h> 00028 #endif 00029 00030 namespace DNSSD 00031 { 00032 00033 const QString ServiceBrowser::AllServices = "_services._dns-sd._udp"; 00034 00035 class ServiceBrowserPrivate 00036 { 00037 public: 00038 ServiceBrowserPrivate() : m_running(false) 00039 {} 00040 QValueList<RemoteService::Ptr> m_services; 00041 QValueList<RemoteService::Ptr> m_duringResolve; 00042 QString m_type; 00043 bool m_autoresolve; 00044 DomainBrowser* m_domains; 00045 bool m_running; 00046 bool m_finished; 00047 QDict<Query> resolvers; 00048 }; 00049 00050 ServiceBrowser::ServiceBrowser(const QString& type,DomainBrowser* domains,bool autoResolve) 00051 { 00052 if (domains) init(type,domains,autoResolve); 00053 else init(type,new DomainBrowser(this),autoResolve); 00054 } 00055 00056 void ServiceBrowser::init(const QString& type,DomainBrowser* domains,bool autoResolve) 00057 { 00058 d = new ServiceBrowserPrivate(); 00059 d->resolvers.setAutoDelete(true); 00060 d->m_type=type; 00061 d->m_autoresolve=autoResolve; 00062 d->m_domains = domains; 00063 connect(d->m_domains,SIGNAL(domainAdded(const QString& )),this,SLOT(addDomain(const QString& ))); 00064 connect(d->m_domains,SIGNAL(domainRemoved(const QString& )),this, 00065 SLOT(removeDomain(const QString& ))); 00066 } 00067 ServiceBrowser::ServiceBrowser(const QString& type,const QString& domain,bool autoResolve) 00068 { 00069 init(type,new DomainBrowser(domain,false,this),autoResolve); 00070 } 00071 00072 const ServiceBrowser::State ServiceBrowser::isAvailable() 00073 { 00074 #ifdef HAVE_DNSSD 00075 // DNSServiceRef ref; 00076 // bool ok (DNSServiceCreateConnection(&ref)==kDNSServiceErr_NoError); 00077 // if (ok) DNSServiceRefDeallocate(ref); 00078 // return (ok) ? Working : Stopped; 00079 return Working; 00080 #else 00081 return Unsupported; 00082 #endif 00083 } 00084 ServiceBrowser::~ ServiceBrowser() 00085 { 00086 delete d; 00087 } 00088 00089 const DomainBrowser* ServiceBrowser::browsedDomains() const 00090 { 00091 return d->m_domains; 00092 } 00093 00094 void ServiceBrowser::serviceResolved(bool success) 00095 { 00096 QObject* sender_obj = const_cast<QObject*>(sender()); 00097 RemoteService* svr = static_cast<RemoteService*>(sender_obj); 00098 disconnect(svr,SIGNAL(resolved(bool)),this,SLOT(serviceResolved(bool))); 00099 QValueList<RemoteService::Ptr>::Iterator it = d->m_duringResolve.begin(); 00100 QValueList<RemoteService::Ptr>::Iterator itEnd = d->m_duringResolve.end(); 00101 while ( it!= itEnd && svr!= (*it)) ++it; 00102 if (it != itEnd) { 00103 if (success) { 00104 d->m_services+=(*it); 00105 emit serviceAdded(svr); 00106 } 00107 d->m_duringResolve.remove(it); 00108 queryFinished(); 00109 } 00110 } 00111 00112 void ServiceBrowser::startBrowse() 00113 { 00114 if (d->m_running) return; 00115 d->m_running=true; 00116 if (d->m_domains->isRunning()) { 00117 QStringList::const_iterator itEnd = d->m_domains->domains().end(); 00118 for ( QStringList::const_iterator it = d->m_domains->domains().begin(); it != itEnd; ++it ) 00119 addDomain(*it); 00120 } else d->m_domains->startBrowse(); 00121 } 00122 00123 void ServiceBrowser::gotNewService(RemoteService::Ptr svr) 00124 { 00125 if (findDuplicate(svr)==(d->m_services.end())) { 00126 if (d->m_autoresolve) { 00127 connect(svr,SIGNAL(resolved(bool )),this,SLOT(serviceResolved(bool ))); 00128 d->m_duringResolve+=svr; 00129 svr->resolveAsync(); 00130 } else { 00131 d->m_services+=svr; 00132 emit serviceAdded(svr); 00133 } 00134 } 00135 } 00136 00137 void ServiceBrowser::gotRemoveService(RemoteService::Ptr svr) 00138 { 00139 QValueList<RemoteService::Ptr>::Iterator it = findDuplicate(svr); 00140 if (it!=(d->m_services.end())) { 00141 emit serviceRemoved(*it); 00142 d->m_services.remove(it); 00143 } 00144 } 00145 00146 00147 void ServiceBrowser::removeDomain(const QString& domain) 00148 { 00149 d->resolvers.remove(domain); 00150 for ( QValueList<RemoteService::Ptr>::Iterator it = d->m_services.begin(); 00151 it!=d->m_services.end(); ++it) 00152 // use section to skip possible trailing dot 00153 if ((*it)->domain().section('.',0) == domain.section('.',0)) { 00154 emit serviceRemoved(*it); 00155 it = d->m_services.remove(it); 00156 } 00157 } 00158 00159 void ServiceBrowser::addDomain(const QString& domain) 00160 { 00161 if (!d->m_running) return; 00162 if (!(d->resolvers[domain])) { 00163 Query* b = new Query(d->m_type,domain); 00164 connect(b,SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),this, 00165 SLOT(gotNewService(DNSSD::RemoteService::Ptr))); 00166 connect(b,SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr )),this, 00167 SLOT(gotRemoveService(DNSSD::RemoteService::Ptr))); 00168 connect(b,SIGNAL(finished()),this,SLOT(queryFinished())); 00169 b->startQuery(); 00170 d->resolvers.insert(domain,b); 00171 } 00172 } 00173 00174 void ServiceBrowser::queryFinished() 00175 { 00176 if (allFinished()) emit finished(); 00177 } 00178 00179 bool ServiceBrowser::allFinished() 00180 { 00181 if (d->m_duringResolve.count()) return false; 00182 bool all = true; 00183 QDictIterator<Query> it(d->resolvers); 00184 for ( ; it.current(); ++it) all&=(*it)->isFinished(); 00185 return all; 00186 } 00187 00188 const QValueList<RemoteService::Ptr>& ServiceBrowser::services() const 00189 { 00190 return d->m_services; 00191 } 00192 00193 void ServiceBrowser::virtual_hook(int, void*) 00194 {} 00195 00196 QValueList<RemoteService::Ptr>::Iterator ServiceBrowser::findDuplicate(RemoteService::Ptr src) 00197 { 00198 QValueList<RemoteService::Ptr>::Iterator itEnd = d->m_services.end(); 00199 for (QValueList<RemoteService::Ptr>::Iterator it = d->m_services.begin(); it!=itEnd; ++it) 00200 if ((src->type()==(*it)->type()) && (src->serviceName()==(*it)->serviceName()) && 00201 (src->domain() == (*it)->domain())) return it; 00202 return itEnd; 00203 } 00204 00205 00206 } 00207 00208 #include "servicebrowser.moc"
KDE Logo
This file is part of the documentation for dnssd Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 12 23:21:56 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003