blob: 59f8803e386077e67a2143cf163c688ed2b9349f [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>
6
7#define FRAMES_TO_CACHE 100
8
9static ApiTraceCall *
José Fonsecab4a3d142011-10-27 07:43:19 +010010apiCallFromTraceCall(const trace::Call *call,
Zack Rusin20b1f6d2011-09-06 11:50:07 -040011 const QHash<QString, QUrl> &helpHash,
Zack Rusinebf971e2011-09-06 17:44:43 -040012 ApiTraceFrame *frame,
Zack Rusind9d9d222013-10-11 18:02:26 -040013 ApiTraceCall *parentCall,
Zack Rusinebf971e2011-09-06 17:44:43 -040014 TraceLoader *loader)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040015{
Zack Rusind9d9d222013-10-11 18:02:26 -040016 ApiTraceCall *apiCall;
17
18 if (parentCall)
19 apiCall = new ApiTraceCall(parentCall, loader, call);
20 else
21 apiCall = new ApiTraceCall(frame, loader, call);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040022
23 apiCall->setHelpUrl(helpHash.value(apiCall->name()));
24
25 return apiCall;
26}
27
Zack Rusinebf971e2011-09-06 17:44:43 -040028TraceLoader::TraceLoader(QObject *parent)
José Fonseca5cd8d992012-03-25 23:12:20 +010029 : QObject(parent)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040030{
31}
32
33TraceLoader::~TraceLoader()
34{
35 m_parser.close();
Zack Rusin081e59d2011-09-21 00:25:03 -040036 qDeleteAll(m_signatures);
37 qDeleteAll(m_enumSignatures);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040038}
39
40void TraceLoader::loadTrace(const QString &filename)
41{
42 if (m_helpHash.isEmpty()) {
43 loadHelpFile();
44 }
45
Zack Rusindaf82af2011-09-24 13:42:53 -040046 if (!m_frameBookmarks.isEmpty()) {
47 qDeleteAll(m_signatures);
48 qDeleteAll(m_enumSignatures);
49 m_signatures.clear();
50 m_enumSignatures.clear();
51 m_frameBookmarks.clear();
52 m_createdFrames.clear();
53 m_parser.close();
54 }
55
Zack Rusin20b1f6d2011-09-06 11:50:07 -040056 if (!m_parser.open(filename.toLatin1())) {
57 qDebug() << "error: failed to open " << filename;
58 return;
59 }
Zack Rusin59b79552011-09-21 00:37:03 -040060
Zack Rusin20b1f6d2011-09-06 11:50:07 -040061 emit startedParsing();
62
63 if (m_parser.supportsOffsets()) {
Zack Rusinac92a212011-09-06 18:25:34 -040064 scanTrace();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040065 } else {
Zack Rusinac92a212011-09-06 18:25:34 -040066 //Load the entire file into memory
67 parseTrace();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040068 }
José Fonseca67964382012-03-27 23:54:30 +010069 emit guessedApi(static_cast<int>(m_parser.api));
Zack Rusin20b1f6d2011-09-06 11:50:07 -040070 emit finishedParsing();
71}
72
Zack Rusin3176ebe2011-09-06 21:11:36 -040073void TraceLoader::loadFrame(ApiTraceFrame *currentFrame)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040074{
Zack Rusin8f98c3a2011-09-11 18:21:29 -040075 fetchFrameContents(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040076}
77
Zack Rusin20b1f6d2011-09-06 11:50:07 -040078int TraceLoader::numberOfFrames() const
79{
José Fonseca61e61f72011-09-11 16:53:34 +010080 return m_frameBookmarks.size();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040081}
82
83int TraceLoader::numberOfCallsInFrame(int frameIdx) const
84{
José Fonseca6bfa32f2012-03-22 16:26:47 +000085 if (frameIdx >= m_frameBookmarks.size()) {
Zack Rusin20b1f6d2011-09-06 11:50:07 -040086 return 0;
87 }
José Fonseca61e61f72011-09-11 16:53:34 +010088 FrameBookmarks::const_iterator itr =
89 m_frameBookmarks.find(frameIdx);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040090 return itr->numberOfCalls;
91}
92
93void TraceLoader::loadHelpFile()
94{
Zack Rusinac92a212011-09-06 18:25:34 -040095 QFile file(":/resources/glreference.tsv");
96 if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
97 QString line;
98 while (!file.atEnd()) {
99 line = file.readLine();
100 QString function = line.section('\t', 0, 0).trimmed();
101 QUrl url = QUrl(line.section('\t', 1, 1).trimmed());
102 //qDebug()<<"function = "<<function<<", url = "<<url.toString();
103 m_helpHash.insert(function, url);
104 }
105 } else {
106 qWarning() << "Couldn't open reference file "
107 << file.fileName();
108 }
109 file.close();
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400110}
111
112void TraceLoader::scanTrace()
113{
Zack Rusinac92a212011-09-06 18:25:34 -0400114 QList<ApiTraceFrame*> frames;
115 ApiTraceFrame *currentFrame = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400116
José Fonsecab4a3d142011-10-27 07:43:19 +0100117 trace::Call *call;
118 trace::ParseBookmark startBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400119 int numOfFrames = 0;
120 int numOfCalls = 0;
Zack Rusinac92a212011-09-06 18:25:34 -0400121 int lastPercentReport = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400122
José Fonseca61e61f72011-09-11 16:53:34 +0100123 m_parser.getBookmark(startBookmark);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400124
Zack Rusinac92a212011-09-06 18:25:34 -0400125 while ((call = m_parser.scan_call())) {
126 ++numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400127
José Fonseca5cd8d992012-03-25 23:12:20 +0100128 if (call->flags & trace::CALL_FLAG_END_FRAME) {
José Fonseca61e61f72011-09-11 16:53:34 +0100129 FrameBookmark frameBookmark(startBookmark);
130 frameBookmark.numberOfCalls = numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400131
Zack Rusinac92a212011-09-06 18:25:34 -0400132 currentFrame = new ApiTraceFrame();
133 currentFrame->number = numOfFrames;
134 currentFrame->setNumChildren(numOfCalls);
Zack Rusin851d0b02011-09-14 22:04:07 -0400135 currentFrame->setLastCallIndex(call->no);
Zack Rusinac92a212011-09-06 18:25:34 -0400136 frames.append(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400137
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400138 m_createdFrames.append(currentFrame);
José Fonseca61e61f72011-09-11 16:53:34 +0100139 m_frameBookmarks[numOfFrames] = frameBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400140 ++numOfFrames;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400141
Zack Rusinac92a212011-09-06 18:25:34 -0400142 if (m_parser.percentRead() - lastPercentReport >= 5) {
143 emit parsed(m_parser.percentRead());
144 lastPercentReport = m_parser.percentRead();
145 }
José Fonseca61e61f72011-09-11 16:53:34 +0100146 m_parser.getBookmark(startBookmark);
Zack Rusinac92a212011-09-06 18:25:34 -0400147 numOfCalls = 0;
148 }
Zack Rusinac92a212011-09-06 18:25:34 -0400149 delete call;
150 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400151
Zack Rusinac92a212011-09-06 18:25:34 -0400152 if (numOfCalls) {
José Fonsecab4a3d142011-10-27 07:43:19 +0100153 //trace::File::Bookmark endBookmark = m_parser.currentBookmark();
José Fonseca61e61f72011-09-11 16:53:34 +0100154 FrameBookmark frameBookmark(startBookmark);
155 frameBookmark.numberOfCalls = numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400156
Zack Rusinac92a212011-09-06 18:25:34 -0400157 currentFrame = new ApiTraceFrame();
158 currentFrame->number = numOfFrames;
159 currentFrame->setNumChildren(numOfCalls);
160 frames.append(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400161
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400162 m_createdFrames.append(currentFrame);
José Fonseca61e61f72011-09-11 16:53:34 +0100163 m_frameBookmarks[numOfFrames] = frameBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400164 ++numOfFrames;
165 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400166
Zack Rusinac92a212011-09-06 18:25:34 -0400167 emit parsed(100);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400168
Zack Rusinac92a212011-09-06 18:25:34 -0400169 emit framesLoaded(frames);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400170}
171
172void TraceLoader::parseTrace()
173{
Zack Rusinac92a212011-09-06 18:25:34 -0400174 QList<ApiTraceFrame*> frames;
Zack Rusinac92a212011-09-06 18:25:34 -0400175 int frameCount = 0;
Zack Rusinac92a212011-09-06 18:25:34 -0400176 int lastPercentReport = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400177
Lawrence L Love59befce2014-03-20 18:47:39 -0700178 ApiTraceFrame *currentFrame = new ApiTraceFrame();
179 currentFrame->number = frameCount;
180
181 FrameContents frameCalls;
182 while (frameCalls.load(this, currentFrame, m_helpHash, m_parser)) {
183
184 if (frameCalls.topLevelCount() == frameCalls.allCallsCount()) {
185 currentFrame->setCalls(frameCalls.allCalls(),
186 frameCalls.allCalls(),
187 frameCalls.binaryDataSize());
Lawrence L Love3512d982014-03-19 15:18:45 -0700188 } else {
Lawrence L Love59befce2014-03-20 18:47:39 -0700189 currentFrame->setCalls(frameCalls.topLevelCalls(),
190 frameCalls.allCalls(),
191 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400192 }
Lawrence L Love59befce2014-03-20 18:47:39 -0700193 frames.append(currentFrame);
194 if (frames.count() >= FRAMES_TO_CACHE) {
195 emit framesLoaded(frames);
196 frames.clear();
Zack Rusind9d9d222013-10-11 18:02:26 -0400197 }
Lawrence L Love59befce2014-03-20 18:47:39 -0700198 if (m_parser.percentRead() - lastPercentReport >= 5) {
199 emit parsed(m_parser.percentRead());
200 lastPercentReport = m_parser.percentRead();
Zack Rusinac92a212011-09-06 18:25:34 -0400201 }
Lawrence L Love59befce2014-03-20 18:47:39 -0700202 ++frameCount;
203 currentFrame = new ApiTraceFrame();
204 currentFrame->number = frameCount;
205
206 frameCalls.reset();
Zack Rusinac92a212011-09-06 18:25:34 -0400207 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400208
Zack Rusinac92a212011-09-06 18:25:34 -0400209 //last frames won't have markers
210 // it's just a bunch of Delete calls for every object
211 // after the last SwapBuffers
Lawrence L Love59befce2014-03-20 18:47:39 -0700212 if (!frameCalls.isEmpty()) {
213 if (frameCalls.topLevelCount() == frameCalls.allCallsCount()) {
214 currentFrame->setCalls(frameCalls.allCalls(),
215 frameCalls.allCalls(),
216 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400217 } else {
Lawrence L Love59befce2014-03-20 18:47:39 -0700218 currentFrame->setCalls(frameCalls.topLevelCalls(),
219 frameCalls.allCalls(),
220 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400221 }
Zack Rusinac92a212011-09-06 18:25:34 -0400222 frames.append(currentFrame);
Zack Rusinac92a212011-09-06 18:25:34 -0400223 }
224 if (frames.count()) {
225 emit framesLoaded(frames);
226 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400227}
228
229
Zack Rusinebf971e2011-09-06 17:44:43 -0400230ApiTraceCallSignature * TraceLoader::signature(unsigned id)
231{
232 if (id >= m_signatures.count()) {
233 m_signatures.resize(id + 1);
234 return NULL;
235 } else {
236 return m_signatures[id];
237 }
238}
239
240void TraceLoader::addSignature(unsigned id, ApiTraceCallSignature *signature)
241{
242 m_signatures[id] = signature;
243}
244
245ApiTraceEnumSignature * TraceLoader::enumSignature(unsigned id)
246{
247 if (id >= m_enumSignatures.count()) {
248 m_enumSignatures.resize(id + 1);
249 return NULL;
250 } else {
251 return m_enumSignatures[id];
252 }
253}
254
255void TraceLoader::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature)
256{
257 m_enumSignatures[id] = signature;
258}
259
Zack Rusinad513b32011-09-25 14:33:41 -0400260void TraceLoader::searchNext(const ApiTrace::SearchRequest &request)
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400261{
262 Q_ASSERT(m_parser.supportsOffsets());
263 if (m_parser.supportsOffsets()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400264 int startFrame = m_createdFrames.indexOf(request.frame);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400265 const FrameBookmark &frameBookmark = m_frameBookmarks[startFrame];
266 m_parser.setBookmark(frameBookmark.start);
José Fonsecab4a3d142011-10-27 07:43:19 +0100267 trace::Call *call = 0;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400268 while ((call = m_parser.parse_call())) {
269
Zack Rusinad513b32011-09-25 14:33:41 -0400270 if (callContains(call, request.text, request.cs)) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400271 unsigned frameIdx = callInFrame(call->no);
272 ApiTraceFrame *frame = m_createdFrames[frameIdx];
273 const QVector<ApiTraceCall*> calls =
274 fetchFrameContents(frame);
275 for (int i = 0; i < calls.count(); ++i) {
276 if (calls[i]->index() == call->no) {
Zack Rusinad513b32011-09-25 14:33:41 -0400277 emit searchResult(request, ApiTrace::SearchResult_Found,
278 calls[i]);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400279 break;
280 }
281 }
282 delete call;
283 return;
284 }
285
286 delete call;
287 }
288 }
Zack Rusinad513b32011-09-25 14:33:41 -0400289 emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400290}
291
Zack Rusinad513b32011-09-25 14:33:41 -0400292void TraceLoader::searchPrev(const ApiTrace::SearchRequest &request)
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400293{
Zack Rusin121e3162011-09-13 01:35:12 -0400294 Q_ASSERT(m_parser.supportsOffsets());
295 if (m_parser.supportsOffsets()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400296 int startFrame = m_createdFrames.indexOf(request.frame);
José Fonsecab4a3d142011-10-27 07:43:19 +0100297 trace::Call *call = 0;
298 QList<trace::Call*> frameCalls;
Zack Rusin121e3162011-09-13 01:35:12 -0400299 int frameIdx = startFrame;
300
301 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
302 int numCallsToParse = frameBookmark.numberOfCalls;
303 m_parser.setBookmark(frameBookmark.start);
304
305 while ((call = m_parser.parse_call())) {
306
307 frameCalls.append(call);
308 --numCallsToParse;
309
310 if (numCallsToParse == 0) {
311 bool foundCall = searchCallsBackwards(frameCalls,
312 frameIdx,
Zack Rusinad513b32011-09-25 14:33:41 -0400313 request);
Zack Rusin121e3162011-09-13 01:35:12 -0400314
315 qDeleteAll(frameCalls);
316 frameCalls.clear();
317 if (foundCall) {
318 return;
319 }
320
321 --frameIdx;
322
323 if (frameIdx >= 0) {
324 const FrameBookmark &frameBookmark =
325 m_frameBookmarks[frameIdx];
326 m_parser.setBookmark(frameBookmark.start);
327 numCallsToParse = frameBookmark.numberOfCalls;
328 }
329 }
330 }
331 }
Zack Rusinad513b32011-09-25 14:33:41 -0400332 emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
Zack Rusin121e3162011-09-13 01:35:12 -0400333}
334
José Fonsecab4a3d142011-10-27 07:43:19 +0100335bool TraceLoader::searchCallsBackwards(const QList<trace::Call*> &calls,
Zack Rusin121e3162011-09-13 01:35:12 -0400336 int frameIdx,
Zack Rusinad513b32011-09-25 14:33:41 -0400337 const ApiTrace::SearchRequest &request)
Zack Rusin121e3162011-09-13 01:35:12 -0400338{
339 for (int i = calls.count() - 1; i >= 0; --i) {
José Fonsecab4a3d142011-10-27 07:43:19 +0100340 trace::Call *call = calls[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400341 if (callContains(call, request.text, request.cs)) {
Zack Rusin121e3162011-09-13 01:35:12 -0400342 ApiTraceFrame *frame = m_createdFrames[frameIdx];
343 const QVector<ApiTraceCall*> apiCalls =
344 fetchFrameContents(frame);
345 for (int i = 0; i < apiCalls.count(); ++i) {
346 if (apiCalls[i]->index() == call->no) {
Zack Rusinad513b32011-09-25 14:33:41 -0400347 emit searchResult(request,
348 ApiTrace::SearchResult_Found,
349 apiCalls[i]);
Zack Rusin121e3162011-09-13 01:35:12 -0400350 break;
351 }
352 }
353 return true;
354 }
355 }
356 return false;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400357}
358
359int TraceLoader::callInFrame(int callIdx) const
360{
361 unsigned numCalls = 0;
362
José Fonseca6bfa32f2012-03-22 16:26:47 +0000363 for (int frameIdx = 0; frameIdx < m_frameBookmarks.size(); ++frameIdx) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400364 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
365 unsigned firstCall = numCalls;
366 unsigned endCall = numCalls + frameBookmark.numberOfCalls;
367 if (firstCall <= callIdx && endCall > callIdx) {
368 return frameIdx;
369 }
370 numCalls = endCall;
371 }
372 Q_ASSERT(!"call not in the trace");
373 return 0;
374}
375
José Fonsecab4a3d142011-10-27 07:43:19 +0100376bool TraceLoader::callContains(trace::Call *call,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400377 const QString &str,
378 Qt::CaseSensitivity sensitivity)
379{
José Fonsecacb7c76f2014-03-27 16:57:22 +0000380 /*
381 * FIXME: do string comparison directly on trace::Call
382 */
383 ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash,
384 0, 0, this);
385 bool result = apiCall->contains(str, sensitivity);
386 delete apiCall;
387 return result;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400388}
389
390QVector<ApiTraceCall*>
391TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame)
392{
393 Q_ASSERT(currentFrame);
Zack Rusin99f84fa2011-09-19 23:44:25 -0400394
Zack Rusin447f4a52011-09-19 23:45:39 -0400395 if (currentFrame->isLoaded()) {
Zack Rusin99f84fa2011-09-19 23:44:25 -0400396 return currentFrame->calls();
397 }
398
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400399 if (m_parser.supportsOffsets()) {
400 unsigned frameIdx = currentFrame->number;
401 int numOfCalls = numberOfCallsInFrame(frameIdx);
402
403 if (numOfCalls) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400404 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
405
406 m_parser.setBookmark(frameBookmark.start);
407
Lawrence L Love59befce2014-03-20 18:47:39 -0700408 FrameContents frameCalls(numOfCalls);
409 frameCalls.load(this, currentFrame, m_helpHash, m_parser);
410 if (frameCalls.topLevelCount() == frameCalls.allCallsCount()) {
411 emit frameContentsLoaded(currentFrame,
412 frameCalls.allCalls(),
413 frameCalls.allCalls(),
414 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400415 } else {
Lawrence L Love59befce2014-03-20 18:47:39 -0700416 emit frameContentsLoaded(currentFrame,
417 frameCalls.topLevelCalls(),
418 frameCalls.allCalls(),
419 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400420 }
Lawrence L Love59befce2014-03-20 18:47:39 -0700421 return frameCalls.allCalls();
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400422 }
423 }
424 return QVector<ApiTraceCall*>();
425}
426
Zack Rusin93e4d152011-09-13 02:23:39 -0400427void TraceLoader::findFrameStart(ApiTraceFrame *frame)
428{
Zack Rusin99f84fa2011-09-19 23:44:25 -0400429 if (!frame->isLoaded()) {
430 loadFrame(frame);
431 }
Zack Rusin93e4d152011-09-13 02:23:39 -0400432 emit foundFrameStart(frame);
433}
434
435void TraceLoader::findFrameEnd(ApiTraceFrame *frame)
436{
Zack Rusin99f84fa2011-09-19 23:44:25 -0400437 if (!frame->isLoaded()) {
438 loadFrame(frame);
439 }
Zack Rusin93e4d152011-09-13 02:23:39 -0400440 emit foundFrameEnd(frame);
441}
442
Zack Rusinda7579b2011-09-13 17:33:05 -0400443void TraceLoader::findCallIndex(int index)
444{
445 int frameIdx = callInFrame(index);
446 ApiTraceFrame *frame = m_createdFrames[frameIdx];
447 QVector<ApiTraceCall*> calls = fetchFrameContents(frame);
448 QVector<ApiTraceCall*>::const_iterator itr;
449 ApiTraceCall *call = 0;
450 for (itr = calls.constBegin(); itr != calls.constEnd(); ++itr) {
451 if ((*itr)->index() == index) {
452 call = *itr;
Lawrence L Love53a40802014-02-12 15:26:55 -0800453 break;
Zack Rusinda7579b2011-09-13 17:33:05 -0400454 }
455 }
José Fonsecacaa84282013-04-11 18:54:06 +0100456 if (call) {
457 emit foundCallIndex(call);
458 }
Zack Rusinda7579b2011-09-13 17:33:05 -0400459}
460
Zack Rusinad513b32011-09-25 14:33:41 -0400461void TraceLoader::search(const ApiTrace::SearchRequest &request)
462{
463 if (request.direction == ApiTrace::SearchRequest::Next) {
464 searchNext(request);
465 } else {
466 searchPrev(request);
467 }
468}
469
Lawrence L Love59befce2014-03-20 18:47:39 -0700470TraceLoader::FrameContents::FrameContents(int numOfCalls)
471 : m_allCalls(numOfCalls),
472 m_binaryDataSize(0),
473 m_parsedCalls(0)
474{}
475
476
477void
478TraceLoader::FrameContents::reset()
479{
480 m_groups.clear();
481 m_allCalls.clear();
482 m_topLevelItems.clear();
483 m_binaryDataSize = 0;
484}
485
486int
487TraceLoader::FrameContents::topLevelCount() const
488{
489 return m_topLevelItems.count();
490}
491
492int
493TraceLoader::FrameContents::allCallsCount() const
494{
495 return m_allCalls.count();
496}
497
498quint64
499TraceLoader::FrameContents::binaryDataSize() const
500{
501 return m_binaryDataSize;
502}
503QVector<ApiTraceCall*>
504TraceLoader::FrameContents::topLevelCalls() const
505{
506 return m_topLevelItems;
507}
508
509QVector<ApiTraceCall*>
510TraceLoader::FrameContents::allCalls() const
511{
512 return m_allCalls;
513}
514
515bool
516TraceLoader::FrameContents::isEmpty()
517{
518 return (m_allCalls.count() == 0);
519}
520
521bool
522TraceLoader::FrameContents::load(TraceLoader *loader,
523 ApiTraceFrame *currentFrame,
524 QHash<QString, QUrl> helpHash,
525 trace::Parser &parser)
526{
527 bool bEndFrameReached = false;
528 int initNumOfCalls = m_allCalls.count();
529 trace::Call *call;
530 ApiTraceCall *apiCall = NULL;
531
532 while ((call = parser.parse_call())) {
533
534 apiCall = apiCallFromTraceCall(call, helpHash, currentFrame,
535 m_groups.isEmpty() ? 0 : m_groups.top(),
536 loader);
537 Q_ASSERT(apiCall);
538 if (initNumOfCalls) {
539 Q_ASSERT(m_parsedCalls < m_allCalls.size());
540 m_allCalls[m_parsedCalls++] = apiCall;
541 } else {
542 m_allCalls.append(apiCall);
543 }
544 if (m_groups.count() == 0) {
545 m_topLevelItems.append(apiCall);
546 } else {
547 m_groups.top()->addChild(apiCall);
548 }
549 if (call->flags & trace::CALL_FLAG_MARKER_PUSH) {
550 m_groups.push(apiCall);
551 } else if (call->flags & trace::CALL_FLAG_MARKER_POP) {
552 if (m_groups.count()) {
553 m_groups.top()->finishedAddingChildren();
554 m_groups.pop();
555 }
556 }
557 if (apiCall->hasBinaryData()) {
558 QByteArray data =
559 apiCall->arguments()[apiCall->binaryDataIndex()].
560 toByteArray();
561 m_binaryDataSize += data.size();
562 }
563
564 delete call;
565
566 if (apiCall->flags() & trace::CALL_FLAG_END_FRAME) {
567 bEndFrameReached = true;
568 break;
569 }
570 }
571 if (initNumOfCalls) {
572 // There can be fewer parsed calls when call in different
573 // threads cross the frame boundary
574 Q_ASSERT(m_parsedCalls <= initNumOfCalls);
575 Q_ASSERT(m_parsedCalls <= m_allCalls.size());
576 m_allCalls.resize(m_parsedCalls);
577 Q_ASSERT(m_parsedCalls <= currentFrame->numChildrenToLoad());
578 }
579 m_allCalls.squeeze();
580 m_topLevelItems.squeeze();
581
582 return bEndFrameReached;
583}
584
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400585#include "traceloader.moc"