blob: 5ad9a91f6eb59da0466f129c3b5b8b7ac8639f6b [file] [log] [blame]
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001#include "traceloader.h"
2
Zack Rusin3176ebe2011-09-06 21:11:36 -04003#include "apitrace.h"
Zack Rusin20b1f6d2011-09-06 11:50:07 -04004#include <QDebug>
5#include <QFile>
Zack Rusind9d9d222013-10-11 18:02:26 -04006#include <QStack>
Zack Rusin20b1f6d2011-09-06 11:50:07 -04007
8#define FRAMES_TO_CACHE 100
9
10static ApiTraceCall *
José Fonsecab4a3d142011-10-27 07:43:19 +010011apiCallFromTraceCall(const trace::Call *call,
Zack Rusin20b1f6d2011-09-06 11:50:07 -040012 const QHash<QString, QUrl> &helpHash,
Zack Rusinebf971e2011-09-06 17:44:43 -040013 ApiTraceFrame *frame,
Zack Rusind9d9d222013-10-11 18:02:26 -040014 ApiTraceCall *parentCall,
Zack Rusinebf971e2011-09-06 17:44:43 -040015 TraceLoader *loader)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040016{
Zack Rusind9d9d222013-10-11 18:02:26 -040017 ApiTraceCall *apiCall;
18
19 if (parentCall)
20 apiCall = new ApiTraceCall(parentCall, loader, call);
21 else
22 apiCall = new ApiTraceCall(frame, loader, call);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040023
24 apiCall->setHelpUrl(helpHash.value(apiCall->name()));
25
26 return apiCall;
27}
28
Zack Rusinebf971e2011-09-06 17:44:43 -040029TraceLoader::TraceLoader(QObject *parent)
José Fonseca5cd8d992012-03-25 23:12:20 +010030 : QObject(parent)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040031{
32}
33
34TraceLoader::~TraceLoader()
35{
36 m_parser.close();
Zack Rusin081e59d2011-09-21 00:25:03 -040037 qDeleteAll(m_signatures);
38 qDeleteAll(m_enumSignatures);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040039}
40
41void TraceLoader::loadTrace(const QString &filename)
42{
43 if (m_helpHash.isEmpty()) {
44 loadHelpFile();
45 }
46
Zack Rusindaf82af2011-09-24 13:42:53 -040047 if (!m_frameBookmarks.isEmpty()) {
48 qDeleteAll(m_signatures);
49 qDeleteAll(m_enumSignatures);
50 m_signatures.clear();
51 m_enumSignatures.clear();
52 m_frameBookmarks.clear();
53 m_createdFrames.clear();
54 m_parser.close();
55 }
56
Zack Rusin20b1f6d2011-09-06 11:50:07 -040057 if (!m_parser.open(filename.toLatin1())) {
58 qDebug() << "error: failed to open " << filename;
59 return;
60 }
Zack Rusin59b79552011-09-21 00:37:03 -040061
Zack Rusin20b1f6d2011-09-06 11:50:07 -040062 emit startedParsing();
63
64 if (m_parser.supportsOffsets()) {
Zack Rusinac92a212011-09-06 18:25:34 -040065 scanTrace();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040066 } else {
Zack Rusinac92a212011-09-06 18:25:34 -040067 //Load the entire file into memory
68 parseTrace();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040069 }
José Fonseca67964382012-03-27 23:54:30 +010070 emit guessedApi(static_cast<int>(m_parser.api));
Zack Rusin20b1f6d2011-09-06 11:50:07 -040071 emit finishedParsing();
72}
73
Zack Rusin3176ebe2011-09-06 21:11:36 -040074void TraceLoader::loadFrame(ApiTraceFrame *currentFrame)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040075{
Zack Rusin8f98c3a2011-09-11 18:21:29 -040076 fetchFrameContents(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040077}
78
Zack Rusin20b1f6d2011-09-06 11:50:07 -040079int TraceLoader::numberOfFrames() const
80{
José Fonseca61e61f72011-09-11 16:53:34 +010081 return m_frameBookmarks.size();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040082}
83
84int TraceLoader::numberOfCallsInFrame(int frameIdx) const
85{
José Fonseca6bfa32f2012-03-22 16:26:47 +000086 if (frameIdx >= m_frameBookmarks.size()) {
Zack Rusin20b1f6d2011-09-06 11:50:07 -040087 return 0;
88 }
José Fonseca61e61f72011-09-11 16:53:34 +010089 FrameBookmarks::const_iterator itr =
90 m_frameBookmarks.find(frameIdx);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040091 return itr->numberOfCalls;
92}
93
94void TraceLoader::loadHelpFile()
95{
Zack Rusinac92a212011-09-06 18:25:34 -040096 QFile file(":/resources/glreference.tsv");
97 if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
98 QString line;
99 while (!file.atEnd()) {
100 line = file.readLine();
101 QString function = line.section('\t', 0, 0).trimmed();
102 QUrl url = QUrl(line.section('\t', 1, 1).trimmed());
103 //qDebug()<<"function = "<<function<<", url = "<<url.toString();
104 m_helpHash.insert(function, url);
105 }
106 } else {
107 qWarning() << "Couldn't open reference file "
108 << file.fileName();
109 }
110 file.close();
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400111}
112
113void TraceLoader::scanTrace()
114{
Zack Rusinac92a212011-09-06 18:25:34 -0400115 QList<ApiTraceFrame*> frames;
116 ApiTraceFrame *currentFrame = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400117
José Fonsecab4a3d142011-10-27 07:43:19 +0100118 trace::Call *call;
119 trace::ParseBookmark startBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400120 int numOfFrames = 0;
121 int numOfCalls = 0;
Zack Rusinac92a212011-09-06 18:25:34 -0400122 int lastPercentReport = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400123
José Fonseca61e61f72011-09-11 16:53:34 +0100124 m_parser.getBookmark(startBookmark);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400125
Zack Rusinac92a212011-09-06 18:25:34 -0400126 while ((call = m_parser.scan_call())) {
127 ++numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400128
José Fonseca5cd8d992012-03-25 23:12:20 +0100129 if (call->flags & trace::CALL_FLAG_END_FRAME) {
José Fonseca61e61f72011-09-11 16:53:34 +0100130 FrameBookmark frameBookmark(startBookmark);
131 frameBookmark.numberOfCalls = numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400132
Zack Rusinac92a212011-09-06 18:25:34 -0400133 currentFrame = new ApiTraceFrame();
134 currentFrame->number = numOfFrames;
135 currentFrame->setNumChildren(numOfCalls);
Zack Rusin851d0b02011-09-14 22:04:07 -0400136 currentFrame->setLastCallIndex(call->no);
Zack Rusinac92a212011-09-06 18:25:34 -0400137 frames.append(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400138
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400139 m_createdFrames.append(currentFrame);
José Fonseca61e61f72011-09-11 16:53:34 +0100140 m_frameBookmarks[numOfFrames] = frameBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400141 ++numOfFrames;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400142
Zack Rusinac92a212011-09-06 18:25:34 -0400143 if (m_parser.percentRead() - lastPercentReport >= 5) {
144 emit parsed(m_parser.percentRead());
145 lastPercentReport = m_parser.percentRead();
146 }
José Fonseca61e61f72011-09-11 16:53:34 +0100147 m_parser.getBookmark(startBookmark);
Zack Rusinac92a212011-09-06 18:25:34 -0400148 numOfCalls = 0;
149 }
Zack Rusinac92a212011-09-06 18:25:34 -0400150 delete call;
151 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400152
Zack Rusinac92a212011-09-06 18:25:34 -0400153 if (numOfCalls) {
José Fonsecab4a3d142011-10-27 07:43:19 +0100154 //trace::File::Bookmark endBookmark = m_parser.currentBookmark();
José Fonseca61e61f72011-09-11 16:53:34 +0100155 FrameBookmark frameBookmark(startBookmark);
156 frameBookmark.numberOfCalls = numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400157
Zack Rusinac92a212011-09-06 18:25:34 -0400158 currentFrame = new ApiTraceFrame();
159 currentFrame->number = numOfFrames;
160 currentFrame->setNumChildren(numOfCalls);
161 frames.append(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400162
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400163 m_createdFrames.append(currentFrame);
José Fonseca61e61f72011-09-11 16:53:34 +0100164 m_frameBookmarks[numOfFrames] = frameBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400165 ++numOfFrames;
166 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400167
Zack Rusinac92a212011-09-06 18:25:34 -0400168 emit parsed(100);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400169
Zack Rusinac92a212011-09-06 18:25:34 -0400170 emit framesLoaded(frames);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400171}
172
173void TraceLoader::parseTrace()
174{
Zack Rusinac92a212011-09-06 18:25:34 -0400175 QList<ApiTraceFrame*> frames;
176 ApiTraceFrame *currentFrame = 0;
177 int frameCount = 0;
Zack Rusind9d9d222013-10-11 18:02:26 -0400178 QStack<ApiTraceCall*> groups;
179 QVector<ApiTraceCall*> topLevelItems;
180 QVector<ApiTraceCall*> allCalls;
Zack Rusinac92a212011-09-06 18:25:34 -0400181 quint64 binaryDataSize = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400182
Zack Rusinac92a212011-09-06 18:25:34 -0400183 int lastPercentReport = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400184
José Fonsecab4a3d142011-10-27 07:43:19 +0100185 trace::Call *call = m_parser.parse_call();
Zack Rusinac92a212011-09-06 18:25:34 -0400186 while (call) {
187 //std::cout << *call;
188 if (!currentFrame) {
189 currentFrame = new ApiTraceFrame();
190 currentFrame->number = frameCount;
191 ++frameCount;
192 }
193 ApiTraceCall *apiCall =
Zack Rusind9d9d222013-10-11 18:02:26 -0400194 apiCallFromTraceCall(call, m_helpHash, currentFrame, groups.isEmpty() ? 0 : groups.top(), this);
195 allCalls.append(apiCall);
196 if (groups.count() == 0) {
197 topLevelItems.append(apiCall);
Lawrence L Love3512d982014-03-19 15:18:45 -0700198 } else {
199 groups.top()->addChild(apiCall);
Zack Rusind9d9d222013-10-11 18:02:26 -0400200 }
201 if (call->flags & trace::CALL_FLAG_MARKER_PUSH) {
202 groups.push(apiCall);
203 } else if (call->flags & trace::CALL_FLAG_MARKER_POP) {
204 groups.top()->finishedAddingChildren();
205 groups.pop();
206 }
Zack Rusinac92a212011-09-06 18:25:34 -0400207 if (apiCall->hasBinaryData()) {
208 QByteArray data =
Zack Rusind9d9d222013-10-11 18:02:26 -0400209 apiCall->arguments()[apiCall->binaryDataIndex()].toByteArray();
Zack Rusinac92a212011-09-06 18:25:34 -0400210 binaryDataSize += data.size();
211 }
José Fonseca5cd8d992012-03-25 23:12:20 +0100212 if (call->flags & trace::CALL_FLAG_END_FRAME) {
Zack Rusind9d9d222013-10-11 18:02:26 -0400213 allCalls.squeeze();
214 topLevelItems.squeeze();
215 if (topLevelItems.count() == allCalls.count()) {
216 currentFrame->setCalls(allCalls, allCalls, binaryDataSize);
217 } else {
218 currentFrame->setCalls(topLevelItems, allCalls, binaryDataSize);
219 }
220 allCalls.clear();
221 groups.clear();
222 topLevelItems.clear();
Zack Rusinac92a212011-09-06 18:25:34 -0400223 frames.append(currentFrame);
224 currentFrame = 0;
225 binaryDataSize = 0;
226 if (frames.count() >= FRAMES_TO_CACHE) {
227 emit framesLoaded(frames);
228 frames.clear();
229 }
230 if (m_parser.percentRead() - lastPercentReport >= 5) {
231 emit parsed(m_parser.percentRead());
232 lastPercentReport = m_parser.percentRead();
233 }
234 }
235 delete call;
236 call = m_parser.parse_call();
237 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400238
Zack Rusinac92a212011-09-06 18:25:34 -0400239 //last frames won't have markers
240 // it's just a bunch of Delete calls for every object
241 // after the last SwapBuffers
242 if (currentFrame) {
Zack Rusind9d9d222013-10-11 18:02:26 -0400243 allCalls.squeeze();
244 if (topLevelItems.count() == allCalls.count()) {
245 currentFrame->setCalls(allCalls, allCalls, binaryDataSize);
246 } else {
247 currentFrame->setCalls(topLevelItems, allCalls, binaryDataSize);
248 }
Zack Rusinac92a212011-09-06 18:25:34 -0400249 frames.append(currentFrame);
250 currentFrame = 0;
251 }
252 if (frames.count()) {
253 emit framesLoaded(frames);
254 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400255}
256
257
Zack Rusinebf971e2011-09-06 17:44:43 -0400258ApiTraceCallSignature * TraceLoader::signature(unsigned id)
259{
260 if (id >= m_signatures.count()) {
261 m_signatures.resize(id + 1);
262 return NULL;
263 } else {
264 return m_signatures[id];
265 }
266}
267
268void TraceLoader::addSignature(unsigned id, ApiTraceCallSignature *signature)
269{
270 m_signatures[id] = signature;
271}
272
273ApiTraceEnumSignature * TraceLoader::enumSignature(unsigned id)
274{
275 if (id >= m_enumSignatures.count()) {
276 m_enumSignatures.resize(id + 1);
277 return NULL;
278 } else {
279 return m_enumSignatures[id];
280 }
281}
282
283void TraceLoader::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature)
284{
285 m_enumSignatures[id] = signature;
286}
287
Zack Rusinad513b32011-09-25 14:33:41 -0400288void TraceLoader::searchNext(const ApiTrace::SearchRequest &request)
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400289{
290 Q_ASSERT(m_parser.supportsOffsets());
291 if (m_parser.supportsOffsets()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400292 int startFrame = m_createdFrames.indexOf(request.frame);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400293 const FrameBookmark &frameBookmark = m_frameBookmarks[startFrame];
294 m_parser.setBookmark(frameBookmark.start);
José Fonsecab4a3d142011-10-27 07:43:19 +0100295 trace::Call *call = 0;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400296 while ((call = m_parser.parse_call())) {
297
Zack Rusinad513b32011-09-25 14:33:41 -0400298 if (callContains(call, request.text, request.cs)) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400299 unsigned frameIdx = callInFrame(call->no);
300 ApiTraceFrame *frame = m_createdFrames[frameIdx];
301 const QVector<ApiTraceCall*> calls =
302 fetchFrameContents(frame);
303 for (int i = 0; i < calls.count(); ++i) {
304 if (calls[i]->index() == call->no) {
Zack Rusinad513b32011-09-25 14:33:41 -0400305 emit searchResult(request, ApiTrace::SearchResult_Found,
306 calls[i]);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400307 break;
308 }
309 }
310 delete call;
311 return;
312 }
313
314 delete call;
315 }
316 }
Zack Rusinad513b32011-09-25 14:33:41 -0400317 emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400318}
319
Zack Rusinad513b32011-09-25 14:33:41 -0400320void TraceLoader::searchPrev(const ApiTrace::SearchRequest &request)
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400321{
Zack Rusin121e3162011-09-13 01:35:12 -0400322 Q_ASSERT(m_parser.supportsOffsets());
323 if (m_parser.supportsOffsets()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400324 int startFrame = m_createdFrames.indexOf(request.frame);
José Fonsecab4a3d142011-10-27 07:43:19 +0100325 trace::Call *call = 0;
326 QList<trace::Call*> frameCalls;
Zack Rusin121e3162011-09-13 01:35:12 -0400327 int frameIdx = startFrame;
328
329 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
330 int numCallsToParse = frameBookmark.numberOfCalls;
331 m_parser.setBookmark(frameBookmark.start);
332
333 while ((call = m_parser.parse_call())) {
334
335 frameCalls.append(call);
336 --numCallsToParse;
337
338 if (numCallsToParse == 0) {
339 bool foundCall = searchCallsBackwards(frameCalls,
340 frameIdx,
Zack Rusinad513b32011-09-25 14:33:41 -0400341 request);
Zack Rusin121e3162011-09-13 01:35:12 -0400342
343 qDeleteAll(frameCalls);
344 frameCalls.clear();
345 if (foundCall) {
346 return;
347 }
348
349 --frameIdx;
350
351 if (frameIdx >= 0) {
352 const FrameBookmark &frameBookmark =
353 m_frameBookmarks[frameIdx];
354 m_parser.setBookmark(frameBookmark.start);
355 numCallsToParse = frameBookmark.numberOfCalls;
356 }
357 }
358 }
359 }
Zack Rusinad513b32011-09-25 14:33:41 -0400360 emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
Zack Rusin121e3162011-09-13 01:35:12 -0400361}
362
José Fonsecab4a3d142011-10-27 07:43:19 +0100363bool TraceLoader::searchCallsBackwards(const QList<trace::Call*> &calls,
Zack Rusin121e3162011-09-13 01:35:12 -0400364 int frameIdx,
Zack Rusinad513b32011-09-25 14:33:41 -0400365 const ApiTrace::SearchRequest &request)
Zack Rusin121e3162011-09-13 01:35:12 -0400366{
367 for (int i = calls.count() - 1; i >= 0; --i) {
José Fonsecab4a3d142011-10-27 07:43:19 +0100368 trace::Call *call = calls[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400369 if (callContains(call, request.text, request.cs)) {
Zack Rusin121e3162011-09-13 01:35:12 -0400370 ApiTraceFrame *frame = m_createdFrames[frameIdx];
371 const QVector<ApiTraceCall*> apiCalls =
372 fetchFrameContents(frame);
373 for (int i = 0; i < apiCalls.count(); ++i) {
374 if (apiCalls[i]->index() == call->no) {
Zack Rusinad513b32011-09-25 14:33:41 -0400375 emit searchResult(request,
376 ApiTrace::SearchResult_Found,
377 apiCalls[i]);
Zack Rusin121e3162011-09-13 01:35:12 -0400378 break;
379 }
380 }
381 return true;
382 }
383 }
384 return false;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400385}
386
387int TraceLoader::callInFrame(int callIdx) const
388{
389 unsigned numCalls = 0;
390
José Fonseca6bfa32f2012-03-22 16:26:47 +0000391 for (int frameIdx = 0; frameIdx < m_frameBookmarks.size(); ++frameIdx) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400392 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
393 unsigned firstCall = numCalls;
394 unsigned endCall = numCalls + frameBookmark.numberOfCalls;
395 if (firstCall <= callIdx && endCall > callIdx) {
396 return frameIdx;
397 }
398 numCalls = endCall;
399 }
400 Q_ASSERT(!"call not in the trace");
401 return 0;
402}
403
José Fonsecab4a3d142011-10-27 07:43:19 +0100404bool TraceLoader::callContains(trace::Call *call,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400405 const QString &str,
406 Qt::CaseSensitivity sensitivity)
407{
José Fonsecacb7c76f2014-03-27 16:57:22 +0000408 /*
409 * FIXME: do string comparison directly on trace::Call
410 */
411 ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash,
412 0, 0, this);
413 bool result = apiCall->contains(str, sensitivity);
414 delete apiCall;
415 return result;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400416}
417
418QVector<ApiTraceCall*>
419TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame)
420{
421 Q_ASSERT(currentFrame);
Zack Rusin99f84fa2011-09-19 23:44:25 -0400422
Zack Rusin447f4a52011-09-19 23:45:39 -0400423 if (currentFrame->isLoaded()) {
Zack Rusin99f84fa2011-09-19 23:44:25 -0400424 return currentFrame->calls();
425 }
426
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400427 if (m_parser.supportsOffsets()) {
428 unsigned frameIdx = currentFrame->number;
429 int numOfCalls = numberOfCallsInFrame(frameIdx);
430
431 if (numOfCalls) {
432 quint64 binaryDataSize = 0;
Zack Rusind9d9d222013-10-11 18:02:26 -0400433 QStack<ApiTraceCall*> groups;
434 QVector<ApiTraceCall*> topLevelItems;
435 QVector<ApiTraceCall*> allCalls(numOfCalls);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400436 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
437
438 m_parser.setBookmark(frameBookmark.start);
439
José Fonsecab4a3d142011-10-27 07:43:19 +0100440 trace::Call *call;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400441 int parsedCalls = 0;
442 while ((call = m_parser.parse_call())) {
443 ApiTraceCall *apiCall =
444 apiCallFromTraceCall(call, m_helpHash,
Zack Rusind9d9d222013-10-11 18:02:26 -0400445 currentFrame, groups.isEmpty() ? 0 : groups.top(), this);
José Fonsecacaa84282013-04-11 18:54:06 +0100446 Q_ASSERT(apiCall);
José Fonseca77127372013-10-14 15:44:11 -0700447 Q_ASSERT(parsedCalls < allCalls.size());
Zack Rusind9d9d222013-10-11 18:02:26 -0400448 allCalls[parsedCalls++] = apiCall;
449 if (groups.count() == 0) {
450 topLevelItems.append(apiCall);
Lawrence L Lovec0dd0982014-02-21 10:03:44 -0800451 } else {
Zack Rusind9d9d222013-10-11 18:02:26 -0400452 groups.top()->addChild(apiCall);
453 }
454 if (call->flags & trace::CALL_FLAG_MARKER_PUSH) {
455 groups.push(apiCall);
456 } else if (call->flags & trace::CALL_FLAG_MARKER_POP) {
Lawrence L Lovec0dd0982014-02-21 10:03:44 -0800457 if (groups.count()) {
458 groups.top()->finishedAddingChildren();
459 groups.pop();
460 }
Zack Rusind9d9d222013-10-11 18:02:26 -0400461 }
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400462 if (apiCall->hasBinaryData()) {
463 QByteArray data =
464 apiCall->arguments()[
465 apiCall->binaryDataIndex()].toByteArray();
466 binaryDataSize += data.size();
467 }
468
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400469 delete call;
470
José Fonseca5cd8d992012-03-25 23:12:20 +0100471 if (apiCall->flags() & trace::CALL_FLAG_END_FRAME) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400472 break;
473 }
474
475 }
José Fonsecacaa84282013-04-11 18:54:06 +0100476 // There can be fewer parsed calls when call in different
477 // threads cross the frame boundary
478 Q_ASSERT(parsedCalls <= numOfCalls);
José Fonseca77127372013-10-14 15:44:11 -0700479 Q_ASSERT(parsedCalls <= allCalls.size());
Zack Rusind9d9d222013-10-11 18:02:26 -0400480 allCalls.resize(parsedCalls);
481 allCalls.squeeze();
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400482
José Fonsecacaa84282013-04-11 18:54:06 +0100483 Q_ASSERT(parsedCalls <= currentFrame->numChildrenToLoad());
Zack Rusind9d9d222013-10-11 18:02:26 -0400484 if (topLevelItems.count() == allCalls.count()) {
485 emit frameContentsLoaded(currentFrame, allCalls,
486 allCalls, binaryDataSize);
487 } else {
488 emit frameContentsLoaded(currentFrame, topLevelItems,
489 allCalls, binaryDataSize);
490 }
491 return allCalls;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400492 }
493 }
494 return QVector<ApiTraceCall*>();
495}
496
Zack Rusin93e4d152011-09-13 02:23:39 -0400497void TraceLoader::findFrameStart(ApiTraceFrame *frame)
498{
Zack Rusin99f84fa2011-09-19 23:44:25 -0400499 if (!frame->isLoaded()) {
500 loadFrame(frame);
501 }
Zack Rusin93e4d152011-09-13 02:23:39 -0400502 emit foundFrameStart(frame);
503}
504
505void TraceLoader::findFrameEnd(ApiTraceFrame *frame)
506{
Zack Rusin99f84fa2011-09-19 23:44:25 -0400507 if (!frame->isLoaded()) {
508 loadFrame(frame);
509 }
Zack Rusin93e4d152011-09-13 02:23:39 -0400510 emit foundFrameEnd(frame);
511}
512
Zack Rusinda7579b2011-09-13 17:33:05 -0400513void TraceLoader::findCallIndex(int index)
514{
515 int frameIdx = callInFrame(index);
516 ApiTraceFrame *frame = m_createdFrames[frameIdx];
517 QVector<ApiTraceCall*> calls = fetchFrameContents(frame);
518 QVector<ApiTraceCall*>::const_iterator itr;
519 ApiTraceCall *call = 0;
520 for (itr = calls.constBegin(); itr != calls.constEnd(); ++itr) {
521 if ((*itr)->index() == index) {
522 call = *itr;
Lawrence L Love53a40802014-02-12 15:26:55 -0800523 break;
Zack Rusinda7579b2011-09-13 17:33:05 -0400524 }
525 }
José Fonsecacaa84282013-04-11 18:54:06 +0100526 if (call) {
527 emit foundCallIndex(call);
528 }
Zack Rusinda7579b2011-09-13 17:33:05 -0400529}
530
Zack Rusinad513b32011-09-25 14:33:41 -0400531void TraceLoader::search(const ApiTrace::SearchRequest &request)
532{
533 if (request.direction == ApiTrace::SearchRequest::Next) {
534 searchNext(request);
535 } else {
536 searchPrev(request);
537 }
538}
539
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400540#include "traceloader.moc"