console_reader.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2008-2010  Lukas Sommer < SommerLuk at gmail dot com >
00003 
00004     This program is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU General Public License as
00006     published by the Free Software Foundation; either version 2 of
00007     the License or (at your option) version 3 or any later version
00008     accepted by the membership of KDE e.V. (or its successor approved
00009     by the membership of KDE e.V.), which shall act as a proxy
00010     defined in Section 14 of version 3 of the license.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "console_reader.h"
00022 
00023 console_reader::console_reader(QObject *parent) : QObject(parent)
00024 {
00025   internal_splitBehavior = QString::KeepEmptyParts;
00026   //set up m_process
00027   m_process.setOutputChannelMode(KProcess::MergedChannels); //merge stderr into stdout
00028   QObject::connect(&m_process,
00029                     SIGNAL(readyRead()),
00030                     this,
00031                     SLOT(read_console_output()));
00032 }
00033 
00034 console_reader::~console_reader()
00035 {
00036   m_process.kill();
00037   m_process.waitForFinished(-1);
00038 }
00039 
00040 QString console_reader::QByteArray_to_QString(QByteArray & m_byteArray)
00041 {
00042   return QString::fromLocal8Bit(m_byteArray);
00043 }
00044 
00045 void console_reader::read_console_output()
00046 {
00047   // variables
00048   QByteArray temp_bytearray;
00049   bool newLineAtTheEnd;
00050   QStringList m_output_lines;
00051 
00052   // code
00053 
00054   /* Append the process output data to our internal buffer: m_uncomplete_line.
00055   * Because readAllStandardOutput() delivers a Bytearray with the data
00056   * who's actually available, that's not always exactly 1 line, but maybe
00057   * a half line or various (and a half) lines - because of that,
00058   * we need this buffer. */
00059   temp_bytearray = m_process.readAllStandardOutput();
00060   m_uncomplete_line.append(QByteArray_to_QString(temp_bytearray));
00061   // attention: QByteArray_to_QString could modify the bytearray. Don't use the bytearray any more!
00062   /* Use a unified way for "new line": First replace "\x0D\x0A" by "\x0A",
00063   *  than replace also all single "\x0D" by "\x0A". Doing it in this order
00064   *  garanties that we have later exactly as many line breaks as before!
00065   *
00066   *  I'm not sure if C++ doesn't interpretate \n on Windows platform sometimes
00067   *  as (13, 10) instead of (10), so using hex numbers I make sure that
00068   *  that isn't relevant. */
00069   m_uncomplete_line.replace("\x0D\x0A", "\x0A");
00070   m_uncomplete_line.replace("\x0D", "\x0A");
00071 
00072   // now process the data in our internal buffer
00073   newLineAtTheEnd = m_uncomplete_line.endsWith(10);
00074   m_output_lines=m_uncomplete_line.split(10, internal_splitBehavior);
00075   if (m_output_lines.isEmpty()) {
00076     // the internal buffer is made empty (possibly there where \n characters...):
00077     m_uncomplete_line="";
00078   } else {
00079     if (! newLineAtTheEnd) {
00080       /* In this case, the last line in the buffer isn't yet completely written by
00081       the command line program. So this last line stays in the buffer waiting for
00082       being completed the next time when the process writes data. (The
00083       other - complete - lines, saved in m_output_lines, will be processed.) */
00084       m_uncomplete_line=m_output_lines.takeLast(); /* removes the last item from the
00085       list and returns it -> here saving it to the buffer. Works only if m_output_lines
00086       isn't empty - for this, you need to put all this block in the "else" block
00087       from  if (m_output_lines.isEmpty())... */
00088     } else {
00089       m_uncomplete_line="";  // in this case, the last line is completely written. So
00090       // the buffer is made empty, because all the data will be processed now.
00091     };
00092     if (! m_output_lines.isEmpty()) {
00093       interpretate_console_output(m_output_lines);  // process the data // attention:
00094       // interpretate_console_output could modify m_output_lines (isn't const). Don't
00095       // use m_output_lines any more!
00096     };
00097   };
00098 }

doxygen