]> git.cworth.org Git - apitrace/commitdiff
Implement a bulk of trace saving.
authorZack Rusin <zack@kde.org>
Mon, 18 Apr 2011 02:56:58 +0000 (22:56 -0400)
committerZack Rusin <zack@kde.org>
Mon, 18 Apr 2011 02:56:58 +0000 (22:56 -0400)
gui/CMakeLists.txt
gui/apitracecall.cpp
gui/apitracecall.h
gui/saverthread.cpp [new file with mode: 0644]
gui/saverthread.h [new file with mode: 0644]

index fdc6c1349ab76390a1e9bd5f3fdbd82d88c5f27a..b8d5a6908b39f0a8d65f4d6097746988881d6302 100644 (file)
@@ -16,6 +16,7 @@ set(qapitrace_SRCS
    mainwindow.cpp
    main.cpp
    retracer.cpp
+   saverthread.cpp
    searchwidget.cpp
    settingsdialog.cpp
    shaderssourcewidget.cpp
index 6024b15c8a6c8913ce455f21e345d938b1695382..39e4f5515dd8b725dc76dfa5678cbadfe2085eb6 100644 (file)
@@ -8,7 +8,7 @@
 #define QT_USE_FAST_OPERATOR_PLUS
 #include <QStringBuilder>
 
-ApiPointer::ApiPointer(int val)
+ApiPointer::ApiPointer(unsigned long long val)
     : m_value(val)
 {
 }
@@ -722,3 +722,28 @@ QString ApiEnum::name() const
     return m_name;
 }
 
+unsigned long long ApiBitmask::value() const
+{
+    return m_value;
+}
+
+ApiBitmask::Signature ApiBitmask::signature() const
+{
+    return m_sig;
+}
+
+ApiStruct::Signature ApiStruct::signature() const
+{
+    return m_sig;
+}
+
+QList<QVariant> ApiStruct::values() const
+{
+    return m_members;
+}
+
+unsigned long long ApiPointer::value() const
+{
+    return m_value;
+}
+
index 1b4e5ab17b6a2e6c2ff480187972b56729fae326..59c6fe75eec5613025e895033097defd93f423b9 100644 (file)
@@ -55,11 +55,14 @@ Q_DECLARE_METATYPE(ApiEnum);
 class ApiPointer
 {
 public:
-    ApiPointer(int val=0);
+    ApiPointer(unsigned long long val=0);
 
     QString toString() const;
+
+    unsigned long long value() const;
+
 private:
-    int m_value;
+    unsigned long long m_value;
 };
 Q_DECLARE_METATYPE(ApiPointer);
 
@@ -72,6 +75,9 @@ public:
 
     QString toString() const;
 
+    unsigned long long value() const;
+    Signature signature() const;
+
 private:
     void init(const Trace::Bitmask *bitmask);
 private:
@@ -91,6 +97,8 @@ public:
     ApiStruct(const Trace::Struct *s = 0);
 
     QString toString() const;
+    Signature signature() const;
+    QList<QVariant> values() const;
 
 private:
     void init(const Trace::Struct *bitmask);
