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<QImage> 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<QImage> 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);
}
}