#include "packer.h" #include "watchconnector.h" void Packer::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 Packer::writeCString(const QString &s) { _buf->append(s.toUtf8()); _buf->append('\0'); } void Packer::writeUuid(const QUuid &uuid) { writeBytes(16, uuid.toRfc4122()); } void Packer::writeDict(const QMap &d) { int size = d.size(); if (size > 0xFF) { logger()->warn() << "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(WatchConnector::typeINT); writeLE(sizeof(char)); writeLE(it.value().value()); break; case QMetaType::Short: writeLE(WatchConnector::typeINT); writeLE(sizeof(short)); writeLE(it.value().value()); break; case QMetaType::Int: writeLE(WatchConnector::typeINT); writeLE(sizeof(int)); writeLE(it.value().value()); break; case QMetaType::UChar: writeLE(WatchConnector::typeINT); writeLE(sizeof(char)); writeLE(it.value().value()); break; case QMetaType::UShort: writeLE(WatchConnector::typeINT); writeLE(sizeof(short)); writeLE(it.value().value()); break; case QMetaType::UInt: writeLE(WatchConnector::typeINT); writeLE(sizeof(int)); writeLE(it.value().value()); break; case QMetaType::Float: // Treat qreals as ints case QMetaType::Double: writeLE(WatchConnector::typeINT); writeLE(sizeof(int)); writeLE(it.value().value()); break; case QMetaType::QByteArray: { QByteArray ba = it.value().toByteArray(); writeLE(WatchConnector::typeBYTES); 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(WatchConnector::typeBYTES); writeLE(ba.size()); _buf->append(ba); break; } default: logger()->warn() << "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(WatchConnector::typeSTRING); writeLE(s.size()); _buf->append(s); break; } } } }