X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=gui%2Fsaverthread.cpp;h=4ad83c5876c5caf1267d80cc8c8029bdc18b7c93;hb=HEAD;hp=648de593701c885076d570dd938f906951465d2c;hpb=eced747755020ebce502ba33555acb88e382aed8;p=apitrace diff --git a/gui/saverthread.cpp b/gui/saverthread.cpp index 648de59..4ad83c5 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,68 +10,68 @@ #include - -static Trace::FunctionSig * +#if 0 +static trace::FunctionSig * createFunctionSig(ApiTraceCall *call, unsigned id) { - Trace::FunctionSig *sig = new Trace::FunctionSig(); + trace::FunctionSig *sig = new trace::FunctionSig(); sig->id = id; sig->name = qstrdup(call->name().toLocal8Bit()); QStringList args = call->argNames(); sig->num_args = args.count(); - sig->args = new const char*[args.count()]; + sig->arg_names = new const char*[args.count()]; for (int i = 0; i < args.count(); ++i) { - sig->args[i] = qstrdup(args[i].toLocal8Bit()); + sig->arg_names[i] = qstrdup(args[i].toLocal8Bit()); } return sig; } static void -deleteFunctionSig(Trace::FunctionSig *sig) +deleteFunctionSig(trace::FunctionSig *sig) { for (int i = 0; i < sig->num_args; ++i) { - delete [] sig->args[i]; + delete [] sig->arg_names[i]; } - delete [] sig->args; + delete [] sig->arg_names; delete [] sig->name; delete sig; } -static Trace::StructSig * +static trace::StructSig * createStructSig(const ApiStruct &str, unsigned id) { ApiStruct::Signature aSig = str.signature(); - Trace::StructSig *sig = new Trace::StructSig(); + trace::StructSig *sig = new trace::StructSig(); sig->id = id; sig->name = qstrdup(aSig.name.toLocal8Bit()); sig->num_members = aSig.memberNames.count(); - char **members = new char*[aSig.memberNames.count()]; - sig->members = (const char **)members; + char **member_names = new char*[aSig.memberNames.count()]; + sig->member_names = (const char **)member_names; for (int i = 0; i < aSig.memberNames.count(); ++i) { - members[i] = qstrdup(aSig.memberNames[i].toLocal8Bit()); + member_names[i] = qstrdup(aSig.memberNames[i].toLocal8Bit()); } return sig; } static void -deleteStructSig(Trace::StructSig *sig) +deleteStructSig(trace::StructSig *sig) { for (int i = 0; i < sig->num_members; ++i) { - delete [] sig->members[i]; + delete [] sig->member_names[i]; } - delete [] sig->members; + delete [] sig->member_names; delete [] sig->name; delete sig; } -static Trace::EnumSig * +static trace::EnumSig * createEnumSig(const ApiEnum &en, unsigned id) { - Trace::EnumSig *sig = new Trace::EnumSig(); + trace::EnumSig *sig = new trace::EnumSig(); sig->id = id; sig->name = qstrdup(en.name().toLocal8Bit()); @@ -79,46 +81,46 @@ createEnumSig(const ApiEnum &en, unsigned id) } static void -deleteEnumSig(Trace::EnumSig *sig) +deleteEnumSig(trace::EnumSig *sig) { delete [] sig->name; delete sig; } -static Trace::BitmaskSig * +static trace::BitmaskSig * createBitmaskSig(const ApiBitmask &bt, unsigned id) { ApiBitmask::Signature bsig = bt.signature(); ApiBitmask::Signature::const_iterator itr; - Trace::BitmaskSig *sig = new Trace::BitmaskSig(); - Trace::BitmaskVal *values = new Trace::BitmaskVal[bsig.count()]; + trace::BitmaskSig *sig = new trace::BitmaskSig(); + trace::BitmaskFlag *flags = new trace::BitmaskFlag[bsig.count()]; sig->id = id; - sig->count = bsig.count(); - sig->values = values; + sig->num_flags = bsig.count(); + sig->flags = flags; int i = 0; for (itr = bsig.constBegin(); itr != bsig.constEnd(); ++itr, ++i) { - values[i].name = qstrdup(itr->first.toLocal8Bit()); - values[i].value = itr->second; + flags[i].name = qstrdup(itr->first.toLocal8Bit()); + flags[i].value = itr->second; } return sig; } static void -deleteBitmaskSig(Trace::BitmaskSig *sig) +deleteBitmaskSig(trace::BitmaskSig *sig) { - for (int i = 0; i < sig->count; ++i) { - delete [] sig->values[i].name; + for (int i = 0; i < sig->num_flags; ++i) { + delete [] sig->flags[i].name; } - delete [] sig->values; + delete [] sig->flags; delete sig; } static void -writeValue(Trace::Writer &writer, const QVariant &var, unsigned &id) +writeValue(trace::Writer &writer, const QVariant &var, unsigned &id) { int arrayType = QMetaType::type("ApiArray"); int bitmaskType = QMetaType::type("ApiBitmask"); @@ -162,7 +164,7 @@ writeValue(Trace::Writer &writer, const QVariant &var, unsigned &id) default: if (type == arrayType) { ApiArray array = var.value(); - QList vals = array.values(); + QVector vals = array.values(); writer.beginArray(vals.count()); foreach(QVariant el, vals) { writer.beginElement(); @@ -172,13 +174,13 @@ writeValue(Trace::Writer &writer, const QVariant &var, unsigned &id) writer.endArray(); } else if (type == bitmaskType) { ApiBitmask bm = var.value(); - Trace::BitmaskSig *sig = createBitmaskSig(bm, ++id); - writer.writeBitmask(*sig, bm.value()); + trace::BitmaskSig *sig = createBitmaskSig(bm, ++id); + writer.writeBitmask(sig, bm.value()); deleteBitmaskSig(sig); } else if (type == structType) { ApiStruct apiStr = var.value(); QList vals = apiStr.values(); - Trace::StructSig *str = createStructSig(apiStr, ++id); + trace::StructSig *str = createStructSig(apiStr, ++id); writer.beginStruct(str); foreach(QVariant val, vals) { writeValue(writer, val, ++id); @@ -187,14 +189,10 @@ writeValue(Trace::Writer &writer, const QVariant &var, unsigned &id) deleteStructSig(str); } else if (type == pointerType) { ApiPointer apiPtr = var.value(); - //writer.beginArray(1); - //writer.beginElement(); - writer.writeOpaque((const void*)apiPtr.value()); - //writer.endElement(); - //writer.endArray(); + writer.writePointer(apiPtr.value()); } else if (type == enumType) { ApiEnum apiEnum = var.value(); - Trace::EnumSig *sig = createEnumSig(apiEnum, ++id); + trace::EnumSig *sig = createEnumSig(apiEnum, ++id); writer.writeEnum(sig); deleteEnumSig(sig); } else { @@ -203,54 +201,171 @@ 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::Double *node) + { + m_editedValue = new trace::Double(m_variant.toDouble()); + } + + virtual void visit(trace::String *node) + { + QString str = m_variant.toString(); + char *newString = new char[str.length() + 1]; + QByteArray ba = str.toLocal8Bit(); + strcpy(newString, ba.constData()); + m_editedValue = new trace::String(newString); + } + + 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[i] = 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].value; + origValue->visit(visitor); + + if (visitor.value() && origValue != visitor.value()) { + delete origValue; + call->args[index].value = visitor.value(); + } +} SaverThread::SaverThread(QObject *parent) : QThread(parent) { } -void SaverThread::saveFile(const QString &fileName, - const QList &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; - 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 - QVariantList 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(); + 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_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.writeCall(call); + } else { + writer.writeCall(call); } - writer.endLeave(); - - deleteFunctionSig(funcSig); } + writer.close(); emit traceSaved();