Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qndefnfcsmartposterrecord.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 - 2012 Research In Motion
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <qndefnfcsmartposterrecord.h>
6#include <qndefmessage.h>
7
8#include <QtCore/QString>
9#include <QtCore/QStringList>
10#include <QtCore/QUrl>
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 \class QNdefNfcIconRecord
16 \brief The QNdefNfcIconRecord class provides an NFC MIME record to hold an
17 icon.
18
19 \ingroup connectivity-nfc
20 \inmodule QtNfc
21 \since Qt 5.2
22
23 This class wraps the image data into an NDEF message.
24 It provides an NDEF record of type \l QNdefRecord::Mime.
25 The \l {QNdefRecord::}{payload}() contains the raw image data.
26*/
27
28/*!
29 \fn QNdefNfcIconRecord::QNdefNfcIconRecord()
30
31 Constructs an empty NDEF record of type \l QNdefRecord::Mime.
32*/
33
34/*!
35 \fn QNdefNfcIconRecord::QNdefNfcIconRecord(const QNdefRecord &other)
36
37 Constructs an NDEF icon record that is a copy of \a other.
38*/
39
40/*!
41 \class QNdefNfcSmartPosterRecord
42 \brief The QNdefNfcSmartPosterRecord class provides an NFC RTD-SmartPoster.
43
44 \ingroup connectivity-nfc
45 \inmodule QtNfc
46 \since Qt 5.2
47
48 RTD-SmartPoster encapsulates a Smart Poster.
49 */
50
51/*!
52 \enum QNdefNfcSmartPosterRecord::Action
53
54 This enum describes the course of action that a device should take with the content.
55
56 \value UnspecifiedAction The action is not defined.
57 \value DoAction Do the action (send the SMS, launch the browser, make the telephone call).
58 \value SaveAction Save for later (store the SMS in INBOX, put the URI in a bookmark, save the telephone number in contacts).
59 \value EditAction Open for editing (open an SMS in the SMS editor, open the URI in a URI editor, open the telephone number for editing).
60 */
61
62QNdefNfcSmartPosterRecordPrivate::~QNdefNfcSmartPosterRecordPrivate()
63{
64 cleanup();
65}
66
67void QNdefNfcSmartPosterRecordPrivate::cleanup()
68{
69 // Clean-up existing internal structure
70 m_titleList.clear();
71 delete m_uri;
72 delete m_action;
73 m_iconList.clear();
74 delete m_size;
75 delete m_type;
76}
77
78/*!
79 Constructs a new empty smart poster.
80*/
81QNdefNfcSmartPosterRecord::QNdefNfcSmartPosterRecord()
82 : QNdefRecord(QNdefRecord::NfcRtd, "Sp"),
83 d(new QNdefNfcSmartPosterRecordPrivate)
84{
85}
86
87/*!
88 Constructs a new smart poster that is a copy of \a other.
89*/
90QNdefNfcSmartPosterRecord::QNdefNfcSmartPosterRecord(const QNdefRecord &other)
91 : QNdefRecord(other, QNdefRecord::NfcRtd, "Sp"),
92 d(new QNdefNfcSmartPosterRecordPrivate)
93{
94 // Need to set payload again to create internal structure
95 setPayload(other.payload());
96}
97
98/*!
99 Constructs a new smart poster that is a copy of \a other.
100*/
101QNdefNfcSmartPosterRecord::QNdefNfcSmartPosterRecord(const QNdefNfcSmartPosterRecord &other)
102 : QNdefRecord(other, QNdefRecord::NfcRtd, "Sp"), d(other.d)
103{
104}
105
106/*!
107 Assigns the \a other smart poster record to this record and returns a reference to
108 this record.
109*/
110QNdefNfcSmartPosterRecord &QNdefNfcSmartPosterRecord::operator=(const QNdefNfcSmartPosterRecord &other)
111{
112 if (this != &other)
113 d = other.d;
114
115 return *this;
116}
117
118/*!
119 Destroys the smart poster.
120*/
121QNdefNfcSmartPosterRecord::~QNdefNfcSmartPosterRecord()
122{
123}
124
125void QNdefNfcSmartPosterRecord::cleanup()
126{
127 if (d)
128 d->cleanup();
129}
130
131/*!
132 \internal
133 Sets the payload of the NDEF record to \a payload
134*/
135void QNdefNfcSmartPosterRecord::setPayload(const QByteArray &payload)
136{
137 QNdefRecord::setPayload(payload);
138
139 cleanup();
140
141 if (!payload.isEmpty()) {
142 // Create new structure
143 const QNdefMessage message = QNdefMessage::fromByteArray(payload);
144
145 // Iterate through all the records contained in the payload's message.
146 for (const QNdefRecord& record : message) {
147 // Title
148 if (record.isRecordType<QNdefNfcTextRecord>()) {
149 addTitleInternal(record);
150 }
151
152 // URI
153 else if (record.isRecordType<QNdefNfcUriRecord>()) {
154 d->m_uri = new QNdefNfcUriRecord(record);
155 }
156
157 // Action
158 else if (record.isRecordType<QNdefNfcActRecord>()) {
159 d->m_action = new QNdefNfcActRecord(record);
160 }
161
162 // Icon
163 else if (record.isRecordType<QNdefNfcIconRecord>()) {
164 addIconInternal(record);
165 }
166
167 // Size
168 else if (record.isRecordType<QNdefNfcSizeRecord>()) {
169 d->m_size = new QNdefNfcSizeRecord(record);
170 }
171
172 // Type
173 else if (record.isRecordType<QNdefNfcTypeRecord>()) {
174 d->m_type = new QNdefNfcTypeRecord(record);
175 }
176 }
177 }
178}
179
180void QNdefNfcSmartPosterRecord::convertToPayload()
181{
182 QNdefMessage message;
183
184 // Title
185 for (qsizetype t = 0; t < titleCount(); t++)
186 message.append(titleRecord(t));
187
188 // URI
189 if (d->m_uri)
190 message.append(*(d->m_uri));
191
192 // Action
193 if (d->m_action)
194 message.append(*(d->m_action));
195
196 // Icon
197 for (qsizetype i = 0; i < iconCount(); i++)
198 message.append(iconRecord(i));
199
200 // Size
201 if (d->m_size)
202 message.append(*(d->m_size));
203
204 // Type
205 if (d->m_type)
206 message.append(*(d->m_type));
207
208 QNdefRecord::setPayload(message.toByteArray());
209}
210
211/*!
212 Returns \c true if the smart poster contains a title record using the locale
213 \a locale. If \a locale is empty, then \c true is returned if the smart
214 poster contains at least one title record. In all other cases, \c false is
215 returned.
216 */
217bool QNdefNfcSmartPosterRecord::hasTitle(const QString &locale) const
218{
219 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
220 const QNdefNfcTextRecord &text = d->m_titleList[i];
221
222 if (locale.isEmpty() || text.locale() == locale)
223 return true;
224 }
225
226 return false;
227}
228
229/*!
230 Returns \c true if the smart poster contains an action record, otherwise
231 returns \c false.
232 */
233bool QNdefNfcSmartPosterRecord::hasAction() const
234{
235 return d->m_action != nullptr;
236}
237
238/*!
239 Returns \c true if the smart poster contains an icon record using the type
240 \a mimetype. If \a mimetype is empty, then \c true is returned if the smart
241 poster contains at least one icon record.
242 In all other cases, \c false is returned.
243 */
244bool QNdefNfcSmartPosterRecord::hasIcon(const QByteArray &mimetype) const
245{
246 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
247 const QNdefNfcIconRecord &icon = d->m_iconList[i];
248
249 if (mimetype.isEmpty() || icon.type() == mimetype)
250 return true;
251 }
252
253 return false;
254}
255
256/*!
257 Returns \c true if the smart poster contains a size record, otherwise
258 returns \c false.
259 */
260bool QNdefNfcSmartPosterRecord::hasSize() const
261{
262 return d->m_size != nullptr;
263}
264
265/*!
266 Returns \c true if the smart poster contains a type record, otherwise
267 returns \c false.
268 */
269bool QNdefNfcSmartPosterRecord::hasTypeInfo() const
270{
271 return d->m_type != nullptr;
272}
273
274/*!
275 Returns the number of title records contained inside the smart poster.
276 */
277qsizetype QNdefNfcSmartPosterRecord::titleCount() const
278{
279 return d->m_titleList.size();
280}
281
282/*!
283 Returns the title record corresponding to the index \a index inside the
284 smart poster, where \a index is a value between 0 and titleCount() - 1.
285 Values outside of this range return an empty record.
286 */
287QNdefNfcTextRecord QNdefNfcSmartPosterRecord::titleRecord(qsizetype index) const
288{
289 if (index >= 0 && index < d->m_titleList.size())
290 return d->m_titleList[index];
291
292 return QNdefNfcTextRecord();
293}
294
295/*!
296 Returns the title record text associated with locale \a locale if available. If \a locale
297 is empty then the title text of the first available record is returned. In all other
298 cases an empty string is returned.
299 */
300QString QNdefNfcSmartPosterRecord::title(const QString &locale) const
301{
302 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
303 const QNdefNfcTextRecord &text = d->m_titleList[i];
304
305 if (locale.isEmpty() || text.locale() == locale)
306 return text.text();
307 }
308
309 return QString();
310}
311
312/*!
313 Returns a copy of all title records inside the smart poster.
314 */
315QList<QNdefNfcTextRecord> QNdefNfcSmartPosterRecord::titleRecords() const
316{
317 return d->m_titleList;
318}
319
320/*!
321 Attempts to add a title record \a text to the smart poster. If the smart poster does not already
322 contain a title record with the same locale as title record \a text, then the title record is added
323 and the function returns \c true. Otherwise \c false is returned.
324 */
325bool QNdefNfcSmartPosterRecord::addTitle(const QNdefNfcTextRecord &text)
326{
327 const bool status = addTitleInternal(text);
328
329 // Convert to payload if the title is added
330 if (status)
331 convertToPayload();
332
333 return status;
334}
335
336bool QNdefNfcSmartPosterRecord::addTitleInternal(const QNdefNfcTextRecord &text)
337{
338 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
339 const QNdefNfcTextRecord &rec = d->m_titleList[i];
340
341 if (rec.locale() == text.locale())
342 return false;
343 }
344
345 d->m_titleList.append(text);
346 return true;
347}
348
349/*!
350 Attempts to add a new title record with title \a text, locale \a locale and encoding \a encoding.
351 If the smart poster does not already contain a title record with locale \a locale, then the title record
352 is added and the function returns \c true. Otherwise \c false is returned.
353 */
354bool QNdefNfcSmartPosterRecord::addTitle(const QString &text, const QString &locale, QNdefNfcTextRecord::Encoding encoding)
355{
356 QNdefNfcTextRecord rec;
357 rec.setText(text);
358 rec.setLocale(locale);
359 rec.setEncoding(encoding);
360
361 return addTitle(rec);
362}
363
364/*!
365 Attempts to remove the title record \a text from the smart poster. Removes
366 the record and returns \c true if the smart poster contains a matching
367 record, otherwise \c false is returned.
368 */
369bool QNdefNfcSmartPosterRecord::removeTitle(const QNdefNfcTextRecord &text)
370{
371 bool status = false;
372
373 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
374 const QNdefNfcTextRecord &rec = d->m_titleList[i];
375
376 if (rec.text() == text.text() && rec.locale() == text.locale() && rec.encoding() == text.encoding()) {
377 d->m_titleList.removeAt(i);
378 status = true;
379 break;
380 }
381 }
382
383 // Convert to payload if the title list has changed
384 if (status)
385 convertToPayload();
386
387 return status;
388}
389
390/*!
391 Attempts to remove a title record with the locale \a locale from the smart
392 poster. Removes the record and returns \c true if the smart poster contains
393 a matching record, otherwise \c false is returned.
394 */
395bool QNdefNfcSmartPosterRecord::removeTitle(const QString &locale)
396{
397 bool status = false;
398
399 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
400 const QNdefNfcTextRecord &rec = d->m_titleList[i];
401
402 if (rec.locale() == locale) {
403 d->m_titleList.removeAt(i);
404 status = true;
405 break;
406 }
407 }
408
409 // Convert to payload if the title list has changed
410 if (status)
411 convertToPayload();
412
413 return status;
414}
415
416/*!
417 Adds the title record list \a titles to the smart poster. Any existing records are overwritten.
418 */
419void QNdefNfcSmartPosterRecord::setTitles(const QList<QNdefNfcTextRecord> &titles)
420{
421 d->m_titleList = titles;
422
423 // Convert to payload
424 convertToPayload();
425}
426
427/*!
428 Returns the URI from the smart poster's URI record if set. Otherwise an empty URI is returned.
429
430 \warning Application developers are advised to validate the returned
431 URI before acting on it. See \l{Qt NFC Security Considerations} for guidance.
432 */
433QUrl QNdefNfcSmartPosterRecord::uri() const
434{
435 if (d->m_uri)
436 return d->m_uri->uri();
437
438 return QUrl();
439}
440
441/*!
442 Returns the smart poster's URI record if set. Otherwise an empty URI is returned.
443 */
444QNdefNfcUriRecord QNdefNfcSmartPosterRecord::uriRecord() const
445{
446 if (d->m_uri)
447 return *(d->m_uri);
448
449 return QNdefNfcUriRecord();
450}
451
452/*!
453 Sets the URI record to \a url
454 */
455void QNdefNfcSmartPosterRecord::setUri(const QNdefNfcUriRecord &url)
456{
457 if (d->m_uri)
458 delete d->m_uri;
459
460 d->m_uri = new QNdefNfcUriRecord(url);
461
462 // Convert to payload
463 convertToPayload();
464}
465
466/*!
467 Constructs a URI record and sets its content inside the smart poster to \a url
468 */
469void QNdefNfcSmartPosterRecord::setUri(const QUrl &url)
470{
471 QNdefNfcUriRecord rec;
472 rec.setUri(url);
473
474 setUri(rec);
475}
476
477/*!
478 Returns the action from the action record if available. Otherwise \l UnspecifiedAction is returned.
479 */
480QNdefNfcSmartPosterRecord::Action QNdefNfcSmartPosterRecord::action() const
481{
482 if (d->m_action)
483 return d->m_action->action();
484
485 return UnspecifiedAction;
486}
487
488/*!
489 Sets the action record to \a act
490 */
491void QNdefNfcSmartPosterRecord::setAction(Action act)
492{
493 if (!d->m_action)
494 d->m_action = new QNdefNfcActRecord();
495
496 d->m_action->setAction(act);
497
498 // Convert to payload
499 convertToPayload();
500}
501
502/*!
503 Returns the number of icon records contained inside the smart poster.
504 */
505qsizetype QNdefNfcSmartPosterRecord::iconCount() const
506{
507 return d->m_iconList.size();
508}
509
510/*!
511 Returns the icon record corresponding to the index \a index inside the smart
512 poster, where \a index is a value between 0 and \l iconCount() - 1.
513 Values outside of this range return an empty record.
514 */
515QNdefNfcIconRecord QNdefNfcSmartPosterRecord::iconRecord(qsizetype index) const
516{
517 if (index >= 0 && index < d->m_iconList.size())
518 return d->m_iconList[index];
519
520 return QNdefNfcIconRecord();
521}
522
523/*!
524 Returns the associated icon record data if the smart poster contains an icon record with MIME type \a mimetype.
525 If \a mimetype is omitted or empty then the first icon's record data is returned. In all other cases, an empty array is returned.
526
527 \warning Application developers are advised to validate the returned data
528 before processing it. See \l{Qt NFC Security Considerations} for guidance.
529 */
530QByteArray QNdefNfcSmartPosterRecord::icon(const QByteArray& mimetype) const
531{
532 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
533 const QNdefNfcIconRecord &icon = d->m_iconList[i];
534
535 if (mimetype.isEmpty() || icon.type() == mimetype)
536 return icon.data();
537 }
538
539 return QByteArray();
540}
541
542/*!
543 Returns a copy of all icon records inside the smart poster.
544 */
545QList<QNdefNfcIconRecord> QNdefNfcSmartPosterRecord::iconRecords() const
546{
547 return d->m_iconList;
548}
549
550/*!
551 Adds an icon record \a icon to the smart poster. If the smart poster already contains an icon
552 record with the same type then the existing icon record is replaced.
553 */
554void QNdefNfcSmartPosterRecord::addIcon(const QNdefNfcIconRecord &icon)
555{
556 addIconInternal(icon);
557
558 // Convert to payload
559 convertToPayload();
560}
561
562void QNdefNfcSmartPosterRecord::addIconInternal(const QNdefNfcIconRecord &icon)
563{
564 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
565 const QNdefNfcIconRecord &rec = d->m_iconList[i];
566
567 if (rec.type() == icon.type())
568 d->m_iconList.removeAt(i);
569 }
570
571 d->m_iconList.append(icon);
572}
573
574/*!
575 Adds an icon record with type \a type and data \a data to the smart poster. If the smart poster
576 already contains an icon record with the same type then the existing icon record is replaced.
577 */
578void QNdefNfcSmartPosterRecord::addIcon(const QByteArray &type, const QByteArray &data)
579{
580 QNdefNfcIconRecord rec;
581 rec.setType(type);
582 rec.setData(data);
583
584 addIcon(rec);
585}
586
587/*!
588 Attempts to remove the icon record \a icon from the smart poster.
589 Removes the record and returns \c true if the smart poster contains
590 a matching record, otherwise \c false is returned.
591 */
592bool QNdefNfcSmartPosterRecord::removeIcon(const QNdefNfcIconRecord &icon)
593{
594 bool status = false;
595
596 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
597 const QNdefNfcIconRecord &rec = d->m_iconList[i];
598
599 if (rec.type() == icon.type() && rec.data() == icon.data()) {
600 d->m_iconList.removeAt(i);
601 status = true;
602 break;
603 }
604 }
605
606 // Convert to payload if the icon list has changed
607 if (status)
608 convertToPayload();
609
610 return status;
611}
612
613/*!
614 Attempts to remove the icon record with the type \a type from the smart
615 poster. Removes the record and returns \c true if the smart poster contains
616 a matching record, otherwise \c false is returned.
617 */
618bool QNdefNfcSmartPosterRecord::removeIcon(const QByteArray &type)
619{
620 bool status = false;
621
622 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
623 const QNdefNfcIconRecord &rec = d->m_iconList[i];
624
625 if (rec.type() == type) {
626 d->m_iconList.removeAt(i);
627 status = true;
628 break;
629 }
630 }
631
632 // Convert to payload if the icon list has changed
633 if (status)
634 convertToPayload();
635
636 return status;
637}
638
639/*!
640 Adds the icon record list \a icons to the smart poster.
641 Any existing records are overwritten.
642
643 \sa hasIcon(), icon()
644 */
645void QNdefNfcSmartPosterRecord::setIcons(const QList<QNdefNfcIconRecord> &icons)
646{
647 d->m_iconList = icons;
648
649 // Convert to payload
650 convertToPayload();
651}
652
653/*!
654 Returns the size from the size record if available; otherwise returns 0.
655
656 The value is optional and contains the size in bytes of the object
657 that the URI refers to. It may be used by the device to determine
658 whether it can accommodate the object.
659
660 \sa setSize()
661 */
662quint32 QNdefNfcSmartPosterRecord::size() const
663{
664 if (d->m_size)
665 return d->m_size->size();
666
667 return 0;
668}
669
670/*!
671 Sets the record \a size. The value contains the size in bytes of
672 the object that the URI refers to.
673
674 \sa size(), hasSize()
675 */
676void QNdefNfcSmartPosterRecord::setSize(quint32 size)
677{
678 if (!d->m_size)
679 d->m_size = new QNdefNfcSizeRecord();
680
681 d->m_size->setSize(size);
682
683 // Convert to payload
684 convertToPayload();
685}
686
687/*!
688 Returns the MIME type that describes the type of the objects that can be
689 reached via uri().
690
691 If the type is not known, the returned QString is empty.
692
693 \sa setTypeInfo(), hasTypeInfo()
694 */
695QString QNdefNfcSmartPosterRecord::typeInfo() const
696{
697 if (d->m_type)
698 return d->m_type->typeInfo();
699
700 return QString();
701}
702
703/*!
704 Sets the type record to \a type. \a type describes the type of the object
705 referenced by uri().
706
707 \sa typeInfo()
708 */
709void QNdefNfcSmartPosterRecord::setTypeInfo(const QString &type)
710{
711 if (d->m_type)
712 delete d->m_type;
713
714 d->m_type = new QNdefNfcTypeRecord();
715 d->m_type->setTypeInfo(type);
716
717 // Convert to payload
718 convertToPayload();
719}
720
721void QNdefNfcActRecord::setAction(QNdefNfcSmartPosterRecord::Action action)
722{
723 QByteArray data(1, action);
724
725 setPayload(data);
726}
727
728QNdefNfcSmartPosterRecord::Action QNdefNfcActRecord::action() const
729{
730 const QByteArray p = payload();
731 QNdefNfcSmartPosterRecord::Action value =
732 QNdefNfcSmartPosterRecord::UnspecifiedAction;
733
734 if (!p.isEmpty())
735 value = QNdefNfcSmartPosterRecord::Action(static_cast<signed char>(p[0]));
736
737 return value;
738}
739
740/*!
741 Sets the contents of the icon record to \a data.
742*/
743void QNdefNfcIconRecord::setData(const QByteArray &data)
744{
745 setPayload(data);
746}
747
748/*!
749 Returns the icon data as \l QByteArray.
750
751 \warning Application developers are advised to validate the returned data
752 before processing it. See \l{Qt NFC Security Considerations} for guidance.
753*/
754QByteArray QNdefNfcIconRecord::data() const
755{
756 return payload();
757}
758
759void QNdefNfcSizeRecord::setSize(quint32 size)
760{
761 QByteArray data(4, 0);
762
763 data[0] = (int) ((size & 0xFF000000) >> 24);
764 data[1] = (int) ((size & 0x00FF0000) >> 16);
765 data[2] = (int) ((size & 0x0000FF00) >> 8);
766 data[3] = (int) ((size & 0x000000FF));
767
768 setPayload(data);
769}
770
771quint32 QNdefNfcSizeRecord::size() const
772{
773 const QByteArray p = payload();
774
775 if (p.isEmpty())
776 return 0;
777
778 return ((p[0] << 24) & 0xFF000000) + ((p[1] << 16) & 0x00FF0000)
779 + ((p[2] << 8) & 0x0000FF00) + (p[3] & 0x000000FF);
780}
781
782void QNdefNfcTypeRecord::setTypeInfo(const QString &type)
783{
784 setPayload(type.toUtf8());
785}
786
787QString QNdefNfcTypeRecord::typeInfo() const
788{
789 return QString::fromUtf8(payload());
790}
791
792QT_END_NAMESPACE