зеркало из https://github.com/mozilla/pjs.git
122361 r=bienvenu sr=sspitzer a=asa. Share the output file stream created for downloading pop3 messages with
the db, so that we don't have two streams writing to Inbox - in case the user reads/deletes mail while downloading.
This commit is contained in:
Родитель
837f42b949
Коммит
2c6aa0110b
|
@ -52,6 +52,7 @@ interface nsIMsgThread;
|
|||
interface nsIDBFolderInfo;
|
||||
interface nsIMsgOfflineImapOperation;
|
||||
interface nsIMsgFolder;
|
||||
interface nsIOFileStream;
|
||||
|
||||
[ptr] native octetPtr(PRUint8);
|
||||
|
||||
|
@ -269,5 +270,7 @@ interface nsIMsgDatabase : nsIDBChangeAnnouncer {
|
|||
|
||||
// for msg hdr hash table allocation. controllable by caller to improve folder loading preformance.
|
||||
attribute unsigned long msgHdrCacheSize;
|
||||
|
||||
void setFolderStream(in nsIOFileStream aFileStream);
|
||||
};
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
NS_IMETHOD DeleteMessages(nsMsgKeyArray* nsMsgKeys, nsIDBChangeListener *instigator);
|
||||
virtual nsresult AdjustExpungedBytesOnDelete(nsIMsgDBHdr *msgHdr);
|
||||
|
||||
NS_IMETHOD SetFolderStream(nsIOFileStream *aFileStream);
|
||||
|
||||
protected:
|
||||
// IMAP does not set local file flags, override does nothing
|
||||
virtual void UpdateFolderFlag(nsIMsgDBHdr *msgHdr, PRBool bSet,
|
||||
|
|
|
@ -83,6 +83,8 @@ public:
|
|||
NS_IMETHOD ListAllOfflineOpIds(nsMsgKeyArray *offlineOpIds);
|
||||
NS_IMETHOD ListAllOfflineDeletes(nsMsgKeyArray *offlineDeletes);
|
||||
|
||||
NS_IMETHOD SetFolderStream(nsIOFileStream *aFileStream);
|
||||
|
||||
friend class nsMsgOfflineOpEnumerator;
|
||||
protected:
|
||||
|
||||
|
@ -103,6 +105,7 @@ protected:
|
|||
PRBool m_reparse;
|
||||
nsFileSpec *m_folderSpec;
|
||||
nsIOFileStream *m_folderStream; /* this is a cache for loops which want file left open */
|
||||
PRBool m_ownFolderStream; //if we are the owner of m_folderStream
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -215,4 +215,9 @@ nsresult nsImapMailDatabase::AdjustExpungedBytesOnDelete(nsIMsgDBHdr *msgHdr)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailDatabase::SetFolderStream(nsIOFileStream *aFileStream)
|
||||
{
|
||||
NS_ASSERTION(0, "Trying to set folderStream, not implemented");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ struct mdbOid gAllOfflineOpsTableOID;
|
|||
|
||||
|
||||
nsMailDatabase::nsMailDatabase()
|
||||
: m_reparse(PR_FALSE), m_folderSpec(nsnull), m_folderStream(nsnull)
|
||||
: m_reparse(PR_FALSE), m_folderSpec(nsnull), m_folderStream(nsnull), m_ownFolderStream(PR_FALSE)
|
||||
{
|
||||
m_mdbAllOfflineOpsTable = nsnull;
|
||||
}
|
||||
|
@ -68,6 +68,12 @@ nsMailDatabase::~nsMailDatabase()
|
|||
m_mdbAllOfflineOpsTable->Release();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::SetFolderStream(nsIOFileStream *aFileStream)
|
||||
{
|
||||
m_folderStream = aFileStream; //m_folderStream is set externally, so m_ownFolderStream is false
|
||||
m_ownFolderStream = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::Open(nsIFileSpec *aFolderName, PRBool create, PRBool upgrading, nsIMsgDatabase** pMessageDB)
|
||||
|
@ -235,20 +241,29 @@ NS_IMETHODIMP nsMailDatabase::StartBatch()
|
|||
{
|
||||
#ifndef XP_MAC
|
||||
if (!m_folderStream)
|
||||
m_folderStream = new nsIOFileStream(nsFileSpec(*m_folderSpec));
|
||||
{
|
||||
m_folderStream = new nsIOFileStream(nsFileSpec(*m_folderSpec));
|
||||
m_ownFolderStream = PR_TRUE;
|
||||
}
|
||||
else
|
||||
m_ownFolderStream = PR_FALSE; //better to set it, if EndBatch was not called last time
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::EndBatch()
|
||||
{
|
||||
#ifndef XP_MAC
|
||||
if (m_folderStream)
|
||||
#ifndef XP_MAC //only if we own the stream, then we should close it
|
||||
if (m_ownFolderStream)
|
||||
{
|
||||
m_folderStream->close();
|
||||
delete m_folderStream;
|
||||
if (m_folderStream)
|
||||
{
|
||||
m_folderStream->close();
|
||||
delete m_folderStream;
|
||||
}
|
||||
m_folderStream = nsnull;
|
||||
m_ownFolderStream = PR_FALSE;
|
||||
}
|
||||
m_folderStream = nsnull;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -258,14 +273,21 @@ NS_IMETHODIMP nsMailDatabase::DeleteMessages(nsMsgKeyArray* nsMsgKeys, nsIDBChan
|
|||
{
|
||||
nsresult ret = NS_OK;
|
||||
if (!m_folderStream)
|
||||
{
|
||||
m_folderStream = new nsIOFileStream(nsFileSpec(*m_folderSpec));
|
||||
m_ownFolderStream = PR_TRUE;
|
||||
}
|
||||
ret = nsMsgDatabase::DeleteMessages(nsMsgKeys, instigator);
|
||||
if (m_folderStream)
|
||||
if (m_ownFolderStream)//only if we own the stream, then we should close it
|
||||
{
|
||||
if (m_folderStream)
|
||||
{
|
||||
m_folderStream->close();
|
||||
delete m_folderStream;
|
||||
delete m_folderStream;
|
||||
}
|
||||
m_folderStream = NULL;
|
||||
m_folderStream = nsnull;
|
||||
m_ownFolderStream = PR_FALSE;
|
||||
}
|
||||
SetFolderInfoValid(m_folderSpec, 0, 0);
|
||||
return ret;
|
||||
}
|
||||
|
@ -276,7 +298,7 @@ PRBool nsMailDatabase::SetHdrFlag(nsIMsgDBHdr *msgHdr, PRBool bSet, MsgFlags fla
|
|||
{
|
||||
nsIOFileStream *fileStream = NULL;
|
||||
PRBool ret = PR_FALSE;
|
||||
|
||||
|
||||
if (nsMsgDatabase::SetHdrFlag(msgHdr, bSet, flag))
|
||||
{
|
||||
UpdateFolderFlag(msgHdr, bSet, flag, &fileStream);
|
||||
|
@ -288,6 +310,7 @@ PRBool nsMailDatabase::SetHdrFlag(nsIMsgDBHdr *msgHdr, PRBool bSet, MsgFlags fla
|
|||
}
|
||||
ret = PR_TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -916,4 +939,3 @@ NS_IMETHODIMP nsMsgOfflineOpEnumerator::HasMoreElements(PRBool *aResult)
|
|||
*aResult = !mDone;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -4309,3 +4309,10 @@ NS_IMETHODIMP nsMsgDatabase::ResetHdrCacheSize(PRUint32 aSize)
|
|||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDatabase::SetFolderStream(nsIOFileStream *aFileStream)
|
||||
{
|
||||
NS_ASSERTION(0, "Trying to set the folderStream, not implemented");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
interface nsIMsgDatabase;
|
||||
interface nsIMsgDBHdr;
|
||||
interface nsIOFileStream;
|
||||
|
||||
%{C++
|
||||
#include "nsIMsgDatabase.h"
|
||||
|
@ -52,6 +53,7 @@ interface nsIMsgParseMailMsgState : nsISupports {
|
|||
|
||||
attribute unsigned long envelopePos;
|
||||
void SetMailDB(in nsIMsgDatabase aDatabase);
|
||||
void setDBFolderStream(in nsIOFileStream fileStream);
|
||||
void Clear();
|
||||
|
||||
void ParseAFolderLine(in string line, in unsigned long lineLength);
|
||||
|
|
|
@ -644,6 +644,14 @@ NS_IMETHODIMP nsParseMailMessageState::SetMailDB(nsIMsgDatabase *mailDB)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsParseMailMessageState::SetDBFolderStream(nsIOFileStream *fileStream)
|
||||
{
|
||||
NS_ASSERTION(m_mailDB, "m_mailDB is not set");
|
||||
if (m_mailDB)
|
||||
m_mailDB->SetFolderStream(fileStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* #define STRICT_ENVELOPE */
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -193,11 +193,17 @@ nsPop3Sink::BeginMailDelivery(PRBool uidlDownload, nsIMsgWindow *aMsgWindow, PRB
|
|||
rv = m_newMailParser->Init(serverFolder, m_folder, fileSpec, m_outFileStream, aMsgWindow);
|
||||
// if we failed to initialize the parser, then just don't use it!!!
|
||||
// we can still continue without one...
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
NS_IF_RELEASE(m_newMailParser);
|
||||
rv = NS_OK;
|
||||
}
|
||||
{
|
||||
NS_IF_RELEASE(m_newMailParser);
|
||||
rv = NS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Share the inbox fileStream so that moz-status-line flags can be set in the Inbox
|
||||
m_newMailParser->SetDBFolderStream(m_outFileStream);
|
||||
}
|
||||
|
||||
if (uidlDownload && m_newMailParser)
|
||||
m_newMailParser->DisableFilters();
|
||||
|
@ -218,6 +224,7 @@ nsPop3Sink::EndMailDelivery()
|
|||
if (m_outFileStream)
|
||||
m_outFileStream->flush(); // try this.
|
||||
m_newMailParser->OnStopRequest(nsnull, nsnull, NS_OK);
|
||||
m_newMailParser->SetDBFolderStream(nsnull); // stream is going away
|
||||
}
|
||||
if (m_outFileStream)
|
||||
{
|
||||
|
@ -256,6 +263,9 @@ nsPop3Sink::ReleaseFolderLock()
|
|||
nsresult
|
||||
nsPop3Sink::AbortMailDelivery()
|
||||
{
|
||||
if (m_newMailParser)
|
||||
m_newMailParser->SetDBFolderStream(nsnull); //stream is going away
|
||||
|
||||
if (m_outFileStream)
|
||||
{
|
||||
if (m_outFileStream->is_open())
|
||||
|
@ -268,7 +278,6 @@ nsPop3Sink::AbortMailDelivery()
|
|||
we have truncated the inbox, so berkeley mailbox and msf file are in sync*/
|
||||
if (m_newMailParser)
|
||||
m_newMailParser->UpdateDBFolderInfo();
|
||||
|
||||
nsresult rv = ReleaseFolderLock();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"folder lock not released successfully");
|
||||
|
||||
|
@ -438,6 +447,11 @@ nsresult nsPop3Sink::WriteLineToMailbox(char *buffer)
|
|||
// See bug 62480
|
||||
if (!m_outFileStream)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
/*This file stream is also used by db so file pos could have changed
|
||||
set it to the end of the file before writing anything */
|
||||
|
||||
m_outFileStream->seek(PR_SEEK_END, 0);
|
||||
PRInt32 bytes = m_outFileStream->write(buffer,bufferLen);
|
||||
if (bytes != bufferLen) return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -461,7 +475,12 @@ nsPop3Sink::IncorporateComplete(nsIMsgWindow *msgWindow)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ASSERTION(m_newMailParser, "could not get m_newMailParser");
|
||||
if (m_newMailParser)
|
||||
m_newMailParser->PublishMsgHeader(msgWindow);
|
||||
{
|
||||
m_newMailParser->PublishMsgHeader(msgWindow);
|
||||
|
||||
//PublishMsgHeader might have changed the postion of file stream pointer, reset it back.
|
||||
m_outFileStream->seek(PR_SEEK_END, 0);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Incorporate message complete.\n");
|
||||
|
|
Загрузка…
Ссылка в новой задаче