add support for counting lines in offline messages so that offline message body search will work, r=naving, sr=sspitzer, a=blizzard 79723

git-svn-id: svn://10.0.0.236/trunk@95968 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bienvenu%netscape.com
2001-05-26 21:49:14 +00:00
parent 8e5c6c7d42
commit fe15e59b3c
9 changed files with 858 additions and 856 deletions

View File

@@ -11,76 +11,73 @@
class nsMsgBodyHandler
{
public:
nsMsgBodyHandler (nsIMsgSearchScopeTerm *,
PRUint32 offset,
PRUint32 length,
nsIMsgDBHdr * msg,
nsIMsgDatabase * db);
// we can also create a body handler when doing arbitrary header
// filtering...we need the list of headers and the header size as well
// if we are doing filtering...if ForFilters is false, headers and
// headersSize is ignored!!!
nsMsgBodyHandler (nsIMsgSearchScopeTerm *, PRUint32 offset,
PRUint32 length, nsIMsgDBHdr * msg, nsIMsgDatabase * db,
const char * headers /* NULL terminated list of headers */,
PRUint32 headersSize, PRBool ForFilters);
virtual ~nsMsgBodyHandler();
// returns next message line in buf, up to bufSize bytes.
PRInt32 GetNextLine(char * buf, int bufSize);
// Transformations
void SetStripHtml (PRBool strip) { m_stripHtml = strip; }
void SetStripHeaders (PRBool strip) { m_stripHeaders = strip; }
nsMsgBodyHandler (nsIMsgSearchScopeTerm *,
PRUint32 offset,
PRUint32 length,
nsIMsgDBHdr * msg,
nsIMsgDatabase * db);
// we can also create a body handler when doing arbitrary header
// filtering...we need the list of headers and the header size as well
// if we are doing filtering...if ForFilters is false, headers and
// headersSize is ignored!!!
nsMsgBodyHandler (nsIMsgSearchScopeTerm *, PRUint32 offset,
PRUint32 length, nsIMsgDBHdr * msg, nsIMsgDatabase * db,
const char * headers /* NULL terminated list of headers */,
PRUint32 headersSize, PRBool ForFilters);
virtual ~nsMsgBodyHandler();
// returns next message line in buf, up to bufSize bytes.
PRInt32 GetNextLine(char * buf, int bufSize);
// Transformations
void SetStripHtml (PRBool strip) { m_stripHtml = strip; }
void SetStripHeaders (PRBool strip) { m_stripHeaders = strip; }
protected:
void Initialize(); // common initialization code
// filter related methods. For filtering we always use the headers
// list instead of the database...
PRBool m_Filtering;
PRInt32 GetNextFilterLine(char * buf, PRUint32 bufSize);
// pointer into the headers list in the original message hdr db...
const char * m_headers;
PRUint32 m_headersSize;
PRUint32 m_headerBytesRead;
// local / POP related methods
void OpenLocalFolder();
// goes through the mail folder
PRInt32 GetNextLocalLine(char * buf, int bufSize);
nsIMsgSearchScopeTerm *m_scope;
// local file state
// XP_File *m_localFile;
// need a file stream here, I bet
// current offset into the mail folder file.
PRInt32 m_localFileOffset;
PRUint32 m_numLocalLines;
// Offline IMAP related methods & state
// goes through the MessageDB
PRInt32 GetNextIMAPLine(char * buf, int bufSize);
nsIMsgDBHdr * m_msgHdr;
nsIMsgDatabase * m_db;
PRInt32 m_IMAPMessageOffset;
// News related methods & state
PRInt32 m_NewsArticleOffset;
// Transformations
PRBool m_stripHeaders; // PR_TRUE if we're supposed to strip of message headers
PRBool m_stripHtml; // PR_TRUE if we're supposed to strip off HTML tags
PRBool m_passedHeaders; // PR_TRUE if we've already skipped over the headers
PRBool m_messageIsHtml; // PR_TRUE if the Content-type header claims text/html
PRInt32 ApplyTransformations (char *buf, PRInt32 length, PRBool &returnThisLine);
void StripHtml (char *buf);
void Initialize(); // common initialization code
// filter related methods. For filtering we always use the headers
// list instead of the database...
PRBool m_Filtering;
PRInt32 GetNextFilterLine(char * buf, PRUint32 bufSize);
// pointer into the headers list in the original message hdr db...
const char * m_headers;
PRUint32 m_headersSize;
PRUint32 m_headerBytesRead;
// local / POP related methods
void OpenLocalFolder();
// goes through the mail folder
PRInt32 GetNextLocalLine(char * buf, int bufSize);
nsIMsgSearchScopeTerm *m_scope;
nsCOMPtr <nsIFileSpec> m_fileSpec;
// local file state
// XP_File *m_localFile;
// need a file stream here, I bet
// current offset into the mail folder file.
PRInt32 m_localFileOffset;
PRUint32 m_numLocalLines;
// Offline IMAP related methods & state
nsIMsgDBHdr * m_msgHdr;
nsIMsgDatabase * m_db;
// News related methods & state
PRInt32 m_NewsArticleOffset;
// Transformations
PRBool m_stripHeaders; // PR_TRUE if we're supposed to strip of message headers
PRBool m_stripHtml; // PR_TRUE if we're supposed to strip off HTML tags
PRBool m_passedHeaders; // PR_TRUE if we've already skipped over the headers
PRBool m_messageIsHtml; // PR_TRUE if the Content-type header claims text/html
PRInt32 ApplyTransformations (char *buf, PRInt32 length, PRBool &returnThisLine);
void StripHtml (char *buf);
};
#endif

