+ 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;