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:
naving%netscape.com 2002-04-05 23:52:28 +00:00
Родитель 837f42b949
Коммит 2c6aa0110b
9 изменённых файлов: 89 добавлений и 18 удалений

Просмотреть файл

@ -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");