]> git.cworth.org Git - apitrace/blobdiff - gui/traceloader.cpp
Attempt to allow to control image dynamic range.
[apitrace] / gui / traceloader.cpp
index 11847fff975b4ed5386df43ce41c191f9eb5142a..7cb07f00aa1331e814c6d7025deffe76498a36fc 100644 (file)
@@ -7,7 +7,7 @@
 #define FRAMES_TO_CACHE 100
 
 static ApiTraceCall *
-apiCallFromTraceCall(const Trace::Call *call,
+apiCallFromTraceCall(const trace::Call *call,
                      const QHash<QString, QUrl> &helpHash,
                      ApiTraceFrame *frame,
                      TraceLoader *loader)
@@ -28,6 +28,8 @@ TraceLoader::TraceLoader(QObject *parent)
 TraceLoader::~TraceLoader()
 {
     m_parser.close();
+    qDeleteAll(m_signatures);
+    qDeleteAll(m_enumSignatures);
 }
 
 void TraceLoader::loadTrace(const QString &filename)
@@ -36,21 +38,29 @@ void TraceLoader::loadTrace(const QString &filename)
         loadHelpFile();
     }
 
+    if (!m_frameBookmarks.isEmpty()) {
+        qDeleteAll(m_signatures);
+        qDeleteAll(m_enumSignatures);
+        m_signatures.clear();
+        m_enumSignatures.clear();
+        m_frameBookmarks.clear();
+        m_createdFrames.clear();
+        m_parser.close();
+    }
+
     if (!m_parser.open(filename.toLatin1())) {
         qDebug() << "error: failed to open " << filename;
         return;
     }
-    qDebug()<<"load trace with "<<filename;
+
     emit startedParsing();
 
-    qDebug() <<"\t support offsets = "<<m_parser.supportsOffsets();
     if (m_parser.supportsOffsets()) {
         scanTrace();
     } else {
         //Load the entire file into memory
         parseTrace();
     }
-
     emit finishedParsing();
 }
 
@@ -64,7 +74,7 @@ void TraceLoader::setFrameMarker(ApiTrace::FrameMarker marker)
     m_frameMarker = marker;
 }
 
