summaryrefslogtreecommitdiff
path: root/rockworkd/libpebble/watchdatawriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rockworkd/libpebble/watchdatawriter.cpp')
-rw-r--r--rockworkd/libpebble/watchdatawriter.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/rockworkd/libpebble/watchdatawriter.cpp b/rockworkd/libpebble/watchdatawriter.cpp
new file mode 100644
index 0000000..e3caf17
--- /dev/null
+++ b/rockworkd/libpebble/watchdatawriter.cpp
@@ -0,0 +1,144 @@
+#include "watchdatawriter.h"
+#include "watchconnection.h"
+
+void WatchDataWriter::writeBytes(int n, const QByteArray &b)
+{
+ if (b.size() > n) {
+ _buf->append(b.constData(), n);
+ } else {
+ int diff = n - b.size();
+ _buf->append(b);
+ if (diff > 0) {
+ _buf->append(QByteArray(diff, '\0'));
+ }
+ }
+}
+
+void WatchDataWriter::writeFixedString(int n, const QString &s)
+{
+ _buf->append(s.left(n).toUtf8());
+ for (int i = s.left(n).length(); i < n; i++) {
+ _buf->append('\0');
+ }
+}
+
+void WatchDataWriter::writeCString(const QString &s)
+{
+ _buf->append(s.toUtf8());
+ _buf->append('\0');
+}
+
+void WatchDataWriter::writePascalString(const QString &s)
+{
+ _buf->append(s.length());
+ _buf->append(s.toLatin1());
+}
+
+void WatchDataWriter::writeUuid(const QUuid &uuid)
+{
+ writeBytes(16, uuid.toRfc4122());
+}
+
+void WatchDataWriter::writeDict(const QMap<int, QVariant> &d)
+{
+ int size = d.size();
+ if (size > 0xFF) {
+ qWarning() << "Dictionary is too large to encode";
+ writeLE<quint8>(0);
+ return;
+ }
+
+ writeLE<quint8>(size);
+
+ for (QMap<int, QVariant>::const_iterator it = d.constBegin(); it != d.constEnd(); ++it) {
+ writeLE<quint32>(it.key());
+
+ switch (int(it.value().type())) {
+ case QMetaType::Char:
+ writeLE<quint8>(WatchConnection::DictItemTypeInt);
+ writeLE<quint16>(sizeof(char));
+ writeLE<char>(it.value().value<char>());
+ break;
+ case QMetaType::Short:
+ writeLE<quint8>(WatchConnection::DictItemTypeInt);
+ writeLE<quint16>(sizeof(short));
+ writeLE<short>(it.value().value<short>());
+ break;
+ case QMetaType::Int:
+ writeLE<quint8>(WatchConnection::DictItemTypeInt);
+ writeLE<quint16>(sizeof(int));
+ writeLE<int>(it.value().value<int>());
+ break;
+
+ case QMetaType::UChar:
+ writeLE<quint8>(WatchConnection::DictItemTypeInt);
+ writeLE<quint16>(sizeof(char));
+ writeLE<char>(it.value().value<char>());
+ break;
+ case QMetaType::UShort:
+ writeLE<quint8>(WatchConnection::DictItemTypeInt);
+ writeLE<quint16>(sizeof(short));
+ writeLE<short>(it.value().value<short>());
+ break;
+ case QMetaType::UInt:
+ writeLE<quint8>(WatchConnection::DictItemTypeInt);
+ writeLE<quint16>(sizeof(int));
+ writeLE<int>(it.value().value<int>());
+ break;
+
+ case QMetaType::Bool:
+ writeLE<quint8>(WatchConnection::DictItemTypeInt);
+ writeLE<quint16>(sizeof(char));
+ writeLE<char>(it.value().value<char>());
+ break;
+
+ case QMetaType::Float: // Treat qreals as ints
+ case QMetaType::Double:
+ writeLE<quint8>(WatchConnection::DictItemTypeInt);
+ writeLE<quint16>(sizeof(int));
+ writeLE<int>(it.value().value<int>());
+ break;
+
+ case QMetaType::QByteArray: {
+ QByteArray ba = it.value().toByteArray();
+ writeLE<quint8>(WatchConnection::DictItemTypeBytes);
+ writeLE<quint16>(ba.size());
+ _buf->append(ba);
+ break;
+ }
+
+ case QMetaType::QVariantList: {
+ // Generally a JS array, which we marshal as a byte array.
+ QVariantList list = it.value().toList();
+ QByteArray ba;
+ ba.reserve(list.size());
+
+ Q_FOREACH (const QVariant &v, list) {
+ ba.append(v.toInt());
+ }
+
+ writeLE<quint8>(WatchConnection::DictItemTypeBytes);
+ writeLE<quint16>(ba.size());
+ _buf->append(ba);
+ break;
+ }
+
+ default:
+ qWarning() << "Unknown dict item type:" << it.value().typeName();
+ /* Fallthrough */
+ case QMetaType::QString:
+ case QMetaType::QUrl:
+ {
+ QByteArray s = it.value().toString().toUtf8();
+ if (s.isEmpty() || s[s.size() - 1] != '\0') {
+ // Add null terminator if it doesn't have one
+ s.append('\0');
+ }
+ writeLE<quint8>(WatchConnection::DictItemTypeString);
+ writeLE<quint16>(s.size());
+ _buf->append(s);
+ break;
+ }
+ }
+ }
+}