diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8a9d35c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.user diff --git a/bonjour.cpp b/bonjour.cpp index 8ded869..9076eb3 100644 --- a/bonjour.cpp +++ b/bonjour.cpp @@ -37,7 +37,7 @@ QZeroConfPrivate::QZeroConfPrivate(QZeroConf *parent) browserSocket = NULL; resolverSocket = NULL; addressSocket = NULL; - newService = NULL; + } void QZeroConfPrivate::bsRead() @@ -69,7 +69,7 @@ void QZeroConfPrivate::resolve(void) { DNSServiceErrorType err; - err = DNSServiceResolve(&resolver, kDNSServiceFlagsTimeout, newService->interfaceIndex, newService->name.toUtf8(), newService->type.toUtf8(), newService->domain.toUtf8(), (DNSServiceResolveReply) resolverCallback, this); + err = DNSServiceResolve(&resolver, kDNSServiceFlagsTimeout, newService.interfaceIndex(), newService.name().toUtf8(), newService.type().toUtf8(), newService.domain().toUtf8(), (DNSServiceResolveReply) resolverCallback, this); if (err == kDNSServiceErr_NoError) { int sockfd = DNSServiceRefSockFD(resolver); if (sockfd == -1) { @@ -103,7 +103,7 @@ void DNSSD_API QZeroConfPrivate::browseCallback(DNSServiceRef, DNSServiceFlags f const char *type, const char *domain, void *userdata) { QString key; - QZeroConfService *zcs; + QZeroConfService zcs; QZeroConfPrivate *ref = static_cast(userdata); //qDebug() << name; @@ -111,12 +111,12 @@ void DNSSD_API QZeroConfPrivate::browseCallback(DNSServiceRef, DNSServiceFlags f key = name + QString::number(interfaceIndex); if (flags & kDNSServiceFlagsAdd) { if (!ref->pub->services.contains(key)) { - zcs = new QZeroConfService; - zcs->name = name; - zcs->type = type; - zcs->domain = domain; - zcs->interfaceIndex = interfaceIndex; - if (!ref->newService) { + //zcs = new QZeroConfService; + zcs.setName(name); + zcs.setType( type); + zcs.setDomain(domain); + zcs.setInterfaceIndex(interfaceIndex); + if (!ref->newService.isValid()) { ref->newService = zcs; ref->resolve(); } @@ -128,7 +128,7 @@ void DNSSD_API QZeroConfPrivate::browseCallback(DNSServiceRef, DNSServiceFlags f zcs = ref->pub->services[key]; ref->pub->services.remove(key); emit ref->pub->serviceRemoved(zcs); - delete zcs; + } } else { @@ -157,15 +157,15 @@ void DNSSD_API QZeroConfPrivate::resolverCallback(DNSServiceRef, DNSServiceFlags QByteArray avahiText((const char *)txtRecord, recLen); QList pair = avahiText.split('='); if (pair.size() == 2) - ref->newService->txt[pair.at(0)] = pair.at(1); + ref->newService.appendTxt(pair.at(0), pair.at(1)); else - ref->newService->txt[pair.at(0)] = ""; + ref->newService.appendTxt(pair.at(0)); txtLen-= recLen + 1; txtRecord+= recLen; } - ref->newService->host = hostName; - ref->newService->port = qFromBigEndian(port); + ref->newService.setHost(hostName); + ref->newService.setPort(qFromBigEndian(port)); err = DNSServiceGetAddrInfo(&ref->resolver, kDNSServiceFlagsForceMulticast, interfaceIndex, ref->protocol, hostName, (DNSServiceGetAddrInfoReply) addressReply, ref); if (err == kDNSServiceErr_NoError) { int sockfd = DNSServiceRefSockFD(ref->resolver); @@ -198,11 +198,11 @@ void DNSSD_API QZeroConfPrivate::addressReply(DNSServiceRef sdRef, if ((flags & kDNSServiceFlagsAdd) != 0) { QHostAddress hAddress(address); if (hAddress.protocol() == QAbstractSocket::IPv6Protocol) - ref->newService->ipv6 = hAddress; + ref->newService.setIpv6(hAddress); else - ref->newService->ip = hAddress; + ref->newService.setIp(hAddress); - QString key = ref->newService->name + QString::number(interfaceIndex); + QString key = ref->newService.name() + QString::number(interfaceIndex); if (!ref->pub->services.contains(key)) { ref->pub->services.insert(key, ref->newService); emit ref->pub->serviceAdded(ref->newService); @@ -212,7 +212,7 @@ void DNSSD_API QZeroConfPrivate::addressReply(DNSServiceRef sdRef, } if (!(flags & kDNSServiceFlagsMoreComing)) { - ref->newService = NULL; // newService resolve succeeded so don't let cleanUp delete it! + ref->newService = QZeroConfService(); // newService resolve succeeded so don't let cleanUp delete it! ref->cleanUp(ref->resolver); } } @@ -233,10 +233,6 @@ void QZeroConfPrivate::cleanUp(DNSServiceRef toClean) delete resolverSocket; resolverSocket = NULL; } - if (newService) { - delete newService; - newService = NULL; - } if (work.size()) { newService = work.first(); work.removeFirst(); @@ -249,9 +245,6 @@ void QZeroConfPrivate::cleanUp(DNSServiceRef toClean) delete browserSocket; browserSocket = NULL; } - QMap::iterator i; - for (i = pub->services.begin(); i != pub->services.end(); i++) - delete *i; pub->services.clear(); } else if (toClean == dnssRef) { @@ -265,7 +258,7 @@ void QZeroConfPrivate::cleanUp(DNSServiceRef toClean) DNSServiceRefDeallocate(toClean); } -QZeroConf::QZeroConf() +QZeroConf::QZeroConf(QObject *parent) : QObject (parent) { pri = new QZeroConfPrivate(this); } diff --git a/bonjour_p.h b/bonjour_p.h index 907634c..792411b 100644 --- a/bonjour_p.h +++ b/bonjour_p.h @@ -64,8 +64,8 @@ public: DNSServiceRef dnssRef, browser, resolver; DNSServiceProtocol protocol; QSocketNotifier *bs, *browserSocket, *resolverSocket, *addressSocket; - QZeroConfService *newService; - QList work; + QZeroConfService newService; + QList work; QByteArray txt; public slots: diff --git a/qtzeroconf.pri b/qtzeroconf.pri index 5143b60..1b29cfa 100644 --- a/qtzeroconf.pri +++ b/qtzeroconf.pri @@ -115,3 +115,9 @@ android { SOURCES+= $$ACR/wide-area.c #avahi-core/iface-none.c avahi-core/iface-pfroute.c avahi-core/avahi-reflector.c } + +HEADERS += \ + $$PWD/qzeroconfservice.h + +SOURCES += \ + $$PWD/qzeroconfservice.cpp diff --git a/qzeroconf.h b/qzeroconf.h index ff28105..3ccb4c8 100644 --- a/qzeroconf.h +++ b/qzeroconf.h @@ -31,6 +31,7 @@ #include #include #include +#include "qzeroconfservice.h" #if (!defined(QT_STATIC) && !defined(QZEROCONF_STATIC)) # ifdef QT_BUILD_ZEROCONF_LIB @@ -42,18 +43,7 @@ # define Q_ZEROCONF_EXPORT #endif -struct QZeroConfService -{ - QString name; - QString type; - QString domain; - QString host; - QHostAddress ip; - QHostAddress ipv6; - quint32 interfaceIndex; - quint16 port; - QMap txt; -}; + class QZeroConfPrivate; @@ -70,7 +60,7 @@ public: serviceNameCollision = -2, browserFailed = -3, }; - QZeroConf(); + QZeroConf(QObject *parent = Q_NULLPTR); ~QZeroConf(); void startServicePublish(const char *name, const char *type, const char *domain, quint16 port); void stopServicePublish(void); @@ -87,13 +77,13 @@ public: Q_SIGNALS: void servicePublished(void); void error(QZeroConf::error_t); - void serviceAdded(QZeroConfService *); - void serviceUpdated(QZeroConfService *); - void serviceRemoved(QZeroConfService *); + void serviceAdded(QZeroConfService); + void serviceUpdated(QZeroConfService); + void serviceRemoved(QZeroConfService); private: QZeroConfPrivate *pri; - QMap services; + QMap services; diff --git a/qzeroconfservice.cpp b/qzeroconfservice.cpp new file mode 100644 index 0000000..48e8e29 --- /dev/null +++ b/qzeroconfservice.cpp @@ -0,0 +1,142 @@ +#include "qzeroconfservice.h" + + +class QZeroConfServiceData : public QSharedData +{ +public: + QString name; + QString type; + QString domain; + QString host; + QHostAddress ip; + QHostAddress ipv6; + quint32 interfaceIndex; + quint16 port = 0; + QMap txt; + +}; + +QZeroConfService::QZeroConfService() : data(new QZeroConfServiceData) +{ + +} + +QZeroConfService::QZeroConfService(const QZeroConfService &rhs) : data(rhs.data) +{ + +} + +QZeroConfService &QZeroConfService::operator=(const QZeroConfService &rhs) +{ + if (this != &rhs) + data.operator=(rhs.data); + return *this; +} + +QZeroConfService::~QZeroConfService() +{ + +} + +QString QZeroConfService::name() const +{ + return data->name; +} + +void QZeroConfService::setName(const QString &name) +{ + data->name = name; +} + +QString QZeroConfService::type() const +{ + return data->type; +} + +void QZeroConfService::setType(const QString &type) +{ + data->type = type; +} + +QString QZeroConfService::domain() const +{ + return data->domain; +} + +void QZeroConfService::setDomain(const QString &domain) +{ + data->domain = domain; +} + +QString QZeroConfService::host() const +{ + return data->host; +} + +void QZeroConfService::setHost(const QString &host) +{ + data->host = host; +} + +QHostAddress QZeroConfService::ip() const +{ + return data->ip; +} + +void QZeroConfService::setIp(QHostAddress &ip) +{ + data->ip = ip; +} + +QHostAddress QZeroConfService::ipv6() const +{ + return data->ipv6; +} + +void QZeroConfService::setIpv6(const QHostAddress &ipv6) +{ + data->ipv6 = ipv6; +} + +quint32 QZeroConfService::interfaceIndex() const +{ + return data->interfaceIndex; +} + +void QZeroConfService::setInterfaceIndex(const quint32 &interfaceIndex) +{ + data->interfaceIndex = interfaceIndex; +} + +quint16 QZeroConfService::port() const +{ + return data->port; +} + +void QZeroConfService::setPort(const quint16 port) +{ + data->port = port; +} + +QMap QZeroConfService::txt() const +{ + return data->txt; +} + +void QZeroConfService::setTxt(const QMap txt) +{ + data->txt = txt; +} + +void QZeroConfService::appendTxt(QByteArray idx, QByteArray val) +{ + data->txt[idx] = val; +} + +bool QZeroConfService::isValid() const +{ + //TODO is this a proper test + return (!data->name.isEmpty()) && (data->port > 0); +} + + diff --git a/qzeroconfservice.h b/qzeroconfservice.h new file mode 100644 index 0000000..35241cc --- /dev/null +++ b/qzeroconfservice.h @@ -0,0 +1,44 @@ +#ifndef QZEROCONFSERVICE_H +#define QZEROCONFSERVICE_H + +#include +#include + +class QZeroConfServiceData; + +class QZeroConfService +{ +public: + QZeroConfService(); + QZeroConfService(const QZeroConfService &); + QZeroConfService &operator=(const QZeroConfService &); + ~QZeroConfService(); + + + QString name() const; + void setName(const QString &name); + QString type() const; + void setType(const QString &type); + QString domain() const; + void setDomain(const QString &domain); + QString host() const; + void setHost(const QString &host); + QHostAddress ip() const; + void setIp(QHostAddress &ip); + QHostAddress ipv6() const; + void setIpv6(const QHostAddress &ipv6); + quint32 interfaceIndex() const; + void setInterfaceIndex(const quint32 &interfaceIndex); + quint16 port() const; + void setPort(const quint16 port); + QMap txt() const; + void setTxt(const QMap txt); + void appendTxt(QByteArray idx, QByteArray val = ""); + + bool isValid() const; + +private: + QSharedDataPointer data; +}; + +#endif // QZEROCONFSERVICE_H