blob: e6e37e6c57036f3cb10f5c52ad557ff713277b17 [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);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040037}
38
39void TraceLoader::loadTrace(const QString &filename)
40{
41 if (m_helpHash.isEmpty()) {
42 loadHelpFile();
43 }
44
Zack Rusindaf82af2011-09-24 13:42:53 -040045 if (!m_frameBookmarks.isEmpty()) {
46 qDeleteAll(m_signatures);
Zack Rusindaf82af2011-09-24 13:42:53 -040047 m_signatures.clear();
Zack Rusindaf82af2011-09-24 13:42:53 -040048 m_frameBookmarks.clear();
49 m_createdFrames.clear();
50 m_parser.close();
51 }
52
Zack Rusin20b1f6d2011-09-06 11:50:07 -040053 if (!m_parser.open(filename.toLatin1())) {
54 qDebug() << "error: failed to open " << filename;
55 return;
56 }
Zack Rusin59b79552011-09-21 00:37:03 -040057
Zack Rusin20b1f6d2011-09-06 11:50:07 -040058 emit startedParsing();
59
60 if (m_parser.supportsOffsets()) {
Zack Rusinac92a212011-09-06 18:25:34 -040061 scanTrace();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040062 } else {
Zack Rusinac92a212011-09-06 18:25:34 -040063 //Load the entire file into memory
64 parseTrace();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040065 }
José Fonseca67964382012-03-27 23:54:30 +010066 emit guessedApi(static_cast<int>(m_parser.api));
Zack Rusin20b1f6d2011-09-06 11:50:07 -040067 emit finishedParsing();
68}
69
Zack Rusin3176ebe2011-09-06 21:11:36 -040070void TraceLoader::loadFrame(ApiTraceFrame *currentFrame)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040071{
Zack Rusin8f98c3a2011-09-11 18:21:29 -040072 fetchFrameContents(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040073}
74
Zack Rusin20b1f6d2011-09-06 11:50:07 -040075int TraceLoader::numberOfFrames() const
76{
José Fonseca61e61f72011-09-11 16:53:34 +010077 return m_frameBookmarks.size();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040078}
79
80int TraceLoader::numberOfCallsInFrame(int frameIdx) const
81{
José Fonseca6bfa32f2012-03-22 16:26:47 +000082 if (frameIdx >= m_frameBookmarks.size()) {
Zack Rusin20b1f6d2011-09-06 11:50:07 -040083 return 0;
84 }
José Fonseca61e61f72011-09-11 16:53:34 +010085 FrameBookmarks::const_iterator itr =
86 m_frameBookmarks.find(frameIdx);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040087 return itr->numberOfCalls;
88}
89
90void TraceLoader::loadHelpFile()
91{
Zack Rusinac92a212011-09-06 18:25:34 -040092 QFile file(":/resources/glreference.tsv");
93 if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
94 QString line;
95 while (!file.atEnd()) {
96 line = file.readLine();
97 QString function = line.section('\t', 0, 0).trimmed();
98 QUrl url = QUrl(line.section('\t', 1, 1).trimmed());
99 //qDebug()<<"function = "<<function<<", url = "<<url.toString();
100 m_helpHash.insert(function, url);
101 }
102 } else {
103 qWarning() << "Couldn't open reference file "
104 << file.fileName();
105 }
106 file.close();
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400107}
108
109void TraceLoader::scanTrace()
110{
Zack Rusinac92a212011-09-06 18:25:34 -0400111 QList<ApiTraceFrame*> frames;
112 ApiTraceFrame *currentFrame = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400113
José Fonsecab4a3d142011-10-27 07:43:19 +0100114 trace::Call *call;
115 trace::ParseBookmark startBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400116 int numOfFrames = 0;
117 int numOfCalls = 0;
Zack Rusinac92a212011-09-06 18:25:34 -0400118 int lastPercentReport = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400119
José Fonseca61e61f72011-09-11 16:53:34 +0100120 m_parser.getBookmark(startBookmark);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400121
Zack Rusinac92a212011-09-06 18:25:34 -0400122 while ((call = m_parser.scan_call())) {
123 ++numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400124
José Fonseca5cd8d992012-03-25 23:12:20 +0100125 if (call->flags & trace::CALL_FLAG_END_FRAME) {
José Fonseca61e61f72011-09-11 16:53:34 +0100126 FrameBookmark frameBookmark(startBookmark);
127 frameBookmark.numberOfCalls = numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400128
Zack Rusinac92a212011-09-06 18:25:34 -0400129 currentFrame = new ApiTraceFrame();
130 currentFrame->number = numOfFrames;
131 currentFrame->setNumChildren(numOfCalls);
Zack Rusin851d0b02011-09-14 22:04:07 -0400132 currentFrame->setLastCallIndex(call->no);
Zack Rusinac92a212011-09-06 18:25:34 -0400133 frames.append(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400134
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400135 m_createdFrames.append(currentFrame);
José Fonseca61e61f72011-09-11 16:53:34 +0100136 m_frameBookmarks[numOfFrames] = frameBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400137 ++numOfFrames;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400138
Zack Rusinac92a212011-09-06 18:25:34 -0400139 if (m_parser.percentRead() - lastPercentReport >= 5) {
140 emit parsed(m_parser.percentRead());
141 lastPercentReport = m_parser.percentRead();
142 }
José Fonseca61e61f72011-09-11 16:53:34 +0100143 m_parser.getBookmark(startBookmark);
Zack Rusinac92a212011-09-06 18:25:34 -0400144 numOfCalls = 0;
145 }
Zack Rusinac92a212011-09-06 18:25:34 -0400146 delete call;
147 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400148
Zack Rusinac92a212011-09-06 18:25:34 -0400149 if (numOfCalls) {
José Fonsecab4a3d142011-10-27 07:43:19 +0100150 //trace::File::Bookmark endBookmark = m_parser.currentBookmark();
José Fonseca61e61f72011-09-11 16:53:34 +0100151 FrameBookmark frameBookmark(startBookmark);
152 frameBookmark.numberOfCalls = numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400153
Zack Rusinac92a212011-09-06 18:25:34 -0400154 currentFrame = new ApiTraceFrame();
155 currentFrame->number = numOfFrames;
156 currentFrame->setNumChildren(numOfCalls);
157 frames.append(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400158
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400159 m_createdFrames.append(currentFrame);
José Fonseca61e61f72011-09-11 16:53:34 +0100160 m_frameBookmarks[numOfFrames] = frameBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400161 ++numOfFrames;
162 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400163
Zack Rusinac92a212011-09-06 18:25:34 -0400164 emit parsed(100);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400165
Zack Rusinac92a212011-09-06 18:25:34 -0400166 emit framesLoaded(frames);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400167}
168
169void TraceLoader::parseTrace()
170{
Zack Rusinac92a212011-09-06 18:25:34 -0400171 QList<ApiTraceFrame*> frames;
Zack Rusinac92a212011-09-06 18:25:34 -0400172 int frameCount = 0;
Zack Rusinac92a212011-09-06 18:25:34 -0400173 int lastPercentReport = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400174
Lawrence L Love59befce2014-03-20 18:47:39 -0700175 ApiTraceFrame *currentFrame = new ApiTraceFrame();
176 currentFrame->number = frameCount;
177
178 FrameContents frameCalls;
179 while (frameCalls.load(this, currentFrame, m_helpHash, m_parser)) {
180
181 if (frameCalls.topLevelCount() == frameCalls.allCallsCount()) {
182 currentFrame->setCalls(frameCalls.allCalls(),
183 frameCalls.allCalls(),
184 frameCalls.binaryDataSize());
Lawrence L Love3512d982014-03-19 15:18:45 -0700185 } else {
Lawrence L Love59befce2014-03-20 18:47:39 -0700186 currentFrame->setCalls(frameCalls.topLevelCalls(),
187 frameCalls.allCalls(),
188 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400189 }
Lawrence L Love59befce2014-03-20 18:47:39 -0700190 frames.append(currentFrame);
191 if (frames.count() >= FRAMES_TO_CACHE) {
192 emit framesLoaded(frames);
193 frames.clear();
Zack Rusind9d9d222013-10-11 18:02:26 -0400194 }
Lawrence L Love59befce2014-03-20 18:47:39 -0700195 if (m_parser.percentRead() - lastPercentReport >= 5) {
196 emit parsed(m_parser.percentRead());
197 lastPercentReport = m_parser.percentRead();
Zack Rusinac92a212011-09-06 18:25:34 -0400198 }
Lawrence L Love59befce2014-03-20 18:47:39 -0700199 ++frameCount;
200 currentFrame = new ApiTraceFrame();
201 currentFrame->number = frameCount;
202
203 frameCalls.reset();
Zack Rusinac92a212011-09-06 18:25:34 -0400204 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400205
Zack Rusinac92a212011-09-06 18:25:34 -0400206 //last frames won't have markers
207 // it's just a bunch of Delete calls for every object
208 // after the last SwapBuffers
Lawrence L Love59befce2014-03-20 18:47:39 -0700209 if (!frameCalls.isEmpty()) {
210 if (frameCalls.topLevelCount() == frameCalls.allCallsCount()) {
211 currentFrame->setCalls(frameCalls.allCalls(),
212 frameCalls.allCalls(),
213 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400214 } else {
Lawrence L Love59befce2014-03-20 18:47:39 -0700215 currentFrame->setCalls(frameCalls.topLevelCalls(),
216 frameCalls.allCalls(),
217 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400218 }
Zack Rusinac92a212011-09-06 18:25:34 -0400219 frames.append(currentFrame);
Zack Rusinac92a212011-09-06 18:25:34 -0400220 }
221 if (frames.count()) {
222 emit framesLoaded(frames);
223 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400224}
225
226
Zack Rusinebf971e2011-09-06 17:44:43 -0400227ApiTraceCallSignature * TraceLoader::signature(unsigned id)
228{
229 if (id >= m_signatures.count()) {
230 m_signatures.resize(id + 1);
231 return NULL;
232 } else {
233 return m_signatures[id];
234 }
235}
236
237void TraceLoader::addSignature(unsigned id, ApiTraceCallSignature *signature)
238{
239 m_signatures[id] = signature;
240}
241
Zack Rusinad513b32011-09-25 14:33:41 -0400242void TraceLoader::searchNext(const ApiTrace::SearchRequest &request)
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400243{
244 Q_ASSERT(m_parser.supportsOffsets());
245 if (m_parser.supportsOffsets()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400246 int startFrame = m_createdFrames.indexOf(request.frame);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400247 const FrameBookmark &frameBookmark = m_frameBookmarks[startFrame];
248 m_parser.setBookmark(frameBookmark.start);
José Fonsecab4a3d142011-10-27 07:43:19 +0100249 trace::Call *call = 0;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400250 while ((call = m_parser.parse_call())) {
251
Zack Rusinad513b32011-09-25 14:33:41 -0400252 if (callContains(call, request.text, request.cs)) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400253 unsigned frameIdx = callInFrame(call->no);
254 ApiTraceFrame *frame = m_createdFrames[frameIdx];
255 const QVector<ApiTraceCall*> calls =
256 fetchFrameContents(frame);
257 for (int i = 0; i < calls.count(); ++i) {
258 if (calls[i]->index() == call->no) {
Zack Rusinad513b32011-09-25 14:33:41 -0400259 emit searchResult(request, ApiTrace::SearchResult_Found,
260 calls[i]);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400261 break;
262 }
263 }
264 delete call;
265 return;
266 }
267
268 delete call;
269 }
270 }
Zack Rusinad513b32011-09-25 14:33:41 -0400271 emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400272}
273
Zack Rusinad513b32011-09-25 14:33:41 -0400274void TraceLoader::searchPrev(const ApiTrace::SearchRequest &request)
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400275{
Zack Rusin121e3162011-09-13 01:35:12 -0400276 Q_ASSERT(m_parser.supportsOffsets());
277 if (m_parser.supportsOffsets()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400278 int startFrame = m_createdFrames.indexOf(request.frame);
José Fonsecab4a3d142011-10-27 07:43:19 +0100279 trace::Call *call = 0;
280 QList<trace::Call*> frameCalls;
Zack Rusin121e3162011-09-13 01:35:12 -0400281 int frameIdx = startFrame;
282
283 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
284 int numCallsToParse = frameBookmark.numberOfCalls;
285 m_parser.setBookmark(frameBookmark.start);
286
287 while ((call = m_parser.parse_call())) {
288
289 frameCalls.append(call);
290 --numCallsToParse;
291
292 if (numCallsToParse == 0) {
293 bool foundCall = searchCallsBackwards(frameCalls,
294 frameIdx,
Zack Rusinad513b32011-09-25 14:33:41 -0400295 request);
Zack Rusin121e3162011-09-13 01:35:12 -0400296
297 qDeleteAll(frameCalls);
298 frameCalls.clear();
299 if (foundCall) {
300 return;
301 }
302
303 --frameIdx;
304
305 if (frameIdx >= 0) {
306 const FrameBookmark &frameBookmark =
307 m_frameBookmarks[frameIdx];
308 m_parser.setBookmark(frameBookmark.start);
309 numCallsToParse = frameBookmark.numberOfCalls;
310 }
311 }
312 }
313 }
Zack Rusinad513b32011-09-25 14:33:41 -0400314 emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
Zack Rusin121e3162011-09-13 01:35:12 -0400315}
316
José Fonsecab4a3d142011-10-27 07:43:19 +0100317bool TraceLoader::searchCallsBackwards(const QList<trace::Call*> &calls,
Zack Rusin121e3162011-09-13 01:35:12 -0400318 int frameIdx,
Zack Rusinad513b32011-09-25 14:33:41 -0400319 const ApiTrace::SearchRequest &request)
Zack Rusin121e3162011-09-13 01:35:12 -0400320{
321 for (int i = calls.count() - 1; i >= 0; --i) {
José Fonsecab4a3d142011-10-27 07:43:19 +0100322 trace::Call *call = calls[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400323 if (callContains(call, request.text, request.cs)) {
Zack Rusin121e3162011-09-13 01:35:12 -0400324 ApiTraceFrame *frame = m_createdFrames[frameIdx];
325 const QVector<ApiTraceCall*> apiCalls =
326 fetchFrameContents(frame);
327 for (int i = 0; i < apiCalls.count(); ++i) {
328 if (apiCalls[i]->index() == call->no) {
Zack Rusinad513b32011-09-25 14:33:41 -0400329 emit searchResult(request,
330 ApiTrace::SearchResult_Found,
331 apiCalls[i]);
Zack Rusin121e3162011-09-13 01:35:12 -0400332 break;
333 }
334 }
335 return true;
336 }
337 }
338 return false;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400339}
340
341int TraceLoader::callInFrame(int callIdx) const
342{
343 unsigned numCalls = 0;
344
José Fonseca6bfa32f2012-03-22 16:26:47 +0000345 for (int frameIdx = 0; frameIdx < m_frameBookmarks.size(); ++frameIdx) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400346 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
347 unsigned firstCall = numCalls;
348 unsigned endCall = numCalls + frameBookmark.numberOfCalls;
349 if (firstCall <= callIdx && endCall > callIdx) {
350 return frameIdx;
351 }
352 numCalls = endCall;
353 }
354 Q_ASSERT(!"call not in the trace");
355 return 0;
356}
357
José Fonsecab4a3d142011-10-27 07:43:19 +0100358bool TraceLoader::callContains(trace::Call *call,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400359 const QString &str,
360 Qt::CaseSensitivity sensitivity)
361{
José Fonsecacb7c76f2014-03-27 16:57:22 +0000362 /*
363 * FIXME: do string comparison directly on trace::Call
364 */
365 ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash,
366 0, 0, this);
367 bool result = apiCall->contains(str, sensitivity);
368 delete apiCall;
369 return result;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400370}
371
372QVector<ApiTraceCall*>
373TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame)
374{
375 Q_ASSERT(currentFrame);
Zack Rusin99f84fa2011-09-19 23:44:25 -0400376
Zack Rusin447f4a52011-09-19 23:45:39 -0400377 if (currentFrame->isLoaded()) {
Zack Rusin99f84fa2011-09-19 23:44:25 -0400378 return currentFrame->calls();
379 }
380
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400381 if (m_parser.supportsOffsets()) {
382 unsigned frameIdx = currentFrame->number;
383 int numOfCalls = numberOfCallsInFrame(frameIdx);
384
385 if (numOfCalls) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400386 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
387
388 m_parser.setBookmark(frameBookmark.start);
389
Lawrence L Love59befce2014-03-20 18:47:39 -0700390 FrameContents frameCalls(numOfCalls);
391 frameCalls.load(this, currentFrame, m_helpHash, m_parser);
392 if (frameCalls.topLevelCount() == frameCalls.allCallsCount()) {
393 emit frameContentsLoaded(currentFrame,
394 frameCalls.allCalls(),
395 frameCalls.allCalls(),
396 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400397 } else {
Lawrence L Love59befce2014-03-20 18:47:39 -0700398 emit frameContentsLoaded(currentFrame,
399 frameCalls.topLevelCalls(),
400 frameCalls.allCalls(),
401 frameCalls.binaryDataSize());
Zack Rusind9d9d222013-10-11 18:02:26 -0400402 }
Lawrence L Love59befce2014-03-20 18:47:39 -0700403 return frameCalls.allCalls();
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400404 }
405 }
406 return QVector<ApiTraceCall*>();
407}
408
Zack Rusin93e4d152011-09-13 02:23:39 -0400409void TraceLoader::findFrameStart(ApiTraceFrame *frame)
410{
Zack Rusin99f84fa2011-09-19 23:44:25 -0400411 if (!frame->isLoaded()) {
412 loadFrame(frame);
413 }
Zack Rusin93e4d152011-09-13 02:23:39 -0400414 emit foundFrameStart(frame);
415}
416
417void TraceLoader::findFrameEnd(ApiTraceFrame *frame)
418{
Zack Rusin99f84fa2011-09-19 23:44:25 -0400419 if (!frame->isLoaded()) {
420 loadFrame(frame);
421 }
Zack Rusin93e4d152011-09-13 02:23:39 -0400422 emit foundFrameEnd(frame);
423}
424
Zack Rusinda7579b2011-09-13 17:33:05 -0400425void TraceLoader::findCallIndex(int index)
426{
427 int frameIdx = callInFrame(index);
428 ApiTraceFrame *frame = m_createdFrames[frameIdx];
429 QVector<ApiTraceCall*> calls = fetchFrameContents(frame);
430 QVector<ApiTraceCall*>::const_iterator itr;
431 ApiTraceCall *call = 0;
432 for (itr = calls.constBegin(); itr != calls.constEnd(); ++itr) {
433 if ((*itr)->index() == index) {
434 call = *itr;
Lawrence L Love53a40802014-02-12 15:26:55 -0800435 break;
Zack Rusinda7579b2011-09-13 17:33:05 -0400436 }
437 }
José Fonsecacaa84282013-04-11 18:54:06 +0100438 if (call) {
439 emit foundCallIndex(call);
440 }
Zack Rusinda7579b2011-09-13 17:33:05 -0400441}
442
Zack Rusinad513b32011-09-25 14:33:41 -0400443void TraceLoader::search(const ApiTrace::SearchRequest &request)
444{
445 if (request.direction == ApiTrace::SearchRequest::Next) {
446 searchNext(request);
447 } else {
448 searchPrev(request);
449 }
450}
451
Lawrence L Love59befce2014-03-20 18:47:39 -0700452TraceLoader::FrameContents::FrameContents(int numOfCalls)
453 : m_allCalls(numOfCalls),
454 m_binaryDataSize(0),
455 m_parsedCalls(0)
456{}
457
458
459void
460TraceLoader::FrameContents::reset()
461{
462 m_groups.clear();
463 m_allCalls.clear();
464 m_topLevelItems.clear();
465 m_binaryDataSize = 0;
466}
467
468int
469TraceLoader::FrameContents::topLevelCount() const
470{
471 return m_topLevelItems.count();
472}
473
474int
475TraceLoader::FrameContents::allCallsCount() const
476{
477 return m_allCalls.count();
478}
479
480quint64
481TraceLoader::FrameContents::binaryDataSize() const
482{
483 return m_binaryDataSize;
484}
485QVector<ApiTraceCall*>
486TraceLoader::FrameContents::topLevelCalls() const
487{
488 return m_topLevelItems;
489}
490
491QVector<ApiTraceCall*>
492TraceLoader::FrameContents::allCalls() const
493{
494 return m_allCalls;
495}
496
497bool
498TraceLoader::FrameContents::isEmpty()
499{
500 return (m_allCalls.count() == 0);
501}
502
503bool
504TraceLoader::FrameContents::load(TraceLoader *loader,
505 ApiTraceFrame *currentFrame,
506 QHash<QString, QUrl> helpHash,
507 trace::Parser &parser)
508{
509 bool bEndFrameReached = false;
510 int initNumOfCalls = m_allCalls.count();
511 trace::Call *call;
512 ApiTraceCall *apiCall = NULL;
513
514 while ((call = parser.parse_call())) {
515
516 apiCall = apiCallFromTraceCall(call, helpHash, currentFrame,
517 m_groups.isEmpty() ? 0 : m_groups.top(),
518 loader);
519 Q_ASSERT(apiCall);
520 if (initNumOfCalls) {
521 Q_ASSERT(m_parsedCalls < m_allCalls.size());
522 m_allCalls[m_parsedCalls++] = apiCall;
523 } else {
524 m_allCalls.append(apiCall);
525 }
526 if (m_groups.count() == 0) {
527 m_topLevelItems.append(apiCall);
528 } else {
529 m_groups.top()->addChild(apiCall);
530 }
531 if (call->flags & trace::CALL_FLAG_MARKER_PUSH) {
532 m_groups.push(apiCall);
533 } else if (call->flags & trace::CALL_FLAG_MARKER_POP) {
534 if (m_groups.count()) {
535 m_groups.top()->finishedAddingChildren();
536 m_groups.pop();
537 }
538 }
539 if (apiCall->hasBinaryData()) {
540 QByteArray data =
541 apiCall->arguments()[apiCall->binaryDataIndex()].
542 toByteArray();
543 m_binaryDataSize += data.size();
544 }
545
546 delete call;
547
548 if (apiCall->flags() & trace::CALL_FLAG_END_FRAME) {
549 bEndFrameReached = true;
550 break;
551 }
552 }
553 if (initNumOfCalls) {
554 // There can be fewer parsed calls when call in different
555 // threads cross the frame boundary
556 Q_ASSERT(m_parsedCalls <= initNumOfCalls);
557 Q_ASSERT(m_parsedCalls <= m_allCalls.size());
558 m_allCalls.resize(m_parsedCalls);
559 Q_ASSERT(m_parsedCalls <= currentFrame->numChildrenToLoad());
560 }
561 m_allCalls.squeeze();
562 m_topLevelItems.squeeze();
563
564 return bEndFrameReached;
565}
566
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400567#include "traceloader.moc"