From 29aaea2d80a9eb1715b6cddfac2d2aacf76358bd Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Thu, 11 Feb 2016 23:55:16 +0100 Subject: launchpad ~mzanetti/rockwork/trunk r87 --- rockworkd/libpebble/watchdatareader.h | 146 ++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 rockworkd/libpebble/watchdatareader.h (limited to 'rockworkd/libpebble/watchdatareader.h') diff --git a/rockworkd/libpebble/watchdatareader.h b/rockworkd/libpebble/watchdatareader.h new file mode 100644 index 0000000..58e77d8 --- /dev/null +++ b/rockworkd/libpebble/watchdatareader.h @@ -0,0 +1,146 @@ +#ifndef WATCHDATAREADER_H +#define WATCHDATAREADER_H + +#include "watchconnection.h" + +#include +#include +#include +#include +#include + +class WatchDataReader { +public: + WatchDataReader(const QByteArray &data): + m_data(data) + { + } + + template + T read() { + if (checkBad(sizeof(T))) return 0; + const uchar *u = p(); + m_offset += sizeof(T); + return qFromBigEndian(u); + } + + inline bool checkBad(int n = 0) + { + if (m_offset + n > m_data.size()) { + m_bad = true; + } + return m_bad; + } + inline const uchar * p() + { + return reinterpret_cast(&m_data.constData()[m_offset]); + } + inline void skip(int n) + { + m_offset += n; + checkBad(); + } + + template + inline T readLE() + { + if (checkBad(sizeof(T))) return 0; + const uchar *u = p(); + m_offset += sizeof(T); + return qFromLittleEndian(u); + } + QString readFixedString(int n) + { + if (checkBad(n)) return QString(); + const char *u = &m_data.constData()[m_offset]; + m_offset += n; + return QString::fromUtf8(u, strnlen(u, n)); + } + QByteArray peek(int n) { + return m_data.left(m_offset + n).right(n); + } + QUuid readUuid() + { + if (checkBad(16)) return QString(); + m_offset += 16; + return QUuid::fromRfc4122(m_data.mid(m_offset - 16, 16)); + } + QByteArray readBytes(int n) + { + if (checkBad(n)) return QByteArray(); + const char *u = &m_data.constData()[m_offset]; + m_offset += n; + return QByteArray(u, n); + } + QMap readDict() + { + QMap d; + if (checkBad(1)) return d; + + const int n = readLE(); + + for (int i = 0; i < n; i++) { + if (checkBad(4 + 1 + 2)) return d; + const int key = readLE(); // For some reason, this is little endian. + const int type = readLE(); + const int width = readLE(); + + switch (type) { + case WatchConnection::DictItemTypeBytes: + d.insert(key, QVariant::fromValue(readBytes(width))); + break; + case WatchConnection::DictItemTypeString: + d.insert(key, QVariant::fromValue(readFixedString(width))); + break; + case WatchConnection::DictItemTypeUInt: + switch (width) { + case sizeof(quint8): + d.insert(key, QVariant::fromValue(readLE())); + break; + case sizeof(quint16): + d.insert(key, QVariant::fromValue(readLE())); + break; + case sizeof(quint32): + d.insert(key, QVariant::fromValue(readLE())); + break; + default: + m_bad = true; + return d; + } + + break; + case WatchConnection::DictItemTypeInt: + switch (width) { + case sizeof(qint8): + d.insert(key, QVariant::fromValue(readLE())); + break; + case sizeof(qint16): + d.insert(key, QVariant::fromValue(readLE())); + break; + case sizeof(qint32): + d.insert(key, QVariant::fromValue(readLE())); + break; + default: + m_bad = true; + return d; + } + + break; + default: + m_bad = true; + return d; + } + } + + return d; + } + bool bad() const; + + +private: + QByteArray m_data; + int m_offset = 0; + bool m_bad = false; +}; + +#endif // WATCHDATAREADER_H -- cgit v1.2.3