| # dnssd Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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"

This file is part of the documentation for dnssd Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:28:19 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003