--nextPart8695634.rKnhTJyKVc Content-Type: multipart/mixed; boundary="Boundary-01=_ruV0H+y8XhYD3XE" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-01=_ruV0H+y8XhYD3XE Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Hi, I'd like to introduce my example of KLineBufferedProcess, which should ease= =20 the handling of line oriented output of processes. Users would be for examp= le=20 KGpg where the interaction with gpg is line based. Also K3b could be a=20 potential user as it parses the output of several different command line=20 tools. The idea behind this class is to receive the data from the process and buff= er=20 it. A signal is emitted only if a complete line of data is available.=20 Everything else (program arguments, start, finished signal, writing data to= =20 the process' stdin) is unmodified from KProcess. Please have a look at the code and give me feedback. Greetings, Eike P.S.: please CC me on replies, I'm not on the list. --Boundary-01=_ruV0H+y8XhYD3XE Content-Type: text/x-c++src; charset="utf-8"; name="klineprocess.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="klineprocess.cpp" /** * Copyright (C) 2008 Rolf Eike Beer */ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "klineprocess.h" class KLineBufferedProcessPrivate { public: KLineBufferedProcessPrivate(); //private slot implementations _k_receivedStdout(); _k_receivedStderr(); QByteArray m_stdoutBuffer; QByteArray m_stderrBuffer; int m_newlineInStdout; int m_newlineInStderr; }; KLineBufferedProcessPrivate::KLineBufferedProcessPrivate() { m_newlineInStdout = -1; m_newlineInStderr = -1; } KLineBufferedProcess::KLineBufferedProcess(QObject *parent) : KProcess(parent), d(new KLineBufferedProcessPrivate()) { connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(_k_receivedStdout())); connect(this, SIGNAL(readyReadStandardError()), this, SLOT(_k_receivedStderr())); } KLineBufferedProcess::~KLineBufferedProcess() { delete d; } void KLineBufferedProcessPrivate::_k_receivedStdout() { QByteArray ndata = readAllStandardOutput(); int oldBufferSize = m_stdoutBuffer.size(); m_stdoutBuffer.append(ndata); if (m_newlineInStdout < 0) { m_newlineInStdout = ndata.indexOf('\n'); if (m_newlineInStdout >= 0) { m_newlineInStdout += oldBufferSize; emit lineReadyStandardOutput(); } } } void KLineBufferedProcessPrivate::_k_receivedStderr() { QByteArray ndata = readAllStandardError(); int oldBufferSize = m_stderrBuffer.size(); m_stderrBuffer.append(ndata); if (m_newlineInStderr < 0) { m_newlineInStderr = ndata.indexOf('\n'); if (m_newlineInStderr >= 0) { m_newlineInStderr += oldBufferSize; emit lineReadyStandardError(); } } } bool KLineBufferedProcess::readLineStandardOutput(QByteArray *line) { if (d->m_newlineInStdout < 0) { return false; } const int len = d->m_newlineInStdout; // don't copy '\n' *line = d->m_stdoutBuffer.left(len); d->m_stdoutBuffer.remove(0, len + 1); d->m_newlineInStdout = d->m_stdoutBuffer.indexOf('\n'); return true; } bool KLineBufferedProcess::readLineStandardError(QByteArray *line) { if (d->m_newlineInStderr < 0) { return false; } const int len = d->m_newlineInStderr; // don't copy '\n' *line = d->m_stderrBuffer.left(len); d->m_stderrBuffer.remove(0, len + 1); d->m_newlineInStderr = d->m_stderrBuffer.indexOf('\n'); return true; } bool KLineBufferedProcess::hasLineStandardOutput() { return d->m_newlineInStdout >= 0; } bool KLineBufferedProcess::hasLineStandardError() { return d->m_newlineInStderr >= 0; } #include "klineprocess.moc" --Boundary-01=_ruV0H+y8XhYD3XE Content-Type: text/x-c++hdr; charset="utf-8"; name="klineprocess.h" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="klineprocess.h" /** * Copyright (C) 2008 Rolf Eike Beer */ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * **************************************************************************= */ #ifndef KLINEBUFFEREDPROCESS_H #define KLINEBUFFEREDPROCESS_H #include class QByteArray; class KLineProcessPrivate; /** * Read output of a process split into lines * * This class reads the output of a process and splits it up into lines. Th= is * is especially useful if you try to parse the output of a command line to= ol. * * \b Usage \n * * The class is created and set up like a KProcess. After this you can do * something like this: * * \code * connect(m_linebufprocess, SIGNAL(lineReadyStandardOutput()), SLOT(dataSt= dout())); * ... * void myobj::dataStdout() * { * while (m_linebufprocess->hasLineStandardOutput()) { * QByteArray line; * m_linebufprocess->readLineStandardOutput(line); * ... * } * } * \endcode * * Never use the read functionality of KProcess with this class. This class * needs to read all data from the process into an internal buffer first. If * you try to use the read funtions of the parent classes you would normally * get no output at all. * * The write functions of the parent classes are not effected. You can use * them exactly the same way as in KProcess. * * @author Rolf Eike Beer */ class KLineBufferedProcess : public KProcess { Q_OBJECT public: /** * Constructor */ explicit KLineBufferedProcess(QObject *parent =3D 0); /** * Destructor */ ~KLineBufferedProcess(); /** * Reads a line of text (excluding '\\n') from stdout. * * Use readLineStdout() in response to a lineReadyStdout() signal or * when hasLineStdout() returns true. You may use it multiple times if * more than one line of data is available. If no complete line is * available the content of line is undefined and the function returns * false. * * @param line is used to store the line that was read. * @return if data was read or not */ bool readLineStandardOutput(QByteArray *line); /** * Reads a line of text (excluding '\\n') from stderr. * * Use readLineStderr() in response to a lineReadyStderr() signal or * when hasLineStderr() returns true. You may use it multiple times if * more than one line of data is available. If no complete line is * available the content of line is undefined and the function returns * false. * * @param line is used to store the line that was read. * @return if data was read or not */ bool readLineStandardError(QByteArray *line); =20 /** * Checks if a line is ready on stdout * * @return true if a complete line can be read */ bool hasLineStandardOutput(); /** * Checks if a line is ready on stdout * * @return true if a complete line can be read */ bool hasLineStandardError(); signals: /** * Emitted when there is a line of data available from stdout when ther= e was * previously none. * There may or may not be more than one line available for reading whe= n this * signal is emitted. */ void lineReadyStandardOutput(); /** * Emitted when there is a line of data available from stderr when ther= e was * previously none. * There may or may not be more than one line available for reading whe= n this * signal is emitted. */ void lineReadyStandardError(); private slots: Q_PRIVATE_SLOT(d, void _k_receivedStdout()) Q_PRIVATE_SLOT(d, void _k_receivedStderr()) private: KLineProcessPrivate* const d; }; #endif // GPGPROC_H --Boundary-01=_ruV0H+y8XhYD3XE-- --nextPart8695634.rKnhTJyKVc Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4-svn0 (GNU/Linux) iD8DBQBH0Vu1XKSJPmm5/E4RArs7AKCIegsYuxAO2h/jq6bHXUCWA5NrPwCfSq0H 7I7dHiGsqYoQhTUWTfPJyDc= =5GlW -----END PGP SIGNATURE----- --nextPart8695634.rKnhTJyKVc--