[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kmail-devel
Subject:    [PATCH] Fixes Bug#39626: kmail silently (!) stops saving huge attachments after ~ 1MB is written
From:       Ingo =?iso-8859-1?q?Kl=F6cker?= <ingo.kloecker () epost ! de>
Date:       2002-03-29 13:06:05
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

this bug was caused by the fact that the size of huge attachments 
doesn't fit in 6 hex digits (the KIO connection uses %6x for the 
length). An ugly hack was introduced in KDE 3.0.1 to fix this. But it 
was agreed that KMail shouldn't write all data at once.

Waldo wrote:
> The solution is to send smaller chunks, something like 64Kb or so.
> Sending 10Mb in a single chunk is a design error on the part of the
> application.

So sending the data in smaller chunks is what the attached patch does.
I tested it with small attachments (< 64 KB) and huge attachments (up to 
19 MB).

Please review!

Regards,
Ingo

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE8pGbDGnR+RTDgudgRAqxpAJ9VSNHiq4wQ853ITnXMFdCCgNbMvQCeN3hq
2dLej509MIB1UdO5Evz+N44=
=/Zk+
-----END PGP SIGNATURE-----

["write_data_in_64KB_chunks.diff" (text/x-diff)]

Index: kmkernel.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmkernel.h,v
retrieving revision 1.33
diff -u -3 -p -r1.33 kmkernel.h
--- kmkernel.h	2002/03/01 13:32:29	1.33
+++ kmkernel.h	2002/03/29 12:57:44
@@ -154,6 +154,7 @@ private:
   {
     KURL url;
     QByteArray data;
+    int offset;
   };
   QMap<KIO::Job *, putData> mPutJobs;
   /** previous KMail version. If different from current,
Index: kmkernel.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmkernel.cpp,v
retrieving revision 1.99
diff -u -3 -p -r1.99 kmkernel.cpp
--- kmkernel.cpp	2002/03/02 12:03:16	1.99
+++ kmkernel.cpp	2002/03/29 12:57:44
@@ -787,7 +787,7 @@ void KMKernel::byteArrayToRemoteFile(con
   bool overwrite)
 {
   KIO::Job *job = KIO::put(aURL, -1, overwrite, FALSE);
-  putData pd; pd.url = aURL; pd.data = aData;
+  putData pd; pd.url = aURL; pd.data = aData; pd.offset = 0;
   mPutJobs.insert(job, pd);
   connect(job, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
     SLOT(slotDataReq(KIO::Job*,QByteArray&)));
@@ -797,10 +797,27 @@ void KMKernel::byteArrayToRemoteFile(con
 
 void KMKernel::slotDataReq(KIO::Job *job, QByteArray &data)
 {
+  // send the data in 64 KB chunks
+  const int MAX_CHUNK_SIZE = 64*1024;
   QMap<KIO::Job*, putData>::Iterator it = mPutJobs.find(job);
   assert(it != mPutJobs.end());
-  data = (*it).data;
-  (*it).data = QByteArray();
+  int remainingBytes = (*it).data.size() - (*it).offset;
+  if( remainingBytes > MAX_CHUNK_SIZE )
+  {
+    // send MAX_CHUNK_SIZE bytes to the receiver (deep copy)
+    data.duplicate( (*it).data.data() + (*it).offset, MAX_CHUNK_SIZE );
+    (*it).offset += MAX_CHUNK_SIZE;
+    //kdDebug( 5006 ) << "Sending " << MAX_CHUNK_SIZE << " bytes ("
+    //                << remainingBytes - MAX_CHUNK_SIZE << " bytes remain)\n";
+  }
+  else
+  {
+    // send the remaining bytes to the receiver (deep copy)
+    data.duplicate( (*it).data.data() + (*it).offset, remainingBytes );
+    (*it).data = QByteArray();
+    (*it).offset = 0;
+    //kdDebug( 5006 ) << "Sending " << remainingBytes << " bytes\n";
+  }
 }
 
 void KMKernel::slotResult(KIO::Job *job)

_______________________________________________
KMail Developers mailing list
kmail@mail.kde.org
http://mail.kde.org/mailman/listinfo/kmail

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic