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 | |
18 | namespace KDNSSD |
19 | { |
20 | class 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 | */ |
40 | class KDNSSD_EXPORT ServiceBase : public QSharedData // krazy:exclude=dpointer (protected) |
41 | { |
42 | public: |
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 | |
175 | protected: |
176 | KDNSSD_NO_EXPORT explicit ServiceBase(ServiceBasePrivate *const d); |
177 | |
178 | virtual void virtual_hook(int, void *); |
179 | |
180 | protected: |
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 | */ |
197 | bool domainIsLocal(const QString &domain); |
198 | |
199 | } |
200 | |
201 | #endif |
202 | |