summaryrefslogtreecommitdiff
path: root/tools/source/inet/inetmime.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tools/source/inet/inetmime.cxx')
-rw-r--r--tools/source/inet/inetmime.cxx743
1 files changed, 12 insertions, 731 deletions
diff --git a/tools/source/inet/inetmime.cxx b/tools/source/inet/inetmime.cxx
index 02b8ec233619..47529674245c 100644
--- a/tools/source/inet/inetmime.cxx
+++ b/tools/source/inet/inetmime.cxx
@@ -1619,692 +1619,18 @@ void INetMIME::writeUTF8(INetMIMEOutputSink & rSink, sal_uInt32 nChar)
// static
void INetMIME::writeHeaderFieldBody(INetMIMEOutputSink & rSink,
- HeaderFieldType eType,
const OUString& rBody,
rtl_TextEncoding ePreferredEncoding,
bool bInitialSpace)
{
- if (eType == HEADER_FIELD_TEXT)
- {
- INetMIMEEncodedWordOutputSink
- aOutput(rSink, INetMIMEEncodedWordOutputSink::CONTEXT_TEXT,
- bInitialSpace ?
- INetMIMEEncodedWordOutputSink::SPACE_ALWAYS :
- INetMIMEEncodedWordOutputSink::SPACE_NO,
- ePreferredEncoding);
- aOutput.write(rBody.getStr(), rBody.getStr() + rBody.getLength());
- aOutput.flush();
- }
- else
- {
- enum Brackets { BRACKETS_OUTSIDE, BRACKETS_OPENING, BRACKETS_INSIDE };
- Brackets eBrackets = BRACKETS_OUTSIDE;
-
- const sal_Unicode * pBodyPtr = rBody.getStr();
- const sal_Unicode * pBodyEnd = pBodyPtr + rBody.getLength();
- while (pBodyPtr != pBodyEnd)
- switch (*pBodyPtr)
- {
- case '\t':
- case ' ':
- // A WSP adds to accumulated space:
- bInitialSpace = true;
- ++pBodyPtr;
- break;
-
- case '(':
- {
- // Write a pending '<' if necessary:
- if (eBrackets == BRACKETS_OPENING)
- {
- if (bInitialSpace)
- rSink << ' ';
- rSink << '<';
- bInitialSpace = false;
- eBrackets = BRACKETS_INSIDE;
- }
-
- // Write the comment, introducing encoded-words where
- // necessary:
- int nLevel = 0;
- INetMIMEEncodedWordOutputSink
- aOutput(
- rSink,
- INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT,
- INetMIMEEncodedWordOutputSink::SPACE_NO,
- ePreferredEncoding);
- while (pBodyPtr != pBodyEnd)
- switch (*pBodyPtr)
- {
- case '(':
- aOutput.flush();
- if (bInitialSpace)
- rSink << ' ';
- rSink << '(';
- bInitialSpace = false;
- ++nLevel;
- ++pBodyPtr;
- break;
-
- case ')':
- aOutput.flush();
- rSink << ')';
- ++pBodyPtr;
- if (--nLevel == 0)
- goto comment_done;
- break;
-
- case '\\':
- if (++pBodyPtr == pBodyEnd)
- break;
- default:
- aOutput.WriteUInt32( *pBodyPtr++ );
- break;
- }
- comment_done:
- break;
- }
-
- case '<':
- // Write an already pending '<' if necessary:
- if (eBrackets == BRACKETS_OPENING)
- {
- if (bInitialSpace)
- rSink << ' ';
- rSink << '<';
- bInitialSpace = false;
- }
-
- // Remember this '<' as pending, and open a bracketed
- // block:
- eBrackets = BRACKETS_OPENING;
- ++pBodyPtr;
- break;
-
- case '>':
- // Write a pending '<' if necessary:
- if (eBrackets == BRACKETS_OPENING)
- {
- if (bInitialSpace)
- rSink << ' ';
- rSink << '<';
- bInitialSpace = false;
- }
-
- // Write this '>', and close any bracketed block:
- if (bInitialSpace)
- rSink << ' ';
- rSink << '>';
- bInitialSpace = false;
- eBrackets = BRACKETS_OUTSIDE;
- ++pBodyPtr;
- break;
-
- case ',':
- case ':':
- case ';':
- case '\\':
- case ']':
- // Write a pending '<' if necessary:
- if (eBrackets == BRACKETS_OPENING)
- {
- if (bInitialSpace)
- rSink << ' ';
- rSink << '<';
- bInitialSpace = false;
- eBrackets = BRACKETS_INSIDE;
- }
-
- // Write this specials:
- if (bInitialSpace)
- rSink << ' ';
- rSink << sal_Char(*pBodyPtr++);
- bInitialSpace = false;
- break;
-
- case '\x0D': // CR
- // A <CRLF WSP> adds to accumulated space, a <CR> not
- // followed by <LF WSP> starts 'junk':
- if (startsWithLineFolding(pBodyPtr, pBodyEnd))
- {
- bInitialSpace = true;
- pBodyPtr += 3;
- break;
- }
- default:
- {
- // The next token is either one of <"." / "@" / atom /
- // quoted-string / domain-literal>, or it's 'junk'; if it
- // is not 'junk', it is either a 'phrase' (i.e., it may
- // contain encoded-words) or a 'non-phrase' (i.e., it may
- // not contain encoded-words):
- enum Entity { ENTITY_JUNK, ENTITY_NON_PHRASE,
- ENTITY_PHRASE };
- Entity eEntity = ENTITY_JUNK;
- switch (*pBodyPtr)
- {
- case '.':
- case '@':
- case '[':
- // A token of <"." / "@" / domain-literal> always
- // starts a 'non-phrase':
- eEntity = ENTITY_NON_PHRASE;
- break;
-
- default:
- if (rtl::isAscii(*pBodyPtr)
- && !isAtomChar(*pBodyPtr))
- {
- eEntity = ENTITY_JUNK;
- break;
- }
- case '"':
- // A token of <atom / quoted-string> can either be
- // a 'phrase' or a 'non-phrase':
- switch (eType)
- {
- case HEADER_FIELD_STRUCTURED:
- eEntity = ENTITY_NON_PHRASE;
- break;
-
- case HEADER_FIELD_PHRASE:
- eEntity = ENTITY_PHRASE;
- break;
-
- case HEADER_FIELD_MESSAGE_ID:
- // A 'phrase' if and only if outside any
- // bracketed block:
- eEntity
- = eBrackets == BRACKETS_OUTSIDE ?
- ENTITY_PHRASE :
- ENTITY_NON_PHRASE;
- break;
-
- case HEADER_FIELD_ADDRESS:
- {
- // A 'non-phrase' if and only if, after
- // skipping this token and any following
- // <linear-white-space> and <comment>s,
- // there is no token left, or the next
- // token is any of <"." / "@" / ">" / ","
- // / ";">, or the next token is <":"> and
- // is within a bracketed block:
- const sal_Unicode * pLookAhead = pBodyPtr;
- if (*pLookAhead == '"')
- {
- pLookAhead
- = skipQuotedString(pLookAhead,
- pBodyEnd);
- if (pLookAhead == pBodyPtr)
- pLookAhead = pBodyEnd;
- }
- else
- while (pLookAhead != pBodyEnd
- && (isAtomChar(*pLookAhead)
- || !rtl::isAscii(
- *pLookAhead)))
- ++pLookAhead;
- while (pLookAhead != pBodyEnd)
- switch (*pLookAhead)
- {
- case '\t':
- case ' ':
- ++pLookAhead;
- break;
-
- case '(':
- {
- const sal_Unicode * pPast
- = skipComment(pLookAhead,
- pBodyEnd);
- pLookAhead
- = pPast == pLookAhead ?
- pBodyEnd : pPast;
- break;
- }
-
- case ',':
- case '.':
- case ';':
- case '>':
- case '@':
- eEntity = ENTITY_NON_PHRASE;
- goto entity_determined;
-
- case ':':
- eEntity
- = eBrackets
- == BRACKETS_OUTSIDE ?
- ENTITY_PHRASE :
- ENTITY_NON_PHRASE;
- goto entity_determined;
-
- case '\x0D': // CR
- if (startsWithLineFolding(
- pLookAhead, pBodyEnd))
- {
- pLookAhead += 3;
- break;
- }
- default:
- eEntity = ENTITY_PHRASE;
- goto entity_determined;
- }
- eEntity = ENTITY_NON_PHRASE;
- entity_determined:
- break;
- }
-
- case HEADER_FIELD_TEXT:
- OSL_ASSERT(false);
- break;
- }
-
- // In a 'non-phrase', a non-US-ASCII character
- // cannot be part of an <atom>, but instead the
- // whole entity is 'junk' rather than 'non-
- // phrase':
- if (eEntity == ENTITY_NON_PHRASE
- && !rtl::isAscii(*pBodyPtr))
- eEntity = ENTITY_JUNK;
- break;
- }
-
- switch (eEntity)
- {
- case ENTITY_JUNK:
- {
- // Write a pending '<' if necessary:
- if (eBrackets == BRACKETS_OPENING)
- {
- if (bInitialSpace)
- rSink << ' ';
- rSink << '<';
- bInitialSpace = false;
- eBrackets = BRACKETS_INSIDE;
- }
-
- // Calculate the length of in- and output:
- const sal_Unicode * pStart = pBodyPtr;
- sal_Size nLength = 0;
- bool bModify = false;
- bool bEnd = false;
- while (pBodyPtr != pBodyEnd && !bEnd)
- switch (*pBodyPtr)
- {
- case '\x0D': // CR
- if (startsWithLineFolding(pBodyPtr,
- pBodyEnd))
- bEnd = true;
- else if (startsWithLineBreak(
- pBodyPtr, pBodyEnd))
- {
- nLength += 3;
- bModify = true;
- pBodyPtr += 2;
- }
- else
- {
- ++nLength;
- ++pBodyPtr;
- }
- break;
-
- case '\t':
- case ' ':
- bEnd = true;
- break;
-
- default:
- if (isVisible(*pBodyPtr))
- bEnd = true;
- else if (rtl::isAscii(*pBodyPtr))
- {
- ++nLength;
- ++pBodyPtr;
- }
- else
- {
- nLength += getUTF8OctetCount(
- *pBodyPtr++);
- bModify = true;
- }
- break;
- }
-
- // Write the output:
- if (bInitialSpace)
- rSink << ' ';
- bInitialSpace = false;
- if (bModify)
- while (pStart != pBodyPtr)
- if (startsWithLineBreak(pStart, pBodyPtr))
- {
- rSink << "\x0D\\\x0A"; // CR, '\', LF
- pStart += 2;
- }
- else
- writeUTF8(rSink, *pStart++);
- else
- rSink.write(pStart, pBodyPtr);
- break;
- }
-
- case ENTITY_NON_PHRASE:
- {
- // Calculate the length of in- and output:
- const sal_Unicode * pStart = pBodyPtr;
- sal_Size nLength = 0;
- bool bBracketedBlock = false;
- bool bSymbol = *pStart != '.' && *pStart != '@';
- bool bModify = false;
- bool bEnd = false;
- while (pBodyPtr != pBodyEnd && !bEnd)
- switch (*pBodyPtr)
- {
- case '\t':
- case ' ':
- case '\x0D': // CR
- {
- const sal_Unicode * pLookAhead
- = skipLinearWhiteSpace(pBodyPtr,
- pBodyEnd);
- if (pLookAhead < pBodyEnd
- && (bSymbol ?
- isAtomChar(*pLookAhead)
- || *pLookAhead == '"'
- || *pLookAhead == '[' :
- *pLookAhead == '.'
- || *pLookAhead == '@'
- || (*pLookAhead == '>'
- && eType
- >= HEADER_FIELD_MESSAGE_ID
- && eBrackets
- == BRACKETS_OPENING)))
- {
- bModify = true;
- pBodyPtr = pLookAhead;
- }
- else
- bEnd = true;
- break;
- }
-
- case '"':
- if (bSymbol)
- {
- pBodyPtr
- = scanQuotedBlock(pBodyPtr,
- pBodyEnd,
- '"', '"',
- nLength,
- bModify);
- bSymbol = false;
- }
- else
- bEnd = true;
- break;
-
- case '[':
- if (bSymbol)
- {
- pBodyPtr
- = scanQuotedBlock(pBodyPtr,
- pBodyEnd,
- '[', ']',
- nLength,
- bModify);
- bSymbol = false;
- }
- else
- bEnd = true;
- break;
-
- case '.':
- case '@':
- if (bSymbol)
- bEnd = true;
- else
- {
- ++nLength;
- bSymbol = true;
- ++pBodyPtr;
- }
- break;
-
- case '>':
- if (eBrackets == BRACKETS_OPENING
- && eType
- >= HEADER_FIELD_MESSAGE_ID)
- {
- ++nLength;
- bBracketedBlock = true;
- ++pBodyPtr;
- }
- bEnd = true;
- break;
-
- default:
- if (isAtomChar(*pBodyPtr) && bSymbol)
- {
- while (pBodyPtr != pBodyEnd
- && isAtomChar(*pBodyPtr))
- {
- ++nLength;
- ++pBodyPtr;
- }
- bSymbol = false;
- }
- else
- {
- if (!rtl::isAscii(*pBodyPtr))
- bModify = true;
- bEnd = true;
- }
- break;
- }
-
- // Write a pending '<' if necessary:
- if (eBrackets == BRACKETS_OPENING
- && !bBracketedBlock)
- {
- if (bInitialSpace)
- rSink << ' ';
- rSink << '<';
- bInitialSpace = false;
- eBrackets = BRACKETS_INSIDE;
- }
-
- // Write the output:
- if (bInitialSpace)
- rSink << ' ';
- bInitialSpace = false;
- if (bBracketedBlock)
- {
- rSink << '<';
- eBrackets = BRACKETS_OUTSIDE;
- }
- if (bModify)
- {
- enum Mode { MODE_PLAIN, MODE_QUOTED_STRING,
- MODE_DOMAIN_LITERAL };
- Mode eMode = MODE_PLAIN;
- while (pStart != pBodyPtr)
- switch (*pStart)
- {
- case '\x0D': // CR
- if (startsWithLineFolding(
- pStart, pBodyPtr))
- {
- if (eMode != MODE_PLAIN)
- rSink << sal_Char(
- pStart[2]);
- pStart += 3;
- }
- else if (startsWithLineBreak(
- pStart, pBodyPtr))
- {
- rSink << "\x0D\\\x0A";
- // CR, '\', LF
- pStart += 2;
- }
- else
- {
- rSink << '\x0D'; // CR
- ++pStart;
- }
- break;
-
- case '\t':
- case ' ':
- if (eMode != MODE_PLAIN)
- rSink << sal_Char(*pStart);
- ++pStart;
- break;
-
- case '"':
- if (eMode == MODE_PLAIN)
- eMode = MODE_QUOTED_STRING;
- else if (eMode
- == MODE_QUOTED_STRING)
- eMode = MODE_PLAIN;
- rSink << '"';
- ++pStart;
- break;
-
- case '[':
- if (eMode == MODE_PLAIN)
- eMode = MODE_DOMAIN_LITERAL;
- rSink << '[';
- ++pStart;
- break;
-
- case ']':
- if (eMode == MODE_DOMAIN_LITERAL)
- eMode = MODE_PLAIN;
- rSink << ']';
- ++pStart;
- break;
-
- case '\\':
- rSink << '\\';
- if (++pStart < pBodyPtr)
- writeUTF8(rSink, *pStart++);
- break;
-
- default:
- writeUTF8(rSink, *pStart++);
- break;
- }
- }
- else
- rSink.write(pStart, pBodyPtr);
- break;
- }
-
- case ENTITY_PHRASE:
- {
- // Write a pending '<' if necessary:
- if (eBrackets == BRACKETS_OPENING)
- {
- if (bInitialSpace)
- rSink << ' ';
- rSink << '<';
- bInitialSpace = false;
- eBrackets = BRACKETS_INSIDE;
- }
-
- // Calculate the length of in- and output:
- const sal_Unicode * pStart = pBodyPtr;
- bool bQuotedString = false;
- bool bEnd = false;
- while (pBodyPtr != pBodyEnd && !bEnd)
- switch (*pBodyPtr)
- {
- case '\t':
- case ' ':
- case '\x0D': // CR
- if (bQuotedString)
- ++pBodyPtr;
- else
- {
- const sal_Unicode * pLookAhead
- = skipLinearWhiteSpace(
- pBodyPtr, pBodyEnd);
- if (pLookAhead != pBodyEnd
- && (isAtomChar(*pLookAhead)
- || !rtl::isAscii(*pLookAhead)
- || *pLookAhead == '"'))
- pBodyPtr = pLookAhead;
- else
- bEnd = true;
- }
- break;
-
- case '"':
- bQuotedString = !bQuotedString;
- ++pBodyPtr;
- break;
-
- case '\\':
- if (bQuotedString)
- {
- if (++pBodyPtr != pBodyEnd)
- ++pBodyPtr;
- }
- else
- bEnd = true;
- break;
-
- default:
- if (bQuotedString
- || isAtomChar(*pBodyPtr)
- || !rtl::isAscii(*pBodyPtr))
- ++pBodyPtr;
- else
- bEnd = true;
- break;
- }
-
- // Write the phrase, introducing encoded-words
- // where necessary:
- INetMIMEEncodedWordOutputSink
- aOutput(
- rSink,
- INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,
- bInitialSpace ?
- INetMIMEEncodedWordOutputSink::SPACE_ALWAYS :
- INetMIMEEncodedWordOutputSink::SPACE_ENCODED,
- ePreferredEncoding);
- while (pStart != pBodyPtr)
- switch (*pStart)
- {
- case '"':
- ++pStart;
- break;
-
- case '\\':
- if (++pStart != pBodyPtr)
- aOutput.WriteUInt32( *pStart++ );
- break;
-
- case '\x0D': // CR
- pStart += 2;
- aOutput.WriteUInt32( *pStart++ );
- break;
-
- default:
- aOutput.WriteUInt32( *pStart++ );
- break;
- }
- bInitialSpace = aOutput.flush();
- break;
- }
- }
- break;
- }
- }
- }
+ INetMIMEEncodedWordOutputSink
+ aOutput(rSink, INetMIMEEncodedWordOutputSink::CONTEXT_TEXT,
+ bInitialSpace ?
+ INetMIMEEncodedWordOutputSink::SPACE_ALWAYS :
+ INetMIMEEncodedWordOutputSink::SPACE_NO,
+ ePreferredEncoding);
+ aOutput.write(rBody.getStr(), rBody.getStr() + rBody.getLength());
+ aOutput.flush();
}
// static
@@ -2383,8 +1709,7 @@ bool INetMIME::translateUTF8Char(const sal_Char *& rBegin,
}
// static
-OUString INetMIME::decodeHeaderFieldBody(HeaderFieldType eType,
- const OString& rBody)
+OUString INetMIME::decodeHeaderFieldBody(const OString& rBody)
{
// Due to a bug in INetCoreRFC822MessageStream::ConvertTo7Bit(), old
// versions of StarOffice send mails with header fields where encoded
@@ -2661,45 +1986,9 @@ OUString INetMIME::decodeHeaderFieldBody(HeaderFieldType eType,
if (bEncodedWord)
{
appendISO88591(sDecoded, pCopyBegin, pWSPBegin);
- if (eType == HEADER_FIELD_TEXT)
- sDecoded += OUString(
- pUnicodeBuffer,
- static_cast< sal_Int32 >(nUnicodeSize));
- else if (nCommentLevel == 0)
- {
- sEncodedText = OUString(pUnicodeBuffer, nUnicodeSize);
- if (!bQuotedEncodedText)
- {
- const sal_Unicode * pTextPtr = pUnicodeBuffer;
- const sal_Unicode * pTextEnd = pTextPtr
- + nUnicodeSize;
- for (; pTextPtr != pTextEnd; ++pTextPtr)
- if (!isEncodedWordTokenChar(*pTextPtr))
- {
- bQuotedEncodedText = true;
- break;
- }
- }
- }
- else
- {
- const sal_Unicode * pTextPtr = pUnicodeBuffer;
- const sal_Unicode * pTextEnd = pTextPtr + nUnicodeSize;
- for (; pTextPtr != pTextEnd; ++pTextPtr)
- {
- switch (*pTextPtr)
- {
- case '(':
- case ')':
- case '\\':
- case '\x0D':
- case '=':
- sDecoded += "\\";
- break;
- }
- sDecoded += OUString(*pTextPtr);
- }
- }
+ sDecoded += OUString(
+ pUnicodeBuffer,
+ static_cast< sal_Int32 >(nUnicodeSize));
delete[] pUnicodeBuffer;
p = q;
pCopyBegin = p;
@@ -2744,18 +2033,10 @@ OUString INetMIME::decodeHeaderFieldBody(HeaderFieldType eType,
switch (*p++)
{
case '"':
- if (eType != HEADER_FIELD_TEXT && nCommentLevel == 0)
- {
- const sal_Char * pQuotedStringEnd
- = skipQuotedString(p - 1, pEnd);
- p = pQuotedStringEnd == p - 1 ? pEnd : pQuotedStringEnd;
- }
/* bStartEncodedWord = true; */
break;
case '(':
- if (eType != HEADER_FIELD_TEXT)
- ++nCommentLevel;
/* bStartEncodedWord = true; */
break;