From: José Fonseca Date: Mon, 26 Mar 2012 09:29:32 +0000 (+0100) Subject: Merge remote-tracking branch 'github/master' into gui-unbuffered-retrace X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=dc9e9c6addb436b7b2d87984d4bd9b0a18d5c5e2;p=apitrace Merge remote-tracking branch 'github/master' into gui-unbuffered-retrace Conflicts: gui/retracer.cpp --- dc9e9c6addb436b7b2d87984d4bd9b0a18d5c5e2 diff --cc gui/retracer.cpp index 50b35d4,7c66f3e..aeac9ba --- a/gui/retracer.cpp +++ b/gui/retracer.cpp @@@ -255,99 -177,81 +256,99 @@@ void Retracer::run( arguments << m_fileName; - m_process->start(prog, arguments); -} - - -void RetraceProcess::replayFinished(int exitCode, QProcess::ExitStatus exitStatus) -{ - QString msg; - - if (exitStatus != QProcess::NormalExit) { - msg = QLatin1String("Process crashed"); - } else if (exitCode != 0) { - msg = QLatin1String("Process exited with non zero exit code"); - } else { - if (m_captureState || m_captureThumbnails) { - if (m_captureState) { - bool ok = false; - m_process->setReadChannel(QProcess::StandardOutput); - QVariantMap parsedJson = m_jsonParser->parse(m_process, &ok).toMap(); - ApiTraceState *state = new ApiTraceState(parsedJson); - emit foundState(state); - msg = tr("State fetched."); - } - if (m_captureThumbnails) { - m_process->setReadChannel(QProcess::StandardOutput); + /* + * Start the process. + */ - QList thumbnails; + QProcess process; - while (!m_process->atEnd()) { - unsigned channels = 0; - unsigned width = 0; - unsigned height = 0; + process.start(prog, arguments, QIODevice::ReadOnly); + if (!process.waitForStarted(-1)) { + emit finished(QLatin1String("Could not start process")); + return; + } - char header[512]; - qint64 headerSize = 0; - int headerLines = 3; // assume no optional comment line + /* + * Process standard output + */ - for (int headerLine = 0; headerLine < headerLines; ++headerLine) { - qint64 headerRead = m_process->readLine(&header[headerSize], sizeof(header) - headerSize); + QList thumbnails; + QVariantMap parsedJson; - // if header actually contains optional comment line, ... - if (headerLine == 1 && header[headerSize] == '#') { - ++headerLines; - } + process.setReadChannel(QProcess::StandardOutput); + if (process.waitForReadyRead(-1)) { + BlockingIODevice io(&process); - headerSize += headerRead; + if (m_captureState) { + /* + * Parse JSON from the output. + * + * XXX: QJSON expects blocking IO. + * + * XXX: QJSON's scanner is inneficient as it abuses single + * character QIODevice::peek (not cheap), instead of maintaining a + * lookahead character on its own. + */ + + bool ok = false; + QJson::Parser jsonParser; + parsedJson = jsonParser.parse(&io, &ok).toMap(); + if (!ok) { + msg = QLatin1String("failed to parse JSON"); + } + } else if (m_captureThumbnails) { + /* + * Parse concatenated PNM images from output. + */ + + while (!io.atEnd()) { + unsigned channels = 0; + unsigned width = 0; + unsigned height = 0; + + char header[512]; + qint64 headerSize = 0; + int headerLines = 3; // assume no optional comment line + + for (int headerLine = 0; headerLine < headerLines; ++headerLine) { + qint64 headerRead = io.readLine(&header[headerSize], sizeof(header) - headerSize); + + // if header actually contains optional comment line, ... + if (headerLine == 1 && header[headerSize] == '#') { + ++headerLines; } - const char *headerEnd = image::readPNMHeader(header, headerSize, &channels, &width, &height); + headerSize += headerRead; + } - // if invalid PNM header was encountered, ... - if (header == headerEnd) { - qDebug() << "error: invalid snapshot stream encountered\n"; - break; - } + const char *headerEnd = image::readPNMHeader(header, headerSize, &channels, &width, &height); - //qDebug() << "channels: " << channels << ", width: " << width << ", height: " << height << "\n"; + // if invalid PNM header was encountered, ... + if (header == headerEnd) { + qDebug() << "error: invalid snapshot stream encountered"; + break; + } - QImage snapshot = QImage(width, height, channels == 1 ? QImage::Format_Mono : QImage::Format_RGB888); + // qDebug() << "channels: " << channels << ", width: " << width << ", height: " << height"; - int rowBytes = channels * width; - for (int y = 0; y < height; ++y) { - unsigned char *scanLine = snapshot.scanLine(y); - m_process->read((char *) scanLine, rowBytes); - } + QImage snapshot = QImage(width, height, channels == 1 ? QImage::Format_Mono : QImage::Format_RGB888); - QImage thumb = thumbnail(snapshot); - thumbnails.append(thumb); + int rowBytes = channels * width; + for (int y = 0; y < height; ++y) { + unsigned char *scanLine = snapshot.scanLine(y); + qint64 readBytes = io.read((char *) scanLine, rowBytes); + Q_ASSERT(readBytes == rowBytes); } - QImage thumbnail = snapshot.scaled(16, 16, Qt::KeepAspectRatio, Qt::FastTransformation); - thumbnails.append(thumbnail); - emit foundThumbnails(thumbnails); - msg = tr("Thumbnails fetched."); ++ QImage thumb = thumbnail(snapshot); ++ thumbnails.append(thumb); } + + Q_ASSERT(process.state() != QProcess::Running); + } else { QByteArray output; - output = m_process->readAllStandardOutput(); + output = process.readAllStandardOutput(); msg = QString::fromUtf8(output); } }