View File

@@ -36,29 +36,28 @@
class nsMsgSearchScopeTerm : public nsIMsgSearchScopeTerm
{
public:
nsMsgSearchScopeTerm (nsIMsgSearchSession *, nsMsgSearchScopeValue, nsIMsgFolder *);
nsMsgSearchScopeTerm ();
virtual ~nsMsgSearchScopeTerm ();
NS_DECL_ISUPPORTS
NS_DECL_NSIMSGSEARCHSCOPETERM
nsMsgSearchScopeTerm (nsIMsgSearchSession *, nsMsgSearchScopeValue, nsIMsgFolder *);
nsMsgSearchScopeTerm ();
virtual ~nsMsgSearchScopeTerm ();
NS_DECL_ISUPPORTS
NS_DECL_NSIMSGSEARCHSCOPETERM
PRBool IsOfflineNews();
PRBool IsOfflineMail ();
PRBool IsOfflineIMAPMail(); // added by mscott
nsresult TimeSlice (PRBool *aDone);
nsresult InitializeAdapter (nsISupportsArray *termList);
char *GetStatusBarName ();
nsMsgSearchScopeValue m_attribute;
char *m_name;
nsCOMPtr <nsIMsgFolder> m_folder;
nsCOMPtr <nsIMsgSearchAdapter> m_adapter;
PRBool IsOfflineNews();
PRBool IsOfflineMail ();
nsresult TimeSlice (PRBool *aDone);
nsresult InitializeAdapter (nsISupportsArray *termList);
char *GetStatusBarName ();
nsMsgSearchScopeValue m_attribute;
char *m_name;
nsCOMPtr <nsIMsgFolder> m_folder;
nsCOMPtr <nsIMsgSearchAdapter> m_adapter;
nsCOMPtr <nsIMsgSearchSession> m_searchSession;
PRBool m_searchServer;
PRBool m_searchServer;
};
#endif

View File

