зеркало из https://github.com/mozilla/pjs.git
move body shell parser to server response parser, fix handling of 'NIL'), patches by hans-a.engel@unibas.ch, sr=bienvenu 312952 312599
This commit is contained in:
Родитель
7f95cfeecf
Коммит
6ab7cd0dac
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -43,7 +43,6 @@ nsIMAPBodyShell and associated classes
|
|||
#define IMAPBODY_H
|
||||
|
||||
#include "nsImapCore.h"
|
||||
#include "nsIMAPGenericParser.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsImapProtocol;
|
||||
|
@ -55,43 +54,45 @@ typedef enum _nsIMAPBodypartType {
|
|||
IMAP_BODY_MULTIPART
|
||||
} nsIMAPBodypartType;
|
||||
|
||||
class nsIMAPGenericParser;
|
||||
class nsIMAPBodyShell;
|
||||
class nsIMAPBodypartMessage;
|
||||
class nsHashtable;
|
||||
|
||||
|
||||
class nsIMAPBodypart : public nsIMAPGenericParser
|
||||
class nsIMAPBodypart
|
||||
{
|
||||
public:
|
||||
// Construction
|
||||
static nsIMAPBodypart *CreatePart(nsIMAPBodyShell *shell, char *partNum, const char *buf, nsIMAPBodypart *parentPart);
|
||||
virtual PRBool GetIsValid() { return m_isValid; }
|
||||
virtual void SetIsValid(PRBool valid);
|
||||
virtual nsIMAPBodypartType GetType() = 0;
|
||||
|
||||
// Generation
|
||||
virtual PRInt32 Generate(PRBool /*stream*/, PRBool /* prefetch */) { return -1; } // Generates an HTML representation of this part. Returns content length generated, -1 if failed.
|
||||
virtual void AdoptPartDataBuffer(char *buf); // Adopts storage for part data buffer. If NULL, sets isValid to PR_FALSE.
|
||||
virtual void AdoptHeaderDataBuffer(char *buf); // Adopts storage for header data buffer. If NULL, sets isValid to PR_FALSE.
|
||||
virtual PRBool ShouldFetchInline() { return PR_TRUE; } // returns PR_TRUE if this part should be fetched inline for generation.
|
||||
virtual PRBool PreflightCheckAllInline() { return PR_TRUE; }
|
||||
// Generates an HTML representation of this part. Returns content length generated, -1 if failed.
|
||||
virtual PRInt32 Generate(nsIMAPBodyShell *aShell, PRBool /*stream*/, PRBool /* prefetch */) { return -1; }
|
||||
virtual void AdoptPartDataBuffer(char *buf); // Adopts storage for part data buffer. If NULL, sets isValid to PR_FALSE.
|
||||
virtual void AdoptHeaderDataBuffer(char *buf); // Adopts storage for header data buffer. If NULL, sets isValid to PR_FALSE.
|
||||
virtual PRBool ShouldFetchInline(nsIMAPBodyShell *aShell) { return PR_TRUE; } // returns PR_TRUE if this part should be fetched inline for generation.
|
||||
virtual PRBool PreflightCheckAllInline(nsIMAPBodyShell *aShell) { return PR_TRUE; }
|
||||
|
||||
virtual PRBool ShouldExplicitlyFetchInline();
|
||||
virtual PRBool ShouldExplicitlyNotFetchInline();
|
||||
virtual PRBool IsLastTextPart(const char *partNumberString) {return PR_TRUE;}
|
||||
|
||||
protected: // If stream is PR_FALSE, simply returns the content length that will be generated
|
||||
virtual PRInt32 GeneratePart(PRBool stream, PRBool prefetch); // the body of the part itself
|
||||
virtual PRInt32 GenerateMIMEHeader(PRBool stream, PRBool prefetch); // the MIME headers of the part
|
||||
virtual PRInt32 GenerateBoundary(PRBool stream, PRBool prefetch, PRBool lastBoundary); // Generates the MIME boundary wrapper for this part.
|
||||
// lastBoundary indicates whether or not this should be the boundary for the
|
||||
// final MIME part of the multipart message.
|
||||
virtual PRInt32 GenerateEmptyFilling(PRBool stream, PRBool prefetch); // Generates (possibly empty) filling for a part that won't be filled in inline.
|
||||
protected:
|
||||
// If stream is PR_FALSE, simply returns the content length that will be generated
|
||||
// the body of the part itself
|
||||
virtual PRInt32 GeneratePart(nsIMAPBodyShell *aShell, PRBool stream, PRBool prefetch);
|
||||
// the MIME headers of the part
|
||||
virtual PRInt32 GenerateMIMEHeader(nsIMAPBodyShell *aShell, PRBool stream, PRBool prefetch);
|
||||
// Generates the MIME boundary wrapper for this part.
|
||||
virtual PRInt32 GenerateBoundary(nsIMAPBodyShell *aShell, PRBool stream, PRBool prefetch, PRBool lastBoundary);
|
||||
// lastBoundary indicates whether or not this should be the boundary for the
|
||||
// final MIME part of the multipart message.
|
||||
// Generates (possibly empty) filling for a part that won't be filled in inline.
|
||||
virtual PRInt32 GenerateEmptyFilling(nsIMAPBodyShell *aShell, PRBool stream, PRBool prefetch);
|
||||
|
||||
// Part Numbers / Hierarchy
|
||||
public:
|
||||
virtual int GetPartNumber() { return m_partNumber; } // Returns the part number on this hierarchy level
|
||||
virtual char *GetPartNumberString() { return m_partNumberString; }
|
||||
virtual nsIMAPBodypart *FindPartWithNumber(const char *partNum); // Returns the part object with the given number
|
||||
virtual nsIMAPBodypart *GetParentPart() { return m_parentPart; } // Returns the parent of this part.
|
||||
|
@ -103,32 +104,25 @@ public:
|
|||
// Other / Helpers
|
||||
public:
|
||||
virtual ~nsIMAPBodypart();
|
||||
virtual PRBool GetNextLineForParser(char **nextLine);
|
||||
virtual PRBool ContinueParse(); // overrides the parser, but calls it anyway
|
||||
virtual nsIMAPBodypartMessage *GetnsIMAPBodypartMessage() { return NULL; }
|
||||
|
||||
const char *GetBodyType() { return m_bodyType; }
|
||||
const char *GetBodySubType() { return m_bodySubType; }
|
||||
void SetBoundaryData(char *boundaryData) { m_boundaryData = boundaryData; }
|
||||
|
||||
protected:
|
||||
virtual void QueuePrefetchMIMEHeader();
|
||||
virtual void QueuePrefetchMIMEHeader(nsIMAPBodyShell *aShell);
|
||||
//virtual void PrefetchMIMEHeader(); // Initiates a prefetch for the MIME header of this part.
|
||||
virtual PRBool ParseIntoObjects() = 0; // Parses buffer and fills in both this and any children with associated objects
|
||||
// Returns PR_TRUE if it produced a valid Shell
|
||||
// Must be overridden in the concerte derived class
|
||||
nsIMAPBodypart(nsIMAPBodyShell *shell, char *partNumber, const char *buf, nsIMAPBodypart *parentPart);
|
||||
nsIMAPBodypart(char *partNumber, nsIMAPBodypart *parentPart);
|
||||
|
||||
protected:
|
||||
nsIMAPBodyShell *m_shell; // points back to the shell
|
||||
PRBool m_isValid; // If this part is valid.
|
||||
int m_partNumber; // part number on this hierarchy level
|
||||
char *m_partNumberString; // string representation of this part's full-hierarchy number. Define 0 to be the top-level message
|
||||
char *m_partData; // data for this part. NULL if not filled in yet.
|
||||
char *m_headerData; // data for this part's MIME header. NULL if not filled in yet.
|
||||
char *m_boundaryData; // MIME boundary for this part
|
||||
PRInt32 m_partLength;
|
||||
PRInt32 m_contentLength; // Total content length which will be Generate()'d. -1 if not filled in yet.
|
||||
char *m_responseBuffer; // The buffer for this object
|
||||
nsIMAPBodypart *m_parentPart; // Parent of this part
|
||||
|
||||
// Fields - Filled in from parsed BODYSTRUCTURE response (as well as others)
|
||||
|
@ -139,8 +133,6 @@ protected:
|
|||
char *m_bodyDescription;
|
||||
char *m_bodyEncoding;
|
||||
// we ignore extension data for now
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -152,32 +144,29 @@ protected:
|
|||
class nsIMAPMessageHeaders : public nsIMAPBodypart
|
||||
{
|
||||
public:
|
||||
nsIMAPMessageHeaders(nsIMAPBodyShell *shell, char *partNum, nsIMAPBodypart *parentPart);
|
||||
nsIMAPMessageHeaders(char *partNum, nsIMAPBodypart *parentPart);
|
||||
virtual nsIMAPBodypartType GetType();
|
||||
virtual PRInt32 Generate(PRBool stream, PRBool prefetch); // Generates an HTML representation of this part. Returns content length generated, -1 if failed.
|
||||
virtual PRBool ShouldFetchInline();
|
||||
virtual void QueuePrefetchMessageHeaders();
|
||||
protected:
|
||||
virtual PRBool ParseIntoObjects(); // Parses m_responseBuffer and fills in m_partList with associated objects
|
||||
// Returns PR_TRUE if it produced a valid Shell
|
||||
|
||||
// Generates an HTML representation of this part. Returns content length generated, -1 if failed.
|
||||
virtual PRInt32 Generate(nsIMAPBodyShell *aShell, PRBool stream, PRBool prefetch);
|
||||
virtual PRBool ShouldFetchInline(nsIMAPBodyShell *aShell);
|
||||
virtual void QueuePrefetchMessageHeaders(nsIMAPBodyShell *aShell);
|
||||
};
|
||||
|
||||
|
||||
class nsIMAPBodypartMultipart : public nsIMAPBodypart
|
||||
{
|
||||
public:
|
||||
nsIMAPBodypartMultipart(nsIMAPBodyShell *shell, char *partNum, const char *buf, nsIMAPBodypart *parentPart);
|
||||
nsIMAPBodypartMultipart(char *partNum, nsIMAPBodypart *parentPart);
|
||||
virtual nsIMAPBodypartType GetType();
|
||||
virtual ~nsIMAPBodypartMultipart();
|
||||
virtual PRBool ShouldFetchInline();
|
||||
virtual PRBool PreflightCheckAllInline();
|
||||
virtual PRInt32 Generate(PRBool stream, PRBool prefetch); // Generates an HTML representation of this part. Returns content length generated, -1 if failed.
|
||||
virtual PRBool ShouldFetchInline(nsIMAPBodyShell *aShell);
|
||||
virtual PRBool PreflightCheckAllInline(nsIMAPBodyShell *aShell);
|
||||
// Generates an HTML representation of this part. Returns content length generated, -1 if failed.
|
||||
virtual PRInt32 Generate(nsIMAPBodyShell *aShell, PRBool stream, PRBool prefetch);
|
||||
virtual nsIMAPBodypart *FindPartWithNumber(const char *partNum); // Returns the part object with the given number
|
||||
virtual PRBool IsLastTextPart(const char *partNumberString);
|
||||
|
||||
protected:
|
||||
virtual PRBool ParseIntoObjects();
|
||||
void AppendPart(nsIMAPBodypart *part) { m_partList->AppendElement(part); }
|
||||
void SetBodySubType(char *bodySubType);
|
||||
|
||||
protected:
|
||||
nsVoidArray *m_partList; // An ordered list of top-level body parts for this shell
|
||||
|
@ -189,27 +178,28 @@ protected:
|
|||
class nsIMAPBodypartLeaf : public nsIMAPBodypart
|
||||
{
|
||||
public:
|
||||
nsIMAPBodypartLeaf(nsIMAPBodyShell *shell, char *partNum, const char *buf, nsIMAPBodypart *parentPart);
|
||||
nsIMAPBodypartLeaf(char *partNum, nsIMAPBodypart *parentPart,
|
||||
char *bodyType, char *bodySubType, char *bodyID, char *bodyDescription, char *bodyEncoding, PRInt32 partLength);
|
||||
virtual nsIMAPBodypartType GetType();
|
||||
virtual PRInt32 Generate(PRBool stream, PRBool prefetch); // Generates an HTML representation of this part. Returns content length generated, -1 if failed.
|
||||
virtual PRBool ShouldFetchInline(); // returns PR_TRUE if this part should be fetched inline for generation.
|
||||
virtual PRBool PreflightCheckAllInline();
|
||||
|
||||
protected:
|
||||
virtual PRBool ParseIntoObjects();
|
||||
|
||||
// Generates an HTML representation of this part. Returns content length generated, -1 if failed.
|
||||
virtual PRInt32 Generate(nsIMAPBodyShell *aShell, PRBool stream, PRBool prefetch);
|
||||
// returns PR_TRUE if this part should be fetched inline for generation.
|
||||
virtual PRBool ShouldFetchInline(nsIMAPBodyShell *aShell);
|
||||
virtual PRBool PreflightCheckAllInline(nsIMAPBodyShell *aShell);
|
||||
};
|
||||
|
||||
|
||||
class nsIMAPBodypartMessage : public nsIMAPBodypartLeaf
|
||||
{
|
||||
public:
|
||||
nsIMAPBodypartMessage(nsIMAPBodyShell *shell, char *partNum, const char *buf, nsIMAPBodypart *parentPart, PRBool topLevelMessage);
|
||||
nsIMAPBodypartMessage(char *partNum, nsIMAPBodypart *parentPart, PRBool topLevelMessage,
|
||||
char *bodyType, char *bodySubType, char *bodyID, char *bodyDescription, char *bodyEncoding, PRInt32 partLength);
|
||||
void SetBody(nsIMAPBodypart *body);
|
||||
virtual nsIMAPBodypartType GetType();
|
||||
virtual ~nsIMAPBodypartMessage();
|
||||
virtual PRInt32 Generate(PRBool stream, PRBool prefetch);
|
||||
virtual PRBool ShouldFetchInline();
|
||||
virtual PRBool PreflightCheckAllInline();
|
||||
virtual PRInt32 Generate(nsIMAPBodyShell *aShell, PRBool stream, PRBool prefetch);
|
||||
virtual PRBool ShouldFetchInline(nsIMAPBodyShell *aShell);
|
||||
virtual PRBool PreflightCheckAllInline(nsIMAPBodyShell *aShell);
|
||||
virtual nsIMAPBodypart *FindPartWithNumber(const char *partNum); // Returns the part object with the given number
|
||||
void AdoptMessageHeaders(char *headers); // Fills in buffer (and adopts storage) for header object
|
||||
// partNum specifies the message part number to which the
|
||||
|
@ -217,9 +207,6 @@ public:
|
|||
virtual nsIMAPBodypartMessage *GetnsIMAPBodypartMessage() { return this; }
|
||||
virtual PRBool GetIsTopLevelMessage() { return m_topLevelMessage; }
|
||||
|
||||
protected:
|
||||
virtual PRBool ParseIntoObjects();
|
||||
|
||||
protected:
|
||||
nsIMAPMessageHeaders *m_headers; // Every body shell should have headers
|
||||
nsIMAPBodypart *m_body;
|
||||
|
@ -233,7 +220,7 @@ class nsIMAPMessagePartIDArray;
|
|||
// We will refer to a Body "Shell" as a hierarchical object representation of a parsed BODYSTRUCTURE
|
||||
// response. A shell contains representations of Shell "Parts." A Body Shell can undergo essentially
|
||||
// two operations: Construction and Generation.
|
||||
// Shell Construction occurs by parsing a BODYSTRUCTURE response into empty Parts.
|
||||
// Shell Construction occurs from a parsed a BODYSTRUCTURE response, split into empty parts.
|
||||
// Shell Generation generates a "MIME Shell" of the message and streams it to libmime for
|
||||
// display. The MIME Shell has selected (inline) parts filled in, and leaves all others
|
||||
// for on-demand retrieval through explicit part fetches.
|
||||
|
@ -241,13 +228,7 @@ class nsIMAPMessagePartIDArray;
|
|||
class nsIMAPBodyShell
|
||||
{
|
||||
public:
|
||||
|
||||
// Construction
|
||||
nsIMAPBodyShell(nsImapProtocol *protocolConnection, const char *bs, PRUint32 UID, const char *folderName); // Constructor takes in a buffer containing an IMAP
|
||||
// bodystructure response from the server, with the associated
|
||||
// tag/command/etc. stripped off.
|
||||
// That is, it takes in something of the form:
|
||||
// (("TEXT" "PLAIN" ..... ))
|
||||
nsIMAPBodyShell(nsImapProtocol *protocolConnection, nsIMAPBodypartMessage *message, PRUint32 UID, const char *folderName);
|
||||
virtual ~nsIMAPBodyShell();
|
||||
void SetConnection(nsImapProtocol *con) { m_protocolConnection = con; } // To be used after a shell is uncached
|
||||
virtual PRBool GetIsValid() { return m_isValid; }
|
||||
|
|
|
@ -124,37 +124,33 @@ void nsIMAPGenericParser::skip_to_CRLF()
|
|||
void nsIMAPGenericParser::skip_to_close_paren()
|
||||
{
|
||||
int numberOfCloseParensNeeded = 1;
|
||||
if (fNextToken && *fNextToken == ')')
|
||||
while (ContinueParse())
|
||||
{
|
||||
numberOfCloseParensNeeded--;
|
||||
fNextToken++;
|
||||
if (!fNextToken || !*fNextToken)
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
|
||||
while (ContinueParse() && numberOfCloseParensNeeded > 0)
|
||||
{
|
||||
// go through fNextToken, count the number
|
||||
// of open and close parens, to account
|
||||
// for nested parens which might come in
|
||||
// the response
|
||||
char *loc = 0;
|
||||
// go through fNextToken, account for nested parens
|
||||
char *loc;
|
||||
for (loc = fNextToken; loc && *loc; loc++)
|
||||
{
|
||||
if (*loc == '(')
|
||||
numberOfCloseParensNeeded++;
|
||||
else if (*loc == ')')
|
||||
numberOfCloseParensNeeded--;
|
||||
if (numberOfCloseParensNeeded == 0)
|
||||
{
|
||||
fNextToken = loc + 1;
|
||||
if (!fNextToken || !*fNextToken)
|
||||
AdvanceToNextToken();
|
||||
break; // exit the loop
|
||||
numberOfCloseParensNeeded--;
|
||||
if (numberOfCloseParensNeeded == 0)
|
||||
{
|
||||
fNextToken = loc + 1;
|
||||
if (!fNextToken || !*fNextToken)
|
||||
AdvanceToNextToken();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (*loc == '{' || *loc == '"') {
|
||||
// quoted or literal
|
||||
char *a = CreateAstring();
|
||||
PR_FREEIF(a);
|
||||
break; // move to next token
|
||||
}
|
||||
}
|
||||
|
||||
if (numberOfCloseParensNeeded > 0)
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -2552,42 +2552,278 @@ void nsImapServerResponseParser::mime_part_data()
|
|||
}
|
||||
|
||||
// FETCH BODYSTRUCTURE parser
|
||||
// After exit, set fNextToken and fCurrentLine to the right things
|
||||
void nsImapServerResponseParser::bodystructure_data()
|
||||
{
|
||||
AdvanceToNextToken();
|
||||
|
||||
// separate it out first
|
||||
if (fNextToken && *fNextToken == '(') // It has to start with an open paren.
|
||||
if (ContinueParse() && fNextToken && *fNextToken == '(') // It has to start with an open paren.
|
||||
{
|
||||
char *buf = CreateParenGroup();
|
||||
|
||||
if (ContinueParse())
|
||||
// Turn the BODYSTRUCTURE response into a form that the nsIMAPBodypartMessage can be constructed from.
|
||||
nsIMAPBodypartMessage *message = new nsIMAPBodypartMessage(NULL, NULL, PR_TRUE,
|
||||
nsCRT::strdup("message"), nsCRT::strdup("rfc822"),
|
||||
NULL, NULL, NULL, 0);
|
||||
nsIMAPBodypart *body = bodystructure_part(PL_strdup("1"), message);
|
||||
if (!body)
|
||||
delete message;
|
||||
else
|
||||
{
|
||||
if (!buf)
|
||||
HandleMemoryFailure();
|
||||
else
|
||||
{
|
||||
// Looks like we have what might be a valid BODYSTRUCTURE response.
|
||||
// Try building the shell from it here.
|
||||
m_shell = new nsIMAPBodyShell(&fServerConnection, buf, CurrentResponseUID(), GetSelectedMailboxName());
|
||||
/*
|
||||
if (m_shell)
|
||||
{
|
||||
if (!m_shell->GetIsValid())
|
||||
{
|
||||
SetSyntaxError(PR_TRUE);
|
||||
}
|
||||
}
|
||||
*/
|
||||
PR_Free(buf);
|
||||
}
|
||||
message->SetBody(body);
|
||||
m_shell = new nsIMAPBodyShell(&fServerConnection, message, CurrentResponseUID(), GetSelectedMailboxName());
|
||||
}
|
||||
}
|
||||
else
|
||||
SetSyntaxError(PR_TRUE);
|
||||
}
|
||||
|
||||
nsIMAPBodypart *
|
||||
nsImapServerResponseParser::bodystructure_part(char *partNum, nsIMAPBodypart *parentPart)
|
||||
{
|
||||
// Check to see if this buffer is a leaf or container
|
||||
// (Look at second character - if an open paren, then it is a container)
|
||||
if (*fNextToken != '(')
|
||||
{
|
||||
NS_ASSERTION(PR_FALSE, "bodystructure_part must begin with '('");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fNextToken[1] == '(')
|
||||
return bodystructure_multipart(partNum, parentPart);
|
||||
else
|
||||
return bodystructure_leaf(partNum, parentPart);
|
||||
}
|
||||
|
||||
nsIMAPBodypart *
|
||||
nsImapServerResponseParser::bodystructure_leaf(char *partNum, nsIMAPBodypart *parentPart)
|
||||
{
|
||||
// historical note: this code was originally in nsIMAPBodypartLeaf::ParseIntoObjects()
|
||||
char *bodyType = nsnull, *bodySubType = nsnull, *bodyID = nsnull, *bodyDescription = nsnull, *bodyEncoding = nsnull;
|
||||
PRInt32 partLength = 0;
|
||||
PRBool isValid = PR_TRUE;
|
||||
|
||||
// body type ("application", "text", "image", etc.)
|
||||
if (ContinueParse())
|
||||
{
|
||||
fNextToken++; // eat the first '('
|
||||
bodyType = CreateNilString();
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
|
||||
// body subtype ("gif", "html", etc.)
|
||||
if (isValid && ContinueParse())
|
||||
{
|
||||
bodySubType = CreateNilString();
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
|
||||
// body parameter: parenthesized list
|
||||
if (isValid && ContinueParse())
|
||||
{
|
||||
if (fNextToken[0] == '(')
|
||||
{
|
||||
fNextToken++;
|
||||
skip_to_close_paren();
|
||||
}
|
||||
else if (!PL_strcasecmp(fNextToken, "NIL"))
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
|
||||
// body id
|
||||
if (isValid && ContinueParse())
|
||||
{
|
||||
bodyID = CreateNilString();
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
|
||||
// body description
|
||||
if (isValid && ContinueParse())
|
||||
{
|
||||
bodyDescription = CreateNilString();
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
|
||||
// body encoding
|
||||
if (isValid && ContinueParse())
|
||||
{
|
||||
bodyEncoding = CreateNilString();
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
|
||||
// body size
|
||||
if (isValid && ContinueParse())
|
||||
{
|
||||
char *bodySizeString = CreateAtom();
|
||||
if (!bodySizeString)
|
||||
isValid = PR_FALSE;
|
||||
else
|
||||
{
|
||||
partLength = atoi(bodySizeString);
|
||||
PR_Free(bodySizeString);
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid || !ContinueParse())
|
||||
{
|
||||
PR_FREEIF(partNum);
|
||||
PR_FREEIF(bodyType);
|
||||
PR_FREEIF(bodySubType);
|
||||
PR_FREEIF(bodyID);
|
||||
PR_FREEIF(bodyDescription);
|
||||
PR_FREEIF(bodyEncoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PL_strcasecmp(bodyType, "message") || PL_strcasecmp(bodySubType, "rfc822"))
|
||||
{
|
||||
skip_to_close_paren();
|
||||
return new nsIMAPBodypartLeaf(partNum, parentPart, bodyType, bodySubType,
|
||||
bodyID, bodyDescription, bodyEncoding, partLength);
|
||||
}
|
||||
|
||||
// This part is of type "message/rfc822" (probably a forwarded message)
|
||||
nsIMAPBodypartMessage *message = new nsIMAPBodypartMessage(partNum, parentPart, PR_FALSE,
|
||||
bodyType, bodySubType, bodyID, bodyDescription, bodyEncoding, partLength);
|
||||
|
||||
// there are three additional fields: envelope structure, bodystructure, and size in lines
|
||||
// historical note: this code was originally in nsIMAPBodypartMessage::ParseIntoObjects()
|
||||
|
||||
// envelope (ignored)
|
||||
if (*fNextToken == '(')
|
||||
{
|
||||
fNextToken++;
|
||||
skip_to_close_paren();
|
||||
}
|
||||
else
|
||||
isValid = PR_FALSE;
|
||||
|
||||
// bodystructure
|
||||
if (isValid && ContinueParse())
|
||||
{
|
||||
if (*fNextToken != '(')
|
||||
isValid = PR_FALSE;
|
||||
else
|
||||
{
|
||||
char *bodyPartNum = PR_smprintf("%s.1", partNum);
|
||||
if (bodyPartNum)
|
||||
{
|
||||
nsIMAPBodypart *body = bodystructure_part(bodyPartNum, message);
|
||||
if (body)
|
||||
message->SetBody(body);
|
||||
else
|
||||
isValid = PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ignore "size in text lines"
|
||||
|
||||
if (isValid && ContinueParse()) {
|
||||
skip_to_close_paren();
|
||||
return message;
|
||||
}
|
||||
delete message;
|
||||
}
|
||||
|
||||
// parsing failed, just move to the end of the parentheses group
|
||||
if (ContinueParse())
|
||||
skip_to_close_paren();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
nsIMAPBodypart *
|
||||
nsImapServerResponseParser::bodystructure_multipart(char *partNum, nsIMAPBodypart *parentPart)
|
||||
{
|
||||
nsIMAPBodypartMultipart *multipart = new nsIMAPBodypartMultipart(partNum, parentPart);
|
||||
PRBool isValid = multipart->GetIsValid();
|
||||
// historical note: this code was originally in nsIMAPBodypartMultipart::ParseIntoObjects()
|
||||
if (ContinueParse())
|
||||
{
|
||||
fNextToken++; // eat the first '('
|
||||
// Parse list of children
|
||||
int childCount = 0;
|
||||
while (isValid && fNextToken[0] == '(' && ContinueParse())
|
||||
{
|
||||
childCount++;
|
||||
char *childPartNum = NULL;
|
||||
// note: the multipart constructor does some magic on partNumber
|
||||
if (PL_strcmp(multipart->GetPartNumberString(), "0")) // not top-level
|
||||
childPartNum = PR_smprintf("%s.%d", multipart->GetPartNumberString(), childCount);
|
||||
else // top-level
|
||||
childPartNum = PR_smprintf("%d", childCount);
|
||||
if (!childPartNum)
|
||||
isValid = PR_FALSE;
|
||||
else
|
||||
{
|
||||
nsIMAPBodypart *child = bodystructure_part(childPartNum, multipart);
|
||||
if (child)
|
||||
multipart->AppendPart(child);
|
||||
else
|
||||
isValid = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// multipart subtype (mixed, alternative, etc.)
|
||||
if (isValid && ContinueParse())
|
||||
{
|
||||
char *bodySubType = CreateNilString();
|
||||
multipart->SetBodySubType(bodySubType);
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
|
||||
// body parameters (includes boundary parameter): parenthesized list
|
||||
// note: this is optional data
|
||||
char *boundaryData = nsnull;
|
||||
if (isValid && ContinueParse() && *fNextToken == '(')
|
||||
{
|
||||
fNextToken++;
|
||||
while (ContinueParse() && *fNextToken != ')')
|
||||
{
|
||||
char *attribute = CreateNilString();
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
if (ContinueParse() && !PL_strcasecmp(attribute, "BOUNDARY"))
|
||||
{
|
||||
char *boundary = CreateNilString();
|
||||
if (boundary)
|
||||
boundaryData = PR_smprintf("--%s", boundary);
|
||||
PR_FREEIF(boundary);
|
||||
}
|
||||
else if (ContinueParse())
|
||||
{
|
||||
char *value = CreateNilString();
|
||||
PR_FREEIF(value);
|
||||
}
|
||||
PR_FREEIF(attribute);
|
||||
if (ContinueParse())
|
||||
AdvanceToNextToken();
|
||||
}
|
||||
if (ContinueParse())
|
||||
fNextToken++; // skip closing ')'
|
||||
}
|
||||
if (boundaryData)
|
||||
multipart->SetBoundaryData(boundaryData);
|
||||
else
|
||||
isValid = PR_FALSE; // Actually, we should probably generate a boundary here.
|
||||
}
|
||||
|
||||
// always move to closing ')', even if part was not successfully read
|
||||
if (ContinueParse())
|
||||
skip_to_close_paren();
|
||||
|
||||
if (isValid)
|
||||
return multipart;
|
||||
delete multipart;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
void nsImapServerResponseParser::quota_data()
|
||||
{
|
||||
nsCString quotaroot;
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
class nsIMAPNamespace;
|
||||
class nsIMAPNamespaceList;
|
||||
class nsIMAPBodyShell;
|
||||
class nsIMAPBodypart;
|
||||
class nsImapSearchResultIterator;
|
||||
class nsImapFlagAndUidState;
|
||||
class nsCString;
|
||||
|
@ -183,6 +184,9 @@ protected:
|
|||
virtual void myrights_data();
|
||||
virtual void acl_data();
|
||||
virtual void bodystructure_data();
|
||||
nsIMAPBodypart *bodystructure_part(char *partNum, nsIMAPBodypart *parentPart);
|
||||
nsIMAPBodypart *bodystructure_leaf(char *partNum, nsIMAPBodypart *parentPart);
|
||||
nsIMAPBodypart *bodystructure_multipart(char *partNum, nsIMAPBodypart *parentPart);
|
||||
virtual void mime_data();
|
||||
virtual void mime_part_data();
|
||||
virtual void mime_header_data();
|
||||
|
|
Загрузка…
Ссылка в новой задаче