61QNdefMessage QNdefMessage::fromByteArray(
const QByteArray &message)
65 bool seenMessageBegin =
false;
66 bool seenMessageEnd =
false;
71 bool chunkStarted =
false;
72 QByteArray partialChunk;
76 while (idx < message.size()) {
77 quint8 flags = message.at(idx);
79 const bool messageBegin = flags & 0x80;
80 const bool messageEnd = flags & 0x40;
82 const bool cf = flags & 0x20;
83 const bool sr = flags & 0x10;
84 const bool il = flags & 0x08;
85 const quint8 typeNameFormat = flags & 0x07;
87 if (messageBegin && seenMessageBegin) {
88 qWarning(
"Got message begin but already parsed some records");
89 return QNdefMessage();
90 }
else if (!messageBegin && !seenMessageBegin) {
91 qWarning(
"Haven't got message begin yet");
92 return QNdefMessage();
93 }
else if (messageBegin && !seenMessageBegin) {
94 seenMessageBegin =
true;
96 if (messageEnd && seenMessageEnd) {
97 qWarning(
"Got message end but already parsed final record");
98 return QNdefMessage();
99 }
else if (messageEnd && !seenMessageEnd) {
100 seenMessageEnd =
true;
103 if ((typeNameFormat != 0x06) && chunkStarted) {
104 qWarning(
"Partial chunk not empty, but TNF not 0x06 as expected");
105 return QNdefMessage();
108 if ((typeNameFormat == 0x06) && !chunkStarted) {
109 qWarning(
"Unexpected TNF=0x06 when chunking was not started");
110 return QNdefMessage();
113 int headerLength = 1;
114 headerLength += (sr) ? 1 : 4;
115 headerLength += (il) ? 1 : 0;
117 if (idx + headerLength >= message.size()) {
118 qWarning(
"Unexpected end of message");
119 return QNdefMessage();
122 const quint8 typeLength = message.at(++idx);
124 if ((typeNameFormat == 0x06) && (typeLength != 0)) {
125 qWarning(
"Invalid chunked data, TYPE_LENGTH != 0");
126 return QNdefMessage();
129 quint32 payloadLength;
131 payloadLength = quint8(message.at(++idx));
133 payloadLength = quint8(message.at(++idx)) << 24;
134 payloadLength |= quint8(message.at(++idx)) << 16;
135 payloadLength |= quint8(message.at(++idx)) << 8;
136 payloadLength |= quint8(message.at(++idx)) << 0;
141 idLength = message.at(++idx);
146 const qsizetype convertedPayloadLength =
static_cast<qsizetype>(payloadLength);
147 const qsizetype contentLength = convertedPayloadLength + typeLength + idLength;
153 if ((contentLength < 0) || (convertedPayloadLength < 0)
154 || ((std::numeric_limits<qsizetype>::max() - idx) < contentLength)) {
155 qWarning(
"Payload can't fit into QByteArray");
156 return QNdefMessage();
159 if (idx + contentLength >= message.size()) {
160 qWarning(
"Unexpected end of message");
161 return QNdefMessage();
164 if ((typeNameFormat == 0x06) && il) {
165 qWarning(
"Invalid chunked data, IL != 0");
166 return QNdefMessage();
169 if (typeNameFormat != 0x06)
170 record.setTypeNameFormat(QNdefRecord::TypeNameFormat(typeNameFormat));
172 if (typeLength > 0) {
173 QByteArray type(&message.constData()[++idx], typeLength);
174 record.setType(type);
175 idx += typeLength - 1;
179 QByteArray id(&message.constData()[++idx], idLength);
186 if (payloadLength > 0) {
187 payload = QByteArray(&message.constData()[++idx], payloadLength);
188 idx += payloadLength - 1;
194 partialChunk.append(payload);
195 }
else if (typeNameFormat == 0x06) {
197 record.setPayload(partialChunk + payload);
198 partialChunk.clear();
199 chunkStarted =
false;
202 record.setPayload(payload);
207 result.append(record);
208 record = QNdefRecord();
211 if (!cf && seenMessageEnd)
218 if (!seenMessageBegin || !seenMessageEnd) {
219 qWarning(
"Malformed NDEF Message, missing begin or end");
220 return QNdefMessage();
255bool QNdefMessage::operator==(
const QNdefMessage &other)
const
258 if (isEmpty() && other.isEmpty())
262 if (isEmpty() && other.size() == 1 && other.first().typeNameFormat() == QNdefRecord::Empty)
264 if (other.isEmpty() && size() == 1 && first().typeNameFormat() == QNdefRecord::Empty)
267 if (size() != other.size())
270 for (qsizetype i = 0; i < size(); ++i) {
271 if (at(i) != other.at(i))
284QByteArray QNdefMessage::toByteArray()
const
288 return QNdefMessage(QNdefRecord()).toByteArray();
292 for (qsizetype i = 0; i < size(); ++i) {
293 const QNdefRecord &record = at(i);
295 quint8 flags = record.typeNameFormat();
304 if (record.payload().size() < 255)
307 if (!record.id().isEmpty())
311 m.append(record.type().size());
314 m.append(quint8(record.payload().size()));
316 quint32 length = record.payload().size();
317 m.append(length >> 24);
318 m.append(length >> 16);
319 m.append(length >> 8);
320 m.append(length & 0x000000ff);
324 m.append(record.id().size());
326 if (!record.type().isEmpty())
327 m.append(record.type());
329 if (!record.id().isEmpty())
330 m.append(record.id());
332 if (!record.payload().isEmpty())
333 m.append(record.payload());