-bool TraceLoader::isCallAFrameMarker(const Trace::Call *call) const
+bool TraceLoader::isCallAFrameMarker(const trace::Call *call) const
 {
     std::string name = call->name();
 
@@ -126,8 +136,8 @@ void TraceLoader::scanTrace()
     QList<ApiTraceFrame*> frames;
     ApiTraceFrame *currentFrame = 0;
 
-    Trace::Call *call;
-    Trace::ParseBookmark startBookmark;
+    trace::Call *call;
+    trace::ParseBookmark startBookmark;
     int numOfFrames = 0;
     int numOfCalls = 0;
     int lastPercentReport = 0;
@@ -144,6 +154,7 @@ void TraceLoader::scanTrace()
             currentFrame = new ApiTraceFrame();
             currentFrame->number = numOfFrames;
             currentFrame->setNumChildren(numOfCalls);
+            currentFrame->setLastCallIndex(call->no);
             frames.append(currentFrame);
 
             m_createdFrames.append(currentFrame);
@@ -161,7 +172,7 @@ void TraceLoader::scanTrace()
     }
 
     if (numOfCalls) {
-        //Trace::File::Bookmark endBookmark = m_parser.currentBookmark();
+        //trace::File::Bookmark endBookmark = m_parser.currentBookmark();
         FrameBookmark frameBookmark(startBookmark);
         frameBookmark.numberOfCalls = numOfCalls;
 
@@ -190,7 +201,7 @@ void TraceLoader::parseTrace()
 
     int lastPercentReport = 0;
 
-    Trace::Call *call = m_parser.parse_call();
+    trace::Call *call = m_parser.parse_call();
     while (call) {
         //std::cout << *call;
         if (!currentFrame) {
@@ -272,25 +283,25 @@ void TraceLoader::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature
     m_enumSignatures[id] = signature;
 }
 
-void TraceLoader::searchNext(int startFrame,
-                             const QString &str,
-                             Qt::CaseSensitivity sensitivity)
+void TraceLoader::searchNext(const ApiTrace::SearchRequest &request)
 {
     Q_ASSERT(m_parser.supportsOffsets());
     if (m_parser.supportsOffsets()) {
+        int startFrame = m_createdFrames.indexOf(request.frame);
         const FrameBookmark &frameBookmark = m_frameBookmarks[startFrame];
         m_parser.setBookmark(frameBookmark.start);
-        Trace::Call *call = 0;
+        trace::Call *call = 0;
         while ((call = m_parser.parse_call())) {
 
-            if (callContains(call, str, sensitivity)) {
+            if (callContains(call, request.text, request.cs)) {
                 unsigned frameIdx = callInFrame(call->no);
                 ApiTraceFrame *frame = m_createdFrames[frameIdx];
                 const QVector<ApiTraceCall*> calls =
                         fetchFrameContents(frame);
                 for (int i = 0; i < calls.count(); ++i) {
                     if (calls[i]->index() == call->no) {
-                        emit searchResult(ApiTrace::SearchFound, calls[i]);
+                        emit searchResult(request, ApiTrace::SearchResult_Found,
+                                          calls[i]);
                         break;
                     }
                 }
@@ -301,13 +312,74 @@ void TraceLoader::searchNext(int startFrame,
             delete call;
         }
     }
-    emit searchResult(ApiTrace::SearchNotFound, 0);
+    emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
 }
 
-void TraceLoader::searchPrev(int startFrame,
-                             const QString &str,
-                             Qt::CaseSensitivity sensitivity)
+void TraceLoader::searchPrev(const ApiTrace::SearchRequest &request)
 {
+    Q_ASSERT(m_parser.supportsOffsets());
+    if (m_parser.supportsOffsets()) {
+        int startFrame = m_createdFrames.indexOf(request.frame);
+        trace::Call *call = 0;
+        QList<trace::Call*> frameCalls;
+        int frameIdx = startFrame;
+
+        const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
+        int numCallsToParse = frameBookmark.numberOfCalls;
+        m_parser.setBookmark(frameBookmark.start);
+
+        while ((call = m_parser.parse_call())) {
+
+            frameCalls.append(call);
+            --numCallsToParse;
+
+            if (numCallsToParse == 0) {
+                bool foundCall = searchCallsBackwards(frameCalls,
+                                                      frameIdx,
+                                                      request);
+
+                qDeleteAll(frameCalls);
+                frameCalls.clear();
+                if (foundCall) {
+                    return;
+                }
+
+                --frameIdx;
+
+                if (frameIdx >= 0) {
+                    const FrameBookmark &frameBookmark =
+                            m_frameBookmarks[frameIdx];
+                    m_parser.setBookmark(frameBookmark.start);
+                    numCallsToParse = frameBookmark.numberOfCalls;
+                }
+            }
+        }
+    }
+    emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
+}
+
+bool TraceLoader::searchCallsBackwards(const QList<trace::Call*> &calls,
+                                       int frameIdx,
+                                       const ApiTrace::SearchRequest &request)
+{
+    for (int i = calls.count() - 1; i >= 0; --i) {
+        trace::Call *call = calls[i];
+        if (callContains(call, request.text, request.cs)) {
+            ApiTraceFrame *frame = m_createdFrames[frameIdx];
+            const QVector<ApiTraceCall*> apiCalls =
+                    fetchFrameContents(frame);
+            for (int i = 0; i < apiCalls.count(); ++i) {
+                if (apiCalls[i]->index() == call->no) {
+                    emit searchResult(request,
+                                      ApiTrace::SearchResult_Found,
+                                      apiCalls[i]);
+                    break;
+                }
+            }
+            return true;
+        }
+    }
+    return false;
 }
 
 int TraceLoader::callInFrame(int callIdx) const
@@ -327,12 +399,12 @@ int TraceLoader::callInFrame(int callIdx) const
     return 0;
 }
 
-bool TraceLoader::callContains(Trace::Call *call,
+bool TraceLoader::callContains(trace::Call *call,
                                const QString &str,
                                Qt::CaseSensitivity sensitivity)
 {
     /*
-     * FIXME: do string comparison directly on Trace::Call
+     * FIXME: do string comparison directly on trace::Call
      */
     ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash,
                                                  0, this);
@@ -345,6 +417,11 @@ QVector<ApiTraceCall*>
 TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame)
 {
     Q_ASSERT(currentFrame);
+
+    if (currentFrame->isLoaded()) {
+        return currentFrame->calls();
+    }
+
     if (m_parser.supportsOffsets()) {
         unsigned frameIdx = currentFrame->number;
         int numOfCalls = numberOfCallsInFrame(frameIdx);
@@ -356,7 +433,7 @@ TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame)
 
             m_parser.setBookmark(frameBookmark.start);
 
-            Trace::Call *call;
+            trace::Call *call;
             int parsedCalls = 0;
             while ((call = m_parser.parse_call())) {
                 ApiTraceCall *apiCall =
@@ -393,4 +470,45 @@ TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame)
     return QVector<ApiTraceCall*>();
 }
 
+void TraceLoader::findFrameStart(ApiTraceFrame *frame)
+{
+    if (!frame->isLoaded()) {
+        loadFrame(frame);
+    }
+    emit foundFrameStart(frame);
+}
+
+void TraceLoader::findFrameEnd(ApiTraceFrame *frame)
+{
+    if (!frame->isLoaded()) {
+        loadFrame(frame);
+    }
+    emit foundFrameEnd(frame);
+}
+
+void TraceLoader::findCallIndex(int index)
+{
+    int frameIdx = callInFrame(index);
+    ApiTraceFrame *frame = m_createdFrames[frameIdx];
+    QVector<ApiTraceCall*> calls = fetchFrameContents(frame);
+    QVector<ApiTraceCall*>::const_iterator itr;
+    ApiTraceCall *call = 0;
+    for (itr = calls.constBegin(); itr != calls.constEnd(); ++itr) {
+        if ((*itr)->index() == index) {
+            call = *itr;
+        }
+    }
+    Q_ASSERT(call);
+    emit foundCallIndex(call);
+}
+
+void TraceLoader::search(const ApiTrace::SearchRequest &request)
+{
+    if (request.direction == ApiTrace::SearchRequest::Next) {
+        searchNext(request);
+    } else {
+        searchPrev(request);
+    }
+}
+
 #include "traceloader.moc"