1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtNfc module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40
41#include "qndefrecord.h"
42#include "qndefrecord_p.h"
43
44#include <QtCore/QHash>
45
46QT_BEGIN_NAMESPACE
47
48/*!
49 \class QNdefRecord
50 \brief The QNdefRecord class provides an NFC NDEF record.
51
52 \ingroup connectivity-nfc
53 \inmodule QtNfc
54 \since 5.2
55
56 QNdefRecord and derived classes are used to parse the contents of
57 \l {QNdefMessage}{NDEF messages} and create new NDEF messages.
58
59 Use typeNameFormat() and setTypeNameFormat() to
60 get and set the type name format of the NDEF record.
61
62 Use type() and setType() to get and set the type of the NDEF record.
63
64 Use id() and setId() to get and set the id of the NDEF record.
65
66 Use payload() and setPayload() to get and set the NDEF record payload. isEmpty() can be used
67 to test if the payload is empty.
68
69 QNdefRecord is an implicitly shared class. This means you can efficiently convert between
70 QNdefRecord and specialized record classes. The isRecordType() template function can be used
71 to test if a conversion is possible. The following example shows how to test if a QNdefRecord
72 is an NFC RTD Text record and extract the text information from it.
73
74 \snippet nfc.cpp Record conversion
75
76 \section1 Creating Specialized NDEF Record Classes
77
78 Specialized NDEF record classes can be easily created with the Q_DECLARE_NDEF_RECORD() and
79 Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD() macros. The following example shows the class
80 declaration of the hypothetical \e {example.com:f} record type that encapsulates a single int
81 property foo.
82
83 \snippet nfc.cpp Specialized class definition
84
85 The developer only needs to provide implementations for the \c {foo()} and \c {setFoo()}
86 functions that parse and set the contents of the NDEF record's payload.
87*/
88
89/*!
90 \enum QNdefRecord::TypeNameFormat
91
92 This enum describes the type name format of an NDEF record.
93
94 \value Empty An empty NDEF record, the record does not contain a payload
95 \value NfcRtd The NDEF record type is defined by an NFC RTD Specification
96 \value Mime The NDEF record type follows the construct described in RFC 2046
97 \value Uri The NDEF record type follows the construct described in RFC 3986
98 \value ExternalRtd The NDEF record type follows the construct for external type names
99 described the NFC RTD Specification
100 \value Unknown The type of the record is unknown and should be treated similar to content
101 with MIME type 'application/octet-stream' without further context
102*/
103
104/*!
105 \fn bool QNdefRecord::isRecordType() const
106
107 Returns true if the NDEF record is of the specified record type; otherwise returns false.
108*/
109
110/*!
111 \fn bool QNdefRecord::operator!=(const QNdefRecord &other) const
112
113 Returns true if this NDEF record does not equal \a other; otherwise return false.
114*/
115
116/*!
117 \macro Q_DECLARE_NDEF_RECORD(className, typeNameFormat, type, initialPayload)
118 \relates QNdefRecord
119
120 This macro declares default and copy constructors for specialized NDEF record classes.
121
122 \a className is the name of the specialized class, \a typeNameFormat is the appropriate
123 QNdefRecord::TypeNameFormat for the custom type and \a type is the type without the NID or NSS
124 prefixes. That is \e {example.com:f} not \e {urn:nfc:ext:example.com:f}. \a initialPayload
125 is the initial payload of an empty record, it must be a QByteArray or a type that can be
126 implicitly converted into a QByteArray.
127
128 See the section on \l {Creating specialized NDEF record classes} for details.
129
130 \sa Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD()
131*/
132
133/*!
134 \macro Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD(className, typeNameFormat, type)
135 \relates QNdefRecord
136
137 This macro declares a template specialization for the QNdefRecord::isRecordType() function.
138
139 This macro should be used in the header file directly after the definition of a specialized
140 NDEF record class.
141
142 \a className is the name of the specialized class, \a typeNameFormat is the appropriate
143 QNdefRecord::TypeNameFormat for the custom type and \a type is the type without the NID or NSS
144 prefixes. That is \e {example.com:f} not \e {urn:nfc:ext:example.com:f}.
145
146 See the section on \l {Creating specialized NDEF record classes} for details.
147
148 \sa Q_DECLARE_NDEF_RECORD()
149*/
150
151uint qHash(const QNdefRecord &key)
152{
153 return qHash(key: key.type() + key.id() + key.payload());
154}
155
156/*!
157 Constructs a new empty NDEF record.
158*/
159QNdefRecord::QNdefRecord()
160{
161}
162
163/*!
164 Constructs a new NDEF record that is a copy of \a other.
165*/
166QNdefRecord::QNdefRecord(const QNdefRecord &other)
167{
168 d = other.d;
169}
170
171/*!
172 \internal
173
174 Constructs an NDEF record that is a copy of \a other if \a other is of the expected type name
175 format identified by \a typeNameFormat and type as identified by \a type; otherwise an empty
176 NDEF record of the expected type name format and type is created.
177*/
178QNdefRecord::QNdefRecord(const QNdefRecord &other, TypeNameFormat typeNameFormat,
179 const QByteArray &type)
180{
181 if (other.d->typeNameFormat == quint8(typeNameFormat) && other.d->type == type) {
182 d = other.d;
183 } else {
184 d = new QNdefRecordPrivate;
185 d->typeNameFormat = typeNameFormat;
186 d->type = type;
187 }
188}
189
190/*!
191 \internal
192
193 Constructs an NDEF record that is a copy of \a other if \a other is of the expected type name
194 format identified by \a typeNameFormat; otherwise an empty NDEF record of the expected type
195 name format and type is created.
196*/
197QNdefRecord::QNdefRecord(const QNdefRecord &other, TypeNameFormat typeNameFormat)
198{
199 if (other.d->typeNameFormat == quint8(typeNameFormat)) {
200 d = other.d;
201 } else {
202 d = new QNdefRecordPrivate;
203 d->typeNameFormat = typeNameFormat;
204 }
205}
206
207/*!
208 \internal
209
210 Constructs an NDEF record with a type name format identified by \a typeNameFormat and type as
211 identified by \a type.
212*/
213QNdefRecord::QNdefRecord(TypeNameFormat typeNameFormat, const QByteArray &type)
214: d(new QNdefRecordPrivate)
215{
216 d->typeNameFormat = typeNameFormat;
217 d->type = type;
218}
219
220/*!
221 Destroys the NDEF record.
222*/
223QNdefRecord::~QNdefRecord()
224{
225}
226
227/*!
228 Assigns this NDEF record to \a other.
229*/
230QNdefRecord &QNdefRecord::operator=(const QNdefRecord &other)
231{
232 if (this != &other)
233 d = other.d;
234
235 return *this;
236}
237
238/*!
239 Sets the type name format of the NDEF record to \a typeNameFormat.
240*/
241void QNdefRecord::setTypeNameFormat(TypeNameFormat typeNameFormat)
242{
243 if (!d)
244 d = new QNdefRecordPrivate;
245
246 d->typeNameFormat = typeNameFormat;
247}
248
249/*!
250 Returns the type name format of the NDEF record.
251*/
252QNdefRecord::TypeNameFormat QNdefRecord::typeNameFormat() const
253{
254 if (!d)
255 return Empty;
256
257 if (d->typeNameFormat > 0x05)
258 return Unknown;
259
260 return TypeNameFormat(d->typeNameFormat);
261}
262
263/*!
264 Sets the type of the NDEF record to \a type.
265*/
266void QNdefRecord::setType(const QByteArray &type)
267{
268 if (!d)
269 d = new QNdefRecordPrivate;
270
271 d->type = type;
272}
273
274/*!
275 Returns the type of the NDEF record.
276*/
277QByteArray QNdefRecord::type() const
278{
279 if (!d)
280 return QByteArray();
281
282 return d->type;
283}
284
285/*!
286 Sets the id of the NDEF record to \a id.
287*/
288void QNdefRecord::setId(const QByteArray &id)
289{
290 if (!d)
291 d = new QNdefRecordPrivate;
292
293 d->id = id;
294}
295
296/*!
297 Returns the id of the NDEF record.
298*/
299QByteArray QNdefRecord::id() const
300{
301 if (!d)
302 return QByteArray();
303
304 return d->id;
305}
306
307/*!
308 Sets the payload of the NDEF record to \a payload.
309*/
310void QNdefRecord::setPayload(const QByteArray &payload)
311{
312 if (!d)
313 d = new QNdefRecordPrivate;
314
315 d->payload = payload;
316}
317
318/*!
319 Returns the payload of the NDEF record.
320*/
321QByteArray QNdefRecord::payload() const
322{
323 if (!d)
324 return QByteArray();
325
326 return d->payload;
327}
328
329/*!
330 Returns true if the NDEF record contains an empty payload; otherwise return false.
331
332 This is equivalent to calling \c {payload().isEmpty()}.
333*/
334bool QNdefRecord::isEmpty() const
335{
336 if (!d)
337 return true;
338
339 return d->payload.isEmpty();
340}
341
342/*!
343 Returns true if \a other and this NDEF record are the same.
344*/
345bool QNdefRecord::operator==(const QNdefRecord &other) const
346{
347 if (d == other.d)
348 return true;
349
350 if (!d || !other.d)
351 return false;
352
353 if (d->typeNameFormat != other.d->typeNameFormat)
354 return false;
355
356 if (d->type != other.d->type)
357 return false;
358
359 if (d->id != other.d->id)
360 return false;
361
362 if (d->payload != other.d->payload)
363 return false;
364
365 return true;
366}
367
368QT_END_NAMESPACE
369

source code of qtconnectivity/src/nfc/qndefrecord.cpp