summaryrefslogtreecommitdiffstats
path: root/src/nfc/qndefrecord.cpp
blob: 167b7617d9ec5118e097f35add6b8f3fa8ef920a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtNfc module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include "qndefrecord.h"
#include "qndefrecord_p.h"

#include <QtCore/QHash>

QT_BEGIN_NAMESPACE

/*!
    \class QNdefRecord
    \brief The QNdefRecord class provides an NFC NDEF record.

    \ingroup connectivity-nfc
    \inmodule QtNfc
    \since 5.2

    QNdefRecord and derived classes are used to parse the contents of
    \l {QNdefMessage}{NDEF messages} and create new NDEF messages.

    Use typeNameFormat() and setTypeNameFormat() to
    get and set the type name format of the NDEF record.

    Use type() and setType() to get and set the type of the NDEF record.

    Use id() and setId() to get and set the id of the NDEF record.

    Use payload() and setPayload() to get and set the NDEF record payload.  isEmpty() can be used
    to test if the payload is empty.

    QNdefRecord is an implicitly shared class.  This means you can efficiently convert between
    QNdefRecord and specialized record classes.  The isRecordType() template function can be used
    to test if a conversion is possible.  The following example shows how to test if a QNdefRecord
    is an NFC RTD Text record and extract the text information from it.

    \snippet nfc.cpp Record conversion

    \section1 Creating Specialized NDEF Record Classes

    Specialized NDEF record classes can be easily created with the Q_DECLARE_NDEF_RECORD() and
    Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD() macros.  The following example shows the class
    declaration of the hypothetical \e {example.com:f} record type that encapsulates a single int
    property foo.

    \snippet nfc.cpp Specialized class definition

    The developer only needs to provide implementations for the \c {foo()} and \c {setFoo()}
    functions that parse and set the contents of the NDEF record's payload.
*/

/*!
    \enum QNdefRecord::TypeNameFormat

    This enum describes the type name format of an NDEF record.

    \value Empty        An empty NDEF record, the record does not contain a payload
    \value NfcRtd       The NDEF record type is defined by an NFC RTD Specification
    \value Mime         The NDEF record type follows the construct described in RFC 2046
    \value Uri          The NDEF record type follows the construct described in RFC 3986
    \value ExternalRtd  The NDEF record type follows the construct for external type names
                        described the NFC RTD Specification
    \value Unknown      The type of the record is unknown and should be treated similar to content
                        with MIME type 'application/octet-stream' without further context
*/

/*!
    \fn bool QNdefRecord::isRecordType() const

    Returns true if the NDEF record is of the specified record type; otherwise returns false.
*/

/*!
    \fn bool QNdefRecord::operator!=(const QNdefRecord &other) const

    Returns true if this NDEF record does not equal \a other; otherwise return false.
*/

/*!
    \macro Q_DECLARE_NDEF_RECORD(className, typeNameFormat, type, initialPayload)
    \relates QNdefRecord

    This macro declares default and copy constructors for specialized NDEF record classes.

    \a className is the name of the specialized class, \a typeNameFormat is the appropriate
    QNdefRecord::TypeNameFormat for the custom type and \a type is the type without the NID or NSS
    prefixes. That is \e {example.com:f} not \e {urn:nfc:ext:example.com:f}.  \a initialPayload
    is the initial payload of an empty record, it must be a QByteArray or a type that can be
    implicitly converted into a QByteArray.

    See the section on \l {Creating specialized NDEF record classes} for details.

    \sa Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD()
*/

/*!
    \macro Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD(className, typeNameFormat, type)
    \relates QNdefRecord

    This macro declares a template specialization for the QNdefRecord::isRecordType() function.

    This macro should be used in the header file directly after the definition of a specialized
    NDEF record class.

    \a className is the name of the specialized class, \a typeNameFormat is the appropriate
    QNdefRecord::TypeNameFormat for the custom type and \a type is the type without the NID or NSS
    prefixes.  That is \e {example.com:f} not \e {urn:nfc:ext:example.com:f}.

    See the secton on \l {Creating specialized NDEF record classes} for details.

    \sa Q_DECLARE_NDEF_RECORD()
*/

uint qHash(const QNdefRecord &key)
{
    return qHash(key.type() + key.id() + key.payload());
}

/*!
    Constructs a new empty NDEF record.
*/
QNdefRecord::QNdefRecord()
{
}

/*!
    Constructs a new NDEF record that is a copy of \a other.
*/
QNdefRecord::QNdefRecord(const QNdefRecord &other)
{
    d = other.d;
}

