aboutsummaryrefslogtreecommitdiff
path: root/replaydata.cc
diff options
context:
space:
mode:
Diffstat (limited to 'replaydata.cc')
-rw-r--r--replaydata.cc183
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;
+}