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 }