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