SVN commit 633978 by dfaure: Reduce some more the memory consumption when sending Improve speed (mainly killing the reparsing which was done in KMMessage::asSendableString()) Kolab issue 1222 M +11 -8 index.cpp M +4 -10 kmcommands.cpp M +7 -7 kmfoldermbox.cpp M +1 -1 kmfoldermbox.h M +12 -7 kmmessage.cpp M +1 -1 kmmessage.h M +11 -0 kmmsgpart.cpp M +2 -0 kmmsgpart.h M +5 -5 kmsender.cpp M +6 -7 kmsender_p.h M +3 -5 objecttreeparser.cpp M +0 -2 tests/utiltests.cpp --- branches/KDE/3.5/kdepim/kmail/index.cpp #633977:633978 @@ -4,12 +4,12 @@ * KMail is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation. - * + * * KMail is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -66,6 +66,7 @@ return res; } + static std::vector QValueListToVector( const QValueList& input ) { std::vector res; @@ -90,7 +91,7 @@ //mSyncTimer( new QTimer( this ) ), mSlowDown( false ) { kdDebug( 5006 ) << "KMMsgIndex::KMMsgIndex()" << endl; - + connect( kmkernel->folderMgr(), SIGNAL( msgRemoved( KMFolder*, Q_UINT32 ) ), SLOT( slotRemoveMessage( KMFolder*, Q_UINT32 ) ) ); connect( kmkernel->folderMgr(), SIGNAL( msgAdded( KMFolder*, Q_UINT32 ) ), SLOT( slotAddMessage( KMFolder*, Q_UINT32 ) ) ); connect( kmkernel->dimapFolderMgr(), SIGNAL( msgRemoved( KMFolder*, Q_UINT32 ) ), SLOT( slotRemoveMessage( KMFolder*, Q_UINT32 ) ) ); @@ -227,7 +228,7 @@ //else fall-through case s_idle: case s_processing: - + case s_error: case s_disabled: // nothing can be done @@ -368,7 +369,7 @@ void KMMsgIndex::create() { kdDebug( 5006 ) << "KMMsgIndex::create()" << endl; - + #ifdef HAVE_INDEXLIB if ( !QFileInfo( mIndexPath ).exists() ) { ::mkdir( mIndexPath, S_IRWXU ); @@ -429,7 +430,7 @@ //} // //void KMMsgIndex::finishSync() { -// +// //} void KMMsgIndex::removeSearch( QObject* destroyed ) { @@ -483,9 +484,10 @@ } void KMMsgIndex::slotAddMessage( KMFolder* folder, Q_UINT32 serNum ) { + Q_UNUSED( folder ); kdDebug( 5006 ) << "KMMsgIndex::slotAddMessage( . , " << serNum << " )" << endl; if ( mState == s_error || mState == s_disabled ) return; - + if ( mState == s_creating ) mAddedMsgs.push_back( serNum ); else mPendingMsgs.push_back( serNum ); @@ -494,6 +496,7 @@ } void KMMsgIndex::slotRemoveMessage( KMFolder* folder, Q_UINT32 serNum ) { + Q_UNUSED( folder ); kdDebug( 5006 ) << "KMMsgIndex::slotRemoveMessage( . , " << serNum << " )" << endl; if ( mState == s_error || mState == s_disabled ) return; @@ -512,7 +515,7 @@ void KMMsgIndex::removeMessage( Q_UINT32 serNum ) { kdDebug( 5006 ) << "KMMsgIndex::removeMessage( " << serNum << " )" << endl; if ( mState == s_error || mState == s_disabled ) return; - + #ifdef HAVE_INDEXLIB mIndex->remove_doc( QString::number( serNum ).latin1() ); ++mMaintenanceCount; --- branches/KDE/3.5/kdepim/kmail/kmcommands.cpp #633977:633978 @@ -876,13 +876,11 @@ void KMSaveMsgCommand::slotMessageRetrievedForSaving(KMMessage *msg) { if ( msg ) { - QCString str( msg->mboxMessageSeparator() ); - str += KMFolderMbox::escapeFrom( msg->asString() ); - str += '\n'; + mData = KMFolderMbox::escapeFrom( msg->asDwString() ); + KMail::Util::insert( mData, 0, msg->mboxMessageSeparator() ); + KMail::Util::append( mData, "\n" ); msg->setTransferInProgress(false); - mData = str; - mData.resize(mData.size() - 1); mOffset = 0; QByteArray data; int size; @@ -1176,7 +1174,6 @@ if (msgList.count() >= 2) { // Multiple forward uint id = 0; - // QCString msgText = ""; QPtrList linklist; for ( KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) { // set the identity @@ -1476,7 +1473,6 @@ if (msgList.count() >= 2) { // Multiple forward uint id = 0; - // QCString msgText = ""; QPtrList linklist; for ( KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) { // set the identity @@ -2563,9 +2559,7 @@ { // This does not decode the Message Content-Transfer-Encoding // but saves the _original_ content of the message part - QCString cstr( node->msgPart().body() ); - data = cstr; - data.resize(data.size() - 1); + data = KMail::Util::ByteArray( node->msgPart().dwBody() ); } else { --- branches/KDE/3.5/kdepim/kmail/kmfoldermbox.cpp #633977:633978 @@ -870,12 +870,12 @@ } //static -QCString KMFolderMbox::escapeFrom( const QCString & str ) { +QByteArray KMFolderMbox::escapeFrom( const DwString & str ) { const unsigned int strLen = str.length(); if ( strLen <= STRDIM("From ") ) - return str; + return KMail::Util::ByteArray( str ); // worst case: \nFrom_\nFrom_\nFrom_... => grows to 7/6 - QCString result( int( strLen + 5 ) / 6 * 7 + 1 ); + QByteArray result( int( strLen + 5 ) / 6 * 7 + 1 ); const char * s = str.data(); const char * const e = s + strLen - STRDIM("From "); @@ -961,7 +961,7 @@ { if (!canAddMsgNow(aMsg, aIndex_ret)) return 0; bool opened = false; - QCString msgText; + QByteArray msgText; char endStr[3]; int idx = -1, rc; KMFolder* msgParent; @@ -1018,8 +1018,8 @@ if (aMsg->headerField("Content-Type").isEmpty()) // This might be added by aMsg->removeHeaderField("Content-Type"); // the line above } - msgText = escapeFrom( aMsg->asString() ); - size_t len = msgText.length(); + msgText = escapeFrom( aMsg->asDwString() ); + size_t len = msgText.size(); assert(mStream != 0); clearerr(mStream); @@ -1059,7 +1059,7 @@ QCString messageSeparator( aMsg->mboxMessageSeparator() ); fwrite( messageSeparator.data(), messageSeparator.length(), 1, mStream ); off_t offs = ftell(mStream); - fwrite(msgText, len, 1, mStream); + fwrite(msgText.data(), len, 1, mStream); if (msgText[(int)len-1]!='\n') fwrite("\n\n", 1, 2, mStream); fflush(mStream); size_t size = ftell(mStream) - offs; --- branches/KDE/3.5/kdepim/kmail/kmfoldermbox.h #633977:633978 @@ -109,7 +109,7 @@ void setProcmailLockFileName( const QString& ); - static QCString escapeFrom( const QCString & str ); + static QByteArray escapeFrom( const DwString & str ); virtual IndexStatus indexStatus(); --- branches/KDE/3.5/kdepim/kmail/kmmessage.cpp #633977:633978 @@ -311,19 +311,24 @@ } -QCString KMMessage::asSendableString() const +QByteArray KMMessage::asSendableString() const { KMMessage msg; - msg.fromDwString(asDwString()); // slow! + // Much faster than msg.fromDwString(asDwString()): + delete msg.mMsg; + msg.mMsg = new DwMessage( *mMsg ); + msg.removePrivateHeaderFields(); msg.removeHeaderField("Bcc"); - return msg.asString(); + return KMail::Util::ByteArray( msg.asDwString() ); // and another copy again! } QCString KMMessage::headerAsSendableString() const { KMMessage msg; - msg.fromDwString(asDwString()); + // Much faster than msg.fromDwString(asDwString()): + delete msg.mMsg; + msg.mMsg = new DwMessage( *mMsg ); msg.removePrivateHeaderFields(); msg.removeHeaderField("Bcc"); return msg.headerAsString().latin1(); @@ -2886,14 +2891,14 @@ void applyHeadersToMessagePart( DwHeaders& headers, KMMessagePart* aPart ) { - // TODO: Instead of manually implementing RFC2231 header encoding (i.e. - // possibly multiple values given as paramname*0=..; parmaname*1=..;... + // TODO: Instead of manually implementing RFC2231 header encoding (i.e. + // possibly multiple values given as paramname*0=..; parmaname*1=..;... // or par as paramname*0*=..; parmaname*1*=..;..., which should be // concatenated), use a generic method to decode the header, using RFC // 2047 or 2231, or whatever future RFC might be appropriate! // Right now, some fields are decoded, while others are not. E.g. // Content-Disposition is not decoded here, rather only on demand in - // KMMsgPart::fileName; Name however is decoded here and stored as a + // KMMsgPart::fileName; Name however is decoded here and stored as a // decoded String in KMMsgPart... // Content-type QCString additionalCTypeParams; --- branches/KDE/3.5/kdepim/kmail/kmmessage.h #633977:633978 @@ -230,7 +230,7 @@ * Return the message contents with the headers that should not be * sent stripped off. */ - QCString asSendableString() const; + QByteArray asSendableString() const; /** * Return the message header with the headers that should not be --- branches/KDE/3.5/kdepim/kmail/kmmsgpart.cpp #633977:633978 @@ -123,6 +123,17 @@ mBodyDecodedSize = -1; // Can't know the decoded size } +void KMMessagePart::setBody(const QByteArray &aStr) +{ + mBody = aStr; + + int enc = cte(); + if (enc == DwMime::kCte7bit || enc == DwMime::kCte8bit || enc == DwMime::kCteBinary) + mBodyDecodedSize = mBody.size(); + else + mBodyDecodedSize = -1; // Can't know the decoded size +} + void KMMessagePart::setBodyFromUnicode( const QString & str ) { QCString encoding = KMMsgBase::autoDetectCharset( charset(), KMMessage::preferredCharsets(), str ); if ( encoding.isEmpty() ) --- branches/KDE/3.5/kdepim/kmail/kmmsgpart.h #633977:633978 @@ -48,6 +48,8 @@ void setBody(const QCString &aStr); DwString dwBody() const; void setBody(const DwString &aStr); + // warning, doesn't detach from 'arr' + void setBody(const QByteArray &arr); /** Sets this body part's content to @p str. @p str is subject to automatic charset and CTE detection. --- branches/KDE/3.5/kdepim/kmail/kmsender.cpp #633977:633978 @@ -605,7 +605,7 @@ if ( messageIsDispositionNotificationReport( mCurrentMsg ) && GlobalSettings::self()->sendMDNsWithEmptySender() ) sender = "<>"; - const QCString message = mCurrentMsg->asSendableString(); + const QByteArray message = mCurrentMsg->asSendableString(); if ( sender.isEmpty() || !mSendProc->send( sender, to, cc, bcc, message ) ) { if ( mCurrentMsg ) mCurrentMsg->setTransferInProgress( false ); @@ -963,7 +963,7 @@ idle(); } -bool KMSendSendmail::doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QCString & message ) { +bool KMSendSendmail::doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QByteArray & message ) { mMailerProc->clearArguments(); *mMailerProc << mSender->transportInfo()->host << "-i" << "-f" << sender @@ -977,7 +977,7 @@ return false; } mMsgPos = mMsgStr.data(); - mMsgRest = mMsgStr.length(); + mMsgRest = mMsgStr.size(); wroteStdin( mMailerProc ); return true; @@ -1048,7 +1048,7 @@ if (mJob) mJob->kill(); } -bool KMSendSMTP::doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QCString & message ) { +bool KMSendSMTP::doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QByteArray & message ) { QString query = "headers=0&from="; query += KURL::encode_string( sender ); @@ -1119,7 +1119,7 @@ // dotstuffing is now done by the slave (see setting of metadata) mMessage = message; - mMessageLength = mMessage.length(); + mMessageLength = mMessage.size(); mMessageOffset = 0; if ( mMessageLength ) --- branches/KDE/3.5/kdepim/kmail/kmsender_p.h #633977:633978 @@ -6,7 +6,6 @@ #define __KMAIL_SENDER_P_H__ #include "kmsender.h" -#include #include #include #include @@ -33,7 +32,7 @@ void start() { emit started( doStart() ); } /** Send given message. May return before message is sent. */ - bool send( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QCString & message ) { + bool send( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QByteArray & message ) { reset(); return doSend( sender, to, cc, bcc, message ); } @@ -72,7 +71,7 @@ private: virtual void doFinish() = 0; - virtual bool doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QCString & message ) = 0; + virtual bool doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QByteArray & message ) = 0; virtual bool doStart() = 0; protected: @@ -102,12 +101,12 @@ /** implemented from KMSendProc */ void doFinish(); /** implemented from KMSendProc */ - bool doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QCString & message ); + bool doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QByteArray & message ); /** implemented from KMSendProc */ bool doStart(); private: - QCString mMsgStr; + QByteArray mMsgStr; char* mMsgPos; int mMsgRest; KProcess* mMailerProc; @@ -132,14 +131,14 @@ /** implemented from KMSendProc */ void doFinish(); /** implemented from KMSendProc */ - bool doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QCString & message ); + bool doSend( const QString & sender, const QStringList & to, const QStringList & cc, const QStringList & bcc, const QByteArray & message ); /** implemented from KMSendProc */ bool doStart() { return true; } void cleanup(); private: - QCString mMessage; + QByteArray mMessage; uint mMessageLength; uint mMessageOffset; --- branches/KDE/3.5/kdepim/kmail/objecttreeparser.cpp #633977:633978 @@ -970,9 +970,8 @@ } bool ObjectTreeParser::processTextPlainSubtype( partNode * curNode, ProcessResult & result ) { - const QCString cstr = curNode->msgPart().bodyDecoded(); if ( !mReader ) { - mRawReplyString = cstr; + mRawReplyString = curNode->msgPart().bodyDecoded(); if ( curNode->isFirstTextPart() ) { mTextualContent += curNode->msgPart().bodyToUnicode(); mTextualContentCharset = curNode->msgPart().charset(); @@ -980,13 +979,12 @@ return true; } - //resultingRawData += cstr; if ( !curNode->isFirstTextPart() && attachmentStrategy()->defaultDisplay( curNode ) != AttachmentStrategy::Inline && !showOnlyOneMimePart() ) return false; - mRawReplyString = cstr; + mRawReplyString = curNode->msgPart().bodyDecoded(); if ( curNode->isFirstTextPart() ) { mTextualContent += curNode->msgPart().bodyToUnicode(); mTextualContentCharset = curNode->msgPart().charset(); @@ -1029,7 +1027,7 @@ // enable verification of the embedded messages' signatures if ( !isMailmanMessage( curNode ) || !processMailmanMessage( curNode ) ) - writeBodyString( cstr, curNode->trueFromAddress(), + writeBodyString( mRawReplyString, curNode->trueFromAddress(), codecFor( curNode ), result, !bDrawFrame ); if ( bDrawFrame ) htmlWriter()->queue( "" ); --- branches/KDE/3.5/kdepim/kmail/tests/utiltests.cpp #633977:633978 @@ -65,8 +65,6 @@ } -// TODO port KMSender to DwString, port asSendableString - void UtilTester::test_append() { QCString test;