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

List:       kmail-devel
Subject:    Re: [PATCH] Fixes Bug#39626: kmail silently (!) stops saving huge attachments after ~ 1MB is written
From:       Marc Mutz <Marc.Mutz () uni-bielefeld ! de>
Date:       2002-03-29 17:24:57
[Download RAW message or body]

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

On Friday 29 March 2002 14:06, Ingo Klöcker wrote:
<snip>
> 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).
<snip>

I'm working on a superior solution ;-) based on the feature of KMime::Codec's 
to maintain state between calls to the codecs.
  Attached is what I have so far. Since the qp decoder isn't ready yet, it is 
currently hard-coded to base64 only.

Disclaimer: I haven't even tried to compile this yet, much less trying to use 
it.

Marc

- -- 
Marc Mutz <mutz@kde.org>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE8pKNp3oWD+L2/6DgRAp5/AKCaaIpdEC8ETgHUF4V+nx8O3BLcTwCghwxL
FU2XmIxRs6TWWzJiWHa8pPY=
=6XIH
-----END PGP SIGNATURE-----

["attachmentsaver.h" (text/x-chdr)]

// -*- c++ -*-

#ifndef _KMAIL_ATTACHMENTSAVER_H_
#define _KMAIL_ATTACHMENTSAVER_H_

#include <qobject.h>
#include <qbytearray.h>
#include <kurl.h>

namespace KIO {
  class Job;
}
namespace KMime {
  class Decoder;
}

class AttachmentSaver : public QObject {
  Q_OBJECT
public:
  AttachmentSaver( const QByteArray & encodedBodyPart, const KURL & url,
		   bool overwrite=false, bool qp=false
		   QObject * parent=0, const char * name=0 );
  ~AttachmentSaver();

signals:
  void finished( AttachmentSaver *, bool success );

public slots:
  void slotDataReq( KIO::Job * job, QByteArray & data );
  void slotResult( KIO::Job * job );

protected slots:
  void slotChildFinished(bool);

protected:
  const QByteArray mData;
  const KURL mUrl;
  QByteArray::ConstIterator mIIt;
  KMime::Decoder * mDecoder;
  const bool mOverwrite : 1;
};


#endif // _KMAIL_ATTACHMENTSAVER_H_

["attachmentsaver.cpp" (text/x-c++src)]

#include "attachmentsaver.h"

#include <kmime_codecs.h>

#include <kio/job.h>
#include <kdebug.h>

using namespace KMime;
using namespace KIO;

AttachmentSaver::AttachmentSaver( const QByteArray & data, const KURL & url,
				  bool overwrite, bool qp,
				  QObject * parent, const char * name )
  : QObject( parent, name ),
    mData( data ),
    mUrl( url ),
    mDecoder( 0 ),
    mOverwrite( overwrite ),
    mInsideFinishing( false );
{
  // sanity checks:
  assert( !url.isEmpty() );
  assert( url.isValid() );
  kdFatal( qp, 5006 ) << "AttachmentSaver: quoted-printable is not yet supported!" << endl;

  // setup decoder machinery:
  mIIt = data.begin();
  Codec * codec = Codec::codecForName( "base64" );
  assert( codec );
  mDecoder = codec->makeDecoder();
  assert( mDecoder );

  // create a job and connect the signals:
  Job * job = put( mUrl, -1 /* no special permissions */,
		   overwrite, FALSE /* this is no resume */ );
  connect( job, SIGNAL(dataReq(KIO::Job*, QByteArray&)),
	   SLOT(slotDataReq(KIO::Job*, QByteArray&)) );
  connect( job, SIGNAL(result(KIO::Job*)),
	   SLOT(slotResult(KIO::Job*)) );

  // finally, delete this if done:
  connect( this, SIGNAL(finished(AttachmentSaver*,bool)),
	   SLOT(deleteLater()) );
}

void AttachmentSaver::slotDataReq( Job * job, QByteArray & data )
{
  // reserve space, but not more than 64k:
  data.resize( QMIN( 64*1024, mData.end() - mIIt ) );
  QByteArray::Iterator oit = data.begin();

  // first, we call decode() until either data is full or we are told
  // by the decoder that we should now proceed to calling finish():
  while ( !mDecoder->decode( mIIt, mData.end(), oit, data.end() ) )
    if ( oit == data.end() ) return;

  // now call finish until either the buffer is full or the decoder
  // signals that we should stop (because all data has been decoded):
  while ( !mDecoder->finish( oit, data.end() ) )
    if ( oit == data.end() ) return;

  // truncate the byte array to the actual size:
  data.truncate( oit - data.begin() );
}

void AttachmentSaver::slotResult( Job * job )
{
  if ( job->error() ) {
    if ( job->error() == ERR_FILE_ALREADY_EXIST ) {
      int result = KMessageBox::warningContinueCancel( 0,
            i18n("File %1 already exists.\n"
		 "Do you want to replace it?").arg( mUrl.prettyURL() ),
	    i18n("Save to file"), i18n("&Replace"));
      if ( result == KMessageBox::Continue ) {
	AttachmentSaver * saver =
	  new AttachmentSaver( mBody, mUrl, true, false, this );
	connect( saver, SIGNAL(finished(AttachmentSaver*,bool)),
		 SLOT(slotChildFinished(bool)) );
      } else {
	emit finished( this, false );
      }
    } else {
      job->showErrorDialog();
      emit finished( this, false );
    }
  } else
    emit finished( this, true );
}

void AttachmentSaver::slotChildFinished( bool success )
{
  emit finished( this, success );
}

AttachmentDialog::~AttachmentDialog()
{
  delete mDecoder;
}

_______________________________________________
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