diff options
Diffstat (limited to 'daemon/unpacker.cpp')
| -rw-r--r-- | daemon/unpacker.cpp | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/daemon/unpacker.cpp b/daemon/unpacker.cpp new file mode 100644 index 0000000..1f1d564 --- /dev/null +++ b/daemon/unpacker.cpp @@ -0,0 +1,90 @@ +#include "unpacker.h" +#include "watchconnector.h" + +QLoggingCategory Unpacker::l("Unpacker"); + +QByteArray Unpacker::readBytes(int n) +{ + if (checkBad(n)) return QByteArray(); + const char *u = &_buf.constData()[_offset]; + _offset += n; + return QByteArray(u, n); +} + +QString Unpacker::readFixedString(int n) +{ + if (checkBad(n)) return QString(); + const char *u = &_buf.constData()[_offset]; + _offset += n; + return QString::fromUtf8(u, strnlen(u, n)); +} + +QUuid Unpacker::readUuid() +{ + if (checkBad(16)) return QString(); + _offset += 16; + return QUuid::fromRfc4122(_buf.mid(_offset - 16, 16)); +} + +QMap<int, QVariant> Unpacker::readDict() +{ + QMap<int, QVariant> d; + if (checkBad(1)) return d; + + const int n = readLE<quint8>(); + + for (int i = 0; i < n; i++) { + if (checkBad(4 + 1 + 2)) return d; + const int key = readLE<qint32>(); // For some reason, this is little endian. + const int type = readLE<quint8>(); + const int width = readLE<quint16>(); + + switch (type) { + case WatchConnector::typeBYTES: + d.insert(key, QVariant::fromValue(readBytes(width))); + break; + case WatchConnector::typeSTRING: + d.insert(key, QVariant::fromValue(readFixedString(width))); + break; + case WatchConnector::typeUINT: + switch (width) { + case sizeof(quint8): + d.insert(key, QVariant::fromValue(readLE<quint8>())); + break; + case sizeof(quint16): + d.insert(key, QVariant::fromValue(readLE<quint16>())); + break; + case sizeof(quint32): + d.insert(key, QVariant::fromValue(readLE<quint32>())); + break; + default: + _bad = true; + return d; + } + + break; + case WatchConnector::typeINT: + switch (width) { + case sizeof(qint8): + d.insert(key, QVariant::fromValue(readLE<qint8>())); + break; + case sizeof(qint16): + d.insert(key, QVariant::fromValue(readLE<qint16>())); + break; + case sizeof(qint32): + d.insert(key, QVariant::fromValue(readLE<qint32>())); + break; + default: + _bad = true; + return d; + } + + break; + default: + _bad = true; + return d; + } + } + + return d; +} |