@@ -30,20 +30,20 @@
nsMsgBodyHandler::nsMsgBodyHandler (nsIMsgSearchScopeTerm * scope, PRUint32 offset, PRUint32 numLines, nsIMsgDBHdr* msg, nsIMsgDatabase * db)
{
m_scope = scope;
m_localFileOffset = offset;
m_numLocalLines = numLines;
m_msgHdr = msg;
m_db = db;
// the following are variables used when the body handler is handling stuff from filters....through this constructor, that is not the
// case so we set them to NULL.
m_headers = NULL;
m_headersSize = 0;
m_Filtering = PR_FALSE; // make sure we set this before we call initialize...
Initialize(); // common initialization stuff
OpenLocalFolder();
m_scope = scope;
m_localFileOffset = offset;
m_numLocalLines = numLines;
m_msgHdr = msg;
m_db = db;
// the following are variables used when the body handler is handling stuff from filters....through this constructor, that is not the
// case so we set them to NULL.
m_headers = NULL;
m_headersSize = 0;
m_Filtering = PR_FALSE; // make sure we set this before we call initialize...
Initialize(); // common initialization stuff
OpenLocalFolder();
}
nsMsgBodyHandler::nsMsgBodyHandler(nsIMsgSearchScopeTerm * scope,
@@ -52,128 +52,124 @@ nsMsgBodyHandler::nsMsgBodyHandler(nsIMsgSearchScopeTerm * scope,
const char * headers, PRUint32 headersSize,
PRBool Filtering)
{
m_scope = scope;
m_localFileOffset = offset;
m_numLocalLines = numLines;
m_msgHdr = msg;
m_db = db;
m_headersSize = headersSize;
m_Filtering = Filtering;
Initialize();
if (m_Filtering)
m_headers = headers;
else
OpenLocalFolder(); // if nothing else applies, then we must be a POP folder file
m_scope = scope;
m_localFileOffset = offset;
m_numLocalLines = numLines;
m_msgHdr = msg;
m_db = db;
m_headersSize = headersSize;
m_Filtering = Filtering;
Initialize();
if (m_Filtering)
m_headers = headers;
else
OpenLocalFolder(); // if nothing else applies, then we must be a POP folder file
}
void nsMsgBodyHandler::Initialize()
// common initialization code regardless of what body type we are handling...
{
// Default transformations for local message search and MAPI access
m_stripHeaders = PR_TRUE;
m_stripHtml = PR_TRUE;
m_messageIsHtml = PR_FALSE;
m_passedHeaders = PR_FALSE;
// set our offsets to 0 since we haven't handled any bytes yet...
m_IMAPMessageOffset = 0;
m_NewsArticleOffset = 0;
m_headerBytesRead = 0;
// Default transformations for local message search and MAPI access
m_stripHeaders = PR_TRUE;
m_stripHtml = PR_TRUE;
m_messageIsHtml = PR_FALSE;
m_passedHeaders = PR_FALSE;
// set our offsets to 0 since we haven't handled any bytes yet...
m_NewsArticleOffset = 0;
m_headerBytesRead = 0;
}
nsMsgBodyHandler::~nsMsgBodyHandler()
{
nsCOMPtr <nsIFileSpec> fileSpec;
nsresult rv = m_scope->GetMailPath(getter_AddRefs(fileSpec));
PRBool isOpen = PR_FALSE;
if (NS_SUCCEEDED(rv) && fileSpec)
{
fileSpec->IsStreamOpen(&isOpen);
if (isOpen)
fileSpec->CloseStream();
}
if (m_fileSpec)
{
PRBool isOpen;
m_fileSpec->IsStreamOpen(&isOpen);
if (isOpen)
m_fileSpec->CloseStream();
}
}
PRInt32 nsMsgBodyHandler::GetNextLine (char * buf, int bufSize)
{
PRInt32 length = 0;
PRBool eatThisLine = PR_FALSE;
do {
// first, handle the filtering case...this is easy....
if (m_Filtering)
length = GetNextFilterLine(buf, bufSize);
else
{
// 3 cases: Offline IMAP, POP, or we are dealing with a news message....
// Offline cases should be same as local mail cases, since we're going
// to store offline messages in berkeley format folders.
if (m_db)
{
length = GetNextLocalLine (buf, bufSize); // (2) POP
}
}
if (length >= 0)
length = ApplyTransformations (buf, length, eatThisLine);
} while (eatThisLine && length >= 0); // if we hit eof, make sure we break out of this loop. Bug #:
return length;
PRInt32 length = 0;
PRBool eatThisLine = PR_FALSE;
do {
// first, handle the filtering case...this is easy....
if (m_Filtering)
length = GetNextFilterLine(buf, bufSize);
else
{
// 3 cases: Offline IMAP, POP, or we are dealing with a news message....
// Offline cases should be same as local mail cases, since we're going
// to store offline messages in berkeley format folders.
if (m_db)
{
length = GetNextLocalLine (buf, bufSize); // (2) POP
}
}
if (length >= 0)
length = ApplyTransformations (buf, length, eatThisLine);
} while (eatThisLine && length >= 0); // if we hit eof, make sure we break out of this loop. Bug #:
return length;
}
void nsMsgBodyHandler::OpenLocalFolder()
{
nsCOMPtr <nsIFileSpec> fileSpec;
nsresult rv = m_scope->GetMailPath(getter_AddRefs(fileSpec));
PRBool isOpen = PR_FALSE;
if (NS_SUCCEEDED(rv) && fileSpec)
{
fileSpec->IsStreamOpen(&isOpen);
if (isOpen) return;
fileSpec->OpenStreamForReading();
fileSpec->Seek(m_localFileOffset);
}
nsresult rv = m_scope->GetMailPath(getter_AddRefs(m_fileSpec));
PRBool isOpen = PR_FALSE;
if (NS_SUCCEEDED(rv) && m_fileSpec)
{
m_fileSpec->IsStreamOpen(&isOpen);
if (!isOpen)
m_fileSpec->OpenStreamForReading();
m_fileSpec->Seek(m_localFileOffset);
}
}
PRInt32 nsMsgBodyHandler::GetNextFilterLine(char * buf, PRUint32 bufSize)
{
// m_nextHdr always points to the next header in the list....the list is NULL terminated...
PRUint32 numBytesCopied = 0;
if (m_headersSize > 0)
{
// #mscott. Ugly hack! filter headers list have CRs & LFs inside the NULL delimited list of header
// strings. It is possible to have: To NULL CR LF From. We want to skip over these CR/LFs if they start
// at the beginning of what we think is another header.
while ((m_headers[0] == nsCRT::CR || m_headers[0] == nsCRT::LF || m_headers[0] == ' ' || m_headers[0] == '\0') && m_headersSize > 0)
{
m_headers++; // skip over these chars...
m_headersSize--;
}
if (m_headersSize > 0)
{
numBytesCopied = nsCRT::strlen(m_headers)+1 /* + 1 to include NULL */ < bufSize ? nsCRT::strlen(m_headers)+1 : (PRInt32) bufSize;
nsCRT::memcpy(buf, m_headers, numBytesCopied);
m_headers += numBytesCopied;
// be careful...m_headersSize is unsigned. Don't let it go negative or we overflow to 2^32....*yikes*
if (m_headersSize < numBytesCopied)
m_headersSize = 0;
else
m_headersSize -= numBytesCopied; // update # bytes we have read from the headers list
return (PRInt32) numBytesCopied;
}
}
else if (m_headersSize == 0) {
buf[0] = '\0';
}
return -1;
// m_nextHdr always points to the next header in the list....the list is NULL terminated...
PRUint32 numBytesCopied = 0;
if (m_headersSize > 0)
{
// #mscott. Ugly hack! filter headers list have CRs & LFs inside the NULL delimited list of header
// strings. It is possible to have: To NULL CR LF From. We want to skip over these CR/LFs if they start
// at the beginning of what we think is another header.
while ((m_headers[0] == nsCRT::CR || m_headers[0] == nsCRT::LF || m_headers[0] == ' ' || m_headers[0] == '\0') && m_headersSize > 0)
{
m_headers++; // skip over these chars...
m_headersSize--;
}
if (m_headersSize > 0)
{
numBytesCopied = nsCRT::strlen(m_headers)+1 /* + 1 to include NULL */ < bufSize ? nsCRT::strlen(m_headers)+1 : (PRInt32) bufSize;
nsCRT::memcpy(buf, m_headers, numBytesCopied);
m_headers += numBytesCopied;
// be careful...m_headersSize is unsigned. Don't let it go negative or we overflow to 2^32....*yikes*
if (m_headersSize < numBytesCopied)
m_headersSize = 0;
else
m_headersSize -= numBytesCopied; // update # bytes we have read from the headers list
return (PRInt32) numBytesCopied;
}
}
else if (m_headersSize == 0) {
buf[0] = '\0';
}
return -1;
}
// return -1 if no more local lines, length of next line otherwise.
@@ -181,90 +177,87 @@ PRInt32 nsMsgBodyHandler::GetNextFilterLine(char * buf, PRUint32 bufSize)
PRInt32 nsMsgBodyHandler::GetNextLocalLine(char * buf, int bufSize)
// returns number of bytes copied
{
if (m_numLocalLines)
{
if (m_passedHeaders)
m_numLocalLines--; // the line count is only for body lines
// do we need to check the return value here?
nsCOMPtr <nsIFileSpec> fileSpec;
nsresult rv = m_scope->GetMailPath(getter_AddRefs(fileSpec));
if (NS_SUCCEEDED(rv) && fileSpec)
{
PRBool isEof = PR_FALSE;
rv = fileSpec->Eof(&isEof);
if (NS_SUCCEEDED(rv) && isEof)
return -1;
PRBool wasTruncated = PR_FALSE;
rv = fileSpec->ReadLine(&buf, bufSize, &wasTruncated);
if (NS_SUCCEEDED(rv) && !wasTruncated)
return nsCRT::strlen(buf);
}
}
return -1;
if (m_numLocalLines)
{
m_numLocalLines--; // the line count is for header and body lines
// do we need to check the return value here?
if (m_fileSpec)
{
PRBool isEof = PR_FALSE;
nsresult rv = m_fileSpec->Eof(&isEof);
if (NS_SUCCEEDED(rv) && isEof)
return -1;
PRBool wasTruncated = PR_FALSE;
rv = m_fileSpec->ReadLine(&buf, bufSize, &wasTruncated);
if (NS_SUCCEEDED(rv) && !wasTruncated)
return nsCRT::strlen(buf);
}
}
return -1;
}
PRInt32 nsMsgBodyHandler::ApplyTransformations (char *buf, PRInt32 length, PRBool &eatThisLine)
{
PRInt32 newLength = length;
eatThisLine = PR_FALSE;
if (!m_passedHeaders) // buf is a line from the message headers
{
if (m_stripHeaders)
eatThisLine = PR_TRUE;
if (!nsCRT::strncasecmp(buf, "Content-Type:", 13) && PL_strcasestr (buf, "text/html"))
m_messageIsHtml = PR_TRUE;
m_passedHeaders = EMPTY_MESSAGE_LINE(buf);
}
else // buf is a line from the message body
{
if (m_stripHtml && m_messageIsHtml)
{
StripHtml (buf);
newLength = nsCRT::strlen (buf);
}
}
return newLength;
PRInt32 newLength = length;
eatThisLine = PR_FALSE;
if (!m_passedHeaders) // buf is a line from the message headers
{
if (m_stripHeaders)
eatThisLine = PR_TRUE;
if (!nsCRT::strncasecmp(buf, "Content-Type:", 13) && PL_strcasestr (buf, "text/html"))
m_messageIsHtml = PR_TRUE;
m_passedHeaders = EMPTY_MESSAGE_LINE(buf);
}
else // buf is a line from the message body
{
if (m_stripHtml && m_messageIsHtml)
{
StripHtml (buf);
newLength = nsCRT::strlen (buf);
}
}
return newLength;
}
void nsMsgBodyHandler::StripHtml (char *pBufInOut)
{
char *pBuf = (char*) PR_Malloc (nsCRT::strlen(pBufInOut) + 1);
if (pBuf)
{
char *pWalk = pBuf;
char *pWalkInOut = pBufInOut;
PRBool inTag = PR_FALSE;
while (*pWalkInOut) // throw away everything inside < >
{
if (!inTag)
if (*pWalkInOut == '<')
inTag = PR_TRUE;
else
*pWalk++ = *pWalkInOut;
else
if (*pWalkInOut == '>')
inTag = PR_FALSE;
pWalkInOut++;
}
*pWalk = 0; // null terminator
// copy the temp buffer back to the real one
pWalk = pBuf;
pWalkInOut = pBufInOut;
while (*pWalk)
*pWalkInOut++ = *pWalk++;
*pWalkInOut = *pWalk; // null terminator
PR_Free (pBuf);
}
char *pBuf = (char*) PR_Malloc (nsCRT::strlen(pBufInOut) + 1);
if (pBuf)
{
char *pWalk = pBuf;
char *pWalkInOut = pBufInOut;
PRBool inTag = PR_FALSE;
while (*pWalkInOut) // throw away everything inside < >
{
if (!inTag)
if (*pWalkInOut == '<')
inTag = PR_TRUE;
else
*pWalk++ = *pWalkInOut;
else
if (*pWalkInOut == '>')
inTag = PR_FALSE;
pWalkInOut++;
}
*pWalk = 0; // null terminator
// copy the temp buffer back to the real one
pWalk = pBuf;
pWalkInOut = pBufInOut;
while (*pWalk)
*pWalkInOut++ = *pWalk++;
*pWalkInOut = *pWalk; // null terminator
PR_Free (pBuf);
}
}

View File

@@ -578,11 +578,11 @@ nsresult nsMsgSearchOfflineMail::MatchTerms(nsIMsgDBHdr *msgToMatch,
break;
case nsMsgSearchAttrib::Body:
{
nsMsgKey messageKey;
nsMsgKey messageOffset;
PRUint32 lineCount;
msgToMatch->GetMessageKey(&messageKey);
msgToMatch->GetMessageOffset(&messageOffset);
msgToMatch->GetLineCount(&lineCount);
err = pTerm->MatchBody (scope, messageKey, lineCount, charset, msgToMatch, db, &result);
err = pTerm->MatchBody (scope, messageOffset, lineCount, charset, msgToMatch, db, &result);
}
break;
case nsMsgSearchAttrib::Date:

View File

@@ -1314,16 +1314,6 @@ PRBool nsMsgSearchScopeTerm::IsOfflineMail ()
return PR_TRUE; // if POP or IMAP in offline mode
}
PRBool nsMsgSearchScopeTerm::IsOfflineIMAPMail()
{
// Find out whether "this" mail folder is an offline IMAP folder
NS_ASSERTION(m_folder, "scope doesn't have folder");
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_folder);
if (imapFolder && (nsMsgSearchAdapter::SearchIsOffline() || !m_searchServer))
return PR_TRUE;
return PR_FALSE; // we are not an IMAP folder that is offline
}
nsresult nsMsgSearchScopeTerm::GetMailPath(nsIFileSpec **aFileSpec)
{
return (m_folder) ? m_folder->GetPath(aFileSpec) : NS_ERROR_NULL_POINTER;
@@ -1337,51 +1327,51 @@ nsresult nsMsgSearchScopeTerm::TimeSlice (PRBool *aDone)
nsresult nsMsgSearchScopeTerm::InitializeAdapter (nsISupportsArray *termList)
{
if (m_adapter)
return NS_OK;
nsresult err = NS_OK;
// mscott: i have added m_searchServer into this switch to take into account the user's preference
// for searching locally or on the server...
switch (m_attribute)
{
case nsMsgSearchScope::MailFolder:
if (m_adapter)
return NS_OK;
nsresult err = NS_OK;
// mscott: i have added m_searchServer into this switch to take into account the user's preference
// for searching locally or on the server...
switch (m_attribute)
{
case nsMsgSearchScope::MailFolder:
// since we don't support offline, we're either doing an online imap search
// or an offline mail search.
if (!IsOfflineMail()) // Online IMAP && searching the server?
m_adapter = new nsMsgSearchOnlineMail (this, termList);
else
m_adapter = new nsMsgSearchOfflineMail (this, termList);
break;
case nsMsgSearchScope::Newsgroup:
if (!IsOfflineMail()) // Online IMAP && searching the server?
m_adapter = new nsMsgSearchOnlineMail (this, termList);
else
m_adapter = new nsMsgSearchOfflineMail (this, termList);
break;
case nsMsgSearchScope::Newsgroup:
#ifdef DOING_EXNEWSSEARCH
if (m_folder->KnowsSearchNntpExtension())
m_adapter = new nsMsgSearchNewsEx (this, termList);
else
if (m_folder->KnowsSearchNntpExtension())
m_adapter = new nsMsgSearchNewsEx (this, termList);
else
#endif
m_adapter = new nsMsgSearchNews (this, termList);
break;
m_adapter = new nsMsgSearchNews (this, termList);
break;
#ifdef DOING_EXNEWSSEARCH
case nsMsgSearchScope::AllSearchableGroups:
m_adapter = new msMsgSearchNewsEx (this, termList);
break;
case nsMsgSearchScope::AllSearchableGroups:
m_adapter = new msMsgSearchNewsEx (this, termList);
break;
#endif
case nsMsgSearchScope::LdapDirectory:
case nsMsgSearchScope::LdapDirectory:
NS_ASSERTION(PR_FALSE, "not supporting LDAP yet");
break;
case nsMsgSearchScope::OfflineNewsgroup:
break;
case nsMsgSearchScope::OfflineNewsgroup:
m_adapter = new nsMsgSearchOfflineNews (this, termList);
break;
default:
NS_ASSERTION(PR_FALSE, "invalid scope");
err = NS_ERROR_FAILURE;
}
if (m_adapter)
err = m_adapter->ValidateTerms ();
return err;
break;
default:
NS_ASSERTION(PR_FALSE, "invalid scope");
err = NS_ERROR_FAILURE;
}
if (m_adapter)
err = m_adapter->ValidateTerms ();
return err;
}

View File

@@ -1295,6 +1295,7 @@ nsresult nsMsgDBFolder::StartNewOfflineMessage()
{
nsresult rv = GetOfflineStoreOutputStream(getter_AddRefs(m_tempMessageStream));
WriteStartOfNewLocalMessage();
m_numOfflineMsgLines = 0;
return rv;
}
@@ -1317,6 +1318,7 @@ nsresult nsMsgDBFolder::EndNewOfflineMessage()
randomStore->Tell(&curStorePos);
m_offlineHeader->GetMessageOffset(&messageOffset);
m_offlineHeader->SetOfflineMessageSize(curStorePos - messageOffset);
m_offlineHeader->SetLineCount(m_numOfflineMsgLines);
}
m_offlineHeader = nsnull;
return NS_OK;

