#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 &d) { int size = d.size(); if (size > 0xFF) { qWarning() << "Dictionary is too large to encode"; writeLE(0); return; } writeLE(size); for (QMap::const_iterator it = d.constBegin(); it != d.constEnd(); ++it) { writeLE(it.key()); switch (int(it.value().type())) { case QMetaType::Char: writeLE(WatchConnection::DictItemTypeInt); writeLE(sizeof(char)); writeLE(it.value().value()); break; case QMetaType::Short: writeLE(WatchConnection::DictItemTypeInt); writeLE(sizeof(short)); writeLE(it.value().value()); break; case QMetaType::Int: writeLE(WatchConnection::DictItemTypeInt); writeLE(sizeof(int)); writeLE(it.value().value()); break; case QMetaType::UChar: writeLE(WatchConnection::DictItemTypeInt); writeLE(sizeof(char)); writeLE(it.value().value()); break; case QMetaType::UShort: writeLE(WatchConnection::DictItemTypeInt); writeLE(sizeof(short)); writeLE(it.value().value()); break; case QMetaType::UInt: writeLE(WatchConnection::DictItemTypeInt); writeLE(sizeof(int)); writeLE(it.value().value()); break; case QMetaType::Bool: writeLE(WatchConnection::DictItemTypeInt); writeLE(sizeof(char)); writeLE(it.value().value()); break; case QMetaType::Float: // Treat qreals as ints case QMetaType::Double: writeLE(WatchConnection::DictItemTypeInt); writeLE(sizeof(int)); writeLE(it.value().value()); break; case QMetaType::QByteArray: { QByteArray ba = it.value().toByteArray(); writeLE(WatchConnection::DictItemTypeBytes); writeLE(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(WatchConnection::DictItemTypeBytes); writeLE(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(WatchConnection::DictItemTypeString); writeLE(s.size()); _buf->append(s); break; } } } }