diff options
Diffstat (limited to 'replaydata.cc')
-rw-r--r-- | replaydata.cc | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/replaydata.cc b/replaydata.cc new file mode 100644 index 0000000..021a79f --- /dev/null +++ b/replaydata.cc @@ -0,0 +1,183 @@ +#include <QtCore/QDebug> +#include <QtCore/QDataStream> +#include <QtCore/QDirIterator> +#include "smartpen.h" +#include "replaydata.h" + +namespace +{ +bool readUtfString(QDataStream &stream, QString &s) +{ + quint16 len; + stream >> len; + QByteArray buffer(len, Qt::Uninitialized); + if (stream.readRawData(buffer.data(), len) != len) { + return false; + } + s = QString::fromUtf8(buffer); + return true; +} +} + +ReplayData::ReplayData(QObject *parent) : + QObject(parent) +{ +} + +bool ReplayData::open(const QString &path) +{ + _dir.setPath(path); + if (!_dir.exists()) { + return false; + } + + QDirIterator iter(_dir.path(), QStringList("session.info"), QDir::Files, QDirIterator::Subdirectories); + while (iter.hasNext()) { + QFileInfo finfo(iter.next()); + QDir sessionDir(finfo.path()); + Session session; + if (!parseSessionInfo(session, finfo.filePath())) { + qWarning() << "Could not parse:" << finfo.absoluteFilePath(); + } + if (!parseSessionPages(session, sessionDir.filePath("session.pages"))) { + qWarning() << "Could not parse:" << sessionDir.absoluteFilePath("session.pages"); + } + } + + return true; +} + +bool ReplayData::parseSessionInfo(Session &session, const QString &path) +{ + QFile f(path); + if (f.open(QIODevice::ReadOnly)) { + return parseSessionInfo(session, &f); + } else { + return false; + } +} + +bool ReplayData::parseSessionInfo(Session &session, QIODevice *dev) +{ + unsigned char magic[2]; + if (dev->read(reinterpret_cast<char*>(magic), 2) != 2 || + magic[0] != 0xFA || magic[1] != 0xCE) { + qWarning() << "Invalid magic"; + return false; + } + + char version = 0; + if (!dev->getChar(&version)) { + qWarning() << "Short read while getting version number"; + return false; + } + + switch (version) { + case 3: + return parseSessionInfoV3(session, dev); + default: + qWarning() << "Unknown version:" << version; + return false; + } +} + +bool ReplayData::parseSessionInfoV3(Session &session, QIODevice *dev) +{ + QDataStream s(dev); + if (s.skipRawData(5) != 5) return false; + + qint64 startTime, endTime, creationTime; + QString name; + + s >> startTime >> endTime >> creationTime; + if (!readUtfString(s, name)) { + return false; + } + + qDebug() << "Name:" << name << Smartpen::fromPenTime(startTime) << Smartpen::fromPenTime(endTime) << creationTime; + + quint16 num_clips; + s >> num_clips; + + for (uint i = 0; i < num_clips; ++i) { + QString file; + if (!readUtfString(s, file)) { + return false; + } + s >> startTime >> endTime; + qDebug() << " Clip:" << file << startTime << endTime; + qDebug() << " " << QDateTime::fromTime_t(startTime) << QDateTime::fromTime_t(endTime); + } + + quint16 num_strokes; + s >> num_strokes; + + for (uint i = 0; i < num_strokes; ++i) { + quint64 a, b, c; + quint32 d; + QString nbGuid; + quint8 f, g; + s >> a >> b >> c >> d; + if (!readUtfString(s, nbGuid)) { + return false; + } + s >> f >> g; + qDebug() << " Stroke:" << a << b << c << d << nbGuid << f << g; + } + + return true; +} + +bool ReplayData::parseSessionPages(Session &session, const QString &path) +{ + QFile f(path); + if (f.open(QIODevice::ReadOnly)) { + return parseSessionPages(session, &f); + } else { + return false; + } +} + +bool ReplayData::parseSessionPages(Session &session, QIODevice *dev) +{ + unsigned char magic[2]; + if (dev->read(reinterpret_cast<char*>(magic), 2) != 2 || + magic[0] != 0xCA || magic[1] != 0xBE) { + qWarning() << "Invalid magic"; + return false; + } + + char version = 0; + if (!dev->getChar(&version)) { + qWarning() << "Short read while getting version number"; + return false; + } + + switch (version) { + case 1: + return parseSessionPagesV1(session, dev); + default: + qWarning() << "Unknown version:" << version; + return false; + } +} + +bool ReplayData::parseSessionPagesV1(Session &session, QIODevice *dev) +{ + QDataStream s(dev); + if (s.skipRawData(1) != 1) return false; + + quint16 num_pages = 0; + s >> num_pages; + session.pages.reserve(session.pages.size() + num_pages); + + for (uint i = 0; i < num_pages; ++i) { + quint64 address, unk; + s >> address >> unk; + + session.pages.append(address); + qDebug() << " Page:" << address << unk; + } + + return true; +} |