View File

@@ -45,43 +45,43 @@ class NS_MSG_BASE nsMsgDBFolder: public nsMsgFolder,
public nsIUrlListener
{
public:
nsMsgDBFolder(void);
virtual ~nsMsgDBFolder(void);
nsMsgDBFolder(void);
virtual ~nsMsgDBFolder(void);
NS_DECL_NSIDBCHANGELISTENER
NS_IMETHOD StartFolderLoading(void);
NS_IMETHOD EndFolderLoading(void);
NS_IMETHOD GetCharset(PRUnichar * *aCharset);
NS_IMETHOD SetCharset(const PRUnichar * aCharset);
NS_IMETHOD GetCharsetOverride(PRBool *aCharsetOverride);
NS_IMETHOD SetCharsetOverride(PRBool aCharsetOverride);
NS_IMETHOD GetFirstNewMessage(nsIMsgDBHdr **firstNewMessage);
NS_IMETHOD ClearNewMessages();
NS_IMETHOD StartFolderLoading(void);
NS_IMETHOD EndFolderLoading(void);
NS_IMETHOD GetCharset(PRUnichar * *aCharset);
NS_IMETHOD SetCharset(const PRUnichar * aCharset);
NS_IMETHOD GetCharsetOverride(PRBool *aCharsetOverride);
NS_IMETHOD SetCharsetOverride(PRBool aCharsetOverride);
NS_IMETHOD GetFirstNewMessage(nsIMsgDBHdr **firstNewMessage);
NS_IMETHOD ClearNewMessages();
NS_IMETHOD GetFlags(PRUint32 *aFlags);
NS_IMETHOD GetExpungedBytes(PRUint32 *count);
NS_IMETHOD GetMsgDatabase(nsIMsgWindow *aMsgWindow,
nsIMsgDatabase** aMsgDatabase);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIURLLISTENER
NS_DECL_NSIURLLISTENER
NS_IMETHOD WriteToFolderCache(nsIMsgFolderCache *folderCache, PRBool deep);
NS_IMETHOD WriteToFolderCacheElem(nsIMsgFolderCacheElement *element);
NS_IMETHOD ReadFromFolderCacheElem(nsIMsgFolderCacheElement *element);
NS_IMETHOD ManyHeadersToDownload(PRBool *_retval);
NS_IMETHOD WriteToFolderCache(nsIMsgFolderCache *folderCache, PRBool deep);
NS_IMETHOD WriteToFolderCacheElem(nsIMsgFolderCacheElement *element);
NS_IMETHOD ReadFromFolderCacheElem(nsIMsgFolderCacheElement *element);
NS_IMETHOD ManyHeadersToDownload(PRBool *_retval);
NS_IMETHOD AddMessageDispositionState(nsIMsgDBHdr *aMessage, nsMsgDispositionState aDispositionFlag);
NS_IMETHOD MarkAllMessagesRead(void);
NS_IMETHOD MarkAllMessagesRead(void);
NS_IMETHOD MarkThreadRead(nsIMsgThread *thread);
NS_IMETHOD SetFlag(PRUint32 flag);
NS_IMETHOD Shutdown(PRBool shutdownChildren);
NS_IMETHOD Shutdown(PRBool shutdownChildren);
NS_IMETHOD ForceDBClosed();
NS_IMETHOD GetHasNewMessages(PRBool *hasNewMessages);
NS_IMETHOD SetHasNewMessages(PRBool hasNewMessages);
NS_IMETHOD GetHasNewMessages(PRBool *hasNewMessages);
NS_IMETHOD SetHasNewMessages(PRBool hasNewMessages);
NS_IMETHOD GetGettingNewMessages(PRBool *gettingNewMessages);
NS_IMETHOD SetGettingNewMessages(PRBool gettingNewMessages);
@@ -96,17 +96,17 @@ public:
NS_IMETHOD SetDownloadSettings(nsIMsgDownloadSettings *settings);
protected:
virtual nsresult ReadDBFolderInfo(PRBool force);
virtual nsresult ReadDBFolderInfo(PRBool force);
virtual nsresult FlushToFolderCache();
virtual nsresult GetDatabase(nsIMsgWindow *aMsgWindow) = 0;
virtual nsresult SendFlagNotifications(nsISupports *item, PRUint32 oldFlags, PRUint32 newFlags);
nsresult CheckWithNewMessagesStatus(PRBool messageAdded);
nsresult OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey , PRInt32 aFlags,
nsIDBChangeListener * aInstigator, PRBool added, PRBool doFlat, PRBool doThread);
nsresult CreatePlatformLeafNameForDisk(const char *userLeafName, nsFileSpec &baseDir, char **resultName);
virtual nsresult GetDatabase(nsIMsgWindow *aMsgWindow) = 0;
virtual nsresult SendFlagNotifications(nsISupports *item, PRUint32 oldFlags, PRUint32 newFlags);
nsresult CheckWithNewMessagesStatus(PRBool messageAdded);
nsresult OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey , PRInt32 aFlags,
nsIDBChangeListener * aInstigator, PRBool added, PRBool doFlat, PRBool doThread);
nsresult CreatePlatformLeafNameForDisk(const char *userLeafName, nsFileSpec &baseDir, char **resultName);
nsresult GetFolderCacheKey(nsIFileSpec **aFileSpec);
nsresult GetFolderCacheElemFromFileSpec(nsIFileSpec *fileSpec, nsIMsgFolderCacheElement **cacheElement);
nsresult GetFolderCacheKey(nsIFileSpec **aFileSpec);
nsresult GetFolderCacheElemFromFileSpec(nsIFileSpec *fileSpec, nsIMsgFolderCacheElement **cacheElement);
nsresult NotifyStoreClosedAllHeaders();
virtual nsresult GetOfflineStoreInputStream(nsIInputStream **inputStream);
@@ -120,16 +120,17 @@ protected:
nsresult MsgFitsDownloadCriteria(nsMsgKey msgKey, PRBool *result);
protected:
nsCOMPtr<nsIMsgDatabase> mDatabase;
nsString mCharset;
PRBool mCharsetOverride;
PRBool mAddListener;
PRBool mNewMessages;
nsCOMPtr<nsIMsgDatabase> mDatabase;
nsString mCharset;
PRBool mCharsetOverride;
PRBool mAddListener;
PRBool mNewMessages;
PRBool mGettingNewMessages;
nsCOMPtr <nsIMsgDBHdr> m_offlineHeader;
PRInt32 m_numOfflineMsgLines;
// this is currently used when we do a save as of an imap or news message..
nsCOMPtr<nsIOutputStream> m_tempMessageStream;
nsCOMPtr<nsIOutputStream> m_tempMessageStream;
nsCOMPtr <nsIMsgRetentionSettings> m_retentionSettings;
nsCOMPtr <nsIMsgDownloadSettings> m_downloadSettings;

