61QNdefMessage QNdefMessage::fromByteArray(
const QByteArray &message)
65 bool seenMessageBegin =
false;
66 bool seenMessageEnd =
false;
68 QByteArray partialChunk;
72 while (idx < message.size()) {
73 quint8 flags = message.at(idx);
75 const bool messageBegin = flags & 0x80;
76 const bool messageEnd = flags & 0x40;
78 const bool cf = flags & 0x20;
79 const bool sr = flags & 0x10;
80 const bool il = flags & 0x08;
81 const quint8 typeNameFormat = flags & 0x07;
83 if (messageBegin && seenMessageBegin) {
84 qWarning(
"Got message begin but already parsed some records");
85 return QNdefMessage();
86 }
else if (!messageBegin && !seenMessageBegin) {
87 qWarning(
"Haven't got message begin yet");
88 return QNdefMessage();
89 }
else if (messageBegin && !seenMessageBegin) {
90 seenMessageBegin =
true;
92 if (messageEnd && seenMessageEnd) {
93 qWarning(
"Got message end but already parsed final record");
94 return QNdefMessage();
95 }
else if (messageEnd && !seenMessageEnd) {
96 seenMessageEnd =
true;
99 if ((typeNameFormat != 0x06) && !partialChunk.isEmpty()) {
100 qWarning(
"Partial chunk not empty, but TNF not 0x06 as expected");
101 return QNdefMessage();
104 int headerLength = 1;
105 headerLength += (sr) ? 1 : 4;
106 headerLength += (il) ? 1 : 0;
108 if (idx + headerLength >= message.size()) {
109 qWarning(
"Unexpected end of message");
110 return QNdefMessage();
113 const quint8 typeLength = message.at(++idx);
115 if ((typeNameFormat == 0x06) && (typeLength != 0)) {
116 qWarning(
"Invalid chunked data, TYPE_LENGTH != 0");
117 return QNdefMessage();
120 quint32 payloadLength;
122 payloadLength = quint8(message.at(++idx));
124 payloadLength = quint8(message.at(++idx)) << 24;
125 payloadLength |= quint8(message.at(++idx)) << 16;
126 payloadLength |= quint8(message.at(++idx)) << 8;
127 payloadLength |= quint8(message.at(++idx)) << 0;
132 idLength = message.at(++idx);
137 const qsizetype convertedPayloadLength =
static_cast<qsizetype>(payloadLength);
138 const qsizetype contentLength = convertedPayloadLength + typeLength + idLength;
144 if ((contentLength < 0) || (convertedPayloadLength < 0)
145 || ((std::numeric_limits<qsizetype>::max() - idx) < contentLength)) {
146 qWarning(
"Payload can't fit into QByteArray");
147 return QNdefMessage();
150 if (idx + contentLength >= message.size()) {
151 qWarning(
"Unexpected end of message");
152 return QNdefMessage();
155 if ((typeNameFormat == 0x06) && il) {
156 qWarning(
"Invalid chunked data, IL != 0");
157 return QNdefMessage();
160 if (typeNameFormat != 0x06)
161 record.setTypeNameFormat(QNdefRecord::TypeNameFormat(typeNameFormat));
163 if (typeLength > 0) {
164 QByteArray type(&message.constData()[++idx], typeLength);
165 record.setType(type);
166 idx += typeLength - 1;
170 QByteArray id(&message.constData()[++idx], idLength);
175 if (payloadLength > 0) {
176 QByteArray payload(&message.constData()[++idx], payloadLength);
180 partialChunk.append(payload);
181 }
else if (typeNameFormat == 0x06) {
183 record.setPayload(partialChunk + payload);
184 partialChunk.clear();
187 record.setPayload(payload);
190 idx += payloadLength - 1;
194 result.append(record);
195 record = QNdefRecord();
198 if (!cf && seenMessageEnd)
205 if (!seenMessageBegin || !seenMessageEnd) {
206 qWarning(
"Malformed NDEF Message, missing begin or end");
207 return QNdefMessage();
242bool QNdefMessage::operator==(
const QNdefMessage &other)
const
245 if (isEmpty() && other.isEmpty())
249 if (isEmpty() && other.size() == 1 && other.first().typeNameFormat() == QNdefRecord::Empty)
251 if (other.isEmpty() && size() == 1 && first().typeNameFormat() == QNdefRecord::Empty)
254 if (size() != other.size())
257 for (qsizetype i = 0; i < size(); ++i) {
258 if (at(i) != other.at(i))
271QByteArray QNdefMessage::toByteArray()
const
275 return QNdefMessage(QNdefRecord()).toByteArray();
279 for (qsizetype i = 0; i < size(); ++i) {
280 const QNdefRecord &record = at(i);
282 quint8 flags = record.typeNameFormat();
291 if (record.payload().size() < 255)
294 if (!record.id().isEmpty())
298 m.append(record.type().size());
301 m.append(quint8(record.payload().size()));
303 quint32 length = record.payload().size();
304 m.append(length >> 24);
305 m.append(length >> 16);
306 m.append(length >> 8);
307 m.append(length & 0x000000ff);
311 m.append(record.id().size());
313 if (!record.type().isEmpty())
314 m.append(record.type());
316 if (!record.id().isEmpty())
317 m.append(record.id());
319 if (!record.payload().isEmpty())
320 m.append(record.payload());