KDE3Support
k3procio.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1997 David Sweet <dsweet@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "k3procio.h" 00020 00021 #include <config.h> 00022 #include <stdio.h> 00023 00024 #include <kdebug.h> 00025 #include <QtCore/QTextCodec> 00026 00027 class KProcIOPrivate 00028 { 00029 public: 00030 KProcIOPrivate( QTextCodec* c ) 00031 : codec( c ), 00032 rbi( 0 ), 00033 readsignalon( true ), 00034 writeready( true ), 00035 comm(K3Process::All) 00036 { 00037 } 00038 00039 QList<QByteArray *> outbuffer; 00040 QByteArray recvbuffer; 00041 QTextCodec *codec; 00042 int rbi; 00043 bool needreadsignal; 00044 bool readsignalon; 00045 bool writeready; 00046 K3Process::Communication comm; 00047 }; 00048 00049 K3ProcIO::K3ProcIO ( QTextCodec *_codec) 00050 : d( new KProcIOPrivate( _codec ) ) 00051 { 00052 if ( !d->codec ) { 00053 d->codec = QTextCodec::codecForName( "ISO 8859-1" ); 00054 if ( !d->codec ) { 00055 kError( 174 ) << "Can't create ISO 8859-1 codec!" << endl; 00056 } 00057 } 00058 } 00059 00060 K3ProcIO::~K3ProcIO() 00061 { 00062 qDeleteAll( d->outbuffer ); 00063 delete d; 00064 } 00065 00066 void 00067 K3ProcIO::resetAll () 00068 { 00069 if (isRunning()) { 00070 kill(); 00071 } 00072 00073 clearArguments(); 00074 d->rbi = 0; 00075 d->readsignalon = true; 00076 d->writeready = true; 00077 00078 disconnect (this, SIGNAL (receivedStdout (K3Process *, char *, int)), 00079 this, SLOT (received (K3Process *, char *, int))); 00080 00081 disconnect (this, SIGNAL (receivedStderr (K3Process *, char *, int)), 00082 this, SLOT (received (K3Process *, char *, int))); 00083 00084 disconnect (this, SIGNAL (wroteStdin(K3Process *)), 00085 this, SLOT (sent (K3Process *))); 00086 00087 qDeleteAll( d->outbuffer ); 00088 d->outbuffer.clear(); 00089 } 00090 00091 void K3ProcIO::setComm (Communication comm) 00092 { 00093 d->comm = comm; 00094 } 00095 00096 bool K3ProcIO::start (RunMode runmode, bool includeStderr) 00097 { 00098 connect (this, SIGNAL (receivedStdout (K3Process *, char *, int)), 00099 this, SLOT (received (K3Process *, char *, int))); 00100 00101 if (includeStderr) 00102 { 00103 connect (this, SIGNAL (receivedStderr (K3Process *, char *, int)), 00104 this, SLOT (received (K3Process *, char *, int))); 00105 } 00106 00107 connect (this, SIGNAL (wroteStdin(K3Process *)), 00108 this, SLOT (sent (K3Process *))); 00109 00110 return K3Process::start (runmode, d->comm); 00111 } 00112 00113 bool K3ProcIO::writeStdin (const QString &line, bool appendnewline) 00114 { 00115 return writeStdin( d->codec->fromUnicode( line ), appendnewline ); 00116 } 00117 00118 bool K3ProcIO::writeStdin (const QByteArray &line, bool appendnewline) 00119 { 00120 QByteArray *qs = new QByteArray(line); 00121 00122 if (appendnewline) 00123 { 00124 *qs += '\n'; 00125 } 00126 00127 int l = qs->length(); 00128 if (!l) 00129 { 00130 delete qs; 00131 return true; 00132 } 00133 00134 QByteArray *b = (QByteArray *) qs; 00135 b->truncate(l); // Strip trailing null 00136 00137 d->outbuffer.append(b); 00138 00139 if ( d->writeready ) { 00140 d->writeready = false; 00141 return K3Process::writeStdin( b->data(), b->size() ); 00142 } 00143 00144 return true; 00145 } 00146 00147 bool K3ProcIO::writeStdin(const QByteArray &data) 00148 { 00149 if (!data.size()) { 00150 return true; 00151 } 00152 QByteArray *b = new QByteArray(data); 00153 d->outbuffer.append(b); 00154 00155 if ( d->writeready ) { 00156 d->writeready=false; 00157 return K3Process::writeStdin( b->data(), b->size() ); 00158 } 00159 00160 return true; 00161 } 00162 00163 void K3ProcIO::closeWhenDone() 00164 { 00165 if (d->writeready) { 00166 closeStdin(); 00167 return; 00168 } 00169 d->outbuffer.append(0); 00170 00171 return; 00172 } 00173 00174 void K3ProcIO::sent(K3Process *) 00175 { 00176 d->outbuffer.removeFirst(); 00177 00178 if ( d->outbuffer.count() == 0 ) { 00179 d->writeready = true; 00180 } else { 00181 QByteArray *b = d->outbuffer.first(); 00182 if (!b) { 00183 closeStdin(); 00184 } else { 00185 K3Process::writeStdin(b->data(), b->size()); 00186 } 00187 } 00188 } 00189 00190 void K3ProcIO::received (K3Process *, char *buffer, int buflen) 00191 { 00192 d->recvbuffer += QByteArray(buffer, buflen); 00193 00194 controlledEmission(); 00195 } 00196 00197 void K3ProcIO::ackRead () 00198 { 00199 d->readsignalon = true; 00200 if ( d->needreadsignal || d->recvbuffer.length() != 0 ) { 00201 controlledEmission(); 00202 } 00203 } 00204 00205 void K3ProcIO::controlledEmission () 00206 { 00207 if ( d->readsignalon ) { 00208 d->needreadsignal = false; 00209 d->readsignalon = false; //will stay off until read is acknowledged 00210 emit readReady (this); 00211 } else { 00212 d->needreadsignal = true; 00213 } 00214 } 00215 00216 void K3ProcIO::enableReadSignals (bool enable) 00217 { 00218 d->readsignalon = enable; 00219 00220 if ( enable && d->needreadsignal ) { 00221 emit readReady(this); 00222 } 00223 } 00224 00225 int K3ProcIO::readln (QString &line, bool autoAck, bool *partial) 00226 { 00227 int len; 00228 00229 if ( autoAck ) { 00230 d->readsignalon=true; 00231 } 00232 00233 //need to reduce the size of recvbuffer at some point... 00234 00235 len = d->recvbuffer.indexOf('\n', d->rbi) - d->rbi; 00236 00237 //kDebug(174) << "KPIO::readln" << endl; 00238 00239 //in case there's no '\n' at the end of the buffer 00240 if ( ( len < 0 ) && 00241 ( d->rbi < d->recvbuffer.length() ) ) { 00242 d->recvbuffer = d->recvbuffer.mid( d->rbi ); 00243 d->rbi = 0; 00244 if (partial) 00245 { 00246 len = d->recvbuffer.length(); 00247 line = d->recvbuffer; 00248 d->recvbuffer = ""; 00249 *partial = true; 00250 return len; 00251 } 00252 return -1; 00253 } 00254 00255 if (len>=0) 00256 { 00257 line = d->codec->toUnicode( d->recvbuffer.mid( d->rbi, len ) ); 00258 d->rbi += len + 1; 00259 if (partial) 00260 *partial = false; 00261 return len; 00262 } 00263 00264 d->recvbuffer = ""; 00265 d->rbi = 0; 00266 00267 //-1 on return signals "no more data" not error 00268 return -1; 00269 00270 } 00271 00272 #include "k3procio.moc" 00273
KDE 4.6 API Reference