From: Zack Rusin Date: Wed, 14 Sep 2011 03:58:45 +0000 (-0400) Subject: Implement trace saving. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=9b31ffcdfff1b7e8528bea8e95870a31eaaa614f;p=apitrace Implement trace saving. --- diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp index 6254d2c..2500489 100644 --- a/gui/apitrace.cpp +++ b/gui/apitrace.cpp @@ -237,8 +237,9 @@ void ApiTrace::save() QDir dir; emit startedSaving(); dir.mkpath(fi.absolutePath()); - Q_ASSERT(!"saving not implemented"); - m_saver->saveFile(m_tempFileName, QVector()); + m_saver->saveFile(m_tempFileName, + m_fileName, + m_editedCalls); } void ApiTrace::slotSaved() diff --git a/gui/saverthread.cpp b/gui/saverthread.cpp index 5837c99..645e25d 100644 --- a/gui/saverthread.cpp +++ b/gui/saverthread.cpp @@ -1,6 +1,8 @@ #include "saverthread.h" #include "trace_writer.hpp" +#include "trace_model.hpp" +#include "trace_parser.hpp" #include #include @@ -8,7 +10,7 @@ #include - +#if 0 static Trace::FunctionSig * createFunctionSig(ApiTraceCall *call, unsigned id) { @@ -203,54 +205,164 @@ writeValue(Trace::Writer &writer, const QVariant &var, unsigned &id) } } } +#endif + +class EditVisitor : public Trace::Visitor +{ +public: + EditVisitor(const QVariant &variant) + : m_variant(variant), + m_editedValue(0) + {} + virtual void visit(Trace::Null *val) + { + m_editedValue = val; + } + + virtual void visit(Trace::Bool *node) + { +// Q_ASSERT(m_variant.userType() == QVariant::Bool); + bool var = m_variant.toBool(); + m_editedValue = new Trace::Bool(var); + } + + virtual void visit(Trace::SInt *node) + { +// Q_ASSERT(m_variant.userType() == QVariant::Int); + m_editedValue = new Trace::SInt(m_variant.toInt()); + } + + virtual void visit(Trace::UInt *node) + { +// Q_ASSERT(m_variant.userType() == QVariant::UInt); + m_editedValue = new Trace::SInt(m_variant.toUInt()); + } + + virtual void visit(Trace::Float *node) + { + m_editedValue = new Trace::Float(m_variant.toFloat()); + } + + virtual void visit(Trace::String *node) + { + QString str = m_variant.toString(); + m_editedValue = new Trace::String(str.toLocal8Bit().constData()); + } + + virtual void visit(Trace::Enum *e) + { + m_editedValue = e; + } + + virtual void visit(Trace::Bitmask *bitmask) + { + m_editedValue = bitmask; + } + + virtual void visit(Trace::Struct *str) + { + m_editedValue = str; + } + + virtual void visit(Trace::Array *array) + { + ApiArray apiArray = m_variant.value(); + QVector vals = apiArray.values(); + + Trace::Array *newArray = new Trace::Array(vals.count()); + for (int i = 0; i < vals.count(); ++i) { + EditVisitor visitor(vals[i]); + + array->values[i]->visit(visitor); + if (array->values[i] == visitor.value()) { + //non-editabled + delete newArray; + m_editedValue = array; + return; + } + + newArray->values.push_back(visitor.value()); + } + m_editedValue = newArray; + } + + virtual void visit(Trace::Blob *blob) + { + m_editedValue = blob; + } + + virtual void visit(Trace::Pointer *ptr) + { + m_editedValue = ptr; + } + + Trace::Value *value() const + { + return m_editedValue; + } +private: + QVariant m_variant; + Trace::Value *m_editedValue; +}; + +static void +overwriteValue(Trace::Call *call, const QVariant &val, int index) +{ + EditVisitor visitor(val); + Trace::Value *origValue = call->args[index]; + origValue->visit(visitor); + + if (visitor.value() && origValue != visitor.value()) { + delete origValue; + call->args[index] = visitor.value(); + } +} SaverThread::SaverThread(QObject *parent) : QThread(parent) { } -void SaverThread::saveFile(const QString &fileName, - const QVector &calls) +void SaverThread::saveFile(const QString &writeFileName, + const QString &readFileName, + const QSet &editedCalls) { - m_fileName = fileName; - m_calls = calls; + m_writeFileName = writeFileName; + m_readFileName = readFileName; + m_editedCalls = editedCalls; start(); } void SaverThread::run() { - unsigned id = 0; - qDebug() << "Saving : " << m_fileName; + qDebug() << "Saving " << m_readFileName + << ", to " << m_writeFileName; + QMap callIndexMap; + + foreach(ApiTraceCall *call, m_editedCalls) { + callIndexMap.insert(call->index(), call); + } + Trace::Writer writer; - writer.open(m_fileName.toLocal8Bit()); - for (int i = 0; i < m_calls.count(); ++i) { - ApiTraceCall *call = m_calls[i]; - Trace::FunctionSig *funcSig = createFunctionSig(call, ++id); - unsigned callNo = writer.beginEnter(funcSig); - { - //args - QVector vars = call->arguments(); - int index = 0; - foreach(QVariant var, vars) { - writer.beginArg(index++); - writeValue(writer, var, ++id); - writer.endArg(); - } - } - writer.endEnter(); - writer.beginLeave(callNo); - { - QVariant ret = call->returnValue(); - if (!ret.isNull()) { - writer.beginReturn(); - writeValue(writer, ret, ++id); - writer.endReturn(); + writer.open(m_writeFileName.toLocal8Bit()); + + Trace::Parser parser; + parser.open(m_readFileName.toLocal8Bit()); + + Trace::Call *call; + while ((call = parser.parse_call())) { + if (callIndexMap.contains(call->no)) { + QVector values = callIndexMap[call->no]->editedValues(); + for (int i = 0; i < values.count(); ++i) { + const QVariant &val = values[i]; + overwriteValue(call, val, i); } - } - writer.endLeave(); - deleteFunctionSig(funcSig); + } else { + writer.writeCall(call); + } } + writer.close(); emit traceSaved(); diff --git a/gui/saverthread.h b/gui/saverthread.h index 3da502c..e8c6889 100644 --- a/gui/saverthread.h +++ b/gui/saverthread.h @@ -16,8 +16,9 @@ public: SaverThread(QObject *parent=0); public slots: - void saveFile(const QString &fileName, - const QVector &calls); + void saveFile(const QString &saveFileName, + const QString &readFileName, + const QSet &editedCalls); signals: void traceSaved(); @@ -26,8 +27,9 @@ protected: virtual void run(); private: - QString m_fileName; - QVector m_calls; + QString m_readFileName; + QString m_writeFileName; + QSet m_editedCalls; };