00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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);
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;
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
00234
00235 len = d->recvbuffer.indexOf('\n', d->rbi) - d->rbi;
00236
00237
00238
00239
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
00268 return -1;
00269
00270 }
00271
00272 #include "k3procio.moc"
00273