View File

@@ -3293,7 +3293,20 @@ nsImapMailFolder::ParseAdoptedMsgLine(const char *adoptedMessageLine, nsMsgKey u
GetMessageHeader(uidOfMessage, getter_AddRefs(m_offlineHeader));
rv = StartNewOfflineMessage();
}
// adoptedMessageLine is actually a string with a lot of message lines, separated by native line terminators
// we need to count the number of MSG_LINEBREAK's to determine how much to increment m_numOfflineMsgLines by.
if (m_downloadMessageForOfflineUse)
{
const char *nextLine = adoptedMessageLine;
do
{
m_numOfflineMsgLines++;
nextLine = PL_strstr(nextLine, MSG_LINEBREAK);
if (nextLine)
nextLine += MSG_LINEBREAK_LEN;
}
while (nextLine && *nextLine);
}
if (m_tempMessageStream)
{
rv = m_tempMessageStream->Write(adoptedMessageLine,
@@ -4462,7 +4475,12 @@ nsImapMailFolder::SetUrlState(nsIImapProtocol* aProtocol,
nsresult statusCode)
{
if (!isRunning)
{
ProgressStatus(aProtocol, IMAP_DONE, nsnull);
m_urlRunning = PR_FALSE;
m_downloadingFolderForOfflineUse = PR_FALSE;
SetNotifyDownloadedLines(PR_FALSE);
}
if (aUrl)
return aUrl->SetUrlState(isRunning, statusCode);

File diff suppressed because it is too large Load Diff