/*!
    \internal

    Constructs an NDEF record that is a copy of \a other if \a other is of the expected type name
    format identified by \a typeNameFormat and type as identified by \a type; otherwise an empty
    NDEF record of the expected type name format and type is created.
*/
QNdefRecord::QNdefRecord(const QNdefRecord &other, TypeNameFormat typeNameFormat,
                         const QByteArray &type)
{
    if (other.d->typeNameFormat == quint8(typeNameFormat) && other.d->type == type) {
        d = other.d;
    } else {
        d = new QNdefRecordPrivate;
        d->typeNameFormat = typeNameFormat;
        d->type = type;
    }
}

/*!
    \internal

    Constructs an NDEF record that is a copy of \a other if \a other is of the expected type name
    format identified by \a typeNameFormat; otherwise an empty NDEF record of the expected type
    name format and type is created.
*/
QNdefRecord::QNdefRecord(const QNdefRecord &other, TypeNameFormat typeNameFormat)
{
    if (other.d->typeNameFormat == quint8(typeNameFormat)) {
        d = other.d;
    } else {
        d = new QNdefRecordPrivate;
        d->typeNameFormat = typeNameFormat;
    }
}

/*!
    \internal

    Constructs an NDEF record with a type name format identified by \a typeNameFormat and type as
    identified by \a type.
*/
QNdefRecord::QNdefRecord(TypeNameFormat typeNameFormat, const QByteArray &type)
:   d(new QNdefRecordPrivate)
{
    d->typeNameFormat = typeNameFormat;
    d->type = type;
}

/*!
    Destroys the NDEF record.
*/
QNdefRecord::~QNdefRecord()
{
}

/*!
    Assigns this NDEF record to \a other.
*/
QNdefRecord &QNdefRecord::operator=(const QNdefRecord &other)
{
    if (this != &other)
        d = other.d;

    return *this;
}

/*!
    Sets the type name format of the NDEF record to \a typeNameFormat.
*/
void QNdefRecord::setTypeNameFormat(TypeNameFormat typeNameFormat)
{
    if (!d)
        d = new QNdefRecordPrivate;

    d->typeNameFormat = typeNameFormat;
}

/*!
    Returns the type name format of the NDEF record.
*/
QNdefRecord::TypeNameFormat QNdefRecord::typeNameFormat() const
{
    if (!d)
        return Empty;

    if (d->typeNameFormat > 0x05)
        return Unknown;

    return TypeNameFormat(d->typeNameFormat);
}

/*!
    Sets the type of the NDEF record to \a type.
*/
void QNdefRecord::setType(const QByteArray &type)
{
    if (!d)
        d = new QNdefRecordPrivate;

    d->type = type;
}

/*!
    Returns the type of the NDEF record.
*/
QByteArray QNdefRecord::type() const
{
    if (!d)
        return QByteArray();

    return d->type;
}

/*!
    Sets the id of the NDEF record to \a id.
*/
void QNdefRecord::setId(const QByteArray &id)
{
    if (!d)
        d = new QNdefRecordPrivate;

    d->id = id;
}

/*!
    Returns the id of the NDEF record.
*/
QByteArray QNdefRecord::id() const
{
    if (!d)
        return QByteArray();

    return d->id;
}

/*!
    Sets the payload of the NDEF record to \a payload.
*/
void QNdefRecord::setPayload(const QByteArray &payload)
{
    if (!d)
        d = new QNdefRecordPrivate;

    d->payload = payload;
}

/*!
    Returns the payload of the NDEF record.
*/
QByteArray QNdefRecord::payload() const
{
    if (!d)
        return QByteArray();

    return d->payload;
}

/*!
    Returns true if the NDEF record contains an empty payload; otherwise return false.

    This is equivalent to calling \c {payload().isEmpty()}.
*/
bool QNdefRecord::isEmpty() const
{
    if (!d)
        return true;

    return d->payload.isEmpty();
}

/*!
    Returns true if \a other and this NDEF record are the same.
*/
bool QNdefRecord::operator==(const QNdefRecord &other) const
{
    if (d == other.d)
        return true;

    if (!d || !other.d)
        return false;

    if (d->typeNameFormat != other.d->typeNameFormat)
        return false;

    if (d->type != other.d->type)
        return false;

    if (d->id != other.d->id)
        return false;

    if (d->payload != other.d->payload)
        return false;

    return true;
}

QT_END_NAMESPACE