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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user