1/*
2 This file is part of the KDE project
3
4 SPDX-FileCopyrightText: 2004 Jakub Stachowski <qbast@go2.pl>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#ifndef KDNSSDSERVICEBASE_H
10#define KDNSSDSERVICEBASE_H
11
12#include "kdnssd_export.h"
13#include <QExplicitlySharedDataPointer>
14#include <QMap>
15#include <QString>
16#include <memory>
17
18namespace KDNSSD
19{
20class ServiceBasePrivate;
21
22/**
23 * @class ServiceBase servicebase.h KDNSSD/ServiceBase
24 * @short Describes a service
25 *
26 * This class is used to describe a service. The service
27 * can be published by the current application (in which
28 * case it is probably a PublicService) or by
29 * another application, either on the current machine or
30 * a remote machine, in which case it is probably a
31 * RemoteService returned by ServiceBrowser.
32 *
33 * You should not normally need to create a ServiceBase
34 * object yourself.
35 *
36 * @author Jakub Stachowski
37 *
38 * @see PublicService
39 */
40class KDNSSD_EXPORT ServiceBase : public QSharedData // krazy:exclude=dpointer (protected)
41{
42public:
43 typedef QExplicitlySharedDataPointer<ServiceBase> Ptr;
44
45 /**
46 * Creates a ServiceBase object
47 *
48 * Note that @p name, @p type and @p domain uniquely identify
49 * the service in the DNS-SD system, and @p host and @p port
50 * provide the actual location of the service.
51 *
52 * For example, RemoteService populates @p host and @p port
53 * based on the @p name, @p type and @p domain attributes
54 * using the DNS-SD resolution system.
55 *
56 * @param name service name
57 * @param type service type
58 * @param domain the DNS-SD domain name for service
59 * @param host the host name of the service (a fully-qualified domain name)
60 * @param port the port number of the service
61 */
62 explicit ServiceBase(const QString &name = QString(),
63 const QString &type = QString(),
64 const QString &domain = QString(),
65 const QString &host = QString(),
66 unsigned short port = 0);
67
68 virtual ~ServiceBase();
69
70 /**
71 * The name of the service
72 */
73 QString serviceName() const;
74
75 /**
76 * The type of the service
77 *
78 * This is always in the format _sometype._udp or _sometype._tcp.
79 *
80 * See the <a href="http://www.dns-sd.org">DNS-SD website</a> for
81 * <a href="http://www.dns-sd.org/ServiceTypes.html">a full list of service types</a>.
82 */
83 QString type() const;
84
85 /**
86 * The domain that the service belongs to
87 *
88 * It is "local." for link-local services.
89 */
90 QString domain() const;
91
92 /**
93 * The hostname of the service
94 *
95 * Only valid for local and resolved remote services.
96 *
97 * Together with port(), this can be used to actually
98 * access the service.
99 *
100 * @see RemoteService::resolve() and RemoteService::resolveAsync()
101 */
102 QString hostName() const;
103
104 /**
105 * The port number of the service
106 *
107 * Only valid for local and resolved remote services.
108 *
109 * Together with hostName(), this can be used to actually
110 * access the service.
111 *
112 * @see RemoteService::resolve() and RemoteService::resolveAsync()
113 */
114 unsigned short port() const;
115
116 /**
117 * Additional text data associated with the service
118 *
119 * Only valid for local and resolved remote services.
120 *
121 * This is data that provides additional information about the
122 * service. For example, it might be used to specify a printer
123 * queue on the printer server specified by hostName() and port().
124 *
125 * You can check for the data that might be associated with a
126 * particular service on the <a
127 * href="http://www.dns-sd.org/ServiceTypes.html">service types list</a>.
128 * If a @c key=value pair is given, this will appear with the @c value
129 * in a QByteArray indexed by the @c key. If the data is on its own
130 * (does not have an @c = in it), it will be used to index an empty
131 * QByteArray, and can be checked for with QMap::contains().
132 *
133 * For example, if you are accessing the _ipp._tcp service, you might
134 * do something like
135 * @code
136 * QString printerModel = "unknown";
137 * if (service->textData().contains("ty")) {
138 * printQueue = QString::fromUtf8(service->textData()["ty"].constData());
139 * }
140 * @endcode
141 * since the TXT data of the IPP service may contain data like
142 * "ty=Apple LaserWriter Pro 630". Note that you actually have to be
143 * a bit more clever than this, since the key should usually be case
144 * insensitive.
145 */
146 QMap<QString, QByteArray> textData() const;
147
148 /**
149 * Compares services based on name, type and domain
150 *
151 * This is enough to for unique identification and omitting
152 * port, host and text data allows to compare resolved and
153 * unresolved services
154 *
155 * @param o the service to compare this service to
156 * @return @c true if this service represents the same
157 * service (from the point of view of DNS-SD) as
158 * @p o, @c false otherwise
159 */
160 bool operator==(const ServiceBase &o) const;
161 /**
162 * Compares services based on name, type and domain
163 *
164 * This is enough to for unique identification and omitting
165 * port, host and text data allows to compare resolved and
166 * unresolved services
167 *
168 * @param o the service to compare this service to
169 * @return @c false if this service represents the same
170 * service (from the point of view of DNS-SD) as
171 * @p o, @c true otherwise
172 */
173 bool operator!=(const ServiceBase &o) const;
174
175protected:
176 KDNSSD_NO_EXPORT explicit ServiceBase(ServiceBasePrivate *const d);
177
178 virtual void virtual_hook(int, void *);
179
180protected:
181 std::unique_ptr<ServiceBasePrivate> const d;
182 // We cannot use Q_DECLARE_PRIVATE_D & Q_D here because of multiple inheritance with some
183 // of the subclasses of ServiceBasePrivate, where ServiceBasePrivate is not the first base class,
184 // so reinterpret_cast as used by the functions defined with Q_DECLARE_PRIVATE_D would fail.
185 // Using a custom macro here with static_cast would require to know about the type definition
186 // of the private classes, which we though want to avoid here in the public class.
187 // So instead some custom KDNSSD_D macros are used internally...
188};
189
190/* Utility functions */
191
192/**
193 * Check if the domain is link-local
194 *
195 * @return @c true if domain is link-local ('local.'), @c false otherwise
196 */
197bool domainIsLocal(const QString &domain);
198
199}
200
201#endif
202

source code of kdnssd/src/servicebase.h