diff --git a/gui/saverthread.cpp b/gui/saverthread.cpp
new file mode 100644 (file)
index 0000000..e45e025
--- /dev/null
@@ -0,0 +1,238 @@
+#include "saverthread.h"
+
+#include "trace_write.hpp"
+
+#include <QFile>
+#include <QHash>
+#include <QUrl>
+
+#include <QDebug>
+
+
+static Trace::FunctionSig *
+createFunctionSig(ApiTraceCall *call, unsigned id)
+{
+    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()];
+    for (int i = 0; i < args.count(); ++i) {
+        sig->args[i] = qstrdup(args[i].toLocal8Bit());
+    }
+
+    return sig;
+}
+
+static void
+deleteFunctionSig(Trace::FunctionSig *sig)
+{
+    for (int i = 0; i < sig->num_args; ++i) {
+        delete [] sig->args[i];
+    }
+    delete [] sig->args;
+    delete [] sig->name;
+    delete sig;
+}
+
+static Trace::StructSig *
+createStructSig(const ApiStruct &str, unsigned id)
+{
+    ApiStruct::Signature aSig = str.signature();
+
+    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;
+    for (int i = 0; i < aSig.memberNames.count(); ++i) {
+        members[i] = qstrdup(aSig.memberNames[i].toLocal8Bit());
+    }
+    return sig;
+}
+
+static void
+deleteStructSig(Trace::StructSig *sig)
+{
+    for (int i = 0; i < sig->num_members; ++i) {
+        delete [] sig->members[i];
+    }
+    delete [] sig->members;
+    delete [] sig->name;
+    delete sig;
+}
+
+static Trace::EnumSig *
+createEnumSig(const ApiEnum &en, unsigned id)
+{
+    Trace::EnumSig *sig = new Trace::EnumSig();
+
+    sig->id = id;
+    sig->name = qstrdup(en.name().toLocal8Bit());
+    sig->value = en.value().toLongLong();
+
+    return sig;
+}
+
+static void
+deleteEnumSig(Trace::EnumSig *sig)
+{
+    delete [] sig->name;
+    delete sig;
+}
+
+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()];
+
+    sig->id = id;
+    sig->count = bsig.count();
+    sig->values = values;
+
+    int i = 0;
+    for (itr != bsig.constBegin(); itr != bsig.constEnd(); ++itr, ++i) {
+        values[i].name = qstrdup(itr->first.toLocal8Bit());
+        values[i].value = itr->second;
+    }
+
+    return sig;
+}
+
+static void
+deleteBitmaskSig(Trace::BitmaskSig *sig)
+{
+    for (int i = 0; i < sig->count; ++i) {
+        delete [] sig->values[i].name;
+    }
+    delete [] sig->values;
+    delete sig;
+}
+
+static void
+writeArgument(const QVariant &var, unsigned &id)
+{
+    int arrayType   = QMetaType::type("ApiArray");
+    int bitmaskType = QMetaType::type("ApiBitmask");
+    int structType  = QMetaType::type("ApiStruct");
+    int pointerType = QMetaType::type("ApiPointer");
+    int enumType    = QMetaType::type("ApiEnum");
+    int type = var.userType();
+
+    switch(type) {
+    case QVariant::Bool:
+    case QVariant::ByteArray:
+    case QVariant::Double:
+    case QVariant::Int:
+    case QVariant::LongLong:
+    case QVariant::String:
+    case QVariant::UInt:
+    case QVariant::ULongLong:
+    default:
+        if (type == arrayType) {
+            ApiArray array = var.value<ApiArray>();
+            QList<QVariant> vals = array.values();
+            Trace::BeginArray(vals.count());
+            foreach(QVariant el, vals) {
+                Trace::BeginElement();
+                writeArgument(el, ++id);
+                Trace::EndElement();
+            }
+            Trace::EndArray();
+        } else if (type == bitmaskType) {
+            ApiBitmask bm = var.value<ApiBitmask>();
+            Trace::BitmaskSig *sig = createBitmaskSig(bm, ++id);
+            LiteralBitmask(*sig, bm.value());
+            deleteBitmaskSig(sig);
+        } else if (type == structType) {
+            ApiStruct apiStr = var.value<ApiStruct>();
+            QList<QVariant> vals = apiStr.values();
+            Trace::StructSig *str = createStructSig(apiStr, ++id);
+            Trace::BeginStruct(str);
+            foreach(QVariant val, vals) {
+                writeArgument(val, ++id);
+            }
+            Trace::EndStruct();
+            deleteStructSig(str);
+        } else if (type == pointerType) {
+            ApiPointer apiPtr = var.value<ApiPointer>();
+            Trace::BeginArray(1);
+            Trace::BeginElement();
+            Trace::LiteralOpaque((const void*)apiPtr.value());
+            Trace::EndElement();
+            Trace::EndArray();
+        } else if (type == enumType) {
+            ApiEnum apiEnum = var.value<ApiEnum>();
+            Trace::EnumSig *sig = createEnumSig(apiEnum, ++id);
+            Trace::LiteralEnum(sig);
+            deleteEnumSig(sig);
+        } else if (type == QVariant::ByteArray) {
+            
+        } else {
+            qWarning()<<"Unsupported write variant : "
+                      << QMetaType::typeName(type);
+        }
+    }
+
+}
+
+
+SaverThread::SaverThread(QObject *parent)
+    : QThread(parent)
+{
+}
+
+void SaverThread::saveFile(const QString &fileName,
+                           const QList<ApiTraceCall*> &calls)
+{
+    m_fileName = fileName;
+    m_calls = calls;
+    start();
+}
+
+void SaverThread::run()
+{
+
+    Trace::Open();
+    unsigned id = 0;
+
+    for (int i = 0; i < m_calls.count(); ++i) {
+        ApiTraceCall *call = m_calls[i];
+        Trace::FunctionSig *funcSig = createFunctionSig(call, ++id);
+        unsigned callNo = BeginEnter(*funcSig);
+        {
+            //args
+            QVariantList vars = call->arguments();
+            foreach(QVariant var, vars) {
+                writeArgument(var, id);
+            }
+        }
+        Trace::EndEnter();
+        Trace::BeginLeave(callNo);
+        {
+            QVariant ret = call->returnValue();
+            if (!ret.isNull()) {
+                Trace::BeginReturn();
+                writeArgument(ret, id);
+                Trace::EndReturn();
+            }
+        }
+        Trace::EndLeave();
+
+        deleteFunctionSig(funcSig);
+    }
+
+    Trace::Close();
+
+    emit traceSaved(m_fileName);
+}
+
+#include "saverthread.moc"
diff --git a/gui/saverthread.h b/gui/saverthread.h
new file mode 100644 (file)
index 0000000..d39d51b
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef SAVERTHREAD_H
+#define SAVERTHREAD_H
+
+
+#include "apitrace.h"
+#include <QThread>
+#include <QList>
+
+class ApiTraceCall;
+class ApiTraceFrame;
+
+class SaverThread : public QThread
+{
+    Q_OBJECT
+public:
+    SaverThread(QObject *parent=0);
+
+public slots:
+    void saveFile(const QString &fileName,
+                  const QList<ApiTraceCall*> &calls);
+
+signals:
+    void traceSaved(const QString &fileName);
+
+protected:
+    virtual void run();
+
+private:
+    QString m_fileName;
+    QList<ApiTraceCall*> m_calls;
+};
+
+
+#endif