File indexing completed on 2024-05-05 04:38:47

0001 /*
0002     SPDX-FileCopyrightText: 2002 John Firebaugh <jfirebaugh@kde.org>
0003     SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de>
0004     SPDX-FileCopyrightText: 2007 Oswald Buddenhagen <ossi@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "processlinemaker.h"
0010 
0011 #include <QProcess>
0012 #include <QStringList>
0013 
0014 namespace KDevelop {
0015 
0016 class ProcessLineMakerPrivate
0017 {
0018 public:
0019     QByteArray stdoutbuf;
0020     QByteArray stderrbuf;
0021     ProcessLineMaker* p;
0022     QProcess* m_proc;
0023 
0024     explicit ProcessLineMakerPrivate(ProcessLineMaker* maker)
0025         : p(maker)
0026     {
0027     }
0028 
0029     void slotReadyReadStdout()
0030     {
0031         stdoutbuf += m_proc->readAllStandardOutput();
0032         processStdOut();
0033     }
0034 
0035     static QStringList streamToStrings(QByteArray& data)
0036     {
0037         QStringList lineList;
0038         int pos;
0039         while ((pos = data.indexOf('\n')) != -1) {
0040             if (pos > 0 && data.at(pos - 1) == '\r')
0041                 lineList << QString::fromLocal8Bit(data.constData(), pos - 1);
0042             else
0043                 lineList << QString::fromLocal8Bit(data.constData(), pos);
0044             data.remove(0, pos + 1);
0045         }
0046         return lineList;
0047     }
0048 
0049     void processStdOut()
0050     {
0051         emit p->receivedStdoutLines(streamToStrings(stdoutbuf));
0052     }
0053 
0054     void slotReadyReadStderr()
0055     {
0056         stderrbuf += m_proc->readAllStandardError();
0057         processStdErr();
0058     }
0059 
0060     void processStdErr()
0061     {
0062         emit p->receivedStderrLines(streamToStrings(stderrbuf));
0063     }
0064 
0065 };
0066 
0067 ProcessLineMaker::ProcessLineMaker(QObject* parent)
0068     : QObject(parent)
0069     , d_ptr(new ProcessLineMakerPrivate(this))
0070 {
0071 }
0072 
0073 ProcessLineMaker::ProcessLineMaker(QProcess* proc, QObject* parent)
0074     : QObject(parent)
0075     , d_ptr(new ProcessLineMakerPrivate(this))
0076 {
0077     Q_D(ProcessLineMaker);
0078 
0079     d->m_proc = proc;
0080     connect(proc, &QProcess::readyReadStandardOutput,
0081             this, [this] {
0082             Q_D(ProcessLineMaker);
0083             d->slotReadyReadStdout();
0084         });
0085     connect(proc, &QProcess::readyReadStandardError,
0086             this, [this] {
0087             Q_D(ProcessLineMaker);
0088             d->slotReadyReadStderr();
0089         });
0090 }
0091 
0092 ProcessLineMaker::~ProcessLineMaker() = default;
0093 
0094 void ProcessLineMaker::slotReceivedStdout(const QByteArray& buffer)
0095 {
0096     Q_D(ProcessLineMaker);
0097 
0098     d->stdoutbuf += buffer;
0099     d->processStdOut();
0100 }
0101 
0102 void ProcessLineMaker::slotReceivedStderr(const QByteArray& buffer)
0103 {
0104     Q_D(ProcessLineMaker);
0105 
0106     d->stderrbuf += buffer;
0107     d->processStdErr();
0108 }
0109 
0110 void ProcessLineMaker::discardBuffers()
0111 {
0112     Q_D(ProcessLineMaker);
0113 
0114     d->stderrbuf.truncate(0);
0115     d->stdoutbuf.truncate(0);
0116 }
0117 
0118 void ProcessLineMaker::flushBuffers()
0119 {
0120     Q_D(ProcessLineMaker);
0121 
0122     if (!d->stdoutbuf.isEmpty())
0123         emit receivedStdoutLines(QStringList(QString::fromLocal8Bit(d->stdoutbuf)));
0124     if (!d->stderrbuf.isEmpty())
0125         emit receivedStderrLines(QStringList(QString::fromLocal8Bit(d->stderrbuf)));
0126     discardBuffers();
0127 }
0128 
0129 }
0130 
0131 #include "moc_processlinemaker.cpp"