[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