[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: [PATCH] KProcIO (Was: KProcess: Can't preload data to be piped to stdin?)
From: Waldo Bastian <bastian () kde ! org>
Date: 2002-03-01 6:52:07
[Download RAW message or body]
[If only I had used that attachment-missing-detection-patch]
On Friday 22 February 2002 04:07 am, Marc Mutz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On Thursday 21 February 2002 23:57, Waldo Bastian wrote:
> <snip>
>
> > > But for GnuPG, e.g., one wants to pipe binary data (e.g. a jpg to
> > > be encrypted).
> >
> > I guess I can fix that and add an overloaded fputs for QByteArray.
> > Would that work for you?
>
> I guess so. Thanks.
Please review the attached patch for KProcIO. It does:
* Adds closeWhenDone(), to close stdin after all data has been written.
* Uses outputbuffer based on QByteArray to make it possible to send binary
data.
* Removes a bunch of "virtuals" which are IMO useless.
Cheers,
Waldo
--
Advanced technology only happens when people take a basic idea and add to it.
-- Bob Bemer
["kprocio.diff" (text/x-diff)]
Index: kprocio.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kprocio.cpp,v
retrieving revision 1.22
diff -u -p -r1.22 kprocio.cpp
--- kprocio.cpp 2001/10/04 23:35:32 1.22
+++ kprocio.cpp 2002/03/01 06:37:20
@@ -34,6 +34,7 @@ KProcIO::KProcIO ( QTextCodec *_codec)
{
rbi=0;
readsignalon=writeready=TRUE;
+ outbuffer.setAutoDelete(true);
if (!codec)
{
@@ -45,11 +46,15 @@ KProcIO::KProcIO ( QTextCodec *_codec)
}
}
+KProcIO::~KProcIO()
+{
+}
+
void
KProcIO::resetAll ()
{
if (isRunning())
- kill();
+ kill();
clearArguments();
rbi=0;
@@ -64,7 +69,7 @@ KProcIO::resetAll ()
disconnect (this, SIGNAL (wroteStdin(KProcess *)),
this, SLOT (sent (KProcess *)));
- qlist.clear();
+ outbuffer.clear();
}
@@ -82,61 +87,96 @@ bool KProcIO::start (RunMode runmode, bo
connect (this, SIGNAL (wroteStdin(KProcess *)),
this, SLOT (sent (KProcess *)));
- qlist.setAutoDelete (TRUE);
-
return KProcess::start (runmode, KProcess::All);
}
bool KProcIO::writeStdin (const QString &line, bool appendnewline)
{
-
- QCString qs(codec->fromUnicode(line));
+ return writeStdin(codec->fromUnicode(line), appendnewline);
+}
+bool KProcIO::writeStdin (const QCString &line, bool appendnewline)
+{
+ QCString *qs = new QCString(line);
+
if (appendnewline)
- qs+='\n';
-
- qlist.append (qs.data());
+ {
+ *qs += '\n';
+ }
+
+ int l = qs->length();
+ if (!l)
+ return true;
- //kdDebug(750) << "KPIO::write [" << buffer << "],[" << qlist.current() << "]" << endl;
+ QByteArray *b = (QByteArray *) qs;
+ b->truncate(l); // Strip trailing null
+
+ outbuffer.append(b);
if (writeready)
- {
- kdDebug(750) << "really writing" << endl;
-
- writeready=FALSE;
- return KProcess::writeStdin (qlist.current(),
- strlen (qlist.current()));
- }
- kdDebug(750) << "NOT really writing" << endl;
- return TRUE;
+ {
+ writeready=FALSE;
+ return KProcess::writeStdin( b->data(), b->size() );
+ }
+ return true;
}
-void KProcIO::sent (KProcess *)
+bool KProcIO::writeStdin(const QByteArray &data)
{
- if (qlist.first()) kdDebug(750) << "KP::sent [" << qlist.first() << "]" << endl;
+ if (!data.size())
+ return true;
+ QByteArray *b = new QByteArray(data);
+ outbuffer.append(b);
+
+ if (writeready)
+ {
+ writeready=FALSE;
+ return KProcess::writeStdin( b->data(), b->size() );
+ }
+ return true;
+}
- qlist.removeFirst();
+void KProcIO::closeWhenDone()
+{
+ if (writeready)
+ {
+ closeStdin();
+ return;
+ }
+ outbuffer.append(0);
+
+ return;
+}
- if (qlist.count()==0)
- {
- kdDebug(750) << "Empty" << endl;
+void KProcIO::sent(KProcess *)
+{
+ outbuffer.removeFirst();
- writeready=TRUE;
- }
+ if (outbuffer.count()==0)
+ {
+ kdDebug(750) << "Empty" << endl;
+ writeready=TRUE;
+ }
else
- {
- kdDebug(750) << "Sending [" << qlist.first() << "]" << endl;
- KProcess::writeStdin (qlist.first(), strlen (qlist.first()));
- }
+ {
+ QByteArray *b = outbuffer.first();
+ if (!b)
+ {
+ kdDebug(750) << "Closing" << endl;
+ closeStdin();
+ }
+ else
+ {
+ kdDebug(750) << "Sending [" << b->size() << "]" << endl;
+ KProcess::writeStdin(b->data(), b->size());
+ }
+ }
}
void KProcIO::received (KProcess *, char *buffer, int buflen)
{
- int i;
-
- for (i=0;i<buflen;i++)
- recvbuffer+=buffer [i];
+ recvbuffer += QCString(buffer, buflen+1);
controlledEmission();
}
@@ -145,20 +185,21 @@ void KProcIO::ackRead ()
{
readsignalon=TRUE;
if (needreadsignal || recvbuffer.length()!=0)
- controlledEmission();
+ controlledEmission();
}
void KProcIO::controlledEmission ()
{
if (readsignalon)
- {
- needreadsignal=FALSE;
- readsignalon=FALSE; //will stay off until read is acknowledged
- emit readReady (this);
- }
+ {
+ needreadsignal=FALSE;
+ readsignalon=FALSE; //will stay off until read is acknowledged
+ emit readReady (this);
+ }
else
+ {
needreadsignal=TRUE;
-
+ }
}
void KProcIO::enableReadSignals (bool enable)
@@ -166,7 +207,7 @@ void KProcIO::enableReadSignals (bool en
readsignalon=enable;
if (enable && needreadsignal)
- emit readReady (this);
+ emit readReady (this);
}
int KProcIO::readln (QString &line, bool autoAck, bool *partial)
@@ -174,39 +215,39 @@ int KProcIO::readln (QString &line, bool
int len;
if (autoAck)
- readsignalon=TRUE;
+ readsignalon=TRUE;
//need to reduce the size of recvbuffer at some point...
len=recvbuffer.find ('\n',rbi)-rbi;
- kdDebug(750) << "KPIO::readln\n" << endl;
+ kdDebug(750) << "KPIO::readln" << endl;
//in case there's no '\n' at the end of the buffer
if ((len<0) &&
((unsigned int)rbi<recvbuffer.length()))
- {
- recvbuffer=recvbuffer.mid (rbi,recvbuffer.length()-rbi);
- rbi=0;
- if (partial)
- {
- len = recvbuffer.length();
- line = recvbuffer;
- recvbuffer = "";
- *partial = true;
- return len;
- }
- return -1;
- }
+ {
+ recvbuffer=recvbuffer.mid (rbi,recvbuffer.length()-rbi);
+ rbi=0;
+ if (partial)
+ {
+ len = recvbuffer.length();
+ line = recvbuffer;
+ recvbuffer = "";
+ *partial = true;
+ return len;
+ }
+ return -1;
+ }
if (len>=0)
- {
- line = codec->toUnicode(recvbuffer.mid(rbi,len), len);
- rbi += len+1;
- if (partial)
- *partial = false;
- return len;
- }
+ {
+ line = codec->toUnicode(recvbuffer.mid(rbi,len), len);
+ rbi += len+1;
+ if (partial)
+ *partial = false;
+ return len;
+ }
recvbuffer="";
rbi=0;
Index: kprocio.h
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kprocio.h,v
retrieving revision 1.11
diff -u -p -r1.11 kprocio.h
--- kprocio.h 2002/01/22 17:36:08 1.11
+++ kprocio.h 2002/03/01 06:37:20
@@ -56,6 +56,8 @@ class KProcIO : public KProcess
public:
KProcIO ( QTextCodec *codec = 0 );
+ ~KProcIO();
+
/**
* Starts the process.
*
@@ -79,20 +81,30 @@ public:
bool start (RunMode runmode = NotifyOnExit, bool includeStderr = false);
/**
- * The buffer is zero terminated.
- * A deep copy is made of the buffer, so you don't
- * need to bother with that. A newline ( '\n' ) is appended
- * unless you specify FALSE as the second parameter.
- * FALSE is returned on an error, or else TRUE is.
+ * Writes text to stdin of the process.
+ * @param line Text to write.
+ * @param AppendNewLine if true, a newline '\n' is appended.
**/
- virtual bool writeStdin(const QString &line, bool AppendNewLine=TRUE);
+ bool writeStdin(const QString &line, bool AppendNewLine=TRUE);
+ bool writeStdin(const QCString &line, bool appendnewline);
+ /**
+ * Writes data to stdin of the process.
+ * @param data Data to write.
+ **/
+ bool writeStdin(const QByteArray &data);
+
//I like fputs better -- it's the same as writeStdin
//inline
bool fputs (const QString &line, bool AppendNewLine=TRUE)
{ return writeStdin(line, AppendNewLine); }
/**
+ * closes stdin after all data has been send.
+ */
+ void closeWhenDone();
+
+ /**
* reads a line of text (up to and including '\n')
*
* Use readln() in response to a readReady() signal.
@@ -113,7 +125,7 @@ public:
*
* @return the number of characters read, or -1 if no data is available.
**/
- virtual int readln (QString &line, bool autoAck=true, bool *partial=0);
+ int readln (QString &line, bool autoAck=true, bool *partial=0);
int fgets (QString &line, bool autoAck=false)
{ return readln (line, autoAck); }
@@ -121,7 +133,7 @@ public:
/**
* Reset the class. Doesn't kill the process.
**/
- virtual void resetAll ();
+ void resetAll ();
/**
* Call this after you have finished processing a readReady()
@@ -132,7 +144,7 @@ public:
* data. If this doesn't matter, then call ackRead() right away in
* your readReady()-processing slot.
**/
- virtual void ackRead ();
+ void ackRead ();
/**
* Turns readReady() signals on and off.
@@ -145,7 +157,7 @@ signals:
void readReady(KProcIO *);
protected:
- QStrList qlist;
+ QPtrList<QByteArray> outbuffer;
QCString recvbuffer;
QTextCodec *codec;
int rbi;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic