xref: /aoo4110/main/tools/source/inet/inetmime.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_tools.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <cstddef>
28*b1cdbd2cSJim Jagielski #include <limits>
29*b1cdbd2cSJim Jagielski 
30*b1cdbd2cSJim Jagielski #include "rtl/tencinfo.h"
31*b1cdbd2cSJim Jagielski #include <tools/datetime.hxx>
32*b1cdbd2cSJim Jagielski #include <tools/inetmime.hxx>
33*b1cdbd2cSJim Jagielski 
34*b1cdbd2cSJim Jagielski namespace unnamed_tools_inetmime {} using namespace unnamed_tools_inetmime;
35*b1cdbd2cSJim Jagielski 	// unnamed namespaces don't work well yet
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski //============================================================================
38*b1cdbd2cSJim Jagielski namespace unnamed_tools_inetmime {
39*b1cdbd2cSJim Jagielski 
40*b1cdbd2cSJim Jagielski class Charset
41*b1cdbd2cSJim Jagielski {
42*b1cdbd2cSJim Jagielski 	rtl_TextEncoding m_eEncoding;
43*b1cdbd2cSJim Jagielski 	const sal_uInt32 * m_pRanges;
44*b1cdbd2cSJim Jagielski 
45*b1cdbd2cSJim Jagielski public:
46*b1cdbd2cSJim Jagielski 	inline Charset(rtl_TextEncoding eTheEncoding,
47*b1cdbd2cSJim Jagielski 				   const sal_uInt32 * pTheRanges);
48*b1cdbd2cSJim Jagielski 
getEncoding() const49*b1cdbd2cSJim Jagielski 	rtl_TextEncoding getEncoding() const { return m_eEncoding; }
50*b1cdbd2cSJim Jagielski 
51*b1cdbd2cSJim Jagielski 	bool contains(sal_uInt32 nChar) const;
52*b1cdbd2cSJim Jagielski };
53*b1cdbd2cSJim Jagielski 
Charset(rtl_TextEncoding eTheEncoding,const sal_uInt32 * pTheRanges)54*b1cdbd2cSJim Jagielski inline Charset::Charset(rtl_TextEncoding eTheEncoding,
55*b1cdbd2cSJim Jagielski 						const sal_uInt32 * pTheRanges):
56*b1cdbd2cSJim Jagielski 	m_eEncoding(eTheEncoding),
57*b1cdbd2cSJim Jagielski 	m_pRanges(pTheRanges)
58*b1cdbd2cSJim Jagielski {
59*b1cdbd2cSJim Jagielski 	DBG_ASSERT(m_pRanges, "Charset::Charset(): Bad ranges");
60*b1cdbd2cSJim Jagielski }
61*b1cdbd2cSJim Jagielski 
62*b1cdbd2cSJim Jagielski //============================================================================
63*b1cdbd2cSJim Jagielski void appendISO88591(UniString & rText, sal_Char const * pBegin,
64*b1cdbd2cSJim Jagielski 					sal_Char const * pEnd);
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski }
67*b1cdbd2cSJim Jagielski 
68*b1cdbd2cSJim Jagielski //============================================================================
69*b1cdbd2cSJim Jagielski class INetMIMECharsetList_Impl
70*b1cdbd2cSJim Jagielski {
71*b1cdbd2cSJim Jagielski 	struct Node
72*b1cdbd2cSJim Jagielski 	{
73*b1cdbd2cSJim Jagielski 		Charset m_aCharset;
74*b1cdbd2cSJim Jagielski 		bool m_bDisabled;
75*b1cdbd2cSJim Jagielski 		Node * m_pNext;
76*b1cdbd2cSJim Jagielski 
77*b1cdbd2cSJim Jagielski 		inline Node(const Charset & rTheCharset, bool bTheDisabled,
78*b1cdbd2cSJim Jagielski 					Node * pTheNext);
79*b1cdbd2cSJim Jagielski 	};
80*b1cdbd2cSJim Jagielski 
81*b1cdbd2cSJim Jagielski 	Node * m_pFirst;
82*b1cdbd2cSJim Jagielski 
83*b1cdbd2cSJim Jagielski public:
INetMIMECharsetList_Impl()84*b1cdbd2cSJim Jagielski 	INetMIMECharsetList_Impl(): m_pFirst(0) {}
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski 	~INetMIMECharsetList_Impl();
87*b1cdbd2cSJim Jagielski 
prepend(const Charset & rCharset)88*b1cdbd2cSJim Jagielski 	void prepend(const Charset & rCharset)
89*b1cdbd2cSJim Jagielski 	{ m_pFirst = new Node(rCharset, false, m_pFirst); }
90*b1cdbd2cSJim Jagielski 
91*b1cdbd2cSJim Jagielski 	void includes(sal_uInt32 nChar);
92*b1cdbd2cSJim Jagielski 
93*b1cdbd2cSJim Jagielski 	rtl_TextEncoding getPreferredEncoding(rtl_TextEncoding eDefault
94*b1cdbd2cSJim Jagielski 										      = RTL_TEXTENCODING_DONTKNOW)
95*b1cdbd2cSJim Jagielski 		const;
96*b1cdbd2cSJim Jagielski 
97*b1cdbd2cSJim Jagielski 	void reset();
98*b1cdbd2cSJim Jagielski };
99*b1cdbd2cSJim Jagielski 
Node(const Charset & rTheCharset,bool bTheDisabled,Node * pTheNext)100*b1cdbd2cSJim Jagielski inline INetMIMECharsetList_Impl::Node::Node(const Charset & rTheCharset,
101*b1cdbd2cSJim Jagielski 											bool bTheDisabled,
102*b1cdbd2cSJim Jagielski 											Node * pTheNext):
103*b1cdbd2cSJim Jagielski 	m_aCharset(rTheCharset),
104*b1cdbd2cSJim Jagielski 	m_bDisabled(bTheDisabled),
105*b1cdbd2cSJim Jagielski 	m_pNext(pTheNext)
106*b1cdbd2cSJim Jagielski {}
107*b1cdbd2cSJim Jagielski 
108*b1cdbd2cSJim Jagielski //============================================================================
109*b1cdbd2cSJim Jagielski namespace unnamed_tools_inetmime {
110*b1cdbd2cSJim Jagielski 
111*b1cdbd2cSJim Jagielski struct Parameter
112*b1cdbd2cSJim Jagielski {
113*b1cdbd2cSJim Jagielski 	Parameter * m_pNext;
114*b1cdbd2cSJim Jagielski 	ByteString m_aAttribute;
115*b1cdbd2cSJim Jagielski 	ByteString m_aCharset;
116*b1cdbd2cSJim Jagielski 	ByteString m_aLanguage;
117*b1cdbd2cSJim Jagielski 	ByteString m_aValue;
118*b1cdbd2cSJim Jagielski 	sal_uInt32 m_nSection;
119*b1cdbd2cSJim Jagielski 	bool m_bExtended;
120*b1cdbd2cSJim Jagielski 
121*b1cdbd2cSJim Jagielski 	inline Parameter(Parameter * pTheNext, ByteString const & rTheAttribute,
122*b1cdbd2cSJim Jagielski 					 ByteString const & rTheCharset,
123*b1cdbd2cSJim Jagielski 					 ByteString const & rTheLanguage,
124*b1cdbd2cSJim Jagielski 					 ByteString const & rTheValue, sal_uInt32 nTheSection,
125*b1cdbd2cSJim Jagielski 					 bool bTheExtended);
126*b1cdbd2cSJim Jagielski };
127*b1cdbd2cSJim Jagielski 
Parameter(Parameter * pTheNext,ByteString const & rTheAttribute,ByteString const & rTheCharset,ByteString const & rTheLanguage,ByteString const & rTheValue,sal_uInt32 nTheSection,bool bTheExtended)128*b1cdbd2cSJim Jagielski inline Parameter::Parameter(Parameter * pTheNext,
129*b1cdbd2cSJim Jagielski 							ByteString const & rTheAttribute,
130*b1cdbd2cSJim Jagielski 							ByteString const & rTheCharset,
131*b1cdbd2cSJim Jagielski 							ByteString const & rTheLanguage,
132*b1cdbd2cSJim Jagielski 							ByteString const & rTheValue,
133*b1cdbd2cSJim Jagielski 							sal_uInt32 nTheSection, bool bTheExtended):
134*b1cdbd2cSJim Jagielski 	m_pNext(pTheNext),
135*b1cdbd2cSJim Jagielski 	m_aAttribute(rTheAttribute),
136*b1cdbd2cSJim Jagielski 	m_aCharset(rTheCharset),
137*b1cdbd2cSJim Jagielski 	m_aLanguage(rTheLanguage),
138*b1cdbd2cSJim Jagielski 	m_aValue(rTheValue),
139*b1cdbd2cSJim Jagielski 	m_nSection(nTheSection),
140*b1cdbd2cSJim Jagielski 	m_bExtended(bTheExtended)
141*b1cdbd2cSJim Jagielski {}
142*b1cdbd2cSJim Jagielski 
143*b1cdbd2cSJim Jagielski //============================================================================
144*b1cdbd2cSJim Jagielski struct ParameterList
145*b1cdbd2cSJim Jagielski {
146*b1cdbd2cSJim Jagielski 	Parameter * m_pList;
147*b1cdbd2cSJim Jagielski 
ParameterListunnamed_tools_inetmime::ParameterList148*b1cdbd2cSJim Jagielski 	ParameterList(): m_pList(0) {}
149*b1cdbd2cSJim Jagielski 
150*b1cdbd2cSJim Jagielski 	inline ~ParameterList();
151*b1cdbd2cSJim Jagielski 
152*b1cdbd2cSJim Jagielski 	Parameter ** find(ByteString const & rAttribute, sal_uInt32 nSection,
153*b1cdbd2cSJim Jagielski 					  bool & rPresent);
154*b1cdbd2cSJim Jagielski };
155*b1cdbd2cSJim Jagielski 
~ParameterList()156*b1cdbd2cSJim Jagielski inline ParameterList::~ParameterList()
157*b1cdbd2cSJim Jagielski {
158*b1cdbd2cSJim Jagielski 	while (m_pList)
159*b1cdbd2cSJim Jagielski 	{
160*b1cdbd2cSJim Jagielski 		Parameter * pNext = m_pList->m_pNext;
161*b1cdbd2cSJim Jagielski 		delete m_pList;
162*b1cdbd2cSJim Jagielski 		m_pList = pNext;
163*b1cdbd2cSJim Jagielski 	}
164*b1cdbd2cSJim Jagielski }
165*b1cdbd2cSJim Jagielski 
166*b1cdbd2cSJim Jagielski //============================================================================
167*b1cdbd2cSJim Jagielski bool parseParameters(ParameterList const & rInput,
168*b1cdbd2cSJim Jagielski 					 INetContentTypeParameterList * pOutput);
169*b1cdbd2cSJim Jagielski 
170*b1cdbd2cSJim Jagielski }
171*b1cdbd2cSJim Jagielski 
172*b1cdbd2cSJim Jagielski //============================================================================
173*b1cdbd2cSJim Jagielski //
174*b1cdbd2cSJim Jagielski //  Charset
175*b1cdbd2cSJim Jagielski //
176*b1cdbd2cSJim Jagielski //============================================================================
177*b1cdbd2cSJim Jagielski 
contains(sal_uInt32 nChar) const178*b1cdbd2cSJim Jagielski bool Charset::contains(sal_uInt32 nChar) const
179*b1cdbd2cSJim Jagielski {
180*b1cdbd2cSJim Jagielski 	for (const sal_uInt32 * p = m_pRanges;;)
181*b1cdbd2cSJim Jagielski 	{
182*b1cdbd2cSJim Jagielski 		if (nChar < *p++)
183*b1cdbd2cSJim Jagielski 			return false;
184*b1cdbd2cSJim Jagielski 		if (nChar <= *p++)
185*b1cdbd2cSJim Jagielski 			return true;
186*b1cdbd2cSJim Jagielski 	}
187*b1cdbd2cSJim Jagielski }
188*b1cdbd2cSJim Jagielski 
189*b1cdbd2cSJim Jagielski //============================================================================
190*b1cdbd2cSJim Jagielski //
191*b1cdbd2cSJim Jagielski //  appendISO88591
192*b1cdbd2cSJim Jagielski //
193*b1cdbd2cSJim Jagielski //============================================================================
194*b1cdbd2cSJim Jagielski 
195*b1cdbd2cSJim Jagielski namespace unnamed_tools_inetmime {
196*b1cdbd2cSJim Jagielski 
appendISO88591(UniString & rText,sal_Char const * pBegin,sal_Char const * pEnd)197*b1cdbd2cSJim Jagielski void appendISO88591(UniString & rText, sal_Char const * pBegin,
198*b1cdbd2cSJim Jagielski 					sal_Char const * pEnd)
199*b1cdbd2cSJim Jagielski {
200*b1cdbd2cSJim Jagielski 	xub_StrLen nLength = static_cast< xub_StrLen >(pEnd - pBegin);
201*b1cdbd2cSJim Jagielski 	sal_Unicode * pBuffer = new sal_Unicode[nLength];
202*b1cdbd2cSJim Jagielski 	for (sal_Unicode * p = pBuffer; pBegin != pEnd;)
203*b1cdbd2cSJim Jagielski 		*p++ = sal_uChar(*pBegin++);
204*b1cdbd2cSJim Jagielski 	rText.Append(pBuffer, nLength);
205*b1cdbd2cSJim Jagielski 	delete[] pBuffer;
206*b1cdbd2cSJim Jagielski }
207*b1cdbd2cSJim Jagielski 
208*b1cdbd2cSJim Jagielski }
209*b1cdbd2cSJim Jagielski 
210*b1cdbd2cSJim Jagielski //============================================================================
211*b1cdbd2cSJim Jagielski //
212*b1cdbd2cSJim Jagielski //  INetMIMECharsetList_Impl
213*b1cdbd2cSJim Jagielski //
214*b1cdbd2cSJim Jagielski //============================================================================
215*b1cdbd2cSJim Jagielski 
~INetMIMECharsetList_Impl()216*b1cdbd2cSJim Jagielski INetMIMECharsetList_Impl::~INetMIMECharsetList_Impl()
217*b1cdbd2cSJim Jagielski {
218*b1cdbd2cSJim Jagielski 	while (m_pFirst)
219*b1cdbd2cSJim Jagielski 	{
220*b1cdbd2cSJim Jagielski 		Node * pRemove = m_pFirst;
221*b1cdbd2cSJim Jagielski 		m_pFirst = m_pFirst->m_pNext;
222*b1cdbd2cSJim Jagielski 		delete pRemove;
223*b1cdbd2cSJim Jagielski 	}
224*b1cdbd2cSJim Jagielski }
225*b1cdbd2cSJim Jagielski 
226*b1cdbd2cSJim Jagielski //============================================================================
includes(sal_uInt32 nChar)227*b1cdbd2cSJim Jagielski void INetMIMECharsetList_Impl::includes(sal_uInt32 nChar)
228*b1cdbd2cSJim Jagielski {
229*b1cdbd2cSJim Jagielski 	for (Node * p = m_pFirst; p; p = p->m_pNext)
230*b1cdbd2cSJim Jagielski 		if (!(p->m_bDisabled || p->m_aCharset.contains(nChar)))
231*b1cdbd2cSJim Jagielski 			p->m_bDisabled = true;
232*b1cdbd2cSJim Jagielski }
233*b1cdbd2cSJim Jagielski 
234*b1cdbd2cSJim Jagielski //============================================================================
235*b1cdbd2cSJim Jagielski rtl_TextEncoding
getPreferredEncoding(rtl_TextEncoding eDefault) const236*b1cdbd2cSJim Jagielski INetMIMECharsetList_Impl::getPreferredEncoding(rtl_TextEncoding eDefault)
237*b1cdbd2cSJim Jagielski 	const
238*b1cdbd2cSJim Jagielski {
239*b1cdbd2cSJim Jagielski 	for (Node * p = m_pFirst; p; p = p->m_pNext)
240*b1cdbd2cSJim Jagielski 		if (!p->m_bDisabled)
241*b1cdbd2cSJim Jagielski 			return p->m_aCharset.getEncoding();
242*b1cdbd2cSJim Jagielski 	return eDefault;
243*b1cdbd2cSJim Jagielski }
244*b1cdbd2cSJim Jagielski 
245*b1cdbd2cSJim Jagielski //============================================================================
reset()246*b1cdbd2cSJim Jagielski void INetMIMECharsetList_Impl::reset()
247*b1cdbd2cSJim Jagielski {
248*b1cdbd2cSJim Jagielski 	for (Node * p = m_pFirst; p; p = p->m_pNext)
249*b1cdbd2cSJim Jagielski 		p->m_bDisabled = false;
250*b1cdbd2cSJim Jagielski }
251*b1cdbd2cSJim Jagielski 
252*b1cdbd2cSJim Jagielski //============================================================================
253*b1cdbd2cSJim Jagielski //
254*b1cdbd2cSJim Jagielski //  ParameterList
255*b1cdbd2cSJim Jagielski //
256*b1cdbd2cSJim Jagielski //============================================================================
257*b1cdbd2cSJim Jagielski 
find(ByteString const & rAttribute,sal_uInt32 nSection,bool & rPresent)258*b1cdbd2cSJim Jagielski Parameter ** ParameterList::find(ByteString const & rAttribute,
259*b1cdbd2cSJim Jagielski 								 sal_uInt32 nSection, bool & rPresent)
260*b1cdbd2cSJim Jagielski {
261*b1cdbd2cSJim Jagielski 	Parameter ** p = &m_pList;
262*b1cdbd2cSJim Jagielski 	for (; *p; p = &(*p)->m_pNext)
263*b1cdbd2cSJim Jagielski 	{
264*b1cdbd2cSJim Jagielski 		StringCompare eCompare = rAttribute.CompareTo((*p)->m_aAttribute);
265*b1cdbd2cSJim Jagielski 		if (eCompare == COMPARE_GREATER)
266*b1cdbd2cSJim Jagielski 			break;
267*b1cdbd2cSJim Jagielski 		else if (eCompare == COMPARE_EQUAL)
268*b1cdbd2cSJim Jagielski         {
269*b1cdbd2cSJim Jagielski 			if (nSection > (*p)->m_nSection)
270*b1cdbd2cSJim Jagielski 				break;
271*b1cdbd2cSJim Jagielski 			else if (nSection == (*p)->m_nSection)
272*b1cdbd2cSJim Jagielski 			{
273*b1cdbd2cSJim Jagielski 				rPresent = true;
274*b1cdbd2cSJim Jagielski 				return p;
275*b1cdbd2cSJim Jagielski 			}
276*b1cdbd2cSJim Jagielski         }
277*b1cdbd2cSJim Jagielski 	}
278*b1cdbd2cSJim Jagielski 	rPresent = false;
279*b1cdbd2cSJim Jagielski 	return p;
280*b1cdbd2cSJim Jagielski }
281*b1cdbd2cSJim Jagielski 
282*b1cdbd2cSJim Jagielski //============================================================================
283*b1cdbd2cSJim Jagielski //
284*b1cdbd2cSJim Jagielski //  parseParameters
285*b1cdbd2cSJim Jagielski //
286*b1cdbd2cSJim Jagielski //============================================================================
287*b1cdbd2cSJim Jagielski 
288*b1cdbd2cSJim Jagielski namespace unnamed_tools_inetmime {
289*b1cdbd2cSJim Jagielski 
parseParameters(ParameterList const & rInput,INetContentTypeParameterList * pOutput)290*b1cdbd2cSJim Jagielski bool parseParameters(ParameterList const & rInput,
291*b1cdbd2cSJim Jagielski 					 INetContentTypeParameterList * pOutput)
292*b1cdbd2cSJim Jagielski {
293*b1cdbd2cSJim Jagielski 	if (pOutput)
294*b1cdbd2cSJim Jagielski 		pOutput->Clear();
295*b1cdbd2cSJim Jagielski 
296*b1cdbd2cSJim Jagielski 	Parameter * pPrev = 0;
297*b1cdbd2cSJim Jagielski 	for (Parameter * p = rInput.m_pList; p; p = p->m_pNext)
298*b1cdbd2cSJim Jagielski 	{
299*b1cdbd2cSJim Jagielski 		if (p->m_nSection > 0
300*b1cdbd2cSJim Jagielski 			&& (!pPrev
301*b1cdbd2cSJim Jagielski 				|| pPrev->m_nSection != p->m_nSection - 1
302*b1cdbd2cSJim Jagielski 				|| pPrev->m_aAttribute != p->m_aAttribute))
303*b1cdbd2cSJim Jagielski 			return false;
304*b1cdbd2cSJim Jagielski 		pPrev = p;
305*b1cdbd2cSJim Jagielski 	}
306*b1cdbd2cSJim Jagielski 
307*b1cdbd2cSJim Jagielski 	if (pOutput)
308*b1cdbd2cSJim Jagielski 		for (Parameter * p = rInput.m_pList; p;)
309*b1cdbd2cSJim Jagielski 		{
310*b1cdbd2cSJim Jagielski 			bool bCharset = p->m_aCharset.Len() != 0;
311*b1cdbd2cSJim Jagielski 			rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW;
312*b1cdbd2cSJim Jagielski 			if (bCharset)
313*b1cdbd2cSJim Jagielski 				eEncoding
314*b1cdbd2cSJim Jagielski 					= INetMIME::getCharsetEncoding(p->m_aCharset.GetBuffer(),
315*b1cdbd2cSJim Jagielski 												   p->m_aCharset.GetBuffer()
316*b1cdbd2cSJim Jagielski 											           + rInput.m_pList->
317*b1cdbd2cSJim Jagielski 												             m_aCharset.
318*b1cdbd2cSJim Jagielski 												                 Len());
319*b1cdbd2cSJim Jagielski 			UniString aValue;
320*b1cdbd2cSJim Jagielski 			bool bBadEncoding = false;
321*b1cdbd2cSJim Jagielski 			Parameter * pNext = p;
322*b1cdbd2cSJim Jagielski 			do
323*b1cdbd2cSJim Jagielski 			{
324*b1cdbd2cSJim Jagielski 				sal_Size nSize;
325*b1cdbd2cSJim Jagielski 				sal_Unicode * pUnicode
326*b1cdbd2cSJim Jagielski 					= INetMIME::convertToUnicode(pNext->m_aValue.GetBuffer(),
327*b1cdbd2cSJim Jagielski 												 pNext->m_aValue.GetBuffer()
328*b1cdbd2cSJim Jagielski 												     + pNext->m_aValue.Len(),
329*b1cdbd2cSJim Jagielski 												 bCharset && p->m_bExtended ?
330*b1cdbd2cSJim Jagielski 												     eEncoding :
331*b1cdbd2cSJim Jagielski 												     RTL_TEXTENCODING_UTF8,
332*b1cdbd2cSJim Jagielski 												 nSize);
333*b1cdbd2cSJim Jagielski 				if (!pUnicode && !(bCharset && p->m_bExtended))
334*b1cdbd2cSJim Jagielski 					pUnicode = INetMIME::convertToUnicode(
335*b1cdbd2cSJim Jagielski 						           pNext->m_aValue.GetBuffer(),
336*b1cdbd2cSJim Jagielski 								   pNext->m_aValue.GetBuffer()
337*b1cdbd2cSJim Jagielski 								       + pNext->m_aValue.Len(),
338*b1cdbd2cSJim Jagielski 								   RTL_TEXTENCODING_ISO_8859_1, nSize);
339*b1cdbd2cSJim Jagielski 				if (!pUnicode)
340*b1cdbd2cSJim Jagielski 				{
341*b1cdbd2cSJim Jagielski 					bBadEncoding = true;
342*b1cdbd2cSJim Jagielski 					break;
343*b1cdbd2cSJim Jagielski 				}
344*b1cdbd2cSJim Jagielski 				aValue += UniString(pUnicode, static_cast< xub_StrLen >(nSize));
345*b1cdbd2cSJim Jagielski 				delete[] pUnicode;
346*b1cdbd2cSJim Jagielski 				pNext = pNext->m_pNext;
347*b1cdbd2cSJim Jagielski 			}
348*b1cdbd2cSJim Jagielski 			while (pNext && pNext->m_nSection > 0);
349*b1cdbd2cSJim Jagielski 			if (bBadEncoding)
350*b1cdbd2cSJim Jagielski 			{
351*b1cdbd2cSJim Jagielski 				aValue.Erase();
352*b1cdbd2cSJim Jagielski 				for (pNext = p;;)
353*b1cdbd2cSJim Jagielski 				{
354*b1cdbd2cSJim Jagielski 					if (pNext->m_bExtended)
355*b1cdbd2cSJim Jagielski 						for (xub_StrLen i = 0; i < pNext->m_aValue.Len(); ++i)
356*b1cdbd2cSJim Jagielski 							aValue += sal_Unicode(
357*b1cdbd2cSJim Jagielski                                 sal_Unicode(
358*b1cdbd2cSJim Jagielski                                     sal_uChar(pNext->m_aValue.GetChar(i)))
359*b1cdbd2cSJim Jagielski                                 | 0xF800);
360*b1cdbd2cSJim Jagielski 					else
361*b1cdbd2cSJim Jagielski 						for (xub_StrLen i = 0; i < pNext->m_aValue.Len(); ++i)
362*b1cdbd2cSJim Jagielski 							aValue
363*b1cdbd2cSJim Jagielski 								+= sal_Unicode(sal_uChar
364*b1cdbd2cSJim Jagielski 											       (pNext->
365*b1cdbd2cSJim Jagielski 													    m_aValue.GetChar(i)));
366*b1cdbd2cSJim Jagielski 					pNext = pNext->m_pNext;
367*b1cdbd2cSJim Jagielski 					if (!pNext || pNext->m_nSection == 0)
368*b1cdbd2cSJim Jagielski 						break;
369*b1cdbd2cSJim Jagielski 				};
370*b1cdbd2cSJim Jagielski 			}
371*b1cdbd2cSJim Jagielski 			pOutput->Insert(new INetContentTypeParameter(p->m_aAttribute,
372*b1cdbd2cSJim Jagielski 															 p->m_aCharset,
373*b1cdbd2cSJim Jagielski 															 p->m_aLanguage,
374*b1cdbd2cSJim Jagielski 															 aValue,
375*b1cdbd2cSJim Jagielski 															 !bBadEncoding),
376*b1cdbd2cSJim Jagielski 								LIST_APPEND);
377*b1cdbd2cSJim Jagielski 			p = pNext;
378*b1cdbd2cSJim Jagielski 		}
379*b1cdbd2cSJim Jagielski 	return true;
380*b1cdbd2cSJim Jagielski }
381*b1cdbd2cSJim Jagielski 
382*b1cdbd2cSJim Jagielski }
383*b1cdbd2cSJim Jagielski 
384*b1cdbd2cSJim Jagielski //============================================================================
385*b1cdbd2cSJim Jagielski //
386*b1cdbd2cSJim Jagielski //  INetMIME
387*b1cdbd2cSJim Jagielski //
388*b1cdbd2cSJim Jagielski //============================================================================
389*b1cdbd2cSJim Jagielski 
390*b1cdbd2cSJim Jagielski // static
isAtomChar(sal_uInt32 nChar)391*b1cdbd2cSJim Jagielski bool INetMIME::isAtomChar(sal_uInt32 nChar)
392*b1cdbd2cSJim Jagielski {
393*b1cdbd2cSJim Jagielski 	static const bool aMap[128]
394*b1cdbd2cSJim Jagielski 		= { false, false, false, false, false, false, false, false,
395*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
396*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
397*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
398*b1cdbd2cSJim Jagielski 			false,  true, false,  true,  true,  true,  true,  true, // !"#$%&'
399*b1cdbd2cSJim Jagielski 			false, false,  true,  true, false,  true, false,  true, //()*+,-./
400*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //01234567
401*b1cdbd2cSJim Jagielski 			 true,  true, false, false, false,  true, false,  true, //89:;<=>?
402*b1cdbd2cSJim Jagielski 			false,  true,  true,  true,  true,  true,  true,  true, //@ABCDEFG
403*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //HIJKLMNO
404*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //PQRSTUVW
405*b1cdbd2cSJim Jagielski 			 true,  true,  true, false, false, false,  true,  true, //XYZ[\]^_
406*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //`abcdefg
407*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //hijklmno
408*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //pqrstuvw
409*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true, false  //xyz{|}~
410*b1cdbd2cSJim Jagielski 		  };
411*b1cdbd2cSJim Jagielski 	return isUSASCII(nChar) && aMap[nChar];
412*b1cdbd2cSJim Jagielski }
413*b1cdbd2cSJim Jagielski 
414*b1cdbd2cSJim Jagielski //============================================================================
415*b1cdbd2cSJim Jagielski // static
isTokenChar(sal_uInt32 nChar)416*b1cdbd2cSJim Jagielski bool INetMIME::isTokenChar(sal_uInt32 nChar)
417*b1cdbd2cSJim Jagielski {
418*b1cdbd2cSJim Jagielski 	static const sal_Char aMap[128]
419*b1cdbd2cSJim Jagielski 		= { false, false, false, false, false, false, false, false,
420*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
421*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
422*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
423*b1cdbd2cSJim Jagielski 			false,  true, false,  true,  true,  true,  true,  true, // !"#$%&'
424*b1cdbd2cSJim Jagielski 			false, false,  true,  true, false,  true,  true, false, //()*+,-./
425*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //01234567
426*b1cdbd2cSJim Jagielski 			 true,  true, false, false, false, false, false, false, //89:;<=>?
427*b1cdbd2cSJim Jagielski 			false,  true,  true,  true,  true,  true,  true,  true, //@ABCDEFG
428*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //HIJKLMNO
429*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //PQRSTUVW
430*b1cdbd2cSJim Jagielski 			 true,  true,  true, false, false, false,  true,  true, //XYZ[\]^_
431*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //`abcdefg
432*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //hijklmno
433*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //pqrstuvw
434*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true, false  //xyz{|}~
435*b1cdbd2cSJim Jagielski 		  };
436*b1cdbd2cSJim Jagielski 	return isUSASCII(nChar) && aMap[nChar];
437*b1cdbd2cSJim Jagielski }
438*b1cdbd2cSJim Jagielski 
439*b1cdbd2cSJim Jagielski //============================================================================
440*b1cdbd2cSJim Jagielski // static
isEncodedWordTokenChar(sal_uInt32 nChar)441*b1cdbd2cSJim Jagielski bool INetMIME::isEncodedWordTokenChar(sal_uInt32 nChar)
442*b1cdbd2cSJim Jagielski {
443*b1cdbd2cSJim Jagielski 	static const sal_Char aMap[128]
444*b1cdbd2cSJim Jagielski 		= { false, false, false, false, false, false, false, false,
445*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
446*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
447*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
448*b1cdbd2cSJim Jagielski 			false,  true, false,  true,  true,  true,  true,  true, // !"#$%&'
449*b1cdbd2cSJim Jagielski 			false, false,  true,  true, false,  true, false, false, //()*+,-./
450*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //01234567
451*b1cdbd2cSJim Jagielski 			 true,  true, false, false, false, false, false, false, //89:;<=>?
452*b1cdbd2cSJim Jagielski 			false,  true,  true,  true,  true,  true,  true,  true, //@ABCDEFG
453*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //HIJKLMNO
454*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //PQRSTUVW
455*b1cdbd2cSJim Jagielski 			 true,  true,  true, false, false, false,  true,  true, //XYZ[\]^_
456*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //`abcdefg
457*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //hijklmno
458*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //pqrstuvw
459*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true, false  //xyz{|}~
460*b1cdbd2cSJim Jagielski 		  };
461*b1cdbd2cSJim Jagielski 	return isUSASCII(nChar) && aMap[nChar];
462*b1cdbd2cSJim Jagielski }
463*b1cdbd2cSJim Jagielski 
464*b1cdbd2cSJim Jagielski //============================================================================
465*b1cdbd2cSJim Jagielski // static
isIMAPAtomChar(sal_uInt32 nChar)466*b1cdbd2cSJim Jagielski bool INetMIME::isIMAPAtomChar(sal_uInt32 nChar)
467*b1cdbd2cSJim Jagielski {
468*b1cdbd2cSJim Jagielski 	static const sal_Char aMap[128]
469*b1cdbd2cSJim Jagielski 		= { false, false, false, false, false, false, false, false,
470*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
471*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
472*b1cdbd2cSJim Jagielski 			false, false, false, false, false, false, false, false,
473*b1cdbd2cSJim Jagielski 			false,  true, false,  true,  true, false,  true,  true, // !"#$%&'
474*b1cdbd2cSJim Jagielski 			false, false, false,  true,  true,  true,  true,  true, //()*+,-./
475*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //01234567
476*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //89:;<=>?
477*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //@ABCDEFG
478*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //HIJKLMNO
479*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //PQRSTUVW
480*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true, false,  true,  true,  true, //XYZ[\]^_
481*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //`abcdefg
482*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //hijklmno
483*b1cdbd2cSJim Jagielski 			 true,  true,  true,  true,  true,  true,  true,  true, //pqrstuvw
484*b1cdbd2cSJim Jagielski 			 true,  true,  true, false,  true,  true,  true, false  //xyz{|}~
485*b1cdbd2cSJim Jagielski 		  };
486*b1cdbd2cSJim Jagielski 	return isUSASCII(nChar) && aMap[nChar];
487*b1cdbd2cSJim Jagielski }
488*b1cdbd2cSJim Jagielski 
489*b1cdbd2cSJim Jagielski //============================================================================
490*b1cdbd2cSJim Jagielski // static
getDigit(int nWeight)491*b1cdbd2cSJim Jagielski sal_uInt32 INetMIME::getDigit(int nWeight)
492*b1cdbd2cSJim Jagielski {
493*b1cdbd2cSJim Jagielski 	DBG_ASSERT(nWeight >= 0 && nWeight < 10,
494*b1cdbd2cSJim Jagielski 			   "INetMIME::getDigit(): Bad weight");
495*b1cdbd2cSJim Jagielski 
496*b1cdbd2cSJim Jagielski 	static const sal_Char aDigits[16]
497*b1cdbd2cSJim Jagielski 		= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
498*b1cdbd2cSJim Jagielski 	return aDigits[nWeight];
499*b1cdbd2cSJim Jagielski }
500*b1cdbd2cSJim Jagielski 
501*b1cdbd2cSJim Jagielski //============================================================================
502*b1cdbd2cSJim Jagielski // static
getHexDigit(int nWeight)503*b1cdbd2cSJim Jagielski sal_uInt32 INetMIME::getHexDigit(int nWeight)
504*b1cdbd2cSJim Jagielski {
505*b1cdbd2cSJim Jagielski 	DBG_ASSERT(nWeight >= 0 && nWeight < 16,
506*b1cdbd2cSJim Jagielski 			   "INetMIME::getHexDigit(): Bad weight");
507*b1cdbd2cSJim Jagielski 
508*b1cdbd2cSJim Jagielski 	static const sal_Char aDigits[16]
509*b1cdbd2cSJim Jagielski 		= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
510*b1cdbd2cSJim Jagielski 			'D', 'E', 'F' };
511*b1cdbd2cSJim Jagielski 	return aDigits[nWeight];
512*b1cdbd2cSJim Jagielski }
513*b1cdbd2cSJim Jagielski 
514*b1cdbd2cSJim Jagielski //============================================================================
515*b1cdbd2cSJim Jagielski // static
getBase64Digit(int nWeight)516*b1cdbd2cSJim Jagielski sal_uInt32 INetMIME::getBase64Digit(int nWeight)
517*b1cdbd2cSJim Jagielski {
518*b1cdbd2cSJim Jagielski 	DBG_ASSERT(nWeight >= 0 && nWeight < 64,
519*b1cdbd2cSJim Jagielski 			   "INetMIME::getBase64Digit(): Bad weight");
520*b1cdbd2cSJim Jagielski 
521*b1cdbd2cSJim Jagielski 	static const sal_Char aDigits[64]
522*b1cdbd2cSJim Jagielski 		= { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
523*b1cdbd2cSJim Jagielski 			'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
524*b1cdbd2cSJim Jagielski 			'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
525*b1cdbd2cSJim Jagielski 			'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
526*b1cdbd2cSJim Jagielski 			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
527*b1cdbd2cSJim Jagielski 	return aDigits[nWeight];
528*b1cdbd2cSJim Jagielski }
529*b1cdbd2cSJim Jagielski 
530*b1cdbd2cSJim Jagielski //============================================================================
531*b1cdbd2cSJim Jagielski // static
equalIgnoreCase(const sal_Char * pBegin1,const sal_Char * pEnd1,const sal_Char * pBegin2,const sal_Char * pEnd2)532*b1cdbd2cSJim Jagielski bool INetMIME::equalIgnoreCase(const sal_Char * pBegin1,
533*b1cdbd2cSJim Jagielski 							   const sal_Char * pEnd1,
534*b1cdbd2cSJim Jagielski 							   const sal_Char * pBegin2,
535*b1cdbd2cSJim Jagielski 							   const sal_Char * pEnd2)
536*b1cdbd2cSJim Jagielski {
537*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin1 && pBegin1 <= pEnd1 && pBegin2 && pBegin2 <= pEnd2,
538*b1cdbd2cSJim Jagielski 			   "INetMIME::equalIgnoreCase(): Bad sequences");
539*b1cdbd2cSJim Jagielski 
540*b1cdbd2cSJim Jagielski 	if (pEnd1 - pBegin1 != pEnd2 - pBegin2)
541*b1cdbd2cSJim Jagielski 		return false;
542*b1cdbd2cSJim Jagielski 	while (pBegin1 != pEnd1)
543*b1cdbd2cSJim Jagielski 		if (toUpperCase(*pBegin1++) != toUpperCase(*pBegin2++))
544*b1cdbd2cSJim Jagielski 			return false;
545*b1cdbd2cSJim Jagielski 	return true;
546*b1cdbd2cSJim Jagielski }
547*b1cdbd2cSJim Jagielski 
548*b1cdbd2cSJim Jagielski //============================================================================
549*b1cdbd2cSJim Jagielski // static
equalIgnoreCase(const sal_Char * pBegin1,const sal_Char * pEnd1,const sal_Char * pString2)550*b1cdbd2cSJim Jagielski bool INetMIME::equalIgnoreCase(const sal_Char * pBegin1,
551*b1cdbd2cSJim Jagielski 							   const sal_Char * pEnd1,
552*b1cdbd2cSJim Jagielski 							   const sal_Char * pString2)
553*b1cdbd2cSJim Jagielski {
554*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin1 && pBegin1 <= pEnd1 && pString2,
555*b1cdbd2cSJim Jagielski 			   "INetMIME::equalIgnoreCase(): Bad sequences");
556*b1cdbd2cSJim Jagielski 
557*b1cdbd2cSJim Jagielski 	while (*pString2 != 0)
558*b1cdbd2cSJim Jagielski 		if (pBegin1 == pEnd1
559*b1cdbd2cSJim Jagielski 			|| toUpperCase(*pBegin1++) != toUpperCase(*pString2++))
560*b1cdbd2cSJim Jagielski 			return false;
561*b1cdbd2cSJim Jagielski 	return pBegin1 == pEnd1;
562*b1cdbd2cSJim Jagielski }
563*b1cdbd2cSJim Jagielski 
564*b1cdbd2cSJim Jagielski //============================================================================
565*b1cdbd2cSJim Jagielski // static
equalIgnoreCase(const sal_Unicode * pBegin1,const sal_Unicode * pEnd1,const sal_Char * pString2)566*b1cdbd2cSJim Jagielski bool INetMIME::equalIgnoreCase(const sal_Unicode * pBegin1,
567*b1cdbd2cSJim Jagielski 							   const sal_Unicode * pEnd1,
568*b1cdbd2cSJim Jagielski 							   const sal_Char * pString2)
569*b1cdbd2cSJim Jagielski {
570*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin1 && pBegin1 <= pEnd1 && pString2,
571*b1cdbd2cSJim Jagielski 			   "INetMIME::equalIgnoreCase(): Bad sequences");
572*b1cdbd2cSJim Jagielski 
573*b1cdbd2cSJim Jagielski 	while (*pString2 != 0)
574*b1cdbd2cSJim Jagielski 		if (pBegin1 == pEnd1
575*b1cdbd2cSJim Jagielski 			|| toUpperCase(*pBegin1++) != toUpperCase(*pString2++))
576*b1cdbd2cSJim Jagielski 			return false;
577*b1cdbd2cSJim Jagielski 	return pBegin1 == pEnd1;
578*b1cdbd2cSJim Jagielski }
579*b1cdbd2cSJim Jagielski 
580*b1cdbd2cSJim Jagielski //============================================================================
581*b1cdbd2cSJim Jagielski // static
skipLinearWhiteSpace(const sal_Char * pBegin,const sal_Char * pEnd)582*b1cdbd2cSJim Jagielski const sal_Char * INetMIME::skipLinearWhiteSpace(const sal_Char * pBegin,
583*b1cdbd2cSJim Jagielski 												const sal_Char * pEnd)
584*b1cdbd2cSJim Jagielski {
585*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
586*b1cdbd2cSJim Jagielski 			   "INetMIME::skipLinearWhiteSpace(): Bad sequence");
587*b1cdbd2cSJim Jagielski 
588*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd)
589*b1cdbd2cSJim Jagielski 		switch (*pBegin)
590*b1cdbd2cSJim Jagielski 		{
591*b1cdbd2cSJim Jagielski 			case '\t':
592*b1cdbd2cSJim Jagielski 			case ' ':
593*b1cdbd2cSJim Jagielski 				++pBegin;
594*b1cdbd2cSJim Jagielski 				break;
595*b1cdbd2cSJim Jagielski 
596*b1cdbd2cSJim Jagielski 			case 0x0D: // CR
597*b1cdbd2cSJim Jagielski 				if (startsWithLineFolding(pBegin, pEnd))
598*b1cdbd2cSJim Jagielski 					pBegin += 3;
599*b1cdbd2cSJim Jagielski 				else
600*b1cdbd2cSJim Jagielski 					return pBegin;
601*b1cdbd2cSJim Jagielski 				break;
602*b1cdbd2cSJim Jagielski 
603*b1cdbd2cSJim Jagielski 			default:
604*b1cdbd2cSJim Jagielski 				return pBegin;
605*b1cdbd2cSJim Jagielski 		}
606*b1cdbd2cSJim Jagielski 	return pBegin;
607*b1cdbd2cSJim Jagielski }
608*b1cdbd2cSJim Jagielski 
609*b1cdbd2cSJim Jagielski //============================================================================
610*b1cdbd2cSJim Jagielski // static
skipLinearWhiteSpace(const sal_Unicode * pBegin,const sal_Unicode * pEnd)611*b1cdbd2cSJim Jagielski const sal_Unicode * INetMIME::skipLinearWhiteSpace(const sal_Unicode * pBegin,
612*b1cdbd2cSJim Jagielski 												   const sal_Unicode * pEnd)
613*b1cdbd2cSJim Jagielski {
614*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
615*b1cdbd2cSJim Jagielski 			   "INetMIME::skipLinearWhiteSpace(): Bad sequence");
616*b1cdbd2cSJim Jagielski 
617*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd)
618*b1cdbd2cSJim Jagielski 		switch (*pBegin)
619*b1cdbd2cSJim Jagielski 		{
620*b1cdbd2cSJim Jagielski 			case '\t':
621*b1cdbd2cSJim Jagielski 			case ' ':
622*b1cdbd2cSJim Jagielski 				++pBegin;
623*b1cdbd2cSJim Jagielski 				break;
624*b1cdbd2cSJim Jagielski 
625*b1cdbd2cSJim Jagielski 			case 0x0D: // CR
626*b1cdbd2cSJim Jagielski 				if (startsWithLineFolding(pBegin, pEnd))
627*b1cdbd2cSJim Jagielski 					pBegin += 3;
628*b1cdbd2cSJim Jagielski 				else
629*b1cdbd2cSJim Jagielski 					return pBegin;
630*b1cdbd2cSJim Jagielski 				break;
631*b1cdbd2cSJim Jagielski 
632*b1cdbd2cSJim Jagielski 			default:
633*b1cdbd2cSJim Jagielski 				return pBegin;
634*b1cdbd2cSJim Jagielski 		}
635*b1cdbd2cSJim Jagielski 	return pBegin;
636*b1cdbd2cSJim Jagielski }
637*b1cdbd2cSJim Jagielski 
638*b1cdbd2cSJim Jagielski //============================================================================
639*b1cdbd2cSJim Jagielski // static
skipComment(const sal_Char * pBegin,const sal_Char * pEnd)640*b1cdbd2cSJim Jagielski const sal_Char * INetMIME::skipComment(const sal_Char * pBegin,
641*b1cdbd2cSJim Jagielski 									   const sal_Char * pEnd)
642*b1cdbd2cSJim Jagielski {
643*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
644*b1cdbd2cSJim Jagielski 			   "INetMIME::skipComment(): Bad sequence");
645*b1cdbd2cSJim Jagielski 
646*b1cdbd2cSJim Jagielski 	if (pBegin != pEnd && *pBegin == '(')
647*b1cdbd2cSJim Jagielski 	{
648*b1cdbd2cSJim Jagielski 		sal_uInt32 nLevel = 0;
649*b1cdbd2cSJim Jagielski 		for (const sal_Char * p = pBegin; p != pEnd;)
650*b1cdbd2cSJim Jagielski 			switch (*p++)
651*b1cdbd2cSJim Jagielski 			{
652*b1cdbd2cSJim Jagielski 				case '(':
653*b1cdbd2cSJim Jagielski 					++nLevel;
654*b1cdbd2cSJim Jagielski 					break;
655*b1cdbd2cSJim Jagielski 
656*b1cdbd2cSJim Jagielski 				case ')':
657*b1cdbd2cSJim Jagielski 					if (--nLevel == 0)
658*b1cdbd2cSJim Jagielski 						return p;
659*b1cdbd2cSJim Jagielski 					break;
660*b1cdbd2cSJim Jagielski 
661*b1cdbd2cSJim Jagielski 				case '\\':
662*b1cdbd2cSJim Jagielski 					if (p != pEnd)
663*b1cdbd2cSJim Jagielski 						++p;
664*b1cdbd2cSJim Jagielski 					break;
665*b1cdbd2cSJim Jagielski 			}
666*b1cdbd2cSJim Jagielski 	}
667*b1cdbd2cSJim Jagielski 	return pBegin;
668*b1cdbd2cSJim Jagielski }
669*b1cdbd2cSJim Jagielski 
670*b1cdbd2cSJim Jagielski //============================================================================
671*b1cdbd2cSJim Jagielski // static
skipComment(const sal_Unicode * pBegin,const sal_Unicode * pEnd)672*b1cdbd2cSJim Jagielski const sal_Unicode * INetMIME::skipComment(const sal_Unicode * pBegin,
673*b1cdbd2cSJim Jagielski 										  const sal_Unicode * pEnd)
674*b1cdbd2cSJim Jagielski {
675*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
676*b1cdbd2cSJim Jagielski 			   "INetMIME::skipComment(): Bad sequence");
677*b1cdbd2cSJim Jagielski 
678*b1cdbd2cSJim Jagielski 	if (pBegin != pEnd && *pBegin == '(')
679*b1cdbd2cSJim Jagielski 	{
680*b1cdbd2cSJim Jagielski 		sal_uInt32 nLevel = 0;
681*b1cdbd2cSJim Jagielski 		for (const sal_Unicode * p = pBegin; p != pEnd;)
682*b1cdbd2cSJim Jagielski 			switch (*p++)
683*b1cdbd2cSJim Jagielski 			{
684*b1cdbd2cSJim Jagielski 				case '(':
685*b1cdbd2cSJim Jagielski 					++nLevel;
686*b1cdbd2cSJim Jagielski 					break;
687*b1cdbd2cSJim Jagielski 
688*b1cdbd2cSJim Jagielski 				case ')':
689*b1cdbd2cSJim Jagielski 					if (--nLevel == 0)
690*b1cdbd2cSJim Jagielski 						return p;
691*b1cdbd2cSJim Jagielski 					break;
692*b1cdbd2cSJim Jagielski 
693*b1cdbd2cSJim Jagielski 				case '\\':
694*b1cdbd2cSJim Jagielski 					if (p != pEnd)
695*b1cdbd2cSJim Jagielski 						++p;
696*b1cdbd2cSJim Jagielski 					break;
697*b1cdbd2cSJim Jagielski 			}
698*b1cdbd2cSJim Jagielski 	}
699*b1cdbd2cSJim Jagielski 	return pBegin;
700*b1cdbd2cSJim Jagielski }
701*b1cdbd2cSJim Jagielski 
702*b1cdbd2cSJim Jagielski //============================================================================
703*b1cdbd2cSJim Jagielski // static
skipLinearWhiteSpaceComment(const sal_Char * pBegin,const sal_Char * pEnd)704*b1cdbd2cSJim Jagielski const sal_Char * INetMIME::skipLinearWhiteSpaceComment(const sal_Char *
705*b1cdbd2cSJim Jagielski 													       pBegin,
706*b1cdbd2cSJim Jagielski 													   const sal_Char * pEnd)
707*b1cdbd2cSJim Jagielski {
708*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
709*b1cdbd2cSJim Jagielski 			   "INetMIME::skipLinearWhiteSpaceComment(): Bad sequence");
710*b1cdbd2cSJim Jagielski 
711*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd)
712*b1cdbd2cSJim Jagielski 		switch (*pBegin)
713*b1cdbd2cSJim Jagielski 		{
714*b1cdbd2cSJim Jagielski 			case '\t':
715*b1cdbd2cSJim Jagielski 			case ' ':
716*b1cdbd2cSJim Jagielski 				++pBegin;
717*b1cdbd2cSJim Jagielski 				break;
718*b1cdbd2cSJim Jagielski 
719*b1cdbd2cSJim Jagielski 			case 0x0D: // CR
720*b1cdbd2cSJim Jagielski 				if (startsWithLineFolding(pBegin, pEnd))
721*b1cdbd2cSJim Jagielski 					pBegin += 3;
722*b1cdbd2cSJim Jagielski 				else
723*b1cdbd2cSJim Jagielski 					return pBegin;
724*b1cdbd2cSJim Jagielski 				break;
725*b1cdbd2cSJim Jagielski 
726*b1cdbd2cSJim Jagielski 			case '(':
727*b1cdbd2cSJim Jagielski 			{
728*b1cdbd2cSJim Jagielski 				const sal_Char * p = skipComment(pBegin, pEnd);
729*b1cdbd2cSJim Jagielski 				if (p == pBegin)
730*b1cdbd2cSJim Jagielski 					return pBegin;
731*b1cdbd2cSJim Jagielski 				pBegin = p;
732*b1cdbd2cSJim Jagielski 				break;
733*b1cdbd2cSJim Jagielski 			}
734*b1cdbd2cSJim Jagielski 
735*b1cdbd2cSJim Jagielski 			default:
736*b1cdbd2cSJim Jagielski 				return pBegin;
737*b1cdbd2cSJim Jagielski 		}
738*b1cdbd2cSJim Jagielski 	return pBegin;
739*b1cdbd2cSJim Jagielski }
740*b1cdbd2cSJim Jagielski 
741*b1cdbd2cSJim Jagielski //============================================================================
742*b1cdbd2cSJim Jagielski // static
skipLinearWhiteSpaceComment(const sal_Unicode * pBegin,const sal_Unicode * pEnd)743*b1cdbd2cSJim Jagielski const sal_Unicode * INetMIME::skipLinearWhiteSpaceComment(const sal_Unicode *
744*b1cdbd2cSJim Jagielski 														      pBegin,
745*b1cdbd2cSJim Jagielski 														  const sal_Unicode *
746*b1cdbd2cSJim Jagielski 														      pEnd)
747*b1cdbd2cSJim Jagielski {
748*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
749*b1cdbd2cSJim Jagielski 			   "INetMIME::skipLinearWhiteSpaceComment(): Bad sequence");
750*b1cdbd2cSJim Jagielski 
751*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd)
752*b1cdbd2cSJim Jagielski 		switch (*pBegin)
753*b1cdbd2cSJim Jagielski 		{
754*b1cdbd2cSJim Jagielski 			case '\t':
755*b1cdbd2cSJim Jagielski 			case ' ':
756*b1cdbd2cSJim Jagielski 				++pBegin;
757*b1cdbd2cSJim Jagielski 				break;
758*b1cdbd2cSJim Jagielski 
759*b1cdbd2cSJim Jagielski 			case 0x0D: // CR
760*b1cdbd2cSJim Jagielski 				if (startsWithLineFolding(pBegin, pEnd))
761*b1cdbd2cSJim Jagielski 					pBegin += 3;
762*b1cdbd2cSJim Jagielski 				else
763*b1cdbd2cSJim Jagielski 					return pBegin;
764*b1cdbd2cSJim Jagielski 				break;
765*b1cdbd2cSJim Jagielski 
766*b1cdbd2cSJim Jagielski 			case '(':
767*b1cdbd2cSJim Jagielski 			{
768*b1cdbd2cSJim Jagielski 				const sal_Unicode * p = skipComment(pBegin, pEnd);
769*b1cdbd2cSJim Jagielski 				if (p == pBegin)
770*b1cdbd2cSJim Jagielski 					return pBegin;
771*b1cdbd2cSJim Jagielski 				pBegin = p;
772*b1cdbd2cSJim Jagielski 				break;
773*b1cdbd2cSJim Jagielski 			}
774*b1cdbd2cSJim Jagielski 
775*b1cdbd2cSJim Jagielski 			default:
776*b1cdbd2cSJim Jagielski 				return pBegin;
777*b1cdbd2cSJim Jagielski 		}
778*b1cdbd2cSJim Jagielski 	return pBegin;
779*b1cdbd2cSJim Jagielski }
780*b1cdbd2cSJim Jagielski 
781*b1cdbd2cSJim Jagielski //============================================================================
782*b1cdbd2cSJim Jagielski // static
skipQuotedString(const sal_Char * pBegin,const sal_Char * pEnd)783*b1cdbd2cSJim Jagielski const sal_Char * INetMIME::skipQuotedString(const sal_Char * pBegin,
784*b1cdbd2cSJim Jagielski 											const sal_Char * pEnd)
785*b1cdbd2cSJim Jagielski {
786*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
787*b1cdbd2cSJim Jagielski 			   "INetMIME::skipQuotedString(): Bad sequence");
788*b1cdbd2cSJim Jagielski 
789*b1cdbd2cSJim Jagielski 	if (pBegin != pEnd && *pBegin == '"')
790*b1cdbd2cSJim Jagielski 		for (const sal_Char * p = pBegin + 1; p != pEnd;)
791*b1cdbd2cSJim Jagielski 			switch (*p++)
792*b1cdbd2cSJim Jagielski 			{
793*b1cdbd2cSJim Jagielski 				case 0x0D: // CR
794*b1cdbd2cSJim Jagielski 					if (pEnd - p < 2 || *p++ != 0x0A // LF
795*b1cdbd2cSJim Jagielski 						|| !isWhiteSpace(*p++))
796*b1cdbd2cSJim Jagielski 						return pBegin;
797*b1cdbd2cSJim Jagielski 					break;
798*b1cdbd2cSJim Jagielski 
799*b1cdbd2cSJim Jagielski 				case '"':
800*b1cdbd2cSJim Jagielski 					return p;
801*b1cdbd2cSJim Jagielski 
802*b1cdbd2cSJim Jagielski 				case '\\':
803*b1cdbd2cSJim Jagielski 					if (p != pEnd)
804*b1cdbd2cSJim Jagielski 						++p;
805*b1cdbd2cSJim Jagielski 					break;
806*b1cdbd2cSJim Jagielski 			}
807*b1cdbd2cSJim Jagielski 	return pBegin;
808*b1cdbd2cSJim Jagielski }
809*b1cdbd2cSJim Jagielski 
810*b1cdbd2cSJim Jagielski //============================================================================
811*b1cdbd2cSJim Jagielski // static
skipQuotedString(const sal_Unicode * pBegin,const sal_Unicode * pEnd)812*b1cdbd2cSJim Jagielski const sal_Unicode * INetMIME::skipQuotedString(const sal_Unicode * pBegin,
813*b1cdbd2cSJim Jagielski 											   const sal_Unicode * pEnd)
814*b1cdbd2cSJim Jagielski {
815*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
816*b1cdbd2cSJim Jagielski 			   "INetMIME::skipQuotedString(): Bad sequence");
817*b1cdbd2cSJim Jagielski 
818*b1cdbd2cSJim Jagielski 	if (pBegin != pEnd && *pBegin == '"')
819*b1cdbd2cSJim Jagielski 		for (const sal_Unicode * p = pBegin + 1; p != pEnd;)
820*b1cdbd2cSJim Jagielski 			switch (*p++)
821*b1cdbd2cSJim Jagielski 			{
822*b1cdbd2cSJim Jagielski 				case 0x0D: // CR
823*b1cdbd2cSJim Jagielski 					if (pEnd - p < 2 || *p++ != 0x0A // LF
824*b1cdbd2cSJim Jagielski 						|| !isWhiteSpace(*p++))
825*b1cdbd2cSJim Jagielski 						return pBegin;
826*b1cdbd2cSJim Jagielski 					break;
827*b1cdbd2cSJim Jagielski 
828*b1cdbd2cSJim Jagielski 				case '"':
829*b1cdbd2cSJim Jagielski 					return p;
830*b1cdbd2cSJim Jagielski 
831*b1cdbd2cSJim Jagielski 				case '\\':
832*b1cdbd2cSJim Jagielski 					if (p != pEnd)
833*b1cdbd2cSJim Jagielski 						++p;
834*b1cdbd2cSJim Jagielski 					break;
835*b1cdbd2cSJim Jagielski 			}
836*b1cdbd2cSJim Jagielski 	return pBegin;
837*b1cdbd2cSJim Jagielski }
838*b1cdbd2cSJim Jagielski 
839*b1cdbd2cSJim Jagielski //============================================================================
840*b1cdbd2cSJim Jagielski // static
scanAtom(const sal_Char * pBegin,const sal_Char * pEnd)841*b1cdbd2cSJim Jagielski const sal_Char * INetMIME::scanAtom(const sal_Char * pBegin,
842*b1cdbd2cSJim Jagielski 									const sal_Char * pEnd)
843*b1cdbd2cSJim Jagielski {
844*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd && isAtomChar(*pBegin))
845*b1cdbd2cSJim Jagielski 		++pBegin;
846*b1cdbd2cSJim Jagielski 	return pBegin;
847*b1cdbd2cSJim Jagielski }
848*b1cdbd2cSJim Jagielski 
849*b1cdbd2cSJim Jagielski //============================================================================
850*b1cdbd2cSJim Jagielski // static
scanAtom(const sal_Unicode * pBegin,const sal_Unicode * pEnd)851*b1cdbd2cSJim Jagielski const sal_Unicode * INetMIME::scanAtom(const sal_Unicode * pBegin,
852*b1cdbd2cSJim Jagielski 									   const sal_Unicode * pEnd)
853*b1cdbd2cSJim Jagielski {
854*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd && isAtomChar(*pBegin))
855*b1cdbd2cSJim Jagielski 		++pBegin;
856*b1cdbd2cSJim Jagielski 	return pBegin;
857*b1cdbd2cSJim Jagielski }
858*b1cdbd2cSJim Jagielski 
859*b1cdbd2cSJim Jagielski //============================================================================
860*b1cdbd2cSJim Jagielski // static
scanUnsigned(const sal_Char * & rBegin,const sal_Char * pEnd,bool bLeadingZeroes,sal_uInt32 & rValue)861*b1cdbd2cSJim Jagielski bool INetMIME::scanUnsigned(const sal_Char *& rBegin, const sal_Char * pEnd,
862*b1cdbd2cSJim Jagielski 							bool bLeadingZeroes, sal_uInt32 & rValue)
863*b1cdbd2cSJim Jagielski {
864*b1cdbd2cSJim Jagielski 	sal_uInt64 nTheValue = 0;
865*b1cdbd2cSJim Jagielski 	const sal_Char * p = rBegin;
866*b1cdbd2cSJim Jagielski 	for ( ; p != pEnd; ++p)
867*b1cdbd2cSJim Jagielski 	{
868*b1cdbd2cSJim Jagielski 		int nWeight = getWeight(*p);
869*b1cdbd2cSJim Jagielski 		if (nWeight < 0)
870*b1cdbd2cSJim Jagielski 			break;
871*b1cdbd2cSJim Jagielski 		nTheValue = 10 * nTheValue + nWeight;
872*b1cdbd2cSJim Jagielski 		if (nTheValue > std::numeric_limits< sal_uInt32 >::max())
873*b1cdbd2cSJim Jagielski 			return false;
874*b1cdbd2cSJim Jagielski 	}
875*b1cdbd2cSJim Jagielski 	if (nTheValue == 0 && (p == rBegin || (!bLeadingZeroes && p - rBegin != 1)))
876*b1cdbd2cSJim Jagielski 		return false;
877*b1cdbd2cSJim Jagielski 	rBegin = p;
878*b1cdbd2cSJim Jagielski 	rValue = sal_uInt32(nTheValue);
879*b1cdbd2cSJim Jagielski 	return true;
880*b1cdbd2cSJim Jagielski }
881*b1cdbd2cSJim Jagielski 
882*b1cdbd2cSJim Jagielski //============================================================================
883*b1cdbd2cSJim Jagielski // static
scanUnsigned(const sal_Unicode * & rBegin,const sal_Unicode * pEnd,bool bLeadingZeroes,sal_uInt32 & rValue)884*b1cdbd2cSJim Jagielski bool INetMIME::scanUnsigned(const sal_Unicode *& rBegin,
885*b1cdbd2cSJim Jagielski 							const sal_Unicode * pEnd, bool bLeadingZeroes,
886*b1cdbd2cSJim Jagielski 							sal_uInt32 & rValue)
887*b1cdbd2cSJim Jagielski {
888*b1cdbd2cSJim Jagielski 	sal_uInt64 nTheValue = 0;
889*b1cdbd2cSJim Jagielski 	const sal_Unicode * p = rBegin;
890*b1cdbd2cSJim Jagielski 	for ( ; p != pEnd; ++p)
891*b1cdbd2cSJim Jagielski 	{
892*b1cdbd2cSJim Jagielski 		int nWeight = getWeight(*p);
893*b1cdbd2cSJim Jagielski 		if (nWeight < 0)
894*b1cdbd2cSJim Jagielski 			break;
895*b1cdbd2cSJim Jagielski 		nTheValue = 10 * nTheValue + nWeight;
896*b1cdbd2cSJim Jagielski 		if (nTheValue > std::numeric_limits< sal_uInt32 >::max())
897*b1cdbd2cSJim Jagielski 			return false;
898*b1cdbd2cSJim Jagielski 	}
899*b1cdbd2cSJim Jagielski 	if (nTheValue == 0 && (p == rBegin || (!bLeadingZeroes && p - rBegin != 1)))
900*b1cdbd2cSJim Jagielski 		return false;
901*b1cdbd2cSJim Jagielski 	rBegin = p;
902*b1cdbd2cSJim Jagielski 	rValue = sal_uInt32(nTheValue);
903*b1cdbd2cSJim Jagielski 	return true;
904*b1cdbd2cSJim Jagielski }
905*b1cdbd2cSJim Jagielski 
906*b1cdbd2cSJim Jagielski //============================================================================
907*b1cdbd2cSJim Jagielski // static
scanUnsignedHex(const sal_Char * & rBegin,const sal_Char * pEnd,bool bLeadingZeroes,sal_uInt32 & rValue)908*b1cdbd2cSJim Jagielski bool INetMIME::scanUnsignedHex(const sal_Char *& rBegin,
909*b1cdbd2cSJim Jagielski 							   const sal_Char * pEnd, bool bLeadingZeroes,
910*b1cdbd2cSJim Jagielski 							   sal_uInt32 & rValue)
911*b1cdbd2cSJim Jagielski {
912*b1cdbd2cSJim Jagielski 	sal_uInt64 nTheValue = 0;
913*b1cdbd2cSJim Jagielski 	const sal_Char * p = rBegin;
914*b1cdbd2cSJim Jagielski 	for ( p = rBegin; p != pEnd; ++p)
915*b1cdbd2cSJim Jagielski 	{
916*b1cdbd2cSJim Jagielski 		int nWeight = getHexWeight(*p);
917*b1cdbd2cSJim Jagielski 		if (nWeight < 0)
918*b1cdbd2cSJim Jagielski 			break;
919*b1cdbd2cSJim Jagielski 		nTheValue = nTheValue << 4 | nWeight;
920*b1cdbd2cSJim Jagielski 		if (nTheValue > std::numeric_limits< sal_uInt32 >::max())
921*b1cdbd2cSJim Jagielski 			return false;
922*b1cdbd2cSJim Jagielski 	}
923*b1cdbd2cSJim Jagielski 	if (nTheValue == 0 && (p == rBegin || (!bLeadingZeroes && p - rBegin != 1)))
924*b1cdbd2cSJim Jagielski 		return false;
925*b1cdbd2cSJim Jagielski 	rBegin = p;
926*b1cdbd2cSJim Jagielski 	rValue = sal_uInt32(nTheValue);
927*b1cdbd2cSJim Jagielski 	return true;
928*b1cdbd2cSJim Jagielski }
929*b1cdbd2cSJim Jagielski 
930*b1cdbd2cSJim Jagielski //============================================================================
931*b1cdbd2cSJim Jagielski // static
scanUnsignedHex(const sal_Unicode * & rBegin,const sal_Unicode * pEnd,bool bLeadingZeroes,sal_uInt32 & rValue)932*b1cdbd2cSJim Jagielski bool INetMIME::scanUnsignedHex(const sal_Unicode *& rBegin,
933*b1cdbd2cSJim Jagielski 							   const sal_Unicode * pEnd, bool bLeadingZeroes,
934*b1cdbd2cSJim Jagielski 							   sal_uInt32 & rValue)
935*b1cdbd2cSJim Jagielski {
936*b1cdbd2cSJim Jagielski 	sal_uInt64 nTheValue = 0;
937*b1cdbd2cSJim Jagielski 	const sal_Unicode * p = rBegin;
938*b1cdbd2cSJim Jagielski 	for ( ; p != pEnd; ++p)
939*b1cdbd2cSJim Jagielski 	{
940*b1cdbd2cSJim Jagielski 		int nWeight = getHexWeight(*p);
941*b1cdbd2cSJim Jagielski 		if (nWeight < 0)
942*b1cdbd2cSJim Jagielski 			break;
943*b1cdbd2cSJim Jagielski 		nTheValue = nTheValue << 4 | nWeight;
944*b1cdbd2cSJim Jagielski 		if (nTheValue > std::numeric_limits< sal_uInt32 >::max())
945*b1cdbd2cSJim Jagielski 			return false;
946*b1cdbd2cSJim Jagielski 	}
947*b1cdbd2cSJim Jagielski 	if (nTheValue == 0 && (p == rBegin || (!bLeadingZeroes && p - rBegin != 1)))
948*b1cdbd2cSJim Jagielski 		return false;
949*b1cdbd2cSJim Jagielski 	rBegin = p;
950*b1cdbd2cSJim Jagielski 	rValue = sal_uInt32(nTheValue);
951*b1cdbd2cSJim Jagielski 	return true;
952*b1cdbd2cSJim Jagielski }
953*b1cdbd2cSJim Jagielski 
954*b1cdbd2cSJim Jagielski //============================================================================
955*b1cdbd2cSJim Jagielski // static
scanQuotedBlock(const sal_Char * pBegin,const sal_Char * pEnd,sal_uInt32 nOpening,sal_uInt32 nClosing,sal_Size & rLength,bool & rModify)956*b1cdbd2cSJim Jagielski const sal_Char * INetMIME::scanQuotedBlock(const sal_Char * pBegin,
957*b1cdbd2cSJim Jagielski 										   const sal_Char * pEnd,
958*b1cdbd2cSJim Jagielski 										   sal_uInt32 nOpening,
959*b1cdbd2cSJim Jagielski 										   sal_uInt32 nClosing,
960*b1cdbd2cSJim Jagielski 										   sal_Size & rLength,
961*b1cdbd2cSJim Jagielski 										   bool & rModify)
962*b1cdbd2cSJim Jagielski {
963*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
964*b1cdbd2cSJim Jagielski 			   "INetMIME::scanQuotedBlock(): Bad sequence");
965*b1cdbd2cSJim Jagielski 
966*b1cdbd2cSJim Jagielski 	if (pBegin != pEnd && static_cast< unsigned char >(*pBegin) == nOpening)
967*b1cdbd2cSJim Jagielski 	{
968*b1cdbd2cSJim Jagielski 		++rLength;
969*b1cdbd2cSJim Jagielski 		++pBegin;
970*b1cdbd2cSJim Jagielski 		while (pBegin != pEnd)
971*b1cdbd2cSJim Jagielski 			if (static_cast< unsigned char >(*pBegin) == nClosing)
972*b1cdbd2cSJim Jagielski 			{
973*b1cdbd2cSJim Jagielski 				++rLength;
974*b1cdbd2cSJim Jagielski 				return ++pBegin;
975*b1cdbd2cSJim Jagielski 			}
976*b1cdbd2cSJim Jagielski 			else
977*b1cdbd2cSJim Jagielski 			{
978*b1cdbd2cSJim Jagielski 				sal_uInt32 c = *pBegin++;
979*b1cdbd2cSJim Jagielski 				switch (c)
980*b1cdbd2cSJim Jagielski 				{
981*b1cdbd2cSJim Jagielski 					case 0x0D: // CR
982*b1cdbd2cSJim Jagielski 						if (pBegin != pEnd && *pBegin == 0x0A) // LF
983*b1cdbd2cSJim Jagielski 							if (pEnd - pBegin >= 2 && isWhiteSpace(pBegin[1]))
984*b1cdbd2cSJim Jagielski 							{
985*b1cdbd2cSJim Jagielski 								++rLength;
986*b1cdbd2cSJim Jagielski 								rModify = true;
987*b1cdbd2cSJim Jagielski 								pBegin += 2;
988*b1cdbd2cSJim Jagielski 							}
989*b1cdbd2cSJim Jagielski 							else
990*b1cdbd2cSJim Jagielski 							{
991*b1cdbd2cSJim Jagielski 								rLength += 3;
992*b1cdbd2cSJim Jagielski 								rModify = true;
993*b1cdbd2cSJim Jagielski 								++pBegin;
994*b1cdbd2cSJim Jagielski 							}
995*b1cdbd2cSJim Jagielski 						else
996*b1cdbd2cSJim Jagielski 							++rLength;
997*b1cdbd2cSJim Jagielski 						break;
998*b1cdbd2cSJim Jagielski 
999*b1cdbd2cSJim Jagielski 					case '\\':
1000*b1cdbd2cSJim Jagielski 						++rLength;
1001*b1cdbd2cSJim Jagielski 						if (pBegin != pEnd)
1002*b1cdbd2cSJim Jagielski                         {
1003*b1cdbd2cSJim Jagielski 							if (startsWithLineBreak(pBegin, pEnd)
1004*b1cdbd2cSJim Jagielski 								&& (pEnd - pBegin < 3
1005*b1cdbd2cSJim Jagielski 									|| !isWhiteSpace(pBegin[2])))
1006*b1cdbd2cSJim Jagielski 							{
1007*b1cdbd2cSJim Jagielski 								rLength += 3;
1008*b1cdbd2cSJim Jagielski 								rModify = true;
1009*b1cdbd2cSJim Jagielski 								pBegin += 2;
1010*b1cdbd2cSJim Jagielski 							}
1011*b1cdbd2cSJim Jagielski 							else
1012*b1cdbd2cSJim Jagielski 								++pBegin;
1013*b1cdbd2cSJim Jagielski                         }
1014*b1cdbd2cSJim Jagielski 						break;
1015*b1cdbd2cSJim Jagielski 
1016*b1cdbd2cSJim Jagielski 					default:
1017*b1cdbd2cSJim Jagielski 						++rLength;
1018*b1cdbd2cSJim Jagielski 						if (!isUSASCII(c))
1019*b1cdbd2cSJim Jagielski 							rModify = true;
1020*b1cdbd2cSJim Jagielski 						break;
1021*b1cdbd2cSJim Jagielski 				}
1022*b1cdbd2cSJim Jagielski 			}
1023*b1cdbd2cSJim Jagielski 	}
1024*b1cdbd2cSJim Jagielski 	return pBegin;
1025*b1cdbd2cSJim Jagielski }
1026*b1cdbd2cSJim Jagielski 
1027*b1cdbd2cSJim Jagielski //============================================================================
1028*b1cdbd2cSJim Jagielski // static
scanQuotedBlock(const sal_Unicode * pBegin,const sal_Unicode * pEnd,sal_uInt32 nOpening,sal_uInt32 nClosing,sal_Size & rLength,bool & rModify)1029*b1cdbd2cSJim Jagielski const sal_Unicode * INetMIME::scanQuotedBlock(const sal_Unicode * pBegin,
1030*b1cdbd2cSJim Jagielski 											  const sal_Unicode * pEnd,
1031*b1cdbd2cSJim Jagielski 											  sal_uInt32 nOpening,
1032*b1cdbd2cSJim Jagielski 											  sal_uInt32 nClosing,
1033*b1cdbd2cSJim Jagielski 											  sal_Size & rLength,
1034*b1cdbd2cSJim Jagielski 											  bool & rModify)
1035*b1cdbd2cSJim Jagielski {
1036*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
1037*b1cdbd2cSJim Jagielski 			   "INetMIME::scanQuotedBlock(): Bad sequence");
1038*b1cdbd2cSJim Jagielski 
1039*b1cdbd2cSJim Jagielski 	if (pBegin != pEnd && *pBegin == nOpening)
1040*b1cdbd2cSJim Jagielski 	{
1041*b1cdbd2cSJim Jagielski 		++rLength;
1042*b1cdbd2cSJim Jagielski 		++pBegin;
1043*b1cdbd2cSJim Jagielski 		while (pBegin != pEnd)
1044*b1cdbd2cSJim Jagielski 			if (*pBegin == nClosing)
1045*b1cdbd2cSJim Jagielski 			{
1046*b1cdbd2cSJim Jagielski 				++rLength;
1047*b1cdbd2cSJim Jagielski 				return ++pBegin;
1048*b1cdbd2cSJim Jagielski 			}
1049*b1cdbd2cSJim Jagielski 			else
1050*b1cdbd2cSJim Jagielski 			{
1051*b1cdbd2cSJim Jagielski 				sal_uInt32 c = *pBegin++;
1052*b1cdbd2cSJim Jagielski 				switch (c)
1053*b1cdbd2cSJim Jagielski 				{
1054*b1cdbd2cSJim Jagielski 					case 0x0D: // CR
1055*b1cdbd2cSJim Jagielski 						if (pBegin != pEnd && *pBegin == 0x0A) // LF
1056*b1cdbd2cSJim Jagielski 							if (pEnd - pBegin >= 2 && isWhiteSpace(pBegin[1]))
1057*b1cdbd2cSJim Jagielski 							{
1058*b1cdbd2cSJim Jagielski 								++rLength;
1059*b1cdbd2cSJim Jagielski 								rModify = true;
1060*b1cdbd2cSJim Jagielski 								pBegin += 2;
1061*b1cdbd2cSJim Jagielski 							}
1062*b1cdbd2cSJim Jagielski 							else
1063*b1cdbd2cSJim Jagielski 							{
1064*b1cdbd2cSJim Jagielski 								rLength += 3;
1065*b1cdbd2cSJim Jagielski 								rModify = true;
1066*b1cdbd2cSJim Jagielski 								++pBegin;
1067*b1cdbd2cSJim Jagielski 							}
1068*b1cdbd2cSJim Jagielski 						else
1069*b1cdbd2cSJim Jagielski 							++rLength;
1070*b1cdbd2cSJim Jagielski 						break;
1071*b1cdbd2cSJim Jagielski 
1072*b1cdbd2cSJim Jagielski 					case '\\':
1073*b1cdbd2cSJim Jagielski 						++rLength;
1074*b1cdbd2cSJim Jagielski 						if (pBegin != pEnd)
1075*b1cdbd2cSJim Jagielski                         {
1076*b1cdbd2cSJim Jagielski 							if (startsWithLineBreak(pBegin, pEnd)
1077*b1cdbd2cSJim Jagielski 								&& (pEnd - pBegin < 3
1078*b1cdbd2cSJim Jagielski 									|| !isWhiteSpace(pBegin[2])))
1079*b1cdbd2cSJim Jagielski 							{
1080*b1cdbd2cSJim Jagielski 								rLength += 3;
1081*b1cdbd2cSJim Jagielski 								rModify = true;
1082*b1cdbd2cSJim Jagielski 								pBegin += 2;
1083*b1cdbd2cSJim Jagielski 							}
1084*b1cdbd2cSJim Jagielski 							else
1085*b1cdbd2cSJim Jagielski 								++pBegin;
1086*b1cdbd2cSJim Jagielski                         }
1087*b1cdbd2cSJim Jagielski 						break;
1088*b1cdbd2cSJim Jagielski 
1089*b1cdbd2cSJim Jagielski 					default:
1090*b1cdbd2cSJim Jagielski 						++rLength;
1091*b1cdbd2cSJim Jagielski 						if (!isUSASCII(c))
1092*b1cdbd2cSJim Jagielski 							rModify = true;
1093*b1cdbd2cSJim Jagielski 						break;
1094*b1cdbd2cSJim Jagielski 				}
1095*b1cdbd2cSJim Jagielski 			}
1096*b1cdbd2cSJim Jagielski 	}
1097*b1cdbd2cSJim Jagielski 	return pBegin;
1098*b1cdbd2cSJim Jagielski }
1099*b1cdbd2cSJim Jagielski 
1100*b1cdbd2cSJim Jagielski //============================================================================
1101*b1cdbd2cSJim Jagielski // static
scanParameters(sal_Char const * pBegin,sal_Char const * pEnd,INetContentTypeParameterList * pParameters)1102*b1cdbd2cSJim Jagielski sal_Char const * INetMIME::scanParameters(sal_Char const * pBegin,
1103*b1cdbd2cSJim Jagielski 										  sal_Char const * pEnd,
1104*b1cdbd2cSJim Jagielski 										  INetContentTypeParameterList *
1105*b1cdbd2cSJim Jagielski 										      pParameters)
1106*b1cdbd2cSJim Jagielski {
1107*b1cdbd2cSJim Jagielski 	ParameterList aList;
1108*b1cdbd2cSJim Jagielski 	sal_Char const * pParameterBegin = pBegin;
1109*b1cdbd2cSJim Jagielski 	for (sal_Char const * p = pParameterBegin;; pParameterBegin = p)
1110*b1cdbd2cSJim Jagielski 	{
1111*b1cdbd2cSJim Jagielski 		pParameterBegin = skipLinearWhiteSpaceComment(p, pEnd);
1112*b1cdbd2cSJim Jagielski 		if (pParameterBegin == pEnd || *pParameterBegin != ';')
1113*b1cdbd2cSJim Jagielski 			break;
1114*b1cdbd2cSJim Jagielski 		p = pParameterBegin + 1;
1115*b1cdbd2cSJim Jagielski 
1116*b1cdbd2cSJim Jagielski 		sal_Char const * pAttributeBegin = skipLinearWhiteSpaceComment(p,
1117*b1cdbd2cSJim Jagielski 																	   pEnd);
1118*b1cdbd2cSJim Jagielski 		p = pAttributeBegin;
1119*b1cdbd2cSJim Jagielski 		bool bDowncaseAttribute = false;
1120*b1cdbd2cSJim Jagielski 		while (p != pEnd && isTokenChar(*p) && *p != '*')
1121*b1cdbd2cSJim Jagielski 		{
1122*b1cdbd2cSJim Jagielski 			bDowncaseAttribute = bDowncaseAttribute || isUpperCase(*p);
1123*b1cdbd2cSJim Jagielski 			++p;
1124*b1cdbd2cSJim Jagielski 		}
1125*b1cdbd2cSJim Jagielski 		if (p == pAttributeBegin)
1126*b1cdbd2cSJim Jagielski 			break;
1127*b1cdbd2cSJim Jagielski 		ByteString aAttribute(
1128*b1cdbd2cSJim Jagielski             pAttributeBegin, static_cast< xub_StrLen >(p - pAttributeBegin));
1129*b1cdbd2cSJim Jagielski 		if (bDowncaseAttribute)
1130*b1cdbd2cSJim Jagielski 			aAttribute.ToLowerAscii();
1131*b1cdbd2cSJim Jagielski 
1132*b1cdbd2cSJim Jagielski 		sal_uInt32 nSection = 0;
1133*b1cdbd2cSJim Jagielski 		if (p != pEnd && *p == '*')
1134*b1cdbd2cSJim Jagielski 		{
1135*b1cdbd2cSJim Jagielski 			++p;
1136*b1cdbd2cSJim Jagielski 			if (p != pEnd && isDigit(*p)
1137*b1cdbd2cSJim Jagielski 				&& !scanUnsigned(p, pEnd, false, nSection))
1138*b1cdbd2cSJim Jagielski 				break;
1139*b1cdbd2cSJim Jagielski 		}
1140*b1cdbd2cSJim Jagielski 
1141*b1cdbd2cSJim Jagielski 		bool bPresent;
1142*b1cdbd2cSJim Jagielski 		Parameter ** pPos = aList.find(aAttribute, nSection, bPresent);
1143*b1cdbd2cSJim Jagielski 		if (bPresent)
1144*b1cdbd2cSJim Jagielski 			break;
1145*b1cdbd2cSJim Jagielski 
1146*b1cdbd2cSJim Jagielski 		bool bExtended = false;
1147*b1cdbd2cSJim Jagielski 		if (p != pEnd && *p == '*')
1148*b1cdbd2cSJim Jagielski 		{
1149*b1cdbd2cSJim Jagielski 			++p;
1150*b1cdbd2cSJim Jagielski 			bExtended = true;
1151*b1cdbd2cSJim Jagielski 		}
1152*b1cdbd2cSJim Jagielski 
1153*b1cdbd2cSJim Jagielski 		p = skipLinearWhiteSpaceComment(p, pEnd);
1154*b1cdbd2cSJim Jagielski 
1155*b1cdbd2cSJim Jagielski 		if (p == pEnd || *p != '=')
1156*b1cdbd2cSJim Jagielski 			break;
1157*b1cdbd2cSJim Jagielski 
1158*b1cdbd2cSJim Jagielski 		p = skipLinearWhiteSpaceComment(p + 1, pEnd);
1159*b1cdbd2cSJim Jagielski 
1160*b1cdbd2cSJim Jagielski 		ByteString aCharset;
1161*b1cdbd2cSJim Jagielski 		ByteString aLanguage;
1162*b1cdbd2cSJim Jagielski  		ByteString aValue;
1163*b1cdbd2cSJim Jagielski 		if (bExtended)
1164*b1cdbd2cSJim Jagielski 		{
1165*b1cdbd2cSJim Jagielski 			if (nSection == 0)
1166*b1cdbd2cSJim Jagielski 			{
1167*b1cdbd2cSJim Jagielski 				sal_Char const * pCharsetBegin = p;
1168*b1cdbd2cSJim Jagielski 				bool bDowncaseCharset = false;
1169*b1cdbd2cSJim Jagielski 				while (p != pEnd && isTokenChar(*p) && *p != '\'')
1170*b1cdbd2cSJim Jagielski 				{
1171*b1cdbd2cSJim Jagielski 					bDowncaseCharset = bDowncaseCharset || isUpperCase(*p);
1172*b1cdbd2cSJim Jagielski 					++p;
1173*b1cdbd2cSJim Jagielski 				}
1174*b1cdbd2cSJim Jagielski 				if (p == pCharsetBegin)
1175*b1cdbd2cSJim Jagielski 					break;
1176*b1cdbd2cSJim Jagielski 				if (pParameters)
1177*b1cdbd2cSJim Jagielski 				{
1178*b1cdbd2cSJim Jagielski 					aCharset = ByteString(
1179*b1cdbd2cSJim Jagielski                         pCharsetBegin,
1180*b1cdbd2cSJim Jagielski                         static_cast< xub_StrLen >(p - pCharsetBegin));
1181*b1cdbd2cSJim Jagielski 					if (bDowncaseCharset)
1182*b1cdbd2cSJim Jagielski 						aCharset.ToLowerAscii();
1183*b1cdbd2cSJim Jagielski 				}
1184*b1cdbd2cSJim Jagielski 
1185*b1cdbd2cSJim Jagielski 				if (p == pEnd || *p != '\'')
1186*b1cdbd2cSJim Jagielski 					break;
1187*b1cdbd2cSJim Jagielski 				++p;
1188*b1cdbd2cSJim Jagielski 
1189*b1cdbd2cSJim Jagielski 				sal_Char const * pLanguageBegin = p;
1190*b1cdbd2cSJim Jagielski 				bool bDowncaseLanguage = false;
1191*b1cdbd2cSJim Jagielski 				int nLetters = 0;
1192*b1cdbd2cSJim Jagielski 				for (; p != pEnd; ++p)
1193*b1cdbd2cSJim Jagielski 					if (isAlpha(*p))
1194*b1cdbd2cSJim Jagielski 					{
1195*b1cdbd2cSJim Jagielski 						if (++nLetters > 8)
1196*b1cdbd2cSJim Jagielski 							break;
1197*b1cdbd2cSJim Jagielski 						bDowncaseLanguage = bDowncaseLanguage
1198*b1cdbd2cSJim Jagielski 							                || isUpperCase(*p);
1199*b1cdbd2cSJim Jagielski 					}
1200*b1cdbd2cSJim Jagielski 					else if (*p == '-')
1201*b1cdbd2cSJim Jagielski 					{
1202*b1cdbd2cSJim Jagielski 						if (nLetters == 0)
1203*b1cdbd2cSJim Jagielski 							break;
1204*b1cdbd2cSJim Jagielski 						nLetters = 0;
1205*b1cdbd2cSJim Jagielski 					}
1206*b1cdbd2cSJim Jagielski 					else
1207*b1cdbd2cSJim Jagielski 						break;
1208*b1cdbd2cSJim Jagielski 				if (nLetters == 0 || nLetters > 8)
1209*b1cdbd2cSJim Jagielski 					break;
1210*b1cdbd2cSJim Jagielski 				if (pParameters)
1211*b1cdbd2cSJim Jagielski 				{
1212*b1cdbd2cSJim Jagielski 					aLanguage = ByteString(
1213*b1cdbd2cSJim Jagielski                         pLanguageBegin,
1214*b1cdbd2cSJim Jagielski                         static_cast< xub_StrLen >(p - pLanguageBegin));
1215*b1cdbd2cSJim Jagielski 					if (bDowncaseLanguage)
1216*b1cdbd2cSJim Jagielski 						aLanguage.ToLowerAscii();
1217*b1cdbd2cSJim Jagielski 				}
1218*b1cdbd2cSJim Jagielski 
1219*b1cdbd2cSJim Jagielski 				if (p == pEnd || *p != '\'')
1220*b1cdbd2cSJim Jagielski 					break;
1221*b1cdbd2cSJim Jagielski 				++p;
1222*b1cdbd2cSJim Jagielski 			}
1223*b1cdbd2cSJim Jagielski 			if (pParameters)
1224*b1cdbd2cSJim Jagielski 				while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
1225*b1cdbd2cSJim Jagielski 				{
1226*b1cdbd2cSJim Jagielski 					if (*p == '%')
1227*b1cdbd2cSJim Jagielski 					{
1228*b1cdbd2cSJim Jagielski 						if (p + 2 < pEnd)
1229*b1cdbd2cSJim Jagielski 						{
1230*b1cdbd2cSJim Jagielski 							int nWeight1 = getHexWeight(p[1]);
1231*b1cdbd2cSJim Jagielski 							int nWeight2 = getHexWeight(p[2]);
1232*b1cdbd2cSJim Jagielski 							if (nWeight1 >= 0 && nWeight2 >= 0)
1233*b1cdbd2cSJim Jagielski 							{
1234*b1cdbd2cSJim Jagielski 								aValue += sal_Char(nWeight1 << 4 | nWeight2);
1235*b1cdbd2cSJim Jagielski 								p += 3;
1236*b1cdbd2cSJim Jagielski 								continue;
1237*b1cdbd2cSJim Jagielski 							}
1238*b1cdbd2cSJim Jagielski 						}
1239*b1cdbd2cSJim Jagielski 					}
1240*b1cdbd2cSJim Jagielski 					aValue += *p++;
1241*b1cdbd2cSJim Jagielski 				}
1242*b1cdbd2cSJim Jagielski 			else
1243*b1cdbd2cSJim Jagielski 				while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
1244*b1cdbd2cSJim Jagielski 					++p;
1245*b1cdbd2cSJim Jagielski 		}
1246*b1cdbd2cSJim Jagielski 		else if (p != pEnd && *p == '"')
1247*b1cdbd2cSJim Jagielski 			if (pParameters)
1248*b1cdbd2cSJim Jagielski 			{
1249*b1cdbd2cSJim Jagielski 				bool bInvalid = false;
1250*b1cdbd2cSJim Jagielski 				for (++p;;)
1251*b1cdbd2cSJim Jagielski 				{
1252*b1cdbd2cSJim Jagielski 					if (p == pEnd)
1253*b1cdbd2cSJim Jagielski 					{
1254*b1cdbd2cSJim Jagielski 						bInvalid = true;
1255*b1cdbd2cSJim Jagielski 						break;
1256*b1cdbd2cSJim Jagielski 					}
1257*b1cdbd2cSJim Jagielski 					else if (*p == '"')
1258*b1cdbd2cSJim Jagielski 					{
1259*b1cdbd2cSJim Jagielski 						++p;
1260*b1cdbd2cSJim Jagielski 						break;
1261*b1cdbd2cSJim Jagielski 					}
1262*b1cdbd2cSJim Jagielski 					else if (*p == 0x0D) // CR
1263*b1cdbd2cSJim Jagielski 					{
1264*b1cdbd2cSJim Jagielski 						if (pEnd - p < 3 || p[1] != 0x0A // LF
1265*b1cdbd2cSJim Jagielski 							|| !isWhiteSpace(p[2]))
1266*b1cdbd2cSJim Jagielski 						{
1267*b1cdbd2cSJim Jagielski 							bInvalid = true;
1268*b1cdbd2cSJim Jagielski 							break;
1269*b1cdbd2cSJim Jagielski 						}
1270*b1cdbd2cSJim Jagielski 						p += 2;
1271*b1cdbd2cSJim Jagielski 					}
1272*b1cdbd2cSJim Jagielski 					else if (*p == '\\' && ++p == pEnd)
1273*b1cdbd2cSJim Jagielski 					{
1274*b1cdbd2cSJim Jagielski 						bInvalid = true;
1275*b1cdbd2cSJim Jagielski 						break;
1276*b1cdbd2cSJim Jagielski 					}
1277*b1cdbd2cSJim Jagielski 					aValue += *p++;
1278*b1cdbd2cSJim Jagielski 				}
1279*b1cdbd2cSJim Jagielski 				if (bInvalid)
1280*b1cdbd2cSJim Jagielski 					break;
1281*b1cdbd2cSJim Jagielski 			}
1282*b1cdbd2cSJim Jagielski 			else
1283*b1cdbd2cSJim Jagielski 			{
1284*b1cdbd2cSJim Jagielski 				sal_Char const * pStringEnd = skipQuotedString(p, pEnd);
1285*b1cdbd2cSJim Jagielski 				if (p == pStringEnd)
1286*b1cdbd2cSJim Jagielski 					break;
1287*b1cdbd2cSJim Jagielski 				p = pStringEnd;
1288*b1cdbd2cSJim Jagielski 			}
1289*b1cdbd2cSJim Jagielski 		else
1290*b1cdbd2cSJim Jagielski 		{
1291*b1cdbd2cSJim Jagielski 			sal_Char const * pTokenBegin = p;
1292*b1cdbd2cSJim Jagielski 			while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
1293*b1cdbd2cSJim Jagielski 				++p;
1294*b1cdbd2cSJim Jagielski 			if (p == pTokenBegin)
1295*b1cdbd2cSJim Jagielski 				break;
1296*b1cdbd2cSJim Jagielski 			if (pParameters)
1297*b1cdbd2cSJim Jagielski 				aValue = ByteString(
1298*b1cdbd2cSJim Jagielski                     pTokenBegin, static_cast< xub_StrLen >(p - pTokenBegin));
1299*b1cdbd2cSJim Jagielski 		}
1300*b1cdbd2cSJim Jagielski 
1301*b1cdbd2cSJim Jagielski 		*pPos = new Parameter(*pPos, aAttribute, aCharset, aLanguage, aValue,
1302*b1cdbd2cSJim Jagielski 							  nSection, bExtended);
1303*b1cdbd2cSJim Jagielski 	}
1304*b1cdbd2cSJim Jagielski 	return parseParameters(aList, pParameters) ? pParameterBegin : pBegin;
1305*b1cdbd2cSJim Jagielski }
1306*b1cdbd2cSJim Jagielski 
1307*b1cdbd2cSJim Jagielski //============================================================================
1308*b1cdbd2cSJim Jagielski // static
scanParameters(sal_Unicode const * pBegin,sal_Unicode const * pEnd,INetContentTypeParameterList * pParameters)1309*b1cdbd2cSJim Jagielski sal_Unicode const * INetMIME::scanParameters(sal_Unicode const * pBegin,
1310*b1cdbd2cSJim Jagielski 											 sal_Unicode const * pEnd,
1311*b1cdbd2cSJim Jagielski 											 INetContentTypeParameterList *
1312*b1cdbd2cSJim Jagielski 											     pParameters)
1313*b1cdbd2cSJim Jagielski {
1314*b1cdbd2cSJim Jagielski 	ParameterList aList;
1315*b1cdbd2cSJim Jagielski 	sal_Unicode const * pParameterBegin = pBegin;
1316*b1cdbd2cSJim Jagielski 	for (sal_Unicode const * p = pParameterBegin;; pParameterBegin = p)
1317*b1cdbd2cSJim Jagielski 	{
1318*b1cdbd2cSJim Jagielski 		pParameterBegin = skipLinearWhiteSpaceComment(p, pEnd);
1319*b1cdbd2cSJim Jagielski 		if (pParameterBegin == pEnd || *pParameterBegin != ';')
1320*b1cdbd2cSJim Jagielski 			break;
1321*b1cdbd2cSJim Jagielski 		p = pParameterBegin + 1;
1322*b1cdbd2cSJim Jagielski 
1323*b1cdbd2cSJim Jagielski 		sal_Unicode const * pAttributeBegin
1324*b1cdbd2cSJim Jagielski 			= skipLinearWhiteSpaceComment(p, pEnd);
1325*b1cdbd2cSJim Jagielski 		p = pAttributeBegin;
1326*b1cdbd2cSJim Jagielski 		bool bDowncaseAttribute = false;
1327*b1cdbd2cSJim Jagielski 		while (p != pEnd && isTokenChar(*p) && *p != '*')
1328*b1cdbd2cSJim Jagielski 		{
1329*b1cdbd2cSJim Jagielski 			bDowncaseAttribute = bDowncaseAttribute || isUpperCase(*p);
1330*b1cdbd2cSJim Jagielski 			++p;
1331*b1cdbd2cSJim Jagielski 		}
1332*b1cdbd2cSJim Jagielski 		if (p == pAttributeBegin)
1333*b1cdbd2cSJim Jagielski 			break;
1334*b1cdbd2cSJim Jagielski 		ByteString aAttribute = ByteString(
1335*b1cdbd2cSJim Jagielski             pAttributeBegin, static_cast< xub_StrLen >(p - pAttributeBegin),
1336*b1cdbd2cSJim Jagielski             RTL_TEXTENCODING_ASCII_US);
1337*b1cdbd2cSJim Jagielski 		if (bDowncaseAttribute)
1338*b1cdbd2cSJim Jagielski 			aAttribute.ToLowerAscii();
1339*b1cdbd2cSJim Jagielski 
1340*b1cdbd2cSJim Jagielski 		sal_uInt32 nSection = 0;
1341*b1cdbd2cSJim Jagielski 		if (p != pEnd && *p == '*')
1342*b1cdbd2cSJim Jagielski 		{
1343*b1cdbd2cSJim Jagielski 			++p;
1344*b1cdbd2cSJim Jagielski 			if (p != pEnd && isDigit(*p)
1345*b1cdbd2cSJim Jagielski 				&& !scanUnsigned(p, pEnd, false, nSection))
1346*b1cdbd2cSJim Jagielski 				break;
1347*b1cdbd2cSJim Jagielski 		}
1348*b1cdbd2cSJim Jagielski 
1349*b1cdbd2cSJim Jagielski 		bool bPresent;
1350*b1cdbd2cSJim Jagielski 		Parameter ** pPos = aList.find(aAttribute, nSection, bPresent);
1351*b1cdbd2cSJim Jagielski 		if (bPresent)
1352*b1cdbd2cSJim Jagielski 			break;
1353*b1cdbd2cSJim Jagielski 
1354*b1cdbd2cSJim Jagielski 		bool bExtended = false;
1355*b1cdbd2cSJim Jagielski 		if (p != pEnd && *p == '*')
1356*b1cdbd2cSJim Jagielski 		{
1357*b1cdbd2cSJim Jagielski 			++p;
1358*b1cdbd2cSJim Jagielski 			bExtended = true;
1359*b1cdbd2cSJim Jagielski 		}
1360*b1cdbd2cSJim Jagielski 
1361*b1cdbd2cSJim Jagielski 		p = skipLinearWhiteSpaceComment(p, pEnd);
1362*b1cdbd2cSJim Jagielski 
1363*b1cdbd2cSJim Jagielski 		if (p == pEnd || *p != '=')
1364*b1cdbd2cSJim Jagielski 			break;
1365*b1cdbd2cSJim Jagielski 
1366*b1cdbd2cSJim Jagielski 		p = skipLinearWhiteSpaceComment(p + 1, pEnd);
1367*b1cdbd2cSJim Jagielski 
1368*b1cdbd2cSJim Jagielski 		ByteString aCharset;
1369*b1cdbd2cSJim Jagielski 		ByteString aLanguage;
1370*b1cdbd2cSJim Jagielski  		ByteString aValue;
1371*b1cdbd2cSJim Jagielski 		if (bExtended)
1372*b1cdbd2cSJim Jagielski 		{
1373*b1cdbd2cSJim Jagielski 			if (nSection == 0)
1374*b1cdbd2cSJim Jagielski 			{
1375*b1cdbd2cSJim Jagielski 				sal_Unicode const * pCharsetBegin = p;
1376*b1cdbd2cSJim Jagielski 				bool bDowncaseCharset = false;
1377*b1cdbd2cSJim Jagielski 				while (p != pEnd && isTokenChar(*p) && *p != '\'')
1378*b1cdbd2cSJim Jagielski 				{
1379*b1cdbd2cSJim Jagielski 					bDowncaseCharset = bDowncaseCharset || isUpperCase(*p);
1380*b1cdbd2cSJim Jagielski 					++p;
1381*b1cdbd2cSJim Jagielski 				}
1382*b1cdbd2cSJim Jagielski 				if (p == pCharsetBegin)
1383*b1cdbd2cSJim Jagielski 					break;
1384*b1cdbd2cSJim Jagielski 				if (pParameters)
1385*b1cdbd2cSJim Jagielski 				{
1386*b1cdbd2cSJim Jagielski 					aCharset = ByteString(
1387*b1cdbd2cSJim Jagielski                         pCharsetBegin,
1388*b1cdbd2cSJim Jagielski                         static_cast< xub_StrLen >(p - pCharsetBegin),
1389*b1cdbd2cSJim Jagielski                         RTL_TEXTENCODING_ASCII_US);
1390*b1cdbd2cSJim Jagielski 					if (bDowncaseCharset)
1391*b1cdbd2cSJim Jagielski 						aCharset.ToLowerAscii();
1392*b1cdbd2cSJim Jagielski 				}
1393*b1cdbd2cSJim Jagielski 
1394*b1cdbd2cSJim Jagielski 				if (p == pEnd || *p != '\'')
1395*b1cdbd2cSJim Jagielski 					break;
1396*b1cdbd2cSJim Jagielski 				++p;
1397*b1cdbd2cSJim Jagielski 
1398*b1cdbd2cSJim Jagielski 				sal_Unicode const * pLanguageBegin = p;
1399*b1cdbd2cSJim Jagielski 				bool bDowncaseLanguage = false;
1400*b1cdbd2cSJim Jagielski 				int nLetters = 0;
1401*b1cdbd2cSJim Jagielski 				for (; p != pEnd; ++p)
1402*b1cdbd2cSJim Jagielski 					if (isAlpha(*p))
1403*b1cdbd2cSJim Jagielski 					{
1404*b1cdbd2cSJim Jagielski 						if (++nLetters > 8)
1405*b1cdbd2cSJim Jagielski 							break;
1406*b1cdbd2cSJim Jagielski 						bDowncaseLanguage = bDowncaseLanguage
1407*b1cdbd2cSJim Jagielski 							                || isUpperCase(*p);
1408*b1cdbd2cSJim Jagielski 					}
1409*b1cdbd2cSJim Jagielski 					else if (*p == '-')
1410*b1cdbd2cSJim Jagielski 					{
1411*b1cdbd2cSJim Jagielski 						if (nLetters == 0)
1412*b1cdbd2cSJim Jagielski 							break;
1413*b1cdbd2cSJim Jagielski 						nLetters = 0;
1414*b1cdbd2cSJim Jagielski 					}
1415*b1cdbd2cSJim Jagielski 					else
1416*b1cdbd2cSJim Jagielski 						break;
1417*b1cdbd2cSJim Jagielski 				if (nLetters == 0 || nLetters > 8)
1418*b1cdbd2cSJim Jagielski 					break;
1419*b1cdbd2cSJim Jagielski 				if (pParameters)
1420*b1cdbd2cSJim Jagielski 				{
1421*b1cdbd2cSJim Jagielski 					aLanguage = ByteString(
1422*b1cdbd2cSJim Jagielski                         pLanguageBegin,
1423*b1cdbd2cSJim Jagielski                         static_cast< xub_StrLen >(p - pLanguageBegin),
1424*b1cdbd2cSJim Jagielski                         RTL_TEXTENCODING_ASCII_US);
1425*b1cdbd2cSJim Jagielski 					if (bDowncaseLanguage)
1426*b1cdbd2cSJim Jagielski 						aLanguage.ToLowerAscii();
1427*b1cdbd2cSJim Jagielski 				}
1428*b1cdbd2cSJim Jagielski 
1429*b1cdbd2cSJim Jagielski 				if (p == pEnd || *p != '\'')
1430*b1cdbd2cSJim Jagielski 					break;
1431*b1cdbd2cSJim Jagielski 				++p;
1432*b1cdbd2cSJim Jagielski 			}
1433*b1cdbd2cSJim Jagielski 			if (pParameters)
1434*b1cdbd2cSJim Jagielski 			{
1435*b1cdbd2cSJim Jagielski 				INetMIMEStringOutputSink
1436*b1cdbd2cSJim Jagielski 					aSink(0, INetMIMEOutputSink::NO_LINE_LENGTH_LIMIT);
1437*b1cdbd2cSJim Jagielski 				while (p != pEnd)
1438*b1cdbd2cSJim Jagielski 				{
1439*b1cdbd2cSJim Jagielski 					sal_uInt32 nChar = INetMIME::getUTF32Character(p, pEnd);
1440*b1cdbd2cSJim Jagielski 					if (isUSASCII(nChar) && !isTokenChar(nChar))
1441*b1cdbd2cSJim Jagielski 						break;
1442*b1cdbd2cSJim Jagielski 					if (nChar == '%' && p + 1 < pEnd)
1443*b1cdbd2cSJim Jagielski 					{
1444*b1cdbd2cSJim Jagielski 						int nWeight1 = getHexWeight(p[0]);
1445*b1cdbd2cSJim Jagielski 						int nWeight2 = getHexWeight(p[1]);
1446*b1cdbd2cSJim Jagielski 						if (nWeight1 >= 0 && nWeight2 >= 0)
1447*b1cdbd2cSJim Jagielski 						{
1448*b1cdbd2cSJim Jagielski 							aSink << sal_Char(nWeight1 << 4 | nWeight2);
1449*b1cdbd2cSJim Jagielski 							p += 2;
1450*b1cdbd2cSJim Jagielski 							continue;
1451*b1cdbd2cSJim Jagielski 						}
1452*b1cdbd2cSJim Jagielski 					}
1453*b1cdbd2cSJim Jagielski 					INetMIME::writeUTF8(aSink, nChar);
1454*b1cdbd2cSJim Jagielski 				}
1455*b1cdbd2cSJim Jagielski 				aValue = aSink.takeBuffer();
1456*b1cdbd2cSJim Jagielski 			}
1457*b1cdbd2cSJim Jagielski 			else
1458*b1cdbd2cSJim Jagielski 				while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
1459*b1cdbd2cSJim Jagielski 					++p;
1460*b1cdbd2cSJim Jagielski 		}
1461*b1cdbd2cSJim Jagielski 		else if (p != pEnd && *p == '"')
1462*b1cdbd2cSJim Jagielski 			if (pParameters)
1463*b1cdbd2cSJim Jagielski 			{
1464*b1cdbd2cSJim Jagielski 				INetMIMEStringOutputSink
1465*b1cdbd2cSJim Jagielski 					aSink(0, INetMIMEOutputSink::NO_LINE_LENGTH_LIMIT);
1466*b1cdbd2cSJim Jagielski 				bool bInvalid = false;
1467*b1cdbd2cSJim Jagielski 				for (++p;;)
1468*b1cdbd2cSJim Jagielski 				{
1469*b1cdbd2cSJim Jagielski 					if (p == pEnd)
1470*b1cdbd2cSJim Jagielski 					{
1471*b1cdbd2cSJim Jagielski 						bInvalid = true;
1472*b1cdbd2cSJim Jagielski 						break;
1473*b1cdbd2cSJim Jagielski 					}
1474*b1cdbd2cSJim Jagielski 					sal_uInt32 nChar = INetMIME::getUTF32Character(p, pEnd);
1475*b1cdbd2cSJim Jagielski 					if (nChar == '"')
1476*b1cdbd2cSJim Jagielski 						break;
1477*b1cdbd2cSJim Jagielski 					else if (nChar == 0x0D) // CR
1478*b1cdbd2cSJim Jagielski 					{
1479*b1cdbd2cSJim Jagielski 						if (pEnd - p < 2 || *p++ != 0x0A // LF
1480*b1cdbd2cSJim Jagielski 							|| !isWhiteSpace(*p))
1481*b1cdbd2cSJim Jagielski 						{
1482*b1cdbd2cSJim Jagielski 							bInvalid = true;
1483*b1cdbd2cSJim Jagielski 							break;
1484*b1cdbd2cSJim Jagielski 						}
1485*b1cdbd2cSJim Jagielski 						nChar = sal_uChar(*p++);
1486*b1cdbd2cSJim Jagielski 					}
1487*b1cdbd2cSJim Jagielski 					else if (nChar == '\\')
1488*b1cdbd2cSJim Jagielski 					{
1489*b1cdbd2cSJim Jagielski 						if (p == pEnd)
1490*b1cdbd2cSJim Jagielski 						{
1491*b1cdbd2cSJim Jagielski 							bInvalid = true;
1492*b1cdbd2cSJim Jagielski 							break;
1493*b1cdbd2cSJim Jagielski 						}
1494*b1cdbd2cSJim Jagielski 						nChar = INetMIME::getUTF32Character(p, pEnd);
1495*b1cdbd2cSJim Jagielski 					}
1496*b1cdbd2cSJim Jagielski 					INetMIME::writeUTF8(aSink, nChar);
1497*b1cdbd2cSJim Jagielski 				}
1498*b1cdbd2cSJim Jagielski 				if (bInvalid)
1499*b1cdbd2cSJim Jagielski 					break;
1500*b1cdbd2cSJim Jagielski 				aValue = aSink.takeBuffer();
1501*b1cdbd2cSJim Jagielski 			}
1502*b1cdbd2cSJim Jagielski 			else
1503*b1cdbd2cSJim Jagielski 			{
1504*b1cdbd2cSJim Jagielski 				sal_Unicode const * pStringEnd = skipQuotedString(p, pEnd);
1505*b1cdbd2cSJim Jagielski 				if (p == pStringEnd)
1506*b1cdbd2cSJim Jagielski 					break;
1507*b1cdbd2cSJim Jagielski 				p = pStringEnd;
1508*b1cdbd2cSJim Jagielski 			}
1509*b1cdbd2cSJim Jagielski 		else
1510*b1cdbd2cSJim Jagielski 		{
1511*b1cdbd2cSJim Jagielski 			sal_Unicode const * pTokenBegin = p;
1512*b1cdbd2cSJim Jagielski 			while (p != pEnd && (isTokenChar(*p) || !isUSASCII(*p)))
1513*b1cdbd2cSJim Jagielski 				++p;
1514*b1cdbd2cSJim Jagielski 			if (p == pTokenBegin)
1515*b1cdbd2cSJim Jagielski 				break;
1516*b1cdbd2cSJim Jagielski 			if (pParameters)
1517*b1cdbd2cSJim Jagielski 				aValue = ByteString(
1518*b1cdbd2cSJim Jagielski                     pTokenBegin, static_cast< xub_StrLen >(p - pTokenBegin),
1519*b1cdbd2cSJim Jagielski                     RTL_TEXTENCODING_UTF8);
1520*b1cdbd2cSJim Jagielski 		}
1521*b1cdbd2cSJim Jagielski 
1522*b1cdbd2cSJim Jagielski 		*pPos = new Parameter(*pPos, aAttribute, aCharset, aLanguage, aValue,
1523*b1cdbd2cSJim Jagielski 							  nSection, bExtended);
1524*b1cdbd2cSJim Jagielski 	}
1525*b1cdbd2cSJim Jagielski 	return parseParameters(aList, pParameters) ? pParameterBegin : pBegin;
1526*b1cdbd2cSJim Jagielski }
1527*b1cdbd2cSJim Jagielski 
1528*b1cdbd2cSJim Jagielski //============================================================================
1529*b1cdbd2cSJim Jagielski // static
getCharsetName(rtl_TextEncoding eEncoding)1530*b1cdbd2cSJim Jagielski const sal_Char * INetMIME::getCharsetName(rtl_TextEncoding eEncoding)
1531*b1cdbd2cSJim Jagielski {
1532*b1cdbd2cSJim Jagielski 	if (rtl_isOctetTextEncoding(eEncoding))
1533*b1cdbd2cSJim Jagielski 	{
1534*b1cdbd2cSJim Jagielski         char const * p = rtl_getMimeCharsetFromTextEncoding(eEncoding);
1535*b1cdbd2cSJim Jagielski 		DBG_ASSERT(p, "INetMIME::getCharsetName(): Unsupported encoding");
1536*b1cdbd2cSJim Jagielski 		return p;
1537*b1cdbd2cSJim Jagielski 	}
1538*b1cdbd2cSJim Jagielski 	else
1539*b1cdbd2cSJim Jagielski 		switch (eEncoding)
1540*b1cdbd2cSJim Jagielski 		{
1541*b1cdbd2cSJim Jagielski 			case RTL_TEXTENCODING_UCS4:
1542*b1cdbd2cSJim Jagielski 				return "ISO-10646-UCS-4";
1543*b1cdbd2cSJim Jagielski 
1544*b1cdbd2cSJim Jagielski 			case RTL_TEXTENCODING_UCS2:
1545*b1cdbd2cSJim Jagielski 				return "ISO-10646-UCS-2";
1546*b1cdbd2cSJim Jagielski 
1547*b1cdbd2cSJim Jagielski 			default:
1548*b1cdbd2cSJim Jagielski 				DBG_ERROR("INetMIME::getCharsetName(): Unsupported encoding");
1549*b1cdbd2cSJim Jagielski 				return 0;
1550*b1cdbd2cSJim Jagielski 		}
1551*b1cdbd2cSJim Jagielski }
1552*b1cdbd2cSJim Jagielski 
1553*b1cdbd2cSJim Jagielski //============================================================================
1554*b1cdbd2cSJim Jagielski namespace unnamed_tools_inetmime {
1555*b1cdbd2cSJim Jagielski 
1556*b1cdbd2cSJim Jagielski struct EncodingEntry
1557*b1cdbd2cSJim Jagielski {
1558*b1cdbd2cSJim Jagielski 	sal_Char const * m_aName;
1559*b1cdbd2cSJim Jagielski 	rtl_TextEncoding m_eEncoding;
1560*b1cdbd2cSJim Jagielski };
1561*b1cdbd2cSJim Jagielski 
1562*b1cdbd2cSJim Jagielski //============================================================================
1563*b1cdbd2cSJim Jagielski // The source for the following table is <ftp://ftp.iana.org/in-notes/iana/
1564*b1cdbd2cSJim Jagielski // assignments/character-sets> as of Jan, 21 2000 12:46:00, unless  otherwise
1565*b1cdbd2cSJim Jagielski // noted:
1566*b1cdbd2cSJim Jagielski EncodingEntry const aEncodingMap[]
1567*b1cdbd2cSJim Jagielski 	= { { "US-ASCII", RTL_TEXTENCODING_ASCII_US },
1568*b1cdbd2cSJim Jagielski 		{ "ANSI_X3.4-1968", RTL_TEXTENCODING_ASCII_US },
1569*b1cdbd2cSJim Jagielski 		{ "ISO-IR-6", RTL_TEXTENCODING_ASCII_US },
1570*b1cdbd2cSJim Jagielski 		{ "ANSI_X3.4-1986", RTL_TEXTENCODING_ASCII_US },
1571*b1cdbd2cSJim Jagielski 		{ "ISO_646.IRV:1991", RTL_TEXTENCODING_ASCII_US },
1572*b1cdbd2cSJim Jagielski 		{ "ASCII", RTL_TEXTENCODING_ASCII_US },
1573*b1cdbd2cSJim Jagielski 		{ "ISO646-US", RTL_TEXTENCODING_ASCII_US },
1574*b1cdbd2cSJim Jagielski 		{ "US", RTL_TEXTENCODING_ASCII_US },
1575*b1cdbd2cSJim Jagielski 		{ "IBM367", RTL_TEXTENCODING_ASCII_US },
1576*b1cdbd2cSJim Jagielski 		{ "CP367", RTL_TEXTENCODING_ASCII_US },
1577*b1cdbd2cSJim Jagielski 		{ "CSASCII", RTL_TEXTENCODING_ASCII_US },
1578*b1cdbd2cSJim Jagielski 		{ "ISO-8859-1", RTL_TEXTENCODING_ISO_8859_1 },
1579*b1cdbd2cSJim Jagielski 		{ "ISO_8859-1:1987", RTL_TEXTENCODING_ISO_8859_1 },
1580*b1cdbd2cSJim Jagielski 		{ "ISO-IR-100", RTL_TEXTENCODING_ISO_8859_1 },
1581*b1cdbd2cSJim Jagielski 		{ "ISO_8859-1", RTL_TEXTENCODING_ISO_8859_1 },
1582*b1cdbd2cSJim Jagielski 		{ "LATIN1", RTL_TEXTENCODING_ISO_8859_1 },
1583*b1cdbd2cSJim Jagielski 		{ "L1", RTL_TEXTENCODING_ISO_8859_1 },
1584*b1cdbd2cSJim Jagielski 		{ "IBM819", RTL_TEXTENCODING_ISO_8859_1 },
1585*b1cdbd2cSJim Jagielski 		{ "CP819", RTL_TEXTENCODING_ISO_8859_1 },
1586*b1cdbd2cSJim Jagielski 		{ "CSISOLATIN1", RTL_TEXTENCODING_ISO_8859_1 },
1587*b1cdbd2cSJim Jagielski 		{ "ISO-8859-2", RTL_TEXTENCODING_ISO_8859_2 },
1588*b1cdbd2cSJim Jagielski 		{ "ISO_8859-2:1987", RTL_TEXTENCODING_ISO_8859_2 },
1589*b1cdbd2cSJim Jagielski 		{ "ISO-IR-101", RTL_TEXTENCODING_ISO_8859_2 },
1590*b1cdbd2cSJim Jagielski 		{ "ISO_8859-2", RTL_TEXTENCODING_ISO_8859_2 },
1591*b1cdbd2cSJim Jagielski 		{ "LATIN2", RTL_TEXTENCODING_ISO_8859_2 },
1592*b1cdbd2cSJim Jagielski 		{ "L2", RTL_TEXTENCODING_ISO_8859_2 },
1593*b1cdbd2cSJim Jagielski 		{ "CSISOLATIN2", RTL_TEXTENCODING_ISO_8859_2 },
1594*b1cdbd2cSJim Jagielski 		{ "ISO-8859-3", RTL_TEXTENCODING_ISO_8859_3 },
1595*b1cdbd2cSJim Jagielski 		{ "ISO_8859-3:1988", RTL_TEXTENCODING_ISO_8859_3 },
1596*b1cdbd2cSJim Jagielski 		{ "ISO-IR-109", RTL_TEXTENCODING_ISO_8859_3 },
1597*b1cdbd2cSJim Jagielski 		{ "ISO_8859-3", RTL_TEXTENCODING_ISO_8859_3 },
1598*b1cdbd2cSJim Jagielski 		{ "LATIN3", RTL_TEXTENCODING_ISO_8859_3 },
1599*b1cdbd2cSJim Jagielski 		{ "L3", RTL_TEXTENCODING_ISO_8859_3 },
1600*b1cdbd2cSJim Jagielski 		{ "CSISOLATIN3", RTL_TEXTENCODING_ISO_8859_3 },
1601*b1cdbd2cSJim Jagielski 		{ "ISO-8859-4", RTL_TEXTENCODING_ISO_8859_4 },
1602*b1cdbd2cSJim Jagielski 		{ "ISO_8859-4:1988", RTL_TEXTENCODING_ISO_8859_4 },
1603*b1cdbd2cSJim Jagielski 		{ "ISO-IR-110", RTL_TEXTENCODING_ISO_8859_4 },
1604*b1cdbd2cSJim Jagielski 		{ "ISO_8859-4", RTL_TEXTENCODING_ISO_8859_4 },
1605*b1cdbd2cSJim Jagielski 		{ "LATIN4", RTL_TEXTENCODING_ISO_8859_4 },
1606*b1cdbd2cSJim Jagielski 		{ "L4", RTL_TEXTENCODING_ISO_8859_4 },
1607*b1cdbd2cSJim Jagielski 		{ "CSISOLATIN4", RTL_TEXTENCODING_ISO_8859_4 },
1608*b1cdbd2cSJim Jagielski 		{ "ISO-8859-5", RTL_TEXTENCODING_ISO_8859_5 },
1609*b1cdbd2cSJim Jagielski 		{ "ISO_8859-5:1988", RTL_TEXTENCODING_ISO_8859_5 },
1610*b1cdbd2cSJim Jagielski 		{ "ISO-IR-144", RTL_TEXTENCODING_ISO_8859_5 },
1611*b1cdbd2cSJim Jagielski 		{ "ISO_8859-5", RTL_TEXTENCODING_ISO_8859_5 },
1612*b1cdbd2cSJim Jagielski 		{ "CYRILLIC", RTL_TEXTENCODING_ISO_8859_5 },
1613*b1cdbd2cSJim Jagielski 		{ "CSISOLATINCYRILLIC", RTL_TEXTENCODING_ISO_8859_5 },
1614*b1cdbd2cSJim Jagielski 		{ "ISO-8859-6", RTL_TEXTENCODING_ISO_8859_6 },
1615*b1cdbd2cSJim Jagielski 		{ "ISO_8859-6:1987", RTL_TEXTENCODING_ISO_8859_6 },
1616*b1cdbd2cSJim Jagielski 		{ "ISO-IR-127", RTL_TEXTENCODING_ISO_8859_6 },
1617*b1cdbd2cSJim Jagielski 		{ "ISO_8859-6", RTL_TEXTENCODING_ISO_8859_6 },
1618*b1cdbd2cSJim Jagielski 		{ "ECMA-114", RTL_TEXTENCODING_ISO_8859_6 },
1619*b1cdbd2cSJim Jagielski 		{ "ASMO-708", RTL_TEXTENCODING_ISO_8859_6 },
1620*b1cdbd2cSJim Jagielski 		{ "ARABIC", RTL_TEXTENCODING_ISO_8859_6 },
1621*b1cdbd2cSJim Jagielski 		{ "CSISOLATINARABIC", RTL_TEXTENCODING_ISO_8859_6 },
1622*b1cdbd2cSJim Jagielski 		{ "ISO-8859-7", RTL_TEXTENCODING_ISO_8859_7 },
1623*b1cdbd2cSJim Jagielski 		{ "ISO_8859-7:1987", RTL_TEXTENCODING_ISO_8859_7 },
1624*b1cdbd2cSJim Jagielski 		{ "ISO-IR-126", RTL_TEXTENCODING_ISO_8859_7 },
1625*b1cdbd2cSJim Jagielski 		{ "ISO_8859-7", RTL_TEXTENCODING_ISO_8859_7 },
1626*b1cdbd2cSJim Jagielski 		{ "ELOT_928", RTL_TEXTENCODING_ISO_8859_7 },
1627*b1cdbd2cSJim Jagielski 		{ "ECMA-118", RTL_TEXTENCODING_ISO_8859_7 },
1628*b1cdbd2cSJim Jagielski 		{ "GREEK", RTL_TEXTENCODING_ISO_8859_7 },
1629*b1cdbd2cSJim Jagielski 		{ "GREEK8", RTL_TEXTENCODING_ISO_8859_7 },
1630*b1cdbd2cSJim Jagielski 		{ "CSISOLATINGREEK", RTL_TEXTENCODING_ISO_8859_7 },
1631*b1cdbd2cSJim Jagielski 		{ "ISO-8859-8", RTL_TEXTENCODING_ISO_8859_8 },
1632*b1cdbd2cSJim Jagielski 		{ "ISO_8859-8:1988", RTL_TEXTENCODING_ISO_8859_8 },
1633*b1cdbd2cSJim Jagielski 		{ "ISO-IR-138", RTL_TEXTENCODING_ISO_8859_8 },
1634*b1cdbd2cSJim Jagielski 		{ "ISO_8859-8", RTL_TEXTENCODING_ISO_8859_8 },
1635*b1cdbd2cSJim Jagielski 		{ "HEBREW", RTL_TEXTENCODING_ISO_8859_8 },
1636*b1cdbd2cSJim Jagielski 		{ "CSISOLATINHEBREW", RTL_TEXTENCODING_ISO_8859_8 },
1637*b1cdbd2cSJim Jagielski 		{ "ISO-8859-9", RTL_TEXTENCODING_ISO_8859_9 },
1638*b1cdbd2cSJim Jagielski 		{ "ISO_8859-9:1989", RTL_TEXTENCODING_ISO_8859_9 },
1639*b1cdbd2cSJim Jagielski 		{ "ISO-IR-148", RTL_TEXTENCODING_ISO_8859_9 },
1640*b1cdbd2cSJim Jagielski 		{ "ISO_8859-9", RTL_TEXTENCODING_ISO_8859_9 },
1641*b1cdbd2cSJim Jagielski 		{ "LATIN5", RTL_TEXTENCODING_ISO_8859_9 },
1642*b1cdbd2cSJim Jagielski 		{ "L5", RTL_TEXTENCODING_ISO_8859_9 },
1643*b1cdbd2cSJim Jagielski 		{ "CSISOLATIN5", RTL_TEXTENCODING_ISO_8859_9 },
1644*b1cdbd2cSJim Jagielski 		{ "ISO-8859-14", RTL_TEXTENCODING_ISO_8859_14 }, // RFC 2047
1645*b1cdbd2cSJim Jagielski 		{ "ISO_8859-15", RTL_TEXTENCODING_ISO_8859_15 },
1646*b1cdbd2cSJim Jagielski 		{ "ISO-8859-15", RTL_TEXTENCODING_ISO_8859_15 }, // RFC 2047
1647*b1cdbd2cSJim Jagielski 		{ "MACINTOSH", RTL_TEXTENCODING_APPLE_ROMAN },
1648*b1cdbd2cSJim Jagielski 		{ "MAC", RTL_TEXTENCODING_APPLE_ROMAN },
1649*b1cdbd2cSJim Jagielski 		{ "CSMACINTOSH", RTL_TEXTENCODING_APPLE_ROMAN },
1650*b1cdbd2cSJim Jagielski 		{ "IBM437", RTL_TEXTENCODING_IBM_437 },
1651*b1cdbd2cSJim Jagielski 		{ "CP437", RTL_TEXTENCODING_IBM_437 },
1652*b1cdbd2cSJim Jagielski 		{ "437", RTL_TEXTENCODING_IBM_437 },
1653*b1cdbd2cSJim Jagielski 		{ "CSPC8CODEPAGE437", RTL_TEXTENCODING_IBM_437 },
1654*b1cdbd2cSJim Jagielski 		{ "IBM850", RTL_TEXTENCODING_IBM_850 },
1655*b1cdbd2cSJim Jagielski 		{ "CP850", RTL_TEXTENCODING_IBM_850 },
1656*b1cdbd2cSJim Jagielski 		{ "850", RTL_TEXTENCODING_IBM_850 },
1657*b1cdbd2cSJim Jagielski 		{ "CSPC850MULTILINGUAL", RTL_TEXTENCODING_IBM_850 },
1658*b1cdbd2cSJim Jagielski 		{ "IBM860", RTL_TEXTENCODING_IBM_860 },
1659*b1cdbd2cSJim Jagielski 		{ "CP860", RTL_TEXTENCODING_IBM_860 },
1660*b1cdbd2cSJim Jagielski 		{ "860", RTL_TEXTENCODING_IBM_860 },
1661*b1cdbd2cSJim Jagielski 		{ "CSIBM860", RTL_TEXTENCODING_IBM_860 },
1662*b1cdbd2cSJim Jagielski 		{ "IBM861", RTL_TEXTENCODING_IBM_861 },
1663*b1cdbd2cSJim Jagielski 		{ "CP861", RTL_TEXTENCODING_IBM_861 },
1664*b1cdbd2cSJim Jagielski 		{ "861", RTL_TEXTENCODING_IBM_861 },
1665*b1cdbd2cSJim Jagielski 		{ "CP-IS", RTL_TEXTENCODING_IBM_861 },
1666*b1cdbd2cSJim Jagielski 		{ "CSIBM861", RTL_TEXTENCODING_IBM_861 },
1667*b1cdbd2cSJim Jagielski 		{ "IBM863", RTL_TEXTENCODING_IBM_863 },
1668*b1cdbd2cSJim Jagielski 		{ "CP863", RTL_TEXTENCODING_IBM_863 },
1669*b1cdbd2cSJim Jagielski 		{ "863", RTL_TEXTENCODING_IBM_863 },
1670*b1cdbd2cSJim Jagielski 		{ "CSIBM863", RTL_TEXTENCODING_IBM_863 },
1671*b1cdbd2cSJim Jagielski 		{ "IBM865", RTL_TEXTENCODING_IBM_865 },
1672*b1cdbd2cSJim Jagielski 		{ "CP865", RTL_TEXTENCODING_IBM_865 },
1673*b1cdbd2cSJim Jagielski 		{ "865", RTL_TEXTENCODING_IBM_865 },
1674*b1cdbd2cSJim Jagielski 		{ "CSIBM865", RTL_TEXTENCODING_IBM_865 },
1675*b1cdbd2cSJim Jagielski 		{ "IBM775", RTL_TEXTENCODING_IBM_775 },
1676*b1cdbd2cSJim Jagielski 		{ "CP775", RTL_TEXTENCODING_IBM_775 },
1677*b1cdbd2cSJim Jagielski 		{ "CSPC775BALTIC", RTL_TEXTENCODING_IBM_775 },
1678*b1cdbd2cSJim Jagielski 		{ "IBM852", RTL_TEXTENCODING_IBM_852 },
1679*b1cdbd2cSJim Jagielski 		{ "CP852", RTL_TEXTENCODING_IBM_852 },
1680*b1cdbd2cSJim Jagielski 		{ "852", RTL_TEXTENCODING_IBM_852 },
1681*b1cdbd2cSJim Jagielski 		{ "CSPCP852", RTL_TEXTENCODING_IBM_852 },
1682*b1cdbd2cSJim Jagielski 		{ "IBM855", RTL_TEXTENCODING_IBM_855 },
1683*b1cdbd2cSJim Jagielski 		{ "CP855", RTL_TEXTENCODING_IBM_855 },
1684*b1cdbd2cSJim Jagielski 		{ "855", RTL_TEXTENCODING_IBM_855 },
1685*b1cdbd2cSJim Jagielski 		{ "CSIBM855", RTL_TEXTENCODING_IBM_855 },
1686*b1cdbd2cSJim Jagielski 		{ "IBM857", RTL_TEXTENCODING_IBM_857 },
1687*b1cdbd2cSJim Jagielski 		{ "CP857", RTL_TEXTENCODING_IBM_857 },
1688*b1cdbd2cSJim Jagielski 		{ "857", RTL_TEXTENCODING_IBM_857 },
1689*b1cdbd2cSJim Jagielski 		{ "CSIBM857", RTL_TEXTENCODING_IBM_857 },
1690*b1cdbd2cSJim Jagielski 		{ "IBM862", RTL_TEXTENCODING_IBM_862 },
1691*b1cdbd2cSJim Jagielski 		{ "CP862", RTL_TEXTENCODING_IBM_862 },
1692*b1cdbd2cSJim Jagielski 		{ "862", RTL_TEXTENCODING_IBM_862 },
1693*b1cdbd2cSJim Jagielski 		{ "CSPC862LATINHEBREW", RTL_TEXTENCODING_IBM_862 },
1694*b1cdbd2cSJim Jagielski 		{ "IBM864", RTL_TEXTENCODING_IBM_864 },
1695*b1cdbd2cSJim Jagielski 		{ "CP864", RTL_TEXTENCODING_IBM_864 },
1696*b1cdbd2cSJim Jagielski 		{ "CSIBM864", RTL_TEXTENCODING_IBM_864 },
1697*b1cdbd2cSJim Jagielski 		{ "IBM866", RTL_TEXTENCODING_IBM_866 },
1698*b1cdbd2cSJim Jagielski 		{ "CP866", RTL_TEXTENCODING_IBM_866 },
1699*b1cdbd2cSJim Jagielski 		{ "866", RTL_TEXTENCODING_IBM_866 },
1700*b1cdbd2cSJim Jagielski 		{ "CSIBM866", RTL_TEXTENCODING_IBM_866 },
1701*b1cdbd2cSJim Jagielski 		{ "IBM869", RTL_TEXTENCODING_IBM_869 },
1702*b1cdbd2cSJim Jagielski 		{ "CP869", RTL_TEXTENCODING_IBM_869 },
1703*b1cdbd2cSJim Jagielski 		{ "869", RTL_TEXTENCODING_IBM_869 },
1704*b1cdbd2cSJim Jagielski 		{ "CP-GR", RTL_TEXTENCODING_IBM_869 },
1705*b1cdbd2cSJim Jagielski 		{ "CSIBM869", RTL_TEXTENCODING_IBM_869 },
1706*b1cdbd2cSJim Jagielski 		{ "WINDOWS-1250", RTL_TEXTENCODING_MS_1250 },
1707*b1cdbd2cSJim Jagielski 		{ "WINDOWS-1251", RTL_TEXTENCODING_MS_1251 },
1708*b1cdbd2cSJim Jagielski 		{ "WINDOWS-1253", RTL_TEXTENCODING_MS_1253 },
1709*b1cdbd2cSJim Jagielski 		{ "WINDOWS-1254", RTL_TEXTENCODING_MS_1254 },
1710*b1cdbd2cSJim Jagielski 		{ "WINDOWS-1255", RTL_TEXTENCODING_MS_1255 },
1711*b1cdbd2cSJim Jagielski 		{ "WINDOWS-1256", RTL_TEXTENCODING_MS_1256 },
1712*b1cdbd2cSJim Jagielski 		{ "WINDOWS-1257", RTL_TEXTENCODING_MS_1257 },
1713*b1cdbd2cSJim Jagielski 		{ "WINDOWS-1258", RTL_TEXTENCODING_MS_1258 },
1714*b1cdbd2cSJim Jagielski 		{ "SHIFT_JIS", RTL_TEXTENCODING_SHIFT_JIS },
1715*b1cdbd2cSJim Jagielski 		{ "MS_KANJI", RTL_TEXTENCODING_SHIFT_JIS },
1716*b1cdbd2cSJim Jagielski 		{ "CSSHIFTJIS", RTL_TEXTENCODING_SHIFT_JIS },
1717*b1cdbd2cSJim Jagielski 		{ "GB2312", RTL_TEXTENCODING_GB_2312 },
1718*b1cdbd2cSJim Jagielski 		{ "CSGB2312", RTL_TEXTENCODING_GB_2312 },
1719*b1cdbd2cSJim Jagielski 		{ "BIG5", RTL_TEXTENCODING_BIG5 },
1720*b1cdbd2cSJim Jagielski 		{ "CSBIG5", RTL_TEXTENCODING_BIG5 },
1721*b1cdbd2cSJim Jagielski 		{ "EUC-JP", RTL_TEXTENCODING_EUC_JP },
1722*b1cdbd2cSJim Jagielski 		{ "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE",
1723*b1cdbd2cSJim Jagielski 		  RTL_TEXTENCODING_EUC_JP },
1724*b1cdbd2cSJim Jagielski 		{ "CSEUCPKDFMTJAPANESE", RTL_TEXTENCODING_EUC_JP },
1725*b1cdbd2cSJim Jagielski 		{ "ISO-2022-JP", RTL_TEXTENCODING_ISO_2022_JP },
1726*b1cdbd2cSJim Jagielski 		{ "CSISO2022JP", RTL_TEXTENCODING_ISO_2022_JP },
1727*b1cdbd2cSJim Jagielski 		{ "ISO-2022-CN", RTL_TEXTENCODING_ISO_2022_CN },
1728*b1cdbd2cSJim Jagielski 		{ "KOI8-R", RTL_TEXTENCODING_KOI8_R },
1729*b1cdbd2cSJim Jagielski 		{ "CSKOI8R", RTL_TEXTENCODING_KOI8_R },
1730*b1cdbd2cSJim Jagielski 		{ "UTF-7", RTL_TEXTENCODING_UTF7 },
1731*b1cdbd2cSJim Jagielski 		{ "UTF-8", RTL_TEXTENCODING_UTF8 },
1732*b1cdbd2cSJim Jagielski 		{ "ISO-8859-10", RTL_TEXTENCODING_ISO_8859_10 }, // RFC 2047
1733*b1cdbd2cSJim Jagielski 		{ "ISO-8859-13", RTL_TEXTENCODING_ISO_8859_13 }, // RFC 2047
1734*b1cdbd2cSJim Jagielski 		{ "EUC-KR", RTL_TEXTENCODING_EUC_KR },
1735*b1cdbd2cSJim Jagielski 		{ "CSEUCKR", RTL_TEXTENCODING_EUC_KR },
1736*b1cdbd2cSJim Jagielski 		{ "ISO-2022-KR", RTL_TEXTENCODING_ISO_2022_KR },
1737*b1cdbd2cSJim Jagielski 		{ "CSISO2022KR", RTL_TEXTENCODING_ISO_2022_KR },
1738*b1cdbd2cSJim Jagielski 		{ "ISO-10646-UCS-4", RTL_TEXTENCODING_UCS4 },
1739*b1cdbd2cSJim Jagielski 		{ "CSUCS4", RTL_TEXTENCODING_UCS4 },
1740*b1cdbd2cSJim Jagielski 		{ "ISO-10646-UCS-2", RTL_TEXTENCODING_UCS2 },
1741*b1cdbd2cSJim Jagielski 		{ "CSUNICODE", RTL_TEXTENCODING_UCS2 } };
1742*b1cdbd2cSJim Jagielski 
1743*b1cdbd2cSJim Jagielski //============================================================================
1744*b1cdbd2cSJim Jagielski template< typename T >
getCharsetEncoding_Impl(T const * pBegin,T const * pEnd)1745*b1cdbd2cSJim Jagielski inline rtl_TextEncoding getCharsetEncoding_Impl(T const * pBegin,
1746*b1cdbd2cSJim Jagielski 												T const * pEnd)
1747*b1cdbd2cSJim Jagielski {
1748*b1cdbd2cSJim Jagielski 	for (sal_Size i = 0; i < sizeof aEncodingMap / sizeof (EncodingEntry);
1749*b1cdbd2cSJim Jagielski 		 ++i)
1750*b1cdbd2cSJim Jagielski 		if (INetMIME::equalIgnoreCase(pBegin, pEnd, aEncodingMap[i].m_aName))
1751*b1cdbd2cSJim Jagielski 			return aEncodingMap[i].m_eEncoding;
1752*b1cdbd2cSJim Jagielski 	return RTL_TEXTENCODING_DONTKNOW;
1753*b1cdbd2cSJim Jagielski }
1754*b1cdbd2cSJim Jagielski 
1755*b1cdbd2cSJim Jagielski }
1756*b1cdbd2cSJim Jagielski 
1757*b1cdbd2cSJim Jagielski //============================================================================
1758*b1cdbd2cSJim Jagielski // static
getCharsetEncoding(sal_Char const * pBegin,sal_Char const * pEnd)1759*b1cdbd2cSJim Jagielski rtl_TextEncoding INetMIME::getCharsetEncoding(sal_Char const * pBegin,
1760*b1cdbd2cSJim Jagielski 											  sal_Char const * pEnd)
1761*b1cdbd2cSJim Jagielski {
1762*b1cdbd2cSJim Jagielski 	return getCharsetEncoding_Impl(pBegin, pEnd);
1763*b1cdbd2cSJim Jagielski }
1764*b1cdbd2cSJim Jagielski 
1765*b1cdbd2cSJim Jagielski //============================================================================
1766*b1cdbd2cSJim Jagielski // static
getCharsetEncoding(sal_Unicode const * pBegin,sal_Unicode const * pEnd)1767*b1cdbd2cSJim Jagielski rtl_TextEncoding INetMIME::getCharsetEncoding(sal_Unicode const * pBegin,
1768*b1cdbd2cSJim Jagielski 											  sal_Unicode const * pEnd)
1769*b1cdbd2cSJim Jagielski {
1770*b1cdbd2cSJim Jagielski 	return getCharsetEncoding_Impl(pBegin, pEnd);
1771*b1cdbd2cSJim Jagielski }
1772*b1cdbd2cSJim Jagielski 
1773*b1cdbd2cSJim Jagielski //============================================================================
1774*b1cdbd2cSJim Jagielski // static
1775*b1cdbd2cSJim Jagielski INetMIMECharsetList_Impl *
createPreferredCharsetList(rtl_TextEncoding eEncoding)1776*b1cdbd2cSJim Jagielski INetMIME::createPreferredCharsetList(rtl_TextEncoding eEncoding)
1777*b1cdbd2cSJim Jagielski {
1778*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aUSASCIIRanges[] = { 0, 0x7F, sal_uInt32(-1) };
1779*b1cdbd2cSJim Jagielski 
1780*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO88591Ranges[] = { 0, 0xFF, sal_uInt32(-1) };
1781*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-1.TXT> version
1782*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1783*b1cdbd2cSJim Jagielski 
1784*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO88592Ranges[]
1785*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA4, 0xA4, 0xA7, 0xA8, 0xAD, 0xAD, 0xB0, 0xB0,
1786*b1cdbd2cSJim Jagielski 			0xB4, 0xB4, 0xB8, 0xB8, 0xC1, 0xC2, 0xC4, 0xC4, 0xC7, 0xC7,
1787*b1cdbd2cSJim Jagielski 			0xC9, 0xC9, 0xCB, 0xCB, 0xCD, 0xCE, 0xD3, 0xD4, 0xD6, 0xD7,
1788*b1cdbd2cSJim Jagielski 			0xDA, 0xDA, 0xDC, 0xDD, 0xDF, 0xDF, 0xE1, 0xE2, 0xE4, 0xE4,
1789*b1cdbd2cSJim Jagielski 			0xE7, 0xE7, 0xE9, 0xE9, 0xEB, 0xEB, 0xED, 0xEE, 0xF3, 0xF4,
1790*b1cdbd2cSJim Jagielski 			0xF6, 0xF7, 0xFA, 0xFA, 0xFC, 0xFD, 0x102, 0x107, 0x10C, 0x111,
1791*b1cdbd2cSJim Jagielski 			0x118, 0x11B, 0x139, 0x13A, 0x13D, 0x13E, 0x141, 0x144,
1792*b1cdbd2cSJim Jagielski 			0x147, 0x148, 0x150, 0x151, 0x154, 0x155, 0x158, 0x15B,
1793*b1cdbd2cSJim Jagielski 			0x15E, 0x165, 0x16E, 0x171, 0x179, 0x17E, 0x2C7, 0x2C7,
1794*b1cdbd2cSJim Jagielski 			0x2D8, 0x2D9, 0x2DB, 0x2DB, 0x2DD, 0x2DD, sal_uInt32(-1) };
1795*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-2.TXT> version
1796*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1797*b1cdbd2cSJim Jagielski 
1798*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO88593Ranges[]
1799*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA3, 0xA4, 0xA7, 0xA8, 0xAD, 0xAD, 0xB0, 0xB0,
1800*b1cdbd2cSJim Jagielski 			0xB2, 0xB5, 0xB7, 0xB8, 0xBD, 0xBD, 0xC0, 0xC2, 0xC4, 0xC4,
1801*b1cdbd2cSJim Jagielski 			0xC7, 0xCF, 0xD1, 0xD4, 0xD6, 0xD7, 0xD9, 0xDC, 0xDF, 0xE2,
1802*b1cdbd2cSJim Jagielski 			0xE4, 0xE4, 0xE7, 0xEF, 0xF1, 0xF4, 0xF6, 0xF7, 0xF9, 0xFC,
1803*b1cdbd2cSJim Jagielski 			0x108, 0x10B, 0x11C, 0x121, 0x124, 0x127, 0x130, 0x131,
1804*b1cdbd2cSJim Jagielski 			0x134, 0x135, 0x15C, 0x15F, 0x16C, 0x16D, 0x17B, 0x17C,
1805*b1cdbd2cSJim Jagielski 			0x2D8, 0x2D9, sal_uInt32(-1) };
1806*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-3.TXT> version
1807*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1808*b1cdbd2cSJim Jagielski 
1809*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO88594Ranges[]
1810*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA4, 0xA4, 0xA7, 0xA8, 0xAD, 0xAD, 0xAF, 0xB0,
1811*b1cdbd2cSJim Jagielski 			0xB4, 0xB4, 0xB8, 0xB8, 0xC1, 0xC6, 0xC9, 0xC9, 0xCB, 0xCB,
1812*b1cdbd2cSJim Jagielski 			0xCD, 0xCE, 0xD4, 0xD8, 0xDA, 0xDC, 0xDF, 0xDF, 0xE1, 0xE6,
1813*b1cdbd2cSJim Jagielski 			0xE9, 0xE9, 0xEB, 0xEB, 0xED, 0xEE, 0xF4, 0xF8, 0xFA, 0xFC,
1814*b1cdbd2cSJim Jagielski 			0x100, 0x101, 0x104, 0x105, 0x10C, 0x10D, 0x110, 0x113,
1815*b1cdbd2cSJim Jagielski 			0x116, 0x119, 0x122, 0x123, 0x128, 0x12B, 0x12E, 0x12F,
1816*b1cdbd2cSJim Jagielski 			0x136, 0x138, 0x13B, 0x13C, 0x145, 0x146, 0x14A, 0x14D,
1817*b1cdbd2cSJim Jagielski 			0x156, 0x157, 0x160, 0x161, 0x166, 0x16B, 0x172, 0x173,
1818*b1cdbd2cSJim Jagielski 			0x17D, 0x17E, 0x2C7, 0x2C7, 0x2D9, 0x2D9, 0x2DB, 0x2DB,
1819*b1cdbd2cSJim Jagielski 			sal_uInt32(-1) };
1820*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-4.TXT> version
1821*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1822*b1cdbd2cSJim Jagielski 
1823*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO88595Ranges[]
1824*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA7, 0xA7, 0xAD, 0xAD, 0x401, 0x40C, 0x40E, 0x44F,
1825*b1cdbd2cSJim Jagielski 			0x451, 0x45C, 0x45E, 0x45F, 0x2116, 0x2116, sal_uInt32(-1) };
1826*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-5.TXT> version
1827*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1828*b1cdbd2cSJim Jagielski 
1829*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO88596Ranges[]
1830*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA4, 0xA4, 0xAD, 0xAD, 0x60C, 0x60C, 0x61B, 0x61B,
1831*b1cdbd2cSJim Jagielski 			0x61F, 0x61F, 0x621, 0x63A, 0x640, 0x652, sal_uInt32(-1) };
1832*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-6.TXT> version
1833*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1834*b1cdbd2cSJim Jagielski 
1835*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO88597Ranges[]
1836*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA3, 0xA3, 0xA6, 0xA9, 0xAB, 0xAD, 0xB0, 0xB3,
1837*b1cdbd2cSJim Jagielski 			0xB7, 0xB7, 0xBB, 0xBB, 0xBD, 0xBD, 0x384, 0x386, 0x388, 0x38A,
1838*b1cdbd2cSJim Jagielski 			0x38C, 0x38C, 0x38E, 0x3A1, 0x3A3, 0x3CE, 0x2015, 0x2015,
1839*b1cdbd2cSJim Jagielski 			0x2018, 0x2019, sal_uInt32(-1) };
1840*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-7.TXT> version
1841*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1842*b1cdbd2cSJim Jagielski 
1843*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO88598Ranges[]
1844*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA2, 0xA9, 0xAB, 0xB9, 0xBB, 0xBE, 0xD7, 0xD7,
1845*b1cdbd2cSJim Jagielski 			0xF7, 0xF7, 0x5D0, 0x5EA, 0x200E, 0x200F, 0x2017, 0x2017,
1846*b1cdbd2cSJim Jagielski 			sal_uInt32(-1) };
1847*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-8.TXT> version
1848*b1cdbd2cSJim Jagielski 		// 1.1 of 2000-Jan-03
1849*b1cdbd2cSJim Jagielski 
1850*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO88599Ranges[]
1851*b1cdbd2cSJim Jagielski 		= { 0, 0xCF, 0xD1, 0xDC, 0xDF, 0xEF, 0xF1, 0xFC, 0xFF, 0xFF,
1852*b1cdbd2cSJim Jagielski 			0x11E, 0x11F, 0x130, 0x131, 0x15E, 0x15F, sal_uInt32(-1) };
1853*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-9.TXT> version
1854*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1855*b1cdbd2cSJim Jagielski 
1856*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO885910Ranges[]
1857*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA7, 0xA7, 0xAD, 0xAD, 0xB0, 0xB0, 0xB7, 0xB7,
1858*b1cdbd2cSJim Jagielski 			0xC1, 0xC6, 0xC9, 0xC9, 0xCB, 0xCB, 0xCD, 0xD0, 0xD3, 0xD6,
1859*b1cdbd2cSJim Jagielski 			0xD8, 0xD8, 0xDA, 0xDF, 0xE1, 0xE6, 0xE9, 0xE9, 0xEB, 0xEB,
1860*b1cdbd2cSJim Jagielski 			0xED, 0xF0, 0xF3, 0xF6, 0xF8, 0xF8, 0xFA, 0xFE, 0x100, 0x101,
1861*b1cdbd2cSJim Jagielski 			0x104, 0x105, 0x10C, 0x10D, 0x110, 0x113, 0x116, 0x119,
1862*b1cdbd2cSJim Jagielski 			0x122, 0x123, 0x128, 0x12B, 0x12E, 0x12F, 0x136, 0x138,
1863*b1cdbd2cSJim Jagielski 			0x13B, 0x13C, 0x145, 0x146, 0x14A, 0x14D, 0x160, 0x161,
1864*b1cdbd2cSJim Jagielski 			0x166, 0x16B, 0x172, 0x173, 0x17D, 0x17E, 0x2015, 0x2015,
1865*b1cdbd2cSJim Jagielski 			sal_uInt32(-1) };
1866*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-10.TXT> version
1867*b1cdbd2cSJim Jagielski 		// 1.1 of 1999 October 11
1868*b1cdbd2cSJim Jagielski 
1869*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO885913Ranges[]
1870*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA2, 0xA4, 0xA6, 0xA7, 0xA9, 0xA9, 0xAB, 0xAE,
1871*b1cdbd2cSJim Jagielski 			0xB0, 0xB3, 0xB5, 0xB7, 0xB9, 0xB9, 0xBB, 0xBE, 0xC4, 0xC6,
1872*b1cdbd2cSJim Jagielski 			0xC9, 0xC9, 0xD3, 0xD3, 0xD5, 0xD8, 0xDC, 0xDC, 0xDF, 0xDF,
1873*b1cdbd2cSJim Jagielski 			0xE4, 0xE6, 0xE9, 0xE9, 0xF3, 0xF3, 0xF5, 0xF8, 0xFC, 0xFC,
1874*b1cdbd2cSJim Jagielski 			0x100, 0x101, 0x104, 0x107, 0x10C, 0x10D, 0x112, 0x113,
1875*b1cdbd2cSJim Jagielski 			0x116, 0x119, 0x122, 0x123, 0x12A, 0x12B, 0x12E, 0x12F,
1876*b1cdbd2cSJim Jagielski 			0x136, 0x137, 0x13B, 0x13C, 0x141, 0x146, 0x14C, 0x14D,
1877*b1cdbd2cSJim Jagielski 			0x156, 0x157, 0x15A, 0x15B, 0x160, 0x161, 0x16A, 0x16B,
1878*b1cdbd2cSJim Jagielski 			0x172, 0x173, 0x179, 0x17E, 0x2019, 0x2019, 0x201C, 0x201E,
1879*b1cdbd2cSJim Jagielski 			sal_uInt32(-1) };
1880*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-13.TXT> version
1881*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1882*b1cdbd2cSJim Jagielski 
1883*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO885914Ranges[]
1884*b1cdbd2cSJim Jagielski 		= { 0, 0xA0, 0xA3, 0xA3, 0xA7, 0xA7, 0xA9, 0xA9, 0xAD, 0xAE,
1885*b1cdbd2cSJim Jagielski 			0xB6, 0xB6, 0xC0, 0xCF, 0xD1, 0xD6, 0xD8, 0xDD, 0xDF, 0xEF,
1886*b1cdbd2cSJim Jagielski 			0xF1, 0xF6, 0xF8, 0xFD, 0xFF, 0xFF, 0x10A, 0x10B, 0x120, 0x121,
1887*b1cdbd2cSJim Jagielski 			0x174, 0x178, 0x1E02, 0x1E03, 0x1E0A, 0x1E0B, 0x1E1E, 0x1E1F,
1888*b1cdbd2cSJim Jagielski 			0x1E40, 0x1E41, 0x1E56, 0x1E57, 0x1E60, 0x1E61, 0x1E6A, 0x1E6B,
1889*b1cdbd2cSJim Jagielski 			0x1E80, 0x1E85, 0x1EF2, 0x1EF3, sal_uInt32(-1) };
1890*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-14.TXT> version
1891*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1892*b1cdbd2cSJim Jagielski 
1893*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aISO885915Ranges[]
1894*b1cdbd2cSJim Jagielski 		= { 0, 0xA3, 0xA5, 0xA5, 0xA7, 0xA7, 0xA9, 0xB3, 0xB5, 0xB7,
1895*b1cdbd2cSJim Jagielski 			0xB9, 0xBB, 0xBF, 0xFF, 0x152, 0x153, 0x160, 0x161, 0x178, 0x178,
1896*b1cdbd2cSJim Jagielski 			0x17D, 0x17E, 0x20AC, 0x20AC, sal_uInt32(-1) };
1897*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-15.TXT> version
1898*b1cdbd2cSJim Jagielski 		// 1.0 of 1999 July 27
1899*b1cdbd2cSJim Jagielski 
1900*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aKOI8RRanges[]
1901*b1cdbd2cSJim Jagielski 		= { 0, 0x7F, 0xA0, 0xA0, 0xA9, 0xA9, 0xB0, 0xB0, 0xB2, 0xB2,
1902*b1cdbd2cSJim Jagielski 			0xB7, 0xB7, 0xF7, 0xF7, 0x401, 0x401, 0x410, 0x44F, 0x451, 0x451,
1903*b1cdbd2cSJim Jagielski 			0x2219, 0x221A, 0x2248, 0x2248, 0x2264, 0x2265, 0x2320, 0x2321,
1904*b1cdbd2cSJim Jagielski 			0x2500, 0x2500, 0x2502, 0x2502, 0x250C, 0x250C, 0x2510, 0x2510,
1905*b1cdbd2cSJim Jagielski 			0x2514, 0x2514, 0x2518, 0x2518, 0x251C, 0x251C, 0x2524, 0x2524,
1906*b1cdbd2cSJim Jagielski 			0x252C, 0x252C, 0x2534, 0x2534, 0x253C, 0x253C, 0x2550, 0x256C,
1907*b1cdbd2cSJim Jagielski 			0x2580, 0x2580, 0x2584, 0x2584, 0x2588, 0x2588, 0x258C, 0x258C,
1908*b1cdbd2cSJim Jagielski 			0x2590, 0x2593, 0x25A0, 0x25A0, sal_uInt32(-1) };
1909*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8-R.TXT>
1910*b1cdbd2cSJim Jagielski 		// version 1.0 of 18 August 1999
1911*b1cdbd2cSJim Jagielski 
1912*b1cdbd2cSJim Jagielski #if defined WNT
1913*b1cdbd2cSJim Jagielski 	static const sal_uInt32 aWindows1252Ranges[]
1914*b1cdbd2cSJim Jagielski 		= { 0, 0x7F, 0xA0, 0xFF, 0x152, 0x153, 0x160, 0x161, 0x178, 0x178,
1915*b1cdbd2cSJim Jagielski 			0x17D, 0x17E, 0x192, 0x192, 0x2C6, 0x2C6, 0x2DC, 0x2DC,
1916*b1cdbd2cSJim Jagielski 			0x2013, 0x2014, 0x2018, 0x201A, 0x201C, 0x201E, 0x2020, 0x2022,
1917*b1cdbd2cSJim Jagielski 			0x2026, 0x2026, 0x2030, 0x2030, 0x2039, 0x203A, 0x20AC, 0x20AC,
1918*b1cdbd2cSJim Jagielski 			0x2122, 0x2122, sal_uInt32(-1) };
1919*b1cdbd2cSJim Jagielski 		// <ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/
1920*b1cdbd2cSJim Jagielski 		// CP1252.TXT> version 2.01 of 04/15/98
1921*b1cdbd2cSJim Jagielski #endif // WNT
1922*b1cdbd2cSJim Jagielski 
1923*b1cdbd2cSJim Jagielski 	INetMIMECharsetList_Impl * pList = new INetMIMECharsetList_Impl;
1924*b1cdbd2cSJim Jagielski 	switch (eEncoding)
1925*b1cdbd2cSJim Jagielski 	{
1926*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_MS_1252:
1927*b1cdbd2cSJim Jagielski #if defined WNT
1928*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_MS_1252,
1929*b1cdbd2cSJim Jagielski 								   aWindows1252Ranges));
1930*b1cdbd2cSJim Jagielski #endif // WNT
1931*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_1:
1932*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_UTF7:
1933*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_UTF8:
1934*b1cdbd2cSJim Jagielski 			break;
1935*b1cdbd2cSJim Jagielski 
1936*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_2:
1937*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_2,
1938*b1cdbd2cSJim Jagielski 								   aISO88592Ranges));
1939*b1cdbd2cSJim Jagielski 			break;
1940*b1cdbd2cSJim Jagielski 
1941*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_3:
1942*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_3,
1943*b1cdbd2cSJim Jagielski 								   aISO88593Ranges));
1944*b1cdbd2cSJim Jagielski 			break;
1945*b1cdbd2cSJim Jagielski 
1946*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_4:
1947*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_4,
1948*b1cdbd2cSJim Jagielski 								   aISO88594Ranges));
1949*b1cdbd2cSJim Jagielski 			break;
1950*b1cdbd2cSJim Jagielski 
1951*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_5:
1952*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_5,
1953*b1cdbd2cSJim Jagielski 								   aISO88595Ranges));
1954*b1cdbd2cSJim Jagielski 			break;
1955*b1cdbd2cSJim Jagielski 
1956*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_6:
1957*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_6,
1958*b1cdbd2cSJim Jagielski 								   aISO88596Ranges));
1959*b1cdbd2cSJim Jagielski 			break;
1960*b1cdbd2cSJim Jagielski 
1961*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_7:
1962*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_7,
1963*b1cdbd2cSJim Jagielski 								   aISO88597Ranges));
1964*b1cdbd2cSJim Jagielski 			break;
1965*b1cdbd2cSJim Jagielski 
1966*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_8:
1967*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_8,
1968*b1cdbd2cSJim Jagielski 								   aISO88598Ranges));
1969*b1cdbd2cSJim Jagielski 			break;
1970*b1cdbd2cSJim Jagielski 
1971*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_9:
1972*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_9,
1973*b1cdbd2cSJim Jagielski 								   aISO88599Ranges));
1974*b1cdbd2cSJim Jagielski 			break;
1975*b1cdbd2cSJim Jagielski 
1976*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_10:
1977*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_10,
1978*b1cdbd2cSJim Jagielski 								   aISO885910Ranges));
1979*b1cdbd2cSJim Jagielski 			break;
1980*b1cdbd2cSJim Jagielski 
1981*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_13:
1982*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_13,
1983*b1cdbd2cSJim Jagielski 								   aISO885913Ranges));
1984*b1cdbd2cSJim Jagielski 			break;
1985*b1cdbd2cSJim Jagielski 
1986*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_14:
1987*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_14,
1988*b1cdbd2cSJim Jagielski 								   aISO885914Ranges));
1989*b1cdbd2cSJim Jagielski 			break;
1990*b1cdbd2cSJim Jagielski 
1991*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_ISO_8859_15:
1992*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_15,
1993*b1cdbd2cSJim Jagielski 								   aISO885915Ranges));
1994*b1cdbd2cSJim Jagielski 			break;
1995*b1cdbd2cSJim Jagielski 
1996*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_MS_1250:
1997*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_2,
1998*b1cdbd2cSJim Jagielski 								   aISO88592Ranges));
1999*b1cdbd2cSJim Jagielski 			break;
2000*b1cdbd2cSJim Jagielski 
2001*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_MS_1251:
2002*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_5,
2003*b1cdbd2cSJim Jagielski 								   aISO88595Ranges));
2004*b1cdbd2cSJim Jagielski 			break;
2005*b1cdbd2cSJim Jagielski 
2006*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_MS_1253:
2007*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_7,
2008*b1cdbd2cSJim Jagielski 								   aISO88597Ranges));
2009*b1cdbd2cSJim Jagielski 			break;
2010*b1cdbd2cSJim Jagielski 
2011*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_MS_1254:
2012*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_9,
2013*b1cdbd2cSJim Jagielski 								   aISO88599Ranges));
2014*b1cdbd2cSJim Jagielski 			break;
2015*b1cdbd2cSJim Jagielski 
2016*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_MS_1255:
2017*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_8,
2018*b1cdbd2cSJim Jagielski 								   aISO88598Ranges));
2019*b1cdbd2cSJim Jagielski 			break;
2020*b1cdbd2cSJim Jagielski 
2021*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_MS_1256:
2022*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_6,
2023*b1cdbd2cSJim Jagielski 								   aISO88596Ranges));
2024*b1cdbd2cSJim Jagielski 			break;
2025*b1cdbd2cSJim Jagielski 
2026*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_MS_1257:
2027*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_4,
2028*b1cdbd2cSJim Jagielski 								   aISO88594Ranges));
2029*b1cdbd2cSJim Jagielski 			break;
2030*b1cdbd2cSJim Jagielski 
2031*b1cdbd2cSJim Jagielski 		case RTL_TEXTENCODING_KOI8_R:
2032*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_5,
2033*b1cdbd2cSJim Jagielski 								   aISO88595Ranges));
2034*b1cdbd2cSJim Jagielski 			pList->prepend(Charset(RTL_TEXTENCODING_KOI8_R, aKOI8RRanges));
2035*b1cdbd2cSJim Jagielski 			break;
2036*b1cdbd2cSJim Jagielski 
2037*b1cdbd2cSJim Jagielski 		default: //@@@ more cases are missing!
2038*b1cdbd2cSJim Jagielski 			DBG_ERROR("INetMIME::createPreferredCharsetList():"
2039*b1cdbd2cSJim Jagielski 					      " Unsupported encoding");
2040*b1cdbd2cSJim Jagielski 			break;
2041*b1cdbd2cSJim Jagielski 	}
2042*b1cdbd2cSJim Jagielski 	pList->prepend(Charset(RTL_TEXTENCODING_ISO_8859_1, aISO88591Ranges));
2043*b1cdbd2cSJim Jagielski 	pList->prepend(Charset(RTL_TEXTENCODING_ASCII_US, aUSASCIIRanges));
2044*b1cdbd2cSJim Jagielski 	return pList;
2045*b1cdbd2cSJim Jagielski }
2046*b1cdbd2cSJim Jagielski 
2047*b1cdbd2cSJim Jagielski //============================================================================
2048*b1cdbd2cSJim Jagielski // static
convertToUnicode(const sal_Char * pBegin,const sal_Char * pEnd,rtl_TextEncoding eEncoding,sal_Size & rSize)2049*b1cdbd2cSJim Jagielski sal_Unicode * INetMIME::convertToUnicode(const sal_Char * pBegin,
2050*b1cdbd2cSJim Jagielski 										 const sal_Char * pEnd,
2051*b1cdbd2cSJim Jagielski 										 rtl_TextEncoding eEncoding,
2052*b1cdbd2cSJim Jagielski 										 sal_Size & rSize)
2053*b1cdbd2cSJim Jagielski {
2054*b1cdbd2cSJim Jagielski 	if (eEncoding == RTL_TEXTENCODING_DONTKNOW)
2055*b1cdbd2cSJim Jagielski 		return 0;
2056*b1cdbd2cSJim Jagielski 	rtl_TextToUnicodeConverter hConverter
2057*b1cdbd2cSJim Jagielski 		= rtl_createTextToUnicodeConverter(eEncoding);
2058*b1cdbd2cSJim Jagielski 	rtl_TextToUnicodeContext hContext
2059*b1cdbd2cSJim Jagielski 		= rtl_createTextToUnicodeContext(hConverter);
2060*b1cdbd2cSJim Jagielski 	sal_Unicode * pBuffer;
2061*b1cdbd2cSJim Jagielski 	sal_uInt32 nInfo;
2062*b1cdbd2cSJim Jagielski 	for (sal_Size nBufferSize = pEnd - pBegin;;
2063*b1cdbd2cSJim Jagielski 		 nBufferSize += nBufferSize / 3 + 1)
2064*b1cdbd2cSJim Jagielski 	{
2065*b1cdbd2cSJim Jagielski 		pBuffer = new sal_Unicode[nBufferSize];
2066*b1cdbd2cSJim Jagielski 		sal_Size nSrcCvtBytes;
2067*b1cdbd2cSJim Jagielski 		rSize = rtl_convertTextToUnicode(
2068*b1cdbd2cSJim Jagielski 			        hConverter, hContext, pBegin, pEnd - pBegin, pBuffer,
2069*b1cdbd2cSJim Jagielski 					nBufferSize,
2070*b1cdbd2cSJim Jagielski 					RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
2071*b1cdbd2cSJim Jagielski 					    | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
2072*b1cdbd2cSJim Jagielski 					    | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
2073*b1cdbd2cSJim Jagielski 					&nInfo, &nSrcCvtBytes);
2074*b1cdbd2cSJim Jagielski 		if (nInfo != RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
2075*b1cdbd2cSJim Jagielski 			break;
2076*b1cdbd2cSJim Jagielski 		delete[] pBuffer;
2077*b1cdbd2cSJim Jagielski 		rtl_resetTextToUnicodeContext(hConverter, hContext);
2078*b1cdbd2cSJim Jagielski 	}
2079*b1cdbd2cSJim Jagielski 	rtl_destroyTextToUnicodeContext(hConverter, hContext);
2080*b1cdbd2cSJim Jagielski 	rtl_destroyTextToUnicodeConverter(hConverter);
2081*b1cdbd2cSJim Jagielski 	if (nInfo != 0)
2082*b1cdbd2cSJim Jagielski 	{
2083*b1cdbd2cSJim Jagielski 		delete[] pBuffer;
2084*b1cdbd2cSJim Jagielski 		pBuffer = 0;
2085*b1cdbd2cSJim Jagielski 	}
2086*b1cdbd2cSJim Jagielski 	return pBuffer;
2087*b1cdbd2cSJim Jagielski }
2088*b1cdbd2cSJim Jagielski 
2089*b1cdbd2cSJim Jagielski //============================================================================
2090*b1cdbd2cSJim Jagielski // static
convertFromUnicode(const sal_Unicode * pBegin,const sal_Unicode * pEnd,rtl_TextEncoding eEncoding,sal_Size & rSize)2091*b1cdbd2cSJim Jagielski sal_Char * INetMIME::convertFromUnicode(const sal_Unicode * pBegin,
2092*b1cdbd2cSJim Jagielski 										const sal_Unicode * pEnd,
2093*b1cdbd2cSJim Jagielski 										rtl_TextEncoding eEncoding,
2094*b1cdbd2cSJim Jagielski 										sal_Size & rSize)
2095*b1cdbd2cSJim Jagielski {
2096*b1cdbd2cSJim Jagielski 	if (eEncoding == RTL_TEXTENCODING_DONTKNOW)
2097*b1cdbd2cSJim Jagielski 		return 0;
2098*b1cdbd2cSJim Jagielski 	rtl_UnicodeToTextConverter hConverter
2099*b1cdbd2cSJim Jagielski 		= rtl_createUnicodeToTextConverter(eEncoding);
2100*b1cdbd2cSJim Jagielski 	rtl_UnicodeToTextContext hContext
2101*b1cdbd2cSJim Jagielski 		= rtl_createUnicodeToTextContext(hConverter);
2102*b1cdbd2cSJim Jagielski 	sal_Char * pBuffer;
2103*b1cdbd2cSJim Jagielski 	sal_uInt32 nInfo;
2104*b1cdbd2cSJim Jagielski 	for (sal_Size nBufferSize = pEnd - pBegin;;
2105*b1cdbd2cSJim Jagielski 		 nBufferSize += nBufferSize / 3 + 1)
2106*b1cdbd2cSJim Jagielski 	{
2107*b1cdbd2cSJim Jagielski 		pBuffer = new sal_Char[nBufferSize];
2108*b1cdbd2cSJim Jagielski 		sal_Size nSrcCvtBytes;
2109*b1cdbd2cSJim Jagielski 		rSize = rtl_convertUnicodeToText(
2110*b1cdbd2cSJim Jagielski 			        hConverter, hContext, pBegin, pEnd - pBegin, pBuffer,
2111*b1cdbd2cSJim Jagielski 					nBufferSize,
2112*b1cdbd2cSJim Jagielski 					RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
2113*b1cdbd2cSJim Jagielski 					    | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR
2114*b1cdbd2cSJim Jagielski 					    | RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE
2115*b1cdbd2cSJim Jagielski 					    | RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR,
2116*b1cdbd2cSJim Jagielski 					&nInfo, &nSrcCvtBytes);
2117*b1cdbd2cSJim Jagielski 		if (nInfo != RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL)
2118*b1cdbd2cSJim Jagielski 			break;
2119*b1cdbd2cSJim Jagielski 		delete[] pBuffer;
2120*b1cdbd2cSJim Jagielski 		rtl_resetUnicodeToTextContext(hConverter, hContext);
2121*b1cdbd2cSJim Jagielski 	}
2122*b1cdbd2cSJim Jagielski 	rtl_destroyUnicodeToTextContext(hConverter, hContext);
2123*b1cdbd2cSJim Jagielski 	rtl_destroyUnicodeToTextConverter(hConverter);
2124*b1cdbd2cSJim Jagielski 	if (nInfo != 0)
2125*b1cdbd2cSJim Jagielski 	{
2126*b1cdbd2cSJim Jagielski 		delete[] pBuffer;
2127*b1cdbd2cSJim Jagielski 		pBuffer = 0;
2128*b1cdbd2cSJim Jagielski 	}
2129*b1cdbd2cSJim Jagielski 	return pBuffer;
2130*b1cdbd2cSJim Jagielski }
2131*b1cdbd2cSJim Jagielski 
2132*b1cdbd2cSJim Jagielski //============================================================================
2133*b1cdbd2cSJim Jagielski // static
writeUTF8(INetMIMEOutputSink & rSink,sal_uInt32 nChar)2134*b1cdbd2cSJim Jagielski void INetMIME::writeUTF8(INetMIMEOutputSink & rSink, sal_uInt32 nChar)
2135*b1cdbd2cSJim Jagielski {
2136*b1cdbd2cSJim Jagielski 	// See RFC 2279 for a discussion of UTF-8.
2137*b1cdbd2cSJim Jagielski 	DBG_ASSERT(nChar < 0x80000000, "INetMIME::writeUTF8(): Bad char");
2138*b1cdbd2cSJim Jagielski 
2139*b1cdbd2cSJim Jagielski 	if (nChar < 0x80)
2140*b1cdbd2cSJim Jagielski 		rSink << sal_Char(nChar);
2141*b1cdbd2cSJim Jagielski 	else if (nChar < 0x800)
2142*b1cdbd2cSJim Jagielski 		rSink << sal_Char(nChar >> 6 | 0xC0)
2143*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar & 0x3F) | 0x80);
2144*b1cdbd2cSJim Jagielski 	else if (nChar < 0x10000)
2145*b1cdbd2cSJim Jagielski 		rSink << sal_Char(nChar >> 12 | 0xE0)
2146*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 6 & 0x3F) | 0x80)
2147*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar & 0x3F) | 0x80);
2148*b1cdbd2cSJim Jagielski 	else if (nChar < 0x200000)
2149*b1cdbd2cSJim Jagielski 		rSink << sal_Char(nChar >> 18 | 0xF0)
2150*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 12 & 0x3F) | 0x80)
2151*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 6 & 0x3F) | 0x80)
2152*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar & 0x3F) | 0x80);
2153*b1cdbd2cSJim Jagielski 	else if (nChar < 0x4000000)
2154*b1cdbd2cSJim Jagielski 		rSink << sal_Char(nChar >> 24 | 0xF8)
2155*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 18 & 0x3F) | 0x80)
2156*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 12 & 0x3F) | 0x80)
2157*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 6 & 0x3F) | 0x80)
2158*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar & 0x3F) | 0x80);
2159*b1cdbd2cSJim Jagielski 	else
2160*b1cdbd2cSJim Jagielski 		rSink << sal_Char(nChar >> 30 | 0xFC)
2161*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 24 & 0x3F) | 0x80)
2162*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 18 & 0x3F) | 0x80)
2163*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 12 & 0x3F) | 0x80)
2164*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar >> 6 & 0x3F) | 0x80)
2165*b1cdbd2cSJim Jagielski 			  << sal_Char((nChar & 0x3F) | 0x80);
2166*b1cdbd2cSJim Jagielski }
2167*b1cdbd2cSJim Jagielski 
2168*b1cdbd2cSJim Jagielski //============================================================================
2169*b1cdbd2cSJim Jagielski // static
writeUnsigned(INetMIMEOutputSink & rSink,sal_uInt32 nValue,int nMinDigits)2170*b1cdbd2cSJim Jagielski void INetMIME::writeUnsigned(INetMIMEOutputSink & rSink, sal_uInt32 nValue,
2171*b1cdbd2cSJim Jagielski 							 int nMinDigits)
2172*b1cdbd2cSJim Jagielski {
2173*b1cdbd2cSJim Jagielski 	sal_Char aBuffer[10];
2174*b1cdbd2cSJim Jagielski 	    // max unsigned 32 bit value (4294967295) has 10 places
2175*b1cdbd2cSJim Jagielski 	sal_Char * p = aBuffer;
2176*b1cdbd2cSJim Jagielski 	for (; nValue > 0; nValue /= 10)
2177*b1cdbd2cSJim Jagielski 		*p++ = sal_Char(getDigit(nValue % 10));
2178*b1cdbd2cSJim Jagielski 	nMinDigits -= p - aBuffer;
2179*b1cdbd2cSJim Jagielski 	while (nMinDigits-- > 0)
2180*b1cdbd2cSJim Jagielski 		rSink << '0';
2181*b1cdbd2cSJim Jagielski 	while (p != aBuffer)
2182*b1cdbd2cSJim Jagielski 		rSink << *--p;
2183*b1cdbd2cSJim Jagielski }
2184*b1cdbd2cSJim Jagielski 
2185*b1cdbd2cSJim Jagielski //============================================================================
2186*b1cdbd2cSJim Jagielski // static
writeDateTime(INetMIMEOutputSink & rSink,const DateTime & rUTC)2187*b1cdbd2cSJim Jagielski void INetMIME::writeDateTime(INetMIMEOutputSink & rSink,
2188*b1cdbd2cSJim Jagielski 							 const DateTime & rUTC)
2189*b1cdbd2cSJim Jagielski {
2190*b1cdbd2cSJim Jagielski 	static const sal_Char aDay[7][3]
2191*b1cdbd2cSJim Jagielski 		= { { 'M', 'o', 'n' },
2192*b1cdbd2cSJim Jagielski 			{ 'T', 'u', 'e' },
2193*b1cdbd2cSJim Jagielski 			{ 'W', 'e', 'd' },
2194*b1cdbd2cSJim Jagielski 			{ 'T', 'h', 'u' },
2195*b1cdbd2cSJim Jagielski 			{ 'F', 'r', 'i' },
2196*b1cdbd2cSJim Jagielski 			{ 'S', 'a', 't' },
2197*b1cdbd2cSJim Jagielski 			{ 'S', 'u', 'n' } };
2198*b1cdbd2cSJim Jagielski 	const sal_Char * pTheDay = aDay[rUTC.GetDayOfWeek()];
2199*b1cdbd2cSJim Jagielski 	rSink.write(pTheDay, pTheDay + 3);
2200*b1cdbd2cSJim Jagielski 	rSink << ", ";
2201*b1cdbd2cSJim Jagielski 	writeUnsigned(rSink, rUTC.GetDay());
2202*b1cdbd2cSJim Jagielski 	rSink << ' ';
2203*b1cdbd2cSJim Jagielski 	static const sal_Char aMonth[12][3]
2204*b1cdbd2cSJim Jagielski 		= { { 'J', 'a', 'n' },
2205*b1cdbd2cSJim Jagielski 			{ 'F', 'e', 'b' },
2206*b1cdbd2cSJim Jagielski 			{ 'M', 'a', 'r' },
2207*b1cdbd2cSJim Jagielski 			{ 'A', 'p', 'r' },
2208*b1cdbd2cSJim Jagielski 			{ 'M', 'a', 'y' },
2209*b1cdbd2cSJim Jagielski 			{ 'J', 'u', 'n' },
2210*b1cdbd2cSJim Jagielski 			{ 'J', 'u', 'l' },
2211*b1cdbd2cSJim Jagielski 			{ 'A', 'u', 'g' },
2212*b1cdbd2cSJim Jagielski 			{ 'S', 'e', 'p' },
2213*b1cdbd2cSJim Jagielski 			{ 'O', 'c', 't' },
2214*b1cdbd2cSJim Jagielski 			{ 'N', 'o', 'v' },
2215*b1cdbd2cSJim Jagielski 			{ 'D', 'e', 'c' } };
2216*b1cdbd2cSJim Jagielski 	const sal_Char * pTheMonth = aMonth[rUTC.GetMonth() - 1];
2217*b1cdbd2cSJim Jagielski 	rSink.write(pTheMonth, pTheMonth + 3);
2218*b1cdbd2cSJim Jagielski 	rSink << ' ';
2219*b1cdbd2cSJim Jagielski 	writeUnsigned(rSink, rUTC.GetYear());
2220*b1cdbd2cSJim Jagielski 	rSink << ' ';
2221*b1cdbd2cSJim Jagielski 	writeUnsigned(rSink, rUTC.GetHour(), 2);
2222*b1cdbd2cSJim Jagielski 	rSink << ':';
2223*b1cdbd2cSJim Jagielski 	writeUnsigned(rSink, rUTC.GetMin(), 2);
2224*b1cdbd2cSJim Jagielski 	rSink << ':';
2225*b1cdbd2cSJim Jagielski 	writeUnsigned(rSink, rUTC.GetSec(), 2);
2226*b1cdbd2cSJim Jagielski 	rSink << " +0000";
2227*b1cdbd2cSJim Jagielski }
2228*b1cdbd2cSJim Jagielski 
2229*b1cdbd2cSJim Jagielski //============================================================================
2230*b1cdbd2cSJim Jagielski // static
writeHeaderFieldBody(INetMIMEOutputSink & rSink,HeaderFieldType eType,const ByteString & rBody,rtl_TextEncoding ePreferredEncoding,bool bInitialSpace)2231*b1cdbd2cSJim Jagielski void INetMIME::writeHeaderFieldBody(INetMIMEOutputSink & rSink,
2232*b1cdbd2cSJim Jagielski 									HeaderFieldType eType,
2233*b1cdbd2cSJim Jagielski 									const ByteString & rBody,
2234*b1cdbd2cSJim Jagielski 									rtl_TextEncoding ePreferredEncoding,
2235*b1cdbd2cSJim Jagielski 									bool bInitialSpace)
2236*b1cdbd2cSJim Jagielski {
2237*b1cdbd2cSJim Jagielski 	writeHeaderFieldBody(rSink, eType,
2238*b1cdbd2cSJim Jagielski 						 UniString(rBody, RTL_TEXTENCODING_UTF8),
2239*b1cdbd2cSJim Jagielski 						 ePreferredEncoding, bInitialSpace);
2240*b1cdbd2cSJim Jagielski }
2241*b1cdbd2cSJim Jagielski 
2242*b1cdbd2cSJim Jagielski //============================================================================
2243*b1cdbd2cSJim Jagielski // static
writeHeaderFieldBody(INetMIMEOutputSink & rSink,HeaderFieldType eType,const UniString & rBody,rtl_TextEncoding ePreferredEncoding,bool bInitialSpace)2244*b1cdbd2cSJim Jagielski void INetMIME::writeHeaderFieldBody(INetMIMEOutputSink & rSink,
2245*b1cdbd2cSJim Jagielski 									HeaderFieldType eType,
2246*b1cdbd2cSJim Jagielski 									const UniString & rBody,
2247*b1cdbd2cSJim Jagielski 									rtl_TextEncoding ePreferredEncoding,
2248*b1cdbd2cSJim Jagielski 									bool bInitialSpace)
2249*b1cdbd2cSJim Jagielski {
2250*b1cdbd2cSJim Jagielski 	if (eType == HEADER_FIELD_TEXT)
2251*b1cdbd2cSJim Jagielski 	{
2252*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink
2253*b1cdbd2cSJim Jagielski 			aOutput(rSink, INetMIMEEncodedWordOutputSink::CONTEXT_TEXT,
2254*b1cdbd2cSJim Jagielski 					bInitialSpace ?
2255*b1cdbd2cSJim Jagielski 					    INetMIMEEncodedWordOutputSink::SPACE_ALWAYS :
2256*b1cdbd2cSJim Jagielski 					    INetMIMEEncodedWordOutputSink::SPACE_NO,
2257*b1cdbd2cSJim Jagielski 					ePreferredEncoding);
2258*b1cdbd2cSJim Jagielski 		aOutput.write(rBody.GetBuffer(), rBody.GetBuffer() + rBody.Len());
2259*b1cdbd2cSJim Jagielski 		aOutput.flush();
2260*b1cdbd2cSJim Jagielski 	}
2261*b1cdbd2cSJim Jagielski 	else
2262*b1cdbd2cSJim Jagielski 	{
2263*b1cdbd2cSJim Jagielski 		enum Brackets { BRACKETS_OUTSIDE, BRACKETS_OPENING, BRACKETS_INSIDE };
2264*b1cdbd2cSJim Jagielski 		Brackets eBrackets = BRACKETS_OUTSIDE;
2265*b1cdbd2cSJim Jagielski 
2266*b1cdbd2cSJim Jagielski 		const sal_Unicode * pBodyPtr = rBody.GetBuffer();
2267*b1cdbd2cSJim Jagielski 		const sal_Unicode * pBodyEnd = pBodyPtr + rBody.Len();
2268*b1cdbd2cSJim Jagielski 		while (pBodyPtr != pBodyEnd)
2269*b1cdbd2cSJim Jagielski 			switch (*pBodyPtr)
2270*b1cdbd2cSJim Jagielski 			{
2271*b1cdbd2cSJim Jagielski 				case '\t':
2272*b1cdbd2cSJim Jagielski 				case ' ':
2273*b1cdbd2cSJim Jagielski 					// A WSP adds to accumulated space:
2274*b1cdbd2cSJim Jagielski 					bInitialSpace = true;
2275*b1cdbd2cSJim Jagielski 					++pBodyPtr;
2276*b1cdbd2cSJim Jagielski 					break;
2277*b1cdbd2cSJim Jagielski 
2278*b1cdbd2cSJim Jagielski 				case '(':
2279*b1cdbd2cSJim Jagielski 				{
2280*b1cdbd2cSJim Jagielski 					// Write a pending '<' if necessary:
2281*b1cdbd2cSJim Jagielski 					if (eBrackets == BRACKETS_OPENING)
2282*b1cdbd2cSJim Jagielski 					{
2283*b1cdbd2cSJim Jagielski 						if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
2284*b1cdbd2cSJim Jagielski 							    >= rSink.getLineLengthLimit())
2285*b1cdbd2cSJim Jagielski 							rSink << INetMIMEOutputSink::endl << ' ';
2286*b1cdbd2cSJim Jagielski 						else if (bInitialSpace)
2287*b1cdbd2cSJim Jagielski 							rSink << ' ';
2288*b1cdbd2cSJim Jagielski 						rSink << '<';
2289*b1cdbd2cSJim Jagielski 						bInitialSpace = false;
2290*b1cdbd2cSJim Jagielski 						eBrackets = BRACKETS_INSIDE;
2291*b1cdbd2cSJim Jagielski 					}
2292*b1cdbd2cSJim Jagielski 
2293*b1cdbd2cSJim Jagielski 					// Write the comment, introducing encoded-words where
2294*b1cdbd2cSJim Jagielski 					// necessary:
2295*b1cdbd2cSJim Jagielski 					int nLevel = 0;
2296*b1cdbd2cSJim Jagielski 					INetMIMEEncodedWordOutputSink
2297*b1cdbd2cSJim Jagielski 						aOutput(
2298*b1cdbd2cSJim Jagielski 							rSink,
2299*b1cdbd2cSJim Jagielski 							INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT,
2300*b1cdbd2cSJim Jagielski 							INetMIMEEncodedWordOutputSink::SPACE_NO,
2301*b1cdbd2cSJim Jagielski 							ePreferredEncoding);
2302*b1cdbd2cSJim Jagielski 					while (pBodyPtr != pBodyEnd)
2303*b1cdbd2cSJim Jagielski 						switch (*pBodyPtr)
2304*b1cdbd2cSJim Jagielski 						{
2305*b1cdbd2cSJim Jagielski 							case '(':
2306*b1cdbd2cSJim Jagielski 								aOutput.flush();
2307*b1cdbd2cSJim Jagielski 								if (rSink.getColumn()
2308*b1cdbd2cSJim Jagielski 									        + (bInitialSpace ? 1 : 0)
2309*b1cdbd2cSJim Jagielski 									    >= rSink.getLineLengthLimit())
2310*b1cdbd2cSJim Jagielski 									rSink << INetMIMEOutputSink::endl << ' ';
2311*b1cdbd2cSJim Jagielski 								else if (bInitialSpace)
2312*b1cdbd2cSJim Jagielski 									rSink << ' ';
2313*b1cdbd2cSJim Jagielski 								rSink << '(';
2314*b1cdbd2cSJim Jagielski 								bInitialSpace = false;
2315*b1cdbd2cSJim Jagielski 								++nLevel;
2316*b1cdbd2cSJim Jagielski 								++pBodyPtr;
2317*b1cdbd2cSJim Jagielski 								break;
2318*b1cdbd2cSJim Jagielski 
2319*b1cdbd2cSJim Jagielski 							case ')':
2320*b1cdbd2cSJim Jagielski 								aOutput.flush();
2321*b1cdbd2cSJim Jagielski 								if (rSink.getColumn()
2322*b1cdbd2cSJim Jagielski 									    >= rSink.getLineLengthLimit())
2323*b1cdbd2cSJim Jagielski 									rSink << INetMIMEOutputSink::endl << ' ';
2324*b1cdbd2cSJim Jagielski 								rSink << ')';
2325*b1cdbd2cSJim Jagielski 								++pBodyPtr;
2326*b1cdbd2cSJim Jagielski 								if (--nLevel == 0)
2327*b1cdbd2cSJim Jagielski 									goto comment_done;
2328*b1cdbd2cSJim Jagielski 								break;
2329*b1cdbd2cSJim Jagielski 
2330*b1cdbd2cSJim Jagielski 							case '\\':
2331*b1cdbd2cSJim Jagielski 								if (++pBodyPtr == pBodyEnd)
2332*b1cdbd2cSJim Jagielski 									break;
2333*b1cdbd2cSJim Jagielski 							default:
2334*b1cdbd2cSJim Jagielski 								aOutput << *pBodyPtr++;
2335*b1cdbd2cSJim Jagielski 								break;
2336*b1cdbd2cSJim Jagielski 						}
2337*b1cdbd2cSJim Jagielski 				comment_done:
2338*b1cdbd2cSJim Jagielski 					break;
2339*b1cdbd2cSJim Jagielski 				}
2340*b1cdbd2cSJim Jagielski 
2341*b1cdbd2cSJim Jagielski 				case '<':
2342*b1cdbd2cSJim Jagielski 					// Write an already pending '<' if necessary:
2343*b1cdbd2cSJim Jagielski 					if (eBrackets == BRACKETS_OPENING)
2344*b1cdbd2cSJim Jagielski 					{
2345*b1cdbd2cSJim Jagielski 						if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
2346*b1cdbd2cSJim Jagielski 							    >= rSink.getLineLengthLimit())
2347*b1cdbd2cSJim Jagielski 							rSink << INetMIMEOutputSink::endl << ' ';
2348*b1cdbd2cSJim Jagielski 						else if (bInitialSpace)
2349*b1cdbd2cSJim Jagielski 							rSink << ' ';
2350*b1cdbd2cSJim Jagielski 						rSink << '<';
2351*b1cdbd2cSJim Jagielski 						bInitialSpace = false;
2352*b1cdbd2cSJim Jagielski 					}
2353*b1cdbd2cSJim Jagielski 
2354*b1cdbd2cSJim Jagielski 					// Remember this '<' as pending, and open a bracketed
2355*b1cdbd2cSJim Jagielski 					// block:
2356*b1cdbd2cSJim Jagielski 					eBrackets = BRACKETS_OPENING;
2357*b1cdbd2cSJim Jagielski 					++pBodyPtr;
2358*b1cdbd2cSJim Jagielski 					break;
2359*b1cdbd2cSJim Jagielski 
2360*b1cdbd2cSJim Jagielski 				case '>':
2361*b1cdbd2cSJim Jagielski 					// Write a pending '<' if necessary:
2362*b1cdbd2cSJim Jagielski 					if (eBrackets == BRACKETS_OPENING)
2363*b1cdbd2cSJim Jagielski 					{
2364*b1cdbd2cSJim Jagielski 						if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
2365*b1cdbd2cSJim Jagielski 							    >= rSink.getLineLengthLimit())
2366*b1cdbd2cSJim Jagielski 							rSink << INetMIMEOutputSink::endl << ' ';
2367*b1cdbd2cSJim Jagielski 						else if (bInitialSpace)
2368*b1cdbd2cSJim Jagielski 							rSink << ' ';
2369*b1cdbd2cSJim Jagielski 						rSink << '<';
2370*b1cdbd2cSJim Jagielski 						bInitialSpace = false;
2371*b1cdbd2cSJim Jagielski 					}
2372*b1cdbd2cSJim Jagielski 
2373*b1cdbd2cSJim Jagielski 					// Write this '>', and close any bracketed block:
2374*b1cdbd2cSJim Jagielski 					if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
2375*b1cdbd2cSJim Jagielski 						    >= rSink.getLineLengthLimit())
2376*b1cdbd2cSJim Jagielski 						rSink << INetMIMEOutputSink::endl << ' ';
2377*b1cdbd2cSJim Jagielski 					else if (bInitialSpace)
2378*b1cdbd2cSJim Jagielski 						rSink << ' ';
2379*b1cdbd2cSJim Jagielski 					rSink << '>';
2380*b1cdbd2cSJim Jagielski 					bInitialSpace = false;
2381*b1cdbd2cSJim Jagielski 					eBrackets = BRACKETS_OUTSIDE;
2382*b1cdbd2cSJim Jagielski 					++pBodyPtr;
2383*b1cdbd2cSJim Jagielski 					break;
2384*b1cdbd2cSJim Jagielski 
2385*b1cdbd2cSJim Jagielski 				case ',':
2386*b1cdbd2cSJim Jagielski 				case ':':
2387*b1cdbd2cSJim Jagielski 				case ';':
2388*b1cdbd2cSJim Jagielski 				case '\\':
2389*b1cdbd2cSJim Jagielski 				case ']':
2390*b1cdbd2cSJim Jagielski 					// Write a pending '<' if necessary:
2391*b1cdbd2cSJim Jagielski 					if (eBrackets == BRACKETS_OPENING)
2392*b1cdbd2cSJim Jagielski 					{
2393*b1cdbd2cSJim Jagielski 						if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
2394*b1cdbd2cSJim Jagielski 							    >= rSink.getLineLengthLimit())
2395*b1cdbd2cSJim Jagielski 							rSink << INetMIMEOutputSink::endl << ' ';
2396*b1cdbd2cSJim Jagielski 						else if (bInitialSpace)
2397*b1cdbd2cSJim Jagielski 							rSink << ' ';
2398*b1cdbd2cSJim Jagielski 						rSink << '<';
2399*b1cdbd2cSJim Jagielski 						bInitialSpace = false;
2400*b1cdbd2cSJim Jagielski 						eBrackets = BRACKETS_INSIDE;
2401*b1cdbd2cSJim Jagielski 					}
2402*b1cdbd2cSJim Jagielski 
2403*b1cdbd2cSJim Jagielski 					// Write this specials:
2404*b1cdbd2cSJim Jagielski 					if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
2405*b1cdbd2cSJim Jagielski 						    >= rSink.getLineLengthLimit())
2406*b1cdbd2cSJim Jagielski 						rSink << INetMIMEOutputSink::endl << ' ';
2407*b1cdbd2cSJim Jagielski 					else if (bInitialSpace)
2408*b1cdbd2cSJim Jagielski 						rSink << ' ';
2409*b1cdbd2cSJim Jagielski 					rSink << sal_Char(*pBodyPtr++);
2410*b1cdbd2cSJim Jagielski 					bInitialSpace = false;
2411*b1cdbd2cSJim Jagielski 					break;
2412*b1cdbd2cSJim Jagielski 
2413*b1cdbd2cSJim Jagielski 				case '\x0D': // CR
2414*b1cdbd2cSJim Jagielski 					// A <CRLF WSP> adds to accumulated space, a <CR> not
2415*b1cdbd2cSJim Jagielski 					// followed by <LF WSP> starts 'junk':
2416*b1cdbd2cSJim Jagielski 					if (startsWithLineFolding(pBodyPtr, pBodyEnd))
2417*b1cdbd2cSJim Jagielski 					{
2418*b1cdbd2cSJim Jagielski 						bInitialSpace = true;
2419*b1cdbd2cSJim Jagielski 						pBodyPtr += 3;
2420*b1cdbd2cSJim Jagielski 						break;
2421*b1cdbd2cSJim Jagielski 					}
2422*b1cdbd2cSJim Jagielski 				default:
2423*b1cdbd2cSJim Jagielski 				{
2424*b1cdbd2cSJim Jagielski 					// The next token is either one of <"." / "@" / atom /
2425*b1cdbd2cSJim Jagielski 					// quoted-string / domain-literal>, or it's 'junk'; if it
2426*b1cdbd2cSJim Jagielski 					// is not 'junk', it is either a 'phrase' (i.e., it may
2427*b1cdbd2cSJim Jagielski 					// contain encoded-words) or a 'non-phrase' (i.e., it may
2428*b1cdbd2cSJim Jagielski 					// not contain encoded-words):
2429*b1cdbd2cSJim Jagielski 					enum Entity { ENTITY_JUNK, ENTITY_NON_PHRASE,
2430*b1cdbd2cSJim Jagielski 								  ENTITY_PHRASE };
2431*b1cdbd2cSJim Jagielski 					Entity eEntity = ENTITY_JUNK;
2432*b1cdbd2cSJim Jagielski 					switch (*pBodyPtr)
2433*b1cdbd2cSJim Jagielski 					{
2434*b1cdbd2cSJim Jagielski 						case '.':
2435*b1cdbd2cSJim Jagielski 						case '@':
2436*b1cdbd2cSJim Jagielski 						case '[':
2437*b1cdbd2cSJim Jagielski 							// A token of <"." / "@" / domain-literal> always
2438*b1cdbd2cSJim Jagielski 							// starts a 'non-phrase':
2439*b1cdbd2cSJim Jagielski 							eEntity = ENTITY_NON_PHRASE;
2440*b1cdbd2cSJim Jagielski 							break;
2441*b1cdbd2cSJim Jagielski 
2442*b1cdbd2cSJim Jagielski 						default:
2443*b1cdbd2cSJim Jagielski 							if (isUSASCII(*pBodyPtr)
2444*b1cdbd2cSJim Jagielski 								&& !isAtomChar(*pBodyPtr))
2445*b1cdbd2cSJim Jagielski 							{
2446*b1cdbd2cSJim Jagielski 								eEntity = ENTITY_JUNK;
2447*b1cdbd2cSJim Jagielski 								break;
2448*b1cdbd2cSJim Jagielski 							}
2449*b1cdbd2cSJim Jagielski 						case '"':
2450*b1cdbd2cSJim Jagielski 							// A token of <atom / quoted-string> can either be
2451*b1cdbd2cSJim Jagielski 							// a 'phrase' or a 'non-phrase':
2452*b1cdbd2cSJim Jagielski 							switch (eType)
2453*b1cdbd2cSJim Jagielski 							{
2454*b1cdbd2cSJim Jagielski 								case HEADER_FIELD_STRUCTURED:
2455*b1cdbd2cSJim Jagielski 									eEntity = ENTITY_NON_PHRASE;
2456*b1cdbd2cSJim Jagielski 									break;
2457*b1cdbd2cSJim Jagielski 
2458*b1cdbd2cSJim Jagielski 								case HEADER_FIELD_PHRASE:
2459*b1cdbd2cSJim Jagielski 									eEntity = ENTITY_PHRASE;
2460*b1cdbd2cSJim Jagielski 									break;
2461*b1cdbd2cSJim Jagielski 
2462*b1cdbd2cSJim Jagielski 								case HEADER_FIELD_MESSAGE_ID:
2463*b1cdbd2cSJim Jagielski 									// A 'phrase' if and only if outside any
2464*b1cdbd2cSJim Jagielski 									// bracketed block:
2465*b1cdbd2cSJim Jagielski 									eEntity
2466*b1cdbd2cSJim Jagielski 										= eBrackets == BRACKETS_OUTSIDE ?
2467*b1cdbd2cSJim Jagielski 									          ENTITY_PHRASE :
2468*b1cdbd2cSJim Jagielski 											  ENTITY_NON_PHRASE;
2469*b1cdbd2cSJim Jagielski 									break;
2470*b1cdbd2cSJim Jagielski 
2471*b1cdbd2cSJim Jagielski 								case HEADER_FIELD_ADDRESS:
2472*b1cdbd2cSJim Jagielski 								{
2473*b1cdbd2cSJim Jagielski 									// A 'non-phrase' if and only if, after
2474*b1cdbd2cSJim Jagielski 									// skipping this token and any following
2475*b1cdbd2cSJim Jagielski 									// <linear-white-space> and <comment>s,
2476*b1cdbd2cSJim Jagielski 									// there is no token left, or the next
2477*b1cdbd2cSJim Jagielski 									// token is any of <"." / "@" / ">" / ","
2478*b1cdbd2cSJim Jagielski 									// / ";">, or the next token is <":"> and
2479*b1cdbd2cSJim Jagielski 									// is within a bracketed block:
2480*b1cdbd2cSJim Jagielski 									const sal_Unicode * pLookAhead = pBodyPtr;
2481*b1cdbd2cSJim Jagielski 									if (*pLookAhead == '"')
2482*b1cdbd2cSJim Jagielski 									{
2483*b1cdbd2cSJim Jagielski 										pLookAhead
2484*b1cdbd2cSJim Jagielski 											= skipQuotedString(pLookAhead,
2485*b1cdbd2cSJim Jagielski 															   pBodyEnd);
2486*b1cdbd2cSJim Jagielski 										if (pLookAhead == pBodyPtr)
2487*b1cdbd2cSJim Jagielski 											pLookAhead = pBodyEnd;
2488*b1cdbd2cSJim Jagielski 									}
2489*b1cdbd2cSJim Jagielski 									else
2490*b1cdbd2cSJim Jagielski 										while (pLookAhead != pBodyEnd
2491*b1cdbd2cSJim Jagielski 											   && (isAtomChar(*pLookAhead)
2492*b1cdbd2cSJim Jagielski 												   || !isUSASCII(
2493*b1cdbd2cSJim Jagielski 													       *pLookAhead)))
2494*b1cdbd2cSJim Jagielski 											++pLookAhead;
2495*b1cdbd2cSJim Jagielski 									while (pLookAhead != pBodyEnd)
2496*b1cdbd2cSJim Jagielski 										switch (*pLookAhead)
2497*b1cdbd2cSJim Jagielski 										{
2498*b1cdbd2cSJim Jagielski 											case '\t':
2499*b1cdbd2cSJim Jagielski 											case ' ':
2500*b1cdbd2cSJim Jagielski 												++pLookAhead;
2501*b1cdbd2cSJim Jagielski 												break;
2502*b1cdbd2cSJim Jagielski 
2503*b1cdbd2cSJim Jagielski 											case '(':
2504*b1cdbd2cSJim Jagielski 											{
2505*b1cdbd2cSJim Jagielski 												const sal_Unicode * pPast
2506*b1cdbd2cSJim Jagielski 													= skipComment(pLookAhead,
2507*b1cdbd2cSJim Jagielski 																  pBodyEnd);
2508*b1cdbd2cSJim Jagielski 												pLookAhead
2509*b1cdbd2cSJim Jagielski 													= pPast == pLookAhead ?
2510*b1cdbd2cSJim Jagielski 													      pBodyEnd : pPast;
2511*b1cdbd2cSJim Jagielski 												break;
2512*b1cdbd2cSJim Jagielski 											}
2513*b1cdbd2cSJim Jagielski 
2514*b1cdbd2cSJim Jagielski 											case ',':
2515*b1cdbd2cSJim Jagielski 											case '.':
2516*b1cdbd2cSJim Jagielski 											case ';':
2517*b1cdbd2cSJim Jagielski 											case '>':
2518*b1cdbd2cSJim Jagielski 											case '@':
2519*b1cdbd2cSJim Jagielski 												eEntity = ENTITY_NON_PHRASE;
2520*b1cdbd2cSJim Jagielski 												goto entity_determined;
2521*b1cdbd2cSJim Jagielski 
2522*b1cdbd2cSJim Jagielski 											case ':':
2523*b1cdbd2cSJim Jagielski 												eEntity
2524*b1cdbd2cSJim Jagielski 													= eBrackets
2525*b1cdbd2cSJim Jagielski 													     == BRACKETS_OUTSIDE ?
2526*b1cdbd2cSJim Jagielski 												          ENTITY_PHRASE :
2527*b1cdbd2cSJim Jagielski 														  ENTITY_NON_PHRASE;
2528*b1cdbd2cSJim Jagielski 												goto entity_determined;
2529*b1cdbd2cSJim Jagielski 
2530*b1cdbd2cSJim Jagielski 											case '\x0D': // CR
2531*b1cdbd2cSJim Jagielski 												if (startsWithLineFolding(
2532*b1cdbd2cSJim Jagielski 													    pLookAhead, pBodyEnd))
2533*b1cdbd2cSJim Jagielski 												{
2534*b1cdbd2cSJim Jagielski 													pLookAhead += 3;
2535*b1cdbd2cSJim Jagielski 													break;
2536*b1cdbd2cSJim Jagielski 												}
2537*b1cdbd2cSJim Jagielski 											default:
2538*b1cdbd2cSJim Jagielski 												eEntity = ENTITY_PHRASE;
2539*b1cdbd2cSJim Jagielski 												goto entity_determined;
2540*b1cdbd2cSJim Jagielski 										}
2541*b1cdbd2cSJim Jagielski 									eEntity = ENTITY_NON_PHRASE;
2542*b1cdbd2cSJim Jagielski 								entity_determined:
2543*b1cdbd2cSJim Jagielski 									break;
2544*b1cdbd2cSJim Jagielski 								}
2545*b1cdbd2cSJim Jagielski 
2546*b1cdbd2cSJim Jagielski                                 case HEADER_FIELD_TEXT:
2547*b1cdbd2cSJim Jagielski                                     OSL_ASSERT(false);
2548*b1cdbd2cSJim Jagielski                                     break;
2549*b1cdbd2cSJim Jagielski 							}
2550*b1cdbd2cSJim Jagielski 
2551*b1cdbd2cSJim Jagielski 							// In a 'non-phrase', a non-US-ASCII character
2552*b1cdbd2cSJim Jagielski 							// cannot be part of an <atom>, but instead the
2553*b1cdbd2cSJim Jagielski 							// whole entity is 'junk' rather than 'non-
2554*b1cdbd2cSJim Jagielski 							// phrase':
2555*b1cdbd2cSJim Jagielski 							if (eEntity == ENTITY_NON_PHRASE
2556*b1cdbd2cSJim Jagielski 								&& !isUSASCII(*pBodyPtr))
2557*b1cdbd2cSJim Jagielski 								eEntity = ENTITY_JUNK;
2558*b1cdbd2cSJim Jagielski 							break;
2559*b1cdbd2cSJim Jagielski 					}
2560*b1cdbd2cSJim Jagielski 
2561*b1cdbd2cSJim Jagielski 					switch (eEntity)
2562*b1cdbd2cSJim Jagielski 					{
2563*b1cdbd2cSJim Jagielski 						case ENTITY_JUNK:
2564*b1cdbd2cSJim Jagielski 						{
2565*b1cdbd2cSJim Jagielski 							// Write a pending '<' if necessary:
2566*b1cdbd2cSJim Jagielski 							if (eBrackets == BRACKETS_OPENING)
2567*b1cdbd2cSJim Jagielski 							{
2568*b1cdbd2cSJim Jagielski 								if (rSink.getColumn()
2569*b1cdbd2cSJim Jagielski 									        + (bInitialSpace ? 1 : 0)
2570*b1cdbd2cSJim Jagielski 									    >= rSink.getLineLengthLimit())
2571*b1cdbd2cSJim Jagielski 									rSink << INetMIMEOutputSink::endl << ' ';
2572*b1cdbd2cSJim Jagielski 								else if (bInitialSpace)
2573*b1cdbd2cSJim Jagielski 									rSink << ' ';
2574*b1cdbd2cSJim Jagielski 								rSink << '<';
2575*b1cdbd2cSJim Jagielski 								bInitialSpace = false;
2576*b1cdbd2cSJim Jagielski 								eBrackets = BRACKETS_INSIDE;
2577*b1cdbd2cSJim Jagielski 							}
2578*b1cdbd2cSJim Jagielski 
2579*b1cdbd2cSJim Jagielski 							// Calculate the length of in- and output:
2580*b1cdbd2cSJim Jagielski 							const sal_Unicode * pStart = pBodyPtr;
2581*b1cdbd2cSJim Jagielski 							sal_Size nLength = 0;
2582*b1cdbd2cSJim Jagielski 							bool bModify = false;
2583*b1cdbd2cSJim Jagielski 							bool bEnd = false;
2584*b1cdbd2cSJim Jagielski 							while (pBodyPtr != pBodyEnd && !bEnd)
2585*b1cdbd2cSJim Jagielski 								switch (*pBodyPtr)
2586*b1cdbd2cSJim Jagielski 								{
2587*b1cdbd2cSJim Jagielski 									case '\x0D': // CR
2588*b1cdbd2cSJim Jagielski 										if (startsWithLineFolding(pBodyPtr,
2589*b1cdbd2cSJim Jagielski 																  pBodyEnd))
2590*b1cdbd2cSJim Jagielski 											bEnd = true;
2591*b1cdbd2cSJim Jagielski 										else if (startsWithLineBreak(
2592*b1cdbd2cSJim Jagielski 											         pBodyPtr, pBodyEnd))
2593*b1cdbd2cSJim Jagielski 										{
2594*b1cdbd2cSJim Jagielski 											nLength += 3;
2595*b1cdbd2cSJim Jagielski 											bModify = true;
2596*b1cdbd2cSJim Jagielski 											pBodyPtr += 2;
2597*b1cdbd2cSJim Jagielski 										}
2598*b1cdbd2cSJim Jagielski 										else
2599*b1cdbd2cSJim Jagielski 										{
2600*b1cdbd2cSJim Jagielski 											++nLength;
2601*b1cdbd2cSJim Jagielski 											++pBodyPtr;
2602*b1cdbd2cSJim Jagielski 										}
2603*b1cdbd2cSJim Jagielski 										break;
2604*b1cdbd2cSJim Jagielski 
2605*b1cdbd2cSJim Jagielski 									case '\t':
2606*b1cdbd2cSJim Jagielski 									case ' ':
2607*b1cdbd2cSJim Jagielski 										bEnd = true;
2608*b1cdbd2cSJim Jagielski 										break;
2609*b1cdbd2cSJim Jagielski 
2610*b1cdbd2cSJim Jagielski 									default:
2611*b1cdbd2cSJim Jagielski 										if (isVisible(*pBodyPtr))
2612*b1cdbd2cSJim Jagielski 											bEnd = true;
2613*b1cdbd2cSJim Jagielski 										else if (isUSASCII(*pBodyPtr))
2614*b1cdbd2cSJim Jagielski 										{
2615*b1cdbd2cSJim Jagielski 											++nLength;
2616*b1cdbd2cSJim Jagielski 											++pBodyPtr;
2617*b1cdbd2cSJim Jagielski 										}
2618*b1cdbd2cSJim Jagielski 										else
2619*b1cdbd2cSJim Jagielski 										{
2620*b1cdbd2cSJim Jagielski 											nLength += getUTF8OctetCount(
2621*b1cdbd2cSJim Jagielski 												           *pBodyPtr++);
2622*b1cdbd2cSJim Jagielski 											bModify = true;
2623*b1cdbd2cSJim Jagielski 										}
2624*b1cdbd2cSJim Jagielski 										break;
2625*b1cdbd2cSJim Jagielski 								}
2626*b1cdbd2cSJim Jagielski 
2627*b1cdbd2cSJim Jagielski 							// Write the output:
2628*b1cdbd2cSJim Jagielski 							if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
2629*b1cdbd2cSJim Jagielski 								        + nLength
2630*b1cdbd2cSJim Jagielski 								    > rSink.getLineLengthLimit())
2631*b1cdbd2cSJim Jagielski 								rSink << INetMIMEOutputSink::endl << ' ';
2632*b1cdbd2cSJim Jagielski 							else if (bInitialSpace)
2633*b1cdbd2cSJim Jagielski 								rSink << ' ';
2634*b1cdbd2cSJim Jagielski 							bInitialSpace = false;
2635*b1cdbd2cSJim Jagielski 							if (bModify)
2636*b1cdbd2cSJim Jagielski 								while (pStart != pBodyPtr)
2637*b1cdbd2cSJim Jagielski 									if (startsWithLineBreak(pStart, pBodyPtr))
2638*b1cdbd2cSJim Jagielski 									{
2639*b1cdbd2cSJim Jagielski 										rSink << "\x0D\\\x0A"; // CR, '\', LF
2640*b1cdbd2cSJim Jagielski 										pStart += 2;
2641*b1cdbd2cSJim Jagielski 									}
2642*b1cdbd2cSJim Jagielski 									else
2643*b1cdbd2cSJim Jagielski 										writeUTF8(rSink, *pStart++);
2644*b1cdbd2cSJim Jagielski 							else
2645*b1cdbd2cSJim Jagielski 								rSink.write(pStart, pBodyPtr);
2646*b1cdbd2cSJim Jagielski 							break;
2647*b1cdbd2cSJim Jagielski 						}
2648*b1cdbd2cSJim Jagielski 
2649*b1cdbd2cSJim Jagielski 						case ENTITY_NON_PHRASE:
2650*b1cdbd2cSJim Jagielski 						{
2651*b1cdbd2cSJim Jagielski 							// Calculate the length of in- and output:
2652*b1cdbd2cSJim Jagielski 							const sal_Unicode * pStart = pBodyPtr;
2653*b1cdbd2cSJim Jagielski 							sal_Size nLength = 0;
2654*b1cdbd2cSJim Jagielski 							bool bBracketedBlock = false;
2655*b1cdbd2cSJim Jagielski 							bool bSymbol = *pStart != '.' && *pStart != '@';
2656*b1cdbd2cSJim Jagielski 							bool bModify = false;
2657*b1cdbd2cSJim Jagielski 							bool bEnd = false;
2658*b1cdbd2cSJim Jagielski 							while (pBodyPtr != pBodyEnd && !bEnd)
2659*b1cdbd2cSJim Jagielski 								switch (*pBodyPtr)
2660*b1cdbd2cSJim Jagielski 								{
2661*b1cdbd2cSJim Jagielski 									case '\t':
2662*b1cdbd2cSJim Jagielski 									case ' ':
2663*b1cdbd2cSJim Jagielski 									case '\x0D': // CR
2664*b1cdbd2cSJim Jagielski 									{
2665*b1cdbd2cSJim Jagielski 										const sal_Unicode * pLookAhead
2666*b1cdbd2cSJim Jagielski 											= skipLinearWhiteSpace(pBodyPtr,
2667*b1cdbd2cSJim Jagielski 																   pBodyEnd);
2668*b1cdbd2cSJim Jagielski 										if (pLookAhead < pBodyEnd
2669*b1cdbd2cSJim Jagielski 											&& (bSymbol ?
2670*b1cdbd2cSJim Jagielski 												    isAtomChar(*pLookAhead)
2671*b1cdbd2cSJim Jagielski 												    || *pLookAhead == '"'
2672*b1cdbd2cSJim Jagielski 												    || *pLookAhead == '[' :
2673*b1cdbd2cSJim Jagielski 												    *pLookAhead == '.'
2674*b1cdbd2cSJim Jagielski 												    || *pLookAhead == '@'
2675*b1cdbd2cSJim Jagielski 												    || (*pLookAhead == '>'
2676*b1cdbd2cSJim Jagielski 												       && eType
2677*b1cdbd2cSJim Jagielski 												    >= HEADER_FIELD_MESSAGE_ID
2678*b1cdbd2cSJim Jagielski 												       && eBrackets
2679*b1cdbd2cSJim Jagielski 												         == BRACKETS_OPENING)))
2680*b1cdbd2cSJim Jagielski 										{
2681*b1cdbd2cSJim Jagielski 											bModify = true;
2682*b1cdbd2cSJim Jagielski 											pBodyPtr = pLookAhead;
2683*b1cdbd2cSJim Jagielski 										}
2684*b1cdbd2cSJim Jagielski 										else
2685*b1cdbd2cSJim Jagielski 											bEnd = true;
2686*b1cdbd2cSJim Jagielski 										break;
2687*b1cdbd2cSJim Jagielski 									}
2688*b1cdbd2cSJim Jagielski 
2689*b1cdbd2cSJim Jagielski 									case '"':
2690*b1cdbd2cSJim Jagielski 										if (bSymbol)
2691*b1cdbd2cSJim Jagielski 										{
2692*b1cdbd2cSJim Jagielski 											pBodyPtr
2693*b1cdbd2cSJim Jagielski 												= scanQuotedBlock(pBodyPtr,
2694*b1cdbd2cSJim Jagielski 																  pBodyEnd,
2695*b1cdbd2cSJim Jagielski 																  '"', '"',
2696*b1cdbd2cSJim Jagielski 																  nLength,
2697*b1cdbd2cSJim Jagielski 																  bModify);
2698*b1cdbd2cSJim Jagielski 											bSymbol = false;
2699*b1cdbd2cSJim Jagielski 										}
2700*b1cdbd2cSJim Jagielski 										else
2701*b1cdbd2cSJim Jagielski 											bEnd = true;
2702*b1cdbd2cSJim Jagielski 										break;
2703*b1cdbd2cSJim Jagielski 
2704*b1cdbd2cSJim Jagielski 									case '[':
2705*b1cdbd2cSJim Jagielski 										if (bSymbol)
2706*b1cdbd2cSJim Jagielski 										{
2707*b1cdbd2cSJim Jagielski 											pBodyPtr
2708*b1cdbd2cSJim Jagielski 												= scanQuotedBlock(pBodyPtr,
2709*b1cdbd2cSJim Jagielski 																  pBodyEnd,
2710*b1cdbd2cSJim Jagielski 																  '[', ']',
2711*b1cdbd2cSJim Jagielski 																  nLength,
2712*b1cdbd2cSJim Jagielski 																  bModify);
2713*b1cdbd2cSJim Jagielski 											bSymbol = false;
2714*b1cdbd2cSJim Jagielski 										}
2715*b1cdbd2cSJim Jagielski 										else
2716*b1cdbd2cSJim Jagielski 											bEnd = true;
2717*b1cdbd2cSJim Jagielski 										break;
2718*b1cdbd2cSJim Jagielski 
2719*b1cdbd2cSJim Jagielski 									case '.':
2720*b1cdbd2cSJim Jagielski 									case '@':
2721*b1cdbd2cSJim Jagielski 										if (bSymbol)
2722*b1cdbd2cSJim Jagielski 											bEnd = true;
2723*b1cdbd2cSJim Jagielski 										else
2724*b1cdbd2cSJim Jagielski 										{
2725*b1cdbd2cSJim Jagielski 											++nLength;
2726*b1cdbd2cSJim Jagielski 											bSymbol = true;
2727*b1cdbd2cSJim Jagielski 											++pBodyPtr;
2728*b1cdbd2cSJim Jagielski 										}
2729*b1cdbd2cSJim Jagielski 										break;
2730*b1cdbd2cSJim Jagielski 
2731*b1cdbd2cSJim Jagielski 									case '>':
2732*b1cdbd2cSJim Jagielski 										if (eBrackets == BRACKETS_OPENING
2733*b1cdbd2cSJim Jagielski 											&& eType
2734*b1cdbd2cSJim Jagielski 											       >= HEADER_FIELD_MESSAGE_ID)
2735*b1cdbd2cSJim Jagielski 										{
2736*b1cdbd2cSJim Jagielski 											++nLength;
2737*b1cdbd2cSJim Jagielski 											bBracketedBlock = true;
2738*b1cdbd2cSJim Jagielski 											++pBodyPtr;
2739*b1cdbd2cSJim Jagielski 										}
2740*b1cdbd2cSJim Jagielski 										bEnd = true;
2741*b1cdbd2cSJim Jagielski 										break;
2742*b1cdbd2cSJim Jagielski 
2743*b1cdbd2cSJim Jagielski 									default:
2744*b1cdbd2cSJim Jagielski 										if (isAtomChar(*pBodyPtr) && bSymbol)
2745*b1cdbd2cSJim Jagielski 										{
2746*b1cdbd2cSJim Jagielski 											while (pBodyPtr != pBodyEnd
2747*b1cdbd2cSJim Jagielski 												   && isAtomChar(*pBodyPtr))
2748*b1cdbd2cSJim Jagielski 											{
2749*b1cdbd2cSJim Jagielski 												++nLength;
2750*b1cdbd2cSJim Jagielski 												++pBodyPtr;
2751*b1cdbd2cSJim Jagielski 											}
2752*b1cdbd2cSJim Jagielski 											bSymbol = false;
2753*b1cdbd2cSJim Jagielski 										}
2754*b1cdbd2cSJim Jagielski 										else
2755*b1cdbd2cSJim Jagielski 										{
2756*b1cdbd2cSJim Jagielski 											if (!isUSASCII(*pBodyPtr))
2757*b1cdbd2cSJim Jagielski 												bModify = true;
2758*b1cdbd2cSJim Jagielski 											bEnd = true;
2759*b1cdbd2cSJim Jagielski 										}
2760*b1cdbd2cSJim Jagielski 										break;
2761*b1cdbd2cSJim Jagielski 								}
2762*b1cdbd2cSJim Jagielski 
2763*b1cdbd2cSJim Jagielski 							// Write a pending '<' if necessary:
2764*b1cdbd2cSJim Jagielski 							if (eBrackets == BRACKETS_OPENING
2765*b1cdbd2cSJim Jagielski 								&& !bBracketedBlock)
2766*b1cdbd2cSJim Jagielski 							{
2767*b1cdbd2cSJim Jagielski 								if (rSink.getColumn()
2768*b1cdbd2cSJim Jagielski 									        + (bInitialSpace ? 1 : 0)
2769*b1cdbd2cSJim Jagielski 									    >= rSink.getLineLengthLimit())
2770*b1cdbd2cSJim Jagielski 									rSink << INetMIMEOutputSink::endl << ' ';
2771*b1cdbd2cSJim Jagielski 								else if (bInitialSpace)
2772*b1cdbd2cSJim Jagielski 									rSink << ' ';
2773*b1cdbd2cSJim Jagielski 								rSink << '<';
2774*b1cdbd2cSJim Jagielski 								bInitialSpace = false;
2775*b1cdbd2cSJim Jagielski 								eBrackets = BRACKETS_INSIDE;
2776*b1cdbd2cSJim Jagielski 							}
2777*b1cdbd2cSJim Jagielski 
2778*b1cdbd2cSJim Jagielski 							// Write the output:
2779*b1cdbd2cSJim Jagielski 							if (rSink.getColumn() + (bInitialSpace ? 1 : 0)
2780*b1cdbd2cSJim Jagielski 								        + nLength
2781*b1cdbd2cSJim Jagielski 								    > rSink.getLineLengthLimit())
2782*b1cdbd2cSJim Jagielski 								rSink << INetMIMEOutputSink::endl << ' ';
2783*b1cdbd2cSJim Jagielski 							else if (bInitialSpace)
2784*b1cdbd2cSJim Jagielski 								rSink << ' ';
2785*b1cdbd2cSJim Jagielski 							bInitialSpace = false;
2786*b1cdbd2cSJim Jagielski 							if (bBracketedBlock)
2787*b1cdbd2cSJim Jagielski 							{
2788*b1cdbd2cSJim Jagielski 								rSink << '<';
2789*b1cdbd2cSJim Jagielski 								eBrackets = BRACKETS_OUTSIDE;
2790*b1cdbd2cSJim Jagielski 							}
2791*b1cdbd2cSJim Jagielski 							if (bModify)
2792*b1cdbd2cSJim Jagielski 							{
2793*b1cdbd2cSJim Jagielski 								enum Mode { MODE_PLAIN, MODE_QUOTED_STRING,
2794*b1cdbd2cSJim Jagielski 											MODE_DOMAIN_LITERAL };
2795*b1cdbd2cSJim Jagielski 								Mode eMode = MODE_PLAIN;
2796*b1cdbd2cSJim Jagielski 								while (pStart != pBodyPtr)
2797*b1cdbd2cSJim Jagielski 									switch (*pStart)
2798*b1cdbd2cSJim Jagielski 									{
2799*b1cdbd2cSJim Jagielski 										case '\x0D': // CR
2800*b1cdbd2cSJim Jagielski 											if (startsWithLineFolding(
2801*b1cdbd2cSJim Jagielski 												    pStart, pBodyPtr))
2802*b1cdbd2cSJim Jagielski 											{
2803*b1cdbd2cSJim Jagielski 												if (eMode != MODE_PLAIN)
2804*b1cdbd2cSJim Jagielski 													rSink << sal_Char(
2805*b1cdbd2cSJim Jagielski 														         pStart[2]);
2806*b1cdbd2cSJim Jagielski 												pStart += 3;
2807*b1cdbd2cSJim Jagielski 											}
2808*b1cdbd2cSJim Jagielski 											else if (startsWithLineBreak(
2809*b1cdbd2cSJim Jagielski 												         pStart, pBodyPtr))
2810*b1cdbd2cSJim Jagielski 											{
2811*b1cdbd2cSJim Jagielski 												rSink << "\x0D\\\x0A";
2812*b1cdbd2cSJim Jagielski 												    // CR, '\', LF
2813*b1cdbd2cSJim Jagielski 												pStart += 2;
2814*b1cdbd2cSJim Jagielski 											}
2815*b1cdbd2cSJim Jagielski 											else
2816*b1cdbd2cSJim Jagielski 											{
2817*b1cdbd2cSJim Jagielski 												rSink << '\x0D'; // CR
2818*b1cdbd2cSJim Jagielski 												++pStart;
2819*b1cdbd2cSJim Jagielski 											}
2820*b1cdbd2cSJim Jagielski 											break;
2821*b1cdbd2cSJim Jagielski 
2822*b1cdbd2cSJim Jagielski 										case '\t':
2823*b1cdbd2cSJim Jagielski 										case ' ':
2824*b1cdbd2cSJim Jagielski 											if (eMode != MODE_PLAIN)
2825*b1cdbd2cSJim Jagielski 												rSink << sal_Char(*pStart);
2826*b1cdbd2cSJim Jagielski 											++pStart;
2827*b1cdbd2cSJim Jagielski 											break;
2828*b1cdbd2cSJim Jagielski 
2829*b1cdbd2cSJim Jagielski 										case '"':
2830*b1cdbd2cSJim Jagielski 											if (eMode == MODE_PLAIN)
2831*b1cdbd2cSJim Jagielski 												eMode = MODE_QUOTED_STRING;
2832*b1cdbd2cSJim Jagielski 											else if (eMode
2833*b1cdbd2cSJim Jagielski 													    == MODE_QUOTED_STRING)
2834*b1cdbd2cSJim Jagielski 												eMode = MODE_PLAIN;
2835*b1cdbd2cSJim Jagielski 											rSink << '"';
2836*b1cdbd2cSJim Jagielski 											++pStart;
2837*b1cdbd2cSJim Jagielski 											break;
2838*b1cdbd2cSJim Jagielski 
2839*b1cdbd2cSJim Jagielski 										case '[':
2840*b1cdbd2cSJim Jagielski 											if (eMode == MODE_PLAIN)
2841*b1cdbd2cSJim Jagielski 												eMode = MODE_DOMAIN_LITERAL;
2842*b1cdbd2cSJim Jagielski 											rSink << '[';
2843*b1cdbd2cSJim Jagielski 											++pStart;
2844*b1cdbd2cSJim Jagielski 											break;
2845*b1cdbd2cSJim Jagielski 
2846*b1cdbd2cSJim Jagielski 										case ']':
2847*b1cdbd2cSJim Jagielski 											if (eMode == MODE_DOMAIN_LITERAL)
2848*b1cdbd2cSJim Jagielski 												eMode = MODE_PLAIN;
2849*b1cdbd2cSJim Jagielski 											rSink << ']';
2850*b1cdbd2cSJim Jagielski 											++pStart;
2851*b1cdbd2cSJim Jagielski 											break;
2852*b1cdbd2cSJim Jagielski 
2853*b1cdbd2cSJim Jagielski 										case '\\':
2854*b1cdbd2cSJim Jagielski 											rSink << '\\';
2855*b1cdbd2cSJim Jagielski 											if (++pStart < pBodyPtr)
2856*b1cdbd2cSJim Jagielski 												writeUTF8(rSink, *pStart++);
2857*b1cdbd2cSJim Jagielski 											break;
2858*b1cdbd2cSJim Jagielski 
2859*b1cdbd2cSJim Jagielski 										default:
2860*b1cdbd2cSJim Jagielski 											writeUTF8(rSink, *pStart++);
2861*b1cdbd2cSJim Jagielski 											break;
2862*b1cdbd2cSJim Jagielski 									}
2863*b1cdbd2cSJim Jagielski 							}
2864*b1cdbd2cSJim Jagielski 							else
2865*b1cdbd2cSJim Jagielski 								rSink.write(pStart, pBodyPtr);
2866*b1cdbd2cSJim Jagielski 							break;
2867*b1cdbd2cSJim Jagielski 						}
2868*b1cdbd2cSJim Jagielski 
2869*b1cdbd2cSJim Jagielski 						case ENTITY_PHRASE:
2870*b1cdbd2cSJim Jagielski 						{
2871*b1cdbd2cSJim Jagielski 							// Write a pending '<' if necessary:
2872*b1cdbd2cSJim Jagielski 							if (eBrackets == BRACKETS_OPENING)
2873*b1cdbd2cSJim Jagielski 							{
2874*b1cdbd2cSJim Jagielski 								if (rSink.getColumn()
2875*b1cdbd2cSJim Jagielski 									        + (bInitialSpace ? 1 : 0)
2876*b1cdbd2cSJim Jagielski 									    >= rSink.getLineLengthLimit())
2877*b1cdbd2cSJim Jagielski 									rSink << INetMIMEOutputSink::endl << ' ';
2878*b1cdbd2cSJim Jagielski 								else if (bInitialSpace)
2879*b1cdbd2cSJim Jagielski 									rSink << ' ';
2880*b1cdbd2cSJim Jagielski 								rSink << '<';
2881*b1cdbd2cSJim Jagielski 								bInitialSpace = false;
2882*b1cdbd2cSJim Jagielski 								eBrackets = BRACKETS_INSIDE;
2883*b1cdbd2cSJim Jagielski 							}
2884*b1cdbd2cSJim Jagielski 
2885*b1cdbd2cSJim Jagielski 							// Calculate the length of in- and output:
2886*b1cdbd2cSJim Jagielski 							const sal_Unicode * pStart = pBodyPtr;
2887*b1cdbd2cSJim Jagielski 							bool bQuotedString = false;
2888*b1cdbd2cSJim Jagielski 							bool bEnd = false;
2889*b1cdbd2cSJim Jagielski 							while (pBodyPtr != pBodyEnd && !bEnd)
2890*b1cdbd2cSJim Jagielski 								switch (*pBodyPtr)
2891*b1cdbd2cSJim Jagielski 								{
2892*b1cdbd2cSJim Jagielski 									case '\t':
2893*b1cdbd2cSJim Jagielski 									case ' ':
2894*b1cdbd2cSJim Jagielski 									case '\x0D': // CR
2895*b1cdbd2cSJim Jagielski 										if (bQuotedString)
2896*b1cdbd2cSJim Jagielski 											++pBodyPtr;
2897*b1cdbd2cSJim Jagielski 										else
2898*b1cdbd2cSJim Jagielski 										{
2899*b1cdbd2cSJim Jagielski 											const sal_Unicode * pLookAhead
2900*b1cdbd2cSJim Jagielski 												= skipLinearWhiteSpace(
2901*b1cdbd2cSJim Jagielski 													  pBodyPtr, pBodyEnd);
2902*b1cdbd2cSJim Jagielski 											if (pLookAhead != pBodyEnd
2903*b1cdbd2cSJim Jagielski 												&& (isAtomChar(*pLookAhead)
2904*b1cdbd2cSJim Jagielski 													|| !isUSASCII(*pLookAhead)
2905*b1cdbd2cSJim Jagielski 													|| *pLookAhead == '"'))
2906*b1cdbd2cSJim Jagielski 												pBodyPtr = pLookAhead;
2907*b1cdbd2cSJim Jagielski 											else
2908*b1cdbd2cSJim Jagielski 												bEnd = true;
2909*b1cdbd2cSJim Jagielski 										}
2910*b1cdbd2cSJim Jagielski 										break;
2911*b1cdbd2cSJim Jagielski 
2912*b1cdbd2cSJim Jagielski 									case '"':
2913*b1cdbd2cSJim Jagielski 										bQuotedString = !bQuotedString;
2914*b1cdbd2cSJim Jagielski 										++pBodyPtr;
2915*b1cdbd2cSJim Jagielski 										break;
2916*b1cdbd2cSJim Jagielski 
2917*b1cdbd2cSJim Jagielski 									case '\\':
2918*b1cdbd2cSJim Jagielski 										if (bQuotedString)
2919*b1cdbd2cSJim Jagielski 										{
2920*b1cdbd2cSJim Jagielski 											if (++pBodyPtr != pBodyEnd)
2921*b1cdbd2cSJim Jagielski 												++pBodyPtr;
2922*b1cdbd2cSJim Jagielski 										}
2923*b1cdbd2cSJim Jagielski 										else
2924*b1cdbd2cSJim Jagielski 											bEnd = true;
2925*b1cdbd2cSJim Jagielski 										break;
2926*b1cdbd2cSJim Jagielski 
2927*b1cdbd2cSJim Jagielski 									default:
2928*b1cdbd2cSJim Jagielski 										if (bQuotedString
2929*b1cdbd2cSJim Jagielski 											|| isAtomChar(*pBodyPtr)
2930*b1cdbd2cSJim Jagielski 											|| !isUSASCII(*pBodyPtr))
2931*b1cdbd2cSJim Jagielski 											++pBodyPtr;
2932*b1cdbd2cSJim Jagielski 										else
2933*b1cdbd2cSJim Jagielski 											bEnd = true;
2934*b1cdbd2cSJim Jagielski 										break;
2935*b1cdbd2cSJim Jagielski 								}
2936*b1cdbd2cSJim Jagielski 
2937*b1cdbd2cSJim Jagielski 							// Write the phrase, introducing encoded-words
2938*b1cdbd2cSJim Jagielski 							// where necessary:
2939*b1cdbd2cSJim Jagielski 							INetMIMEEncodedWordOutputSink
2940*b1cdbd2cSJim Jagielski 								aOutput(
2941*b1cdbd2cSJim Jagielski 									rSink,
2942*b1cdbd2cSJim Jagielski 								INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,
2943*b1cdbd2cSJim Jagielski 									bInitialSpace ?
2944*b1cdbd2cSJim Jagielski 								 INetMIMEEncodedWordOutputSink::SPACE_ALWAYS :
2945*b1cdbd2cSJim Jagielski 								 INetMIMEEncodedWordOutputSink::SPACE_ENCODED,
2946*b1cdbd2cSJim Jagielski 							   ePreferredEncoding);
2947*b1cdbd2cSJim Jagielski 							while (pStart != pBodyPtr)
2948*b1cdbd2cSJim Jagielski 								switch (*pStart)
2949*b1cdbd2cSJim Jagielski 								{
2950*b1cdbd2cSJim Jagielski 									case '"':
2951*b1cdbd2cSJim Jagielski 										++pStart;
2952*b1cdbd2cSJim Jagielski 										break;
2953*b1cdbd2cSJim Jagielski 
2954*b1cdbd2cSJim Jagielski 									case '\\':
2955*b1cdbd2cSJim Jagielski 										if (++pStart != pBodyPtr)
2956*b1cdbd2cSJim Jagielski 											aOutput << *pStart++;
2957*b1cdbd2cSJim Jagielski 										break;
2958*b1cdbd2cSJim Jagielski 
2959*b1cdbd2cSJim Jagielski 									case '\x0D': // CR
2960*b1cdbd2cSJim Jagielski 										pStart += 2;
2961*b1cdbd2cSJim Jagielski 										aOutput << *pStart++;
2962*b1cdbd2cSJim Jagielski 										break;
2963*b1cdbd2cSJim Jagielski 
2964*b1cdbd2cSJim Jagielski 									default:
2965*b1cdbd2cSJim Jagielski 										aOutput << *pStart++;
2966*b1cdbd2cSJim Jagielski 										break;
2967*b1cdbd2cSJim Jagielski 								}
2968*b1cdbd2cSJim Jagielski 							bInitialSpace = aOutput.flush();
2969*b1cdbd2cSJim Jagielski 							break;
2970*b1cdbd2cSJim Jagielski 						}
2971*b1cdbd2cSJim Jagielski 					}
2972*b1cdbd2cSJim Jagielski 					break;
2973*b1cdbd2cSJim Jagielski 				}
2974*b1cdbd2cSJim Jagielski 			}
2975*b1cdbd2cSJim Jagielski 	}
2976*b1cdbd2cSJim Jagielski }
2977*b1cdbd2cSJim Jagielski 
2978*b1cdbd2cSJim Jagielski //============================================================================
2979*b1cdbd2cSJim Jagielski // static
translateUTF8Char(const sal_Char * & rBegin,const sal_Char * pEnd,rtl_TextEncoding eEncoding,sal_uInt32 & rCharacter)2980*b1cdbd2cSJim Jagielski bool INetMIME::translateUTF8Char(const sal_Char *& rBegin,
2981*b1cdbd2cSJim Jagielski 								 const sal_Char * pEnd,
2982*b1cdbd2cSJim Jagielski 								 rtl_TextEncoding eEncoding,
2983*b1cdbd2cSJim Jagielski 								 sal_uInt32 & rCharacter)
2984*b1cdbd2cSJim Jagielski {
2985*b1cdbd2cSJim Jagielski 	if (rBegin == pEnd || static_cast< unsigned char >(*rBegin) < 0x80
2986*b1cdbd2cSJim Jagielski         || static_cast< unsigned char >(*rBegin) >= 0xFE)
2987*b1cdbd2cSJim Jagielski 		return false;
2988*b1cdbd2cSJim Jagielski 
2989*b1cdbd2cSJim Jagielski 	int nCount;
2990*b1cdbd2cSJim Jagielski 	sal_uInt32 nMin;
2991*b1cdbd2cSJim Jagielski 	sal_uInt32 nUCS4;
2992*b1cdbd2cSJim Jagielski 	const sal_Char * p = rBegin;
2993*b1cdbd2cSJim Jagielski 	if (static_cast< unsigned char >(*p) < 0xE0)
2994*b1cdbd2cSJim Jagielski 	{
2995*b1cdbd2cSJim Jagielski 		nCount = 1;
2996*b1cdbd2cSJim Jagielski 		nMin = 0x80;
2997*b1cdbd2cSJim Jagielski 		nUCS4 = static_cast< unsigned char >(*p) & 0x1F;
2998*b1cdbd2cSJim Jagielski 	}
2999*b1cdbd2cSJim Jagielski 	else if (static_cast< unsigned char >(*p) < 0xF0)
3000*b1cdbd2cSJim Jagielski 	{
3001*b1cdbd2cSJim Jagielski 		nCount = 2;
3002*b1cdbd2cSJim Jagielski 		nMin = 0x800;
3003*b1cdbd2cSJim Jagielski 		nUCS4 = static_cast< unsigned char >(*p) & 0xF;
3004*b1cdbd2cSJim Jagielski 	}
3005*b1cdbd2cSJim Jagielski 	else if (static_cast< unsigned char >(*p) < 0xF8)
3006*b1cdbd2cSJim Jagielski 	{
3007*b1cdbd2cSJim Jagielski 		nCount = 3;
3008*b1cdbd2cSJim Jagielski 		nMin = 0x10000;
3009*b1cdbd2cSJim Jagielski 		nUCS4 = static_cast< unsigned char >(*p) & 7;
3010*b1cdbd2cSJim Jagielski 	}
3011*b1cdbd2cSJim Jagielski 	else if (static_cast< unsigned char >(*p) < 0xFC)
3012*b1cdbd2cSJim Jagielski 	{
3013*b1cdbd2cSJim Jagielski 		nCount = 4;
3014*b1cdbd2cSJim Jagielski 		nMin = 0x200000;
3015*b1cdbd2cSJim Jagielski 		nUCS4 = static_cast< unsigned char >(*p) & 3;
3016*b1cdbd2cSJim Jagielski 	}
3017*b1cdbd2cSJim Jagielski 	else
3018*b1cdbd2cSJim Jagielski 	{
3019*b1cdbd2cSJim Jagielski 		nCount = 5;
3020*b1cdbd2cSJim Jagielski 		nMin = 0x4000000;
3021*b1cdbd2cSJim Jagielski 		nUCS4 = static_cast< unsigned char >(*p) & 1;
3022*b1cdbd2cSJim Jagielski 	}
3023*b1cdbd2cSJim Jagielski 	++p;
3024*b1cdbd2cSJim Jagielski 
3025*b1cdbd2cSJim Jagielski 	for (; nCount-- > 0; ++p)
3026*b1cdbd2cSJim Jagielski 		if ((static_cast< unsigned char >(*p) & 0xC0) == 0x80)
3027*b1cdbd2cSJim Jagielski 			nUCS4 = (nUCS4 << 6) | (static_cast< unsigned char >(*p) & 0x3F);
3028*b1cdbd2cSJim Jagielski 		else
3029*b1cdbd2cSJim Jagielski 			return false;
3030*b1cdbd2cSJim Jagielski 
3031*b1cdbd2cSJim Jagielski 	if (nUCS4 < nMin || nUCS4 > 0x10FFFF)
3032*b1cdbd2cSJim Jagielski 		return false;
3033*b1cdbd2cSJim Jagielski 
3034*b1cdbd2cSJim Jagielski 	if (eEncoding >= RTL_TEXTENCODING_UCS4)
3035*b1cdbd2cSJim Jagielski 		rCharacter = nUCS4;
3036*b1cdbd2cSJim Jagielski 	else
3037*b1cdbd2cSJim Jagielski 	{
3038*b1cdbd2cSJim Jagielski 		sal_Unicode aUTF16[2];
3039*b1cdbd2cSJim Jagielski 		const sal_Unicode * pUTF16End = putUTF32Character(aUTF16, nUCS4);
3040*b1cdbd2cSJim Jagielski 		sal_Size nSize;
3041*b1cdbd2cSJim Jagielski 		sal_Char * pBuffer = convertFromUnicode(aUTF16, pUTF16End, eEncoding,
3042*b1cdbd2cSJim Jagielski 												nSize);
3043*b1cdbd2cSJim Jagielski 		if (!pBuffer)
3044*b1cdbd2cSJim Jagielski 			return false;
3045*b1cdbd2cSJim Jagielski 		DBG_ASSERT(nSize == 1,
3046*b1cdbd2cSJim Jagielski 				   "INetMIME::translateUTF8Char(): Bad conversion");
3047*b1cdbd2cSJim Jagielski 		rCharacter = *pBuffer;
3048*b1cdbd2cSJim Jagielski 		delete[] pBuffer;
3049*b1cdbd2cSJim Jagielski 	}
3050*b1cdbd2cSJim Jagielski 	rBegin = p;
3051*b1cdbd2cSJim Jagielski 	return true;
3052*b1cdbd2cSJim Jagielski }
3053*b1cdbd2cSJim Jagielski 
3054*b1cdbd2cSJim Jagielski //============================================================================
3055*b1cdbd2cSJim Jagielski // static
decodeUTF8(const ByteString & rText,rtl_TextEncoding eEncoding)3056*b1cdbd2cSJim Jagielski ByteString INetMIME::decodeUTF8(const ByteString & rText,
3057*b1cdbd2cSJim Jagielski 								rtl_TextEncoding eEncoding)
3058*b1cdbd2cSJim Jagielski {
3059*b1cdbd2cSJim Jagielski 	const sal_Char * p = rText.GetBuffer();
3060*b1cdbd2cSJim Jagielski 	const sal_Char * pEnd = p + rText.Len();
3061*b1cdbd2cSJim Jagielski 	ByteString sDecoded;
3062*b1cdbd2cSJim Jagielski 	while (p != pEnd)
3063*b1cdbd2cSJim Jagielski 	{
3064*b1cdbd2cSJim Jagielski 		sal_uInt32 nCharacter;
3065*b1cdbd2cSJim Jagielski 		if (translateUTF8Char(p, pEnd, eEncoding, nCharacter))
3066*b1cdbd2cSJim Jagielski 			sDecoded += sal_Char(nCharacter);
3067*b1cdbd2cSJim Jagielski 		else
3068*b1cdbd2cSJim Jagielski 			sDecoded += sal_Char(*p++);
3069*b1cdbd2cSJim Jagielski 	}
3070*b1cdbd2cSJim Jagielski 	return sDecoded;
3071*b1cdbd2cSJim Jagielski }
3072*b1cdbd2cSJim Jagielski 
3073*b1cdbd2cSJim Jagielski //============================================================================
3074*b1cdbd2cSJim Jagielski // static
decodeHeaderFieldBody(HeaderFieldType eType,const ByteString & rBody)3075*b1cdbd2cSJim Jagielski UniString INetMIME::decodeHeaderFieldBody(HeaderFieldType eType,
3076*b1cdbd2cSJim Jagielski 										  const ByteString & rBody)
3077*b1cdbd2cSJim Jagielski {
3078*b1cdbd2cSJim Jagielski 	// Due to a bug in INetCoreRFC822MessageStream::ConvertTo7Bit(), old
3079*b1cdbd2cSJim Jagielski 	// versions of StarOffice send mails with header fields where encoded
3080*b1cdbd2cSJim Jagielski 	// words can be preceded by '=', ',', '.', '"', or '(', and followed by
3081*b1cdbd2cSJim Jagielski 	// '=', ',', '.', '"', ')', without any required white space in between.
3082*b1cdbd2cSJim Jagielski 	// And there appear to exist some broken mailers that only encode single
3083*b1cdbd2cSJim Jagielski 	// letters within words, like "Appel
3084*b1cdbd2cSJim Jagielski 	// =?iso-8859-1?Q?=E0?=t=?iso-8859-1?Q?=E9?=moin", so it seems best to
3085*b1cdbd2cSJim Jagielski 	// detect encoded words even when not propperly surrounded by white space.
3086*b1cdbd2cSJim Jagielski 	//
3087*b1cdbd2cSJim Jagielski 	// Non US-ASCII characters in rBody are treated as ISO-8859-1.
3088*b1cdbd2cSJim Jagielski 	//
3089*b1cdbd2cSJim Jagielski 	// encoded-word = "=?"
3090*b1cdbd2cSJim Jagielski 	//     1*(%x21 / %x23-27 / %x2A-2B / %x2D / %30-39 / %x41-5A / %x5E-7E)
3091*b1cdbd2cSJim Jagielski 	//     ["*" 1*8ALPHA *("-" 1*8ALPHA)] "?"
3092*b1cdbd2cSJim Jagielski 	//     ("B?" *(4base64) (4base64 / 3base64 "=" / 2base64 "==")
3093*b1cdbd2cSJim Jagielski 	//      / "Q?" 1*(%x21-3C / %x3E / %x40-7E / "=" 2HEXDIG))
3094*b1cdbd2cSJim Jagielski 	//     "?="
3095*b1cdbd2cSJim Jagielski 	//
3096*b1cdbd2cSJim Jagielski 	// base64 = ALPHA / DIGIT / "+" / "/"
3097*b1cdbd2cSJim Jagielski 
3098*b1cdbd2cSJim Jagielski 	const sal_Char * pBegin = rBody.GetBuffer();
3099*b1cdbd2cSJim Jagielski 	const sal_Char * pEnd = pBegin + rBody.Len();
3100*b1cdbd2cSJim Jagielski 
3101*b1cdbd2cSJim Jagielski 	UniString sDecoded;
3102*b1cdbd2cSJim Jagielski 	const sal_Char * pCopyBegin = pBegin;
3103*b1cdbd2cSJim Jagielski 
3104*b1cdbd2cSJim Jagielski 	/* bool bStartEncodedWord = true; */
3105*b1cdbd2cSJim Jagielski 	const sal_Char * pWSPBegin = pBegin;
3106*b1cdbd2cSJim Jagielski 	UniString sEncodedText;
3107*b1cdbd2cSJim Jagielski 	bool bQuotedEncodedText = false;
3108*b1cdbd2cSJim Jagielski 	sal_uInt32 nCommentLevel = 0;
3109*b1cdbd2cSJim Jagielski 
3110*b1cdbd2cSJim Jagielski 	for (const sal_Char * p = pBegin; p != pEnd;)
3111*b1cdbd2cSJim Jagielski 	{
3112*b1cdbd2cSJim Jagielski 		if (p != pEnd && *p == '=' /* && bStartEncodedWord */)
3113*b1cdbd2cSJim Jagielski 		{
3114*b1cdbd2cSJim Jagielski 			const sal_Char * q = p + 1;
3115*b1cdbd2cSJim Jagielski 			bool bEncodedWord = q != pEnd && *q++ == '?';
3116*b1cdbd2cSJim Jagielski 
3117*b1cdbd2cSJim Jagielski 			rtl_TextEncoding eCharsetEncoding = RTL_TEXTENCODING_DONTKNOW;
3118*b1cdbd2cSJim Jagielski 			if (bEncodedWord)
3119*b1cdbd2cSJim Jagielski 			{
3120*b1cdbd2cSJim Jagielski 				const sal_Char * pCharsetBegin = q;
3121*b1cdbd2cSJim Jagielski 				const sal_Char * pLanguageBegin = 0;
3122*b1cdbd2cSJim Jagielski 				int nAlphaCount = 0;
3123*b1cdbd2cSJim Jagielski 				for (bool bDone = false; !bDone;)
3124*b1cdbd2cSJim Jagielski 					if (q == pEnd)
3125*b1cdbd2cSJim Jagielski 					{
3126*b1cdbd2cSJim Jagielski 						bEncodedWord = false;
3127*b1cdbd2cSJim Jagielski 						bDone = true;
3128*b1cdbd2cSJim Jagielski 					}
3129*b1cdbd2cSJim Jagielski 					else
3130*b1cdbd2cSJim Jagielski 					{
3131*b1cdbd2cSJim Jagielski 						sal_Char cChar = *q++;
3132*b1cdbd2cSJim Jagielski 						switch (cChar)
3133*b1cdbd2cSJim Jagielski 						{
3134*b1cdbd2cSJim Jagielski 							case '*':
3135*b1cdbd2cSJim Jagielski 								pLanguageBegin = q - 1;
3136*b1cdbd2cSJim Jagielski 								nAlphaCount = 0;
3137*b1cdbd2cSJim Jagielski 								break;
3138*b1cdbd2cSJim Jagielski 
3139*b1cdbd2cSJim Jagielski 							case '-':
3140*b1cdbd2cSJim Jagielski 								if (pLanguageBegin != 0)
3141*b1cdbd2cSJim Jagielski 								{
3142*b1cdbd2cSJim Jagielski 									if (nAlphaCount == 0)
3143*b1cdbd2cSJim Jagielski 										pLanguageBegin = 0;
3144*b1cdbd2cSJim Jagielski 									else
3145*b1cdbd2cSJim Jagielski 										nAlphaCount = 0;
3146*b1cdbd2cSJim Jagielski 								}
3147*b1cdbd2cSJim Jagielski 								break;
3148*b1cdbd2cSJim Jagielski 
3149*b1cdbd2cSJim Jagielski 							case '?':
3150*b1cdbd2cSJim Jagielski 								if (pCharsetBegin == q - 1)
3151*b1cdbd2cSJim Jagielski 									bEncodedWord = false;
3152*b1cdbd2cSJim Jagielski 								else
3153*b1cdbd2cSJim Jagielski 								{
3154*b1cdbd2cSJim Jagielski 									eCharsetEncoding
3155*b1cdbd2cSJim Jagielski 										= getCharsetEncoding(
3156*b1cdbd2cSJim Jagielski 											  pCharsetBegin,
3157*b1cdbd2cSJim Jagielski 											  pLanguageBegin == 0
3158*b1cdbd2cSJim Jagielski 											  || nAlphaCount == 0 ?
3159*b1cdbd2cSJim Jagielski 											      q - 1 : pLanguageBegin);
3160*b1cdbd2cSJim Jagielski 									bEncodedWord = isMIMECharsetEncoding(
3161*b1cdbd2cSJim Jagielski 										               eCharsetEncoding);
3162*b1cdbd2cSJim Jagielski 									eCharsetEncoding
3163*b1cdbd2cSJim Jagielski 										= translateFromMIME(eCharsetEncoding);
3164*b1cdbd2cSJim Jagielski 								}
3165*b1cdbd2cSJim Jagielski 								bDone = true;
3166*b1cdbd2cSJim Jagielski 								break;
3167*b1cdbd2cSJim Jagielski 
3168*b1cdbd2cSJim Jagielski 							default:
3169*b1cdbd2cSJim Jagielski 								if (pLanguageBegin != 0
3170*b1cdbd2cSJim Jagielski 									&& (!isAlpha(cChar) || ++nAlphaCount > 8))
3171*b1cdbd2cSJim Jagielski 									pLanguageBegin = 0;
3172*b1cdbd2cSJim Jagielski 								break;
3173*b1cdbd2cSJim Jagielski 						}
3174*b1cdbd2cSJim Jagielski 					}
3175*b1cdbd2cSJim Jagielski 			}
3176*b1cdbd2cSJim Jagielski 
3177*b1cdbd2cSJim Jagielski 			bool bEncodingB = false;
3178*b1cdbd2cSJim Jagielski 			if (bEncodedWord)
3179*b1cdbd2cSJim Jagielski             {
3180*b1cdbd2cSJim Jagielski 				if (q == pEnd)
3181*b1cdbd2cSJim Jagielski 					bEncodedWord = false;
3182*b1cdbd2cSJim Jagielski 				else
3183*b1cdbd2cSJim Jagielski                 {
3184*b1cdbd2cSJim Jagielski 					switch (*q++)
3185*b1cdbd2cSJim Jagielski 					{
3186*b1cdbd2cSJim Jagielski 						case 'B':
3187*b1cdbd2cSJim Jagielski 						case 'b':
3188*b1cdbd2cSJim Jagielski 							bEncodingB = true;
3189*b1cdbd2cSJim Jagielski 							break;
3190*b1cdbd2cSJim Jagielski 
3191*b1cdbd2cSJim Jagielski 						case 'Q':
3192*b1cdbd2cSJim Jagielski 						case 'q':
3193*b1cdbd2cSJim Jagielski 							bEncodingB = false;
3194*b1cdbd2cSJim Jagielski 							break;
3195*b1cdbd2cSJim Jagielski 
3196*b1cdbd2cSJim Jagielski 						default:
3197*b1cdbd2cSJim Jagielski 							bEncodedWord = false;
3198*b1cdbd2cSJim Jagielski 							break;
3199*b1cdbd2cSJim Jagielski 					}
3200*b1cdbd2cSJim Jagielski                 }
3201*b1cdbd2cSJim Jagielski             }
3202*b1cdbd2cSJim Jagielski 
3203*b1cdbd2cSJim Jagielski 			bEncodedWord = bEncodedWord && q != pEnd && *q++ == '?';
3204*b1cdbd2cSJim Jagielski 
3205*b1cdbd2cSJim Jagielski 			ByteString sText;
3206*b1cdbd2cSJim Jagielski 			if (bEncodedWord)
3207*b1cdbd2cSJim Jagielski             {
3208*b1cdbd2cSJim Jagielski 				if (bEncodingB)
3209*b1cdbd2cSJim Jagielski                 {
3210*b1cdbd2cSJim Jagielski 					for (bool bDone = false; !bDone;)
3211*b1cdbd2cSJim Jagielski 					{
3212*b1cdbd2cSJim Jagielski 						if (pEnd - q < 4)
3213*b1cdbd2cSJim Jagielski 						{
3214*b1cdbd2cSJim Jagielski 							bEncodedWord = false;
3215*b1cdbd2cSJim Jagielski 							bDone = true;
3216*b1cdbd2cSJim Jagielski 						}
3217*b1cdbd2cSJim Jagielski 						else
3218*b1cdbd2cSJim Jagielski 						{
3219*b1cdbd2cSJim Jagielski 							bool bFinal = false;
3220*b1cdbd2cSJim Jagielski 							int nCount = 3;
3221*b1cdbd2cSJim Jagielski 							sal_uInt32 nValue = 0;
3222*b1cdbd2cSJim Jagielski 							for (int nShift = 18; nShift >= 0; nShift -= 6)
3223*b1cdbd2cSJim Jagielski 							{
3224*b1cdbd2cSJim Jagielski 								int nWeight = getBase64Weight(*q++);
3225*b1cdbd2cSJim Jagielski 								if (nWeight == -2)
3226*b1cdbd2cSJim Jagielski 								{
3227*b1cdbd2cSJim Jagielski 									bEncodedWord = false;
3228*b1cdbd2cSJim Jagielski 									bDone = true;
3229*b1cdbd2cSJim Jagielski 									break;
3230*b1cdbd2cSJim Jagielski 								}
3231*b1cdbd2cSJim Jagielski 								if (nWeight == -1)
3232*b1cdbd2cSJim Jagielski 								{
3233*b1cdbd2cSJim Jagielski 									if (!bFinal)
3234*b1cdbd2cSJim Jagielski 									{
3235*b1cdbd2cSJim Jagielski 										if (nShift >= 12)
3236*b1cdbd2cSJim Jagielski 										{
3237*b1cdbd2cSJim Jagielski 											bEncodedWord = false;
3238*b1cdbd2cSJim Jagielski 											bDone = true;
3239*b1cdbd2cSJim Jagielski 											break;
3240*b1cdbd2cSJim Jagielski 										}
3241*b1cdbd2cSJim Jagielski 										bFinal = true;
3242*b1cdbd2cSJim Jagielski 										nCount = nShift == 6 ? 1 : 2;
3243*b1cdbd2cSJim Jagielski 									}
3244*b1cdbd2cSJim Jagielski 								}
3245*b1cdbd2cSJim Jagielski 								else
3246*b1cdbd2cSJim Jagielski 									nValue |= nWeight << nShift;
3247*b1cdbd2cSJim Jagielski 							}
3248*b1cdbd2cSJim Jagielski 							if (bEncodedWord)
3249*b1cdbd2cSJim Jagielski 							{
3250*b1cdbd2cSJim Jagielski 								for (int nShift = 16; nCount-- > 0;
3251*b1cdbd2cSJim Jagielski 									 nShift -= 8)
3252*b1cdbd2cSJim Jagielski 									sText += sal_Char(nValue >> nShift
3253*b1cdbd2cSJim Jagielski 													      & 0xFF);
3254*b1cdbd2cSJim Jagielski 								if (*q == '?')
3255*b1cdbd2cSJim Jagielski 								{
3256*b1cdbd2cSJim Jagielski 									++q;
3257*b1cdbd2cSJim Jagielski 									bDone = true;
3258*b1cdbd2cSJim Jagielski 								}
3259*b1cdbd2cSJim Jagielski 								if (bFinal && !bDone)
3260*b1cdbd2cSJim Jagielski 								{
3261*b1cdbd2cSJim Jagielski 									bEncodedWord = false;
3262*b1cdbd2cSJim Jagielski 									bDone = true;
3263*b1cdbd2cSJim Jagielski 								}
3264*b1cdbd2cSJim Jagielski 							}
3265*b1cdbd2cSJim Jagielski 						}
3266*b1cdbd2cSJim Jagielski 					}
3267*b1cdbd2cSJim Jagielski                 }
3268*b1cdbd2cSJim Jagielski 				else
3269*b1cdbd2cSJim Jagielski 				{
3270*b1cdbd2cSJim Jagielski 					const sal_Char * pEncodedTextBegin = q;
3271*b1cdbd2cSJim Jagielski 					const sal_Char * pEncodedTextCopyBegin = q;
3272*b1cdbd2cSJim Jagielski 					for (bool bDone = false; !bDone;)
3273*b1cdbd2cSJim Jagielski 						if (q == pEnd)
3274*b1cdbd2cSJim Jagielski 						{
3275*b1cdbd2cSJim Jagielski 							bEncodedWord = false;
3276*b1cdbd2cSJim Jagielski 							bDone = true;
3277*b1cdbd2cSJim Jagielski 						}
3278*b1cdbd2cSJim Jagielski 						else
3279*b1cdbd2cSJim Jagielski 						{
3280*b1cdbd2cSJim Jagielski 							sal_uInt32 nChar = *q++;
3281*b1cdbd2cSJim Jagielski 							switch (nChar)
3282*b1cdbd2cSJim Jagielski 							{
3283*b1cdbd2cSJim Jagielski 								case '=':
3284*b1cdbd2cSJim Jagielski 								{
3285*b1cdbd2cSJim Jagielski 									if (pEnd - q < 2)
3286*b1cdbd2cSJim Jagielski 									{
3287*b1cdbd2cSJim Jagielski 										bEncodedWord = false;
3288*b1cdbd2cSJim Jagielski 										bDone = true;
3289*b1cdbd2cSJim Jagielski 										break;
3290*b1cdbd2cSJim Jagielski 									}
3291*b1cdbd2cSJim Jagielski 									int nDigit1 = getHexWeight(q[0]);
3292*b1cdbd2cSJim Jagielski 									int nDigit2 = getHexWeight(q[1]);
3293*b1cdbd2cSJim Jagielski 									if (nDigit1 < 0 || nDigit2 < 0)
3294*b1cdbd2cSJim Jagielski 									{
3295*b1cdbd2cSJim Jagielski 										bEncodedWord = false;
3296*b1cdbd2cSJim Jagielski 										bDone = true;
3297*b1cdbd2cSJim Jagielski 										break;
3298*b1cdbd2cSJim Jagielski 									}
3299*b1cdbd2cSJim Jagielski 									sText += rBody.Copy(
3300*b1cdbd2cSJim Jagielski                                         static_cast< xub_StrLen >(
3301*b1cdbd2cSJim Jagielski                                             pEncodedTextCopyBegin - pBegin),
3302*b1cdbd2cSJim Jagielski                                         static_cast< xub_StrLen >(
3303*b1cdbd2cSJim Jagielski                                             q - 1 - pEncodedTextCopyBegin));
3304*b1cdbd2cSJim Jagielski 									sText += sal_Char(nDigit1 << 4 | nDigit2);
3305*b1cdbd2cSJim Jagielski 									q += 2;
3306*b1cdbd2cSJim Jagielski 									pEncodedTextCopyBegin = q;
3307*b1cdbd2cSJim Jagielski 									break;
3308*b1cdbd2cSJim Jagielski 								}
3309*b1cdbd2cSJim Jagielski 
3310*b1cdbd2cSJim Jagielski 								case '?':
3311*b1cdbd2cSJim Jagielski 									if (q - pEncodedTextBegin > 1)
3312*b1cdbd2cSJim Jagielski 										sText += rBody.Copy(
3313*b1cdbd2cSJim Jagielski                                             static_cast< xub_StrLen >(
3314*b1cdbd2cSJim Jagielski                                                 pEncodedTextCopyBegin - pBegin),
3315*b1cdbd2cSJim Jagielski                                             static_cast< xub_StrLen >(
3316*b1cdbd2cSJim Jagielski                                                 q - 1 - pEncodedTextCopyBegin));
3317*b1cdbd2cSJim Jagielski 									else
3318*b1cdbd2cSJim Jagielski 										bEncodedWord = false;
3319*b1cdbd2cSJim Jagielski 									bDone = true;
3320*b1cdbd2cSJim Jagielski 									break;
3321*b1cdbd2cSJim Jagielski 
3322*b1cdbd2cSJim Jagielski 								case '_':
3323*b1cdbd2cSJim Jagielski 									sText += rBody.Copy(
3324*b1cdbd2cSJim Jagielski                                         static_cast< xub_StrLen >(
3325*b1cdbd2cSJim Jagielski                                             pEncodedTextCopyBegin - pBegin),
3326*b1cdbd2cSJim Jagielski                                         static_cast< xub_StrLen >(
3327*b1cdbd2cSJim Jagielski                                             q - 1 - pEncodedTextCopyBegin));
3328*b1cdbd2cSJim Jagielski 									sText += ' ';
3329*b1cdbd2cSJim Jagielski 									pEncodedTextCopyBegin = q;
3330*b1cdbd2cSJim Jagielski 									break;
3331*b1cdbd2cSJim Jagielski 
3332*b1cdbd2cSJim Jagielski 								default:
3333*b1cdbd2cSJim Jagielski 									if (!isVisible(nChar))
3334*b1cdbd2cSJim Jagielski 									{
3335*b1cdbd2cSJim Jagielski 										bEncodedWord = false;
3336*b1cdbd2cSJim Jagielski 										bDone = true;
3337*b1cdbd2cSJim Jagielski 									}
3338*b1cdbd2cSJim Jagielski 									break;
3339*b1cdbd2cSJim Jagielski 							}
3340*b1cdbd2cSJim Jagielski 						}
3341*b1cdbd2cSJim Jagielski 				}
3342*b1cdbd2cSJim Jagielski             }
3343*b1cdbd2cSJim Jagielski 
3344*b1cdbd2cSJim Jagielski 			bEncodedWord = bEncodedWord && q != pEnd && *q++ == '=';
3345*b1cdbd2cSJim Jagielski 
3346*b1cdbd2cSJim Jagielski //			if (bEncodedWord && q != pEnd)
3347*b1cdbd2cSJim Jagielski //				switch (*q)
3348*b1cdbd2cSJim Jagielski //				{
3349*b1cdbd2cSJim Jagielski //					case '\t':
3350*b1cdbd2cSJim Jagielski //					case ' ':
3351*b1cdbd2cSJim Jagielski //					case '"':
3352*b1cdbd2cSJim Jagielski //					case ')':
3353*b1cdbd2cSJim Jagielski //					case ',':
3354*b1cdbd2cSJim Jagielski //					case '.':
3355*b1cdbd2cSJim Jagielski //					case '=':
3356*b1cdbd2cSJim Jagielski //						break;
3357*b1cdbd2cSJim Jagielski //
3358*b1cdbd2cSJim Jagielski //					default:
3359*b1cdbd2cSJim Jagielski //						bEncodedWord = false;
3360*b1cdbd2cSJim Jagielski //						break;
3361*b1cdbd2cSJim Jagielski //				}
3362*b1cdbd2cSJim Jagielski 
3363*b1cdbd2cSJim Jagielski 			sal_Unicode * pUnicodeBuffer = 0;
3364*b1cdbd2cSJim Jagielski 			sal_Size nUnicodeSize = 0;
3365*b1cdbd2cSJim Jagielski 			if (bEncodedWord)
3366*b1cdbd2cSJim Jagielski 			{
3367*b1cdbd2cSJim Jagielski 				pUnicodeBuffer
3368*b1cdbd2cSJim Jagielski 					= convertToUnicode(sText.GetBuffer(),
3369*b1cdbd2cSJim Jagielski 									   sText.GetBuffer() + sText.Len(),
3370*b1cdbd2cSJim Jagielski 									   eCharsetEncoding, nUnicodeSize);
3371*b1cdbd2cSJim Jagielski 				if (pUnicodeBuffer == 0)
3372*b1cdbd2cSJim Jagielski 					bEncodedWord = false;
3373*b1cdbd2cSJim Jagielski 			}
3374*b1cdbd2cSJim Jagielski 
3375*b1cdbd2cSJim Jagielski 			if (bEncodedWord)
3376*b1cdbd2cSJim Jagielski 			{
3377*b1cdbd2cSJim Jagielski 				appendISO88591(sDecoded, pCopyBegin, pWSPBegin);
3378*b1cdbd2cSJim Jagielski 				if (eType == HEADER_FIELD_TEXT)
3379*b1cdbd2cSJim Jagielski 					sDecoded.Append(
3380*b1cdbd2cSJim Jagielski                         pUnicodeBuffer,
3381*b1cdbd2cSJim Jagielski                         static_cast< xub_StrLen >(nUnicodeSize));
3382*b1cdbd2cSJim Jagielski 				else if (nCommentLevel == 0)
3383*b1cdbd2cSJim Jagielski 				{
3384*b1cdbd2cSJim Jagielski 					sEncodedText.Append(
3385*b1cdbd2cSJim Jagielski                         pUnicodeBuffer,
3386*b1cdbd2cSJim Jagielski                         static_cast< xub_StrLen >(nUnicodeSize));
3387*b1cdbd2cSJim Jagielski 					if (!bQuotedEncodedText)
3388*b1cdbd2cSJim Jagielski 					{
3389*b1cdbd2cSJim Jagielski 						const sal_Unicode * pTextPtr = pUnicodeBuffer;
3390*b1cdbd2cSJim Jagielski 						const sal_Unicode * pTextEnd = pTextPtr
3391*b1cdbd2cSJim Jagielski 							                               + nUnicodeSize;
3392*b1cdbd2cSJim Jagielski 						for (; pTextPtr != pTextEnd; ++pTextPtr)
3393*b1cdbd2cSJim Jagielski 							if (!isEncodedWordTokenChar(*pTextPtr))
3394*b1cdbd2cSJim Jagielski 							{
3395*b1cdbd2cSJim Jagielski 								bQuotedEncodedText = true;
3396*b1cdbd2cSJim Jagielski 								break;
3397*b1cdbd2cSJim Jagielski 							}
3398*b1cdbd2cSJim Jagielski 					}
3399*b1cdbd2cSJim Jagielski 				}
3400*b1cdbd2cSJim Jagielski 				else
3401*b1cdbd2cSJim Jagielski 				{
3402*b1cdbd2cSJim Jagielski 					const sal_Unicode * pTextPtr = pUnicodeBuffer;
3403*b1cdbd2cSJim Jagielski 					const sal_Unicode * pTextEnd = pTextPtr + nUnicodeSize;
3404*b1cdbd2cSJim Jagielski 					for (; pTextPtr != pTextEnd; ++pTextPtr)
3405*b1cdbd2cSJim Jagielski 					{
3406*b1cdbd2cSJim Jagielski 						switch (*pTextPtr)
3407*b1cdbd2cSJim Jagielski 						{
3408*b1cdbd2cSJim Jagielski 							case '(':
3409*b1cdbd2cSJim Jagielski 							case ')':
3410*b1cdbd2cSJim Jagielski 							case '\\':
3411*b1cdbd2cSJim Jagielski 							case '\x0D':
3412*b1cdbd2cSJim Jagielski 							case '=':
3413*b1cdbd2cSJim Jagielski 								sDecoded += '\\';
3414*b1cdbd2cSJim Jagielski 								break;
3415*b1cdbd2cSJim Jagielski 						}
3416*b1cdbd2cSJim Jagielski 						sDecoded += *pTextPtr;
3417*b1cdbd2cSJim Jagielski 					}
3418*b1cdbd2cSJim Jagielski 				}
3419*b1cdbd2cSJim Jagielski 				delete[] pUnicodeBuffer;
3420*b1cdbd2cSJim Jagielski 				p = q;
3421*b1cdbd2cSJim Jagielski 				pCopyBegin = p;
3422*b1cdbd2cSJim Jagielski 
3423*b1cdbd2cSJim Jagielski 				pWSPBegin = p;
3424*b1cdbd2cSJim Jagielski 				while (p != pEnd && isWhiteSpace(*p))
3425*b1cdbd2cSJim Jagielski 					++p;
3426*b1cdbd2cSJim Jagielski 				/* bStartEncodedWord = p != pWSPBegin; */
3427*b1cdbd2cSJim Jagielski 				continue;
3428*b1cdbd2cSJim Jagielski 			}
3429*b1cdbd2cSJim Jagielski 		}
3430*b1cdbd2cSJim Jagielski 
3431*b1cdbd2cSJim Jagielski 		if (sEncodedText.Len() != 0)
3432*b1cdbd2cSJim Jagielski 		{
3433*b1cdbd2cSJim Jagielski 			if (bQuotedEncodedText)
3434*b1cdbd2cSJim Jagielski 			{
3435*b1cdbd2cSJim Jagielski 				sDecoded += '"';
3436*b1cdbd2cSJim Jagielski 				const sal_Unicode * pTextPtr = sEncodedText.GetBuffer();
3437*b1cdbd2cSJim Jagielski 				const sal_Unicode * pTextEnd = pTextPtr + sEncodedText.Len();
3438*b1cdbd2cSJim Jagielski 				for (;pTextPtr != pTextEnd; ++pTextPtr)
3439*b1cdbd2cSJim Jagielski 				{
3440*b1cdbd2cSJim Jagielski 					switch (*pTextPtr)
3441*b1cdbd2cSJim Jagielski 					{
3442*b1cdbd2cSJim Jagielski 						case '"':
3443*b1cdbd2cSJim Jagielski 						case '\\':
3444*b1cdbd2cSJim Jagielski 						case '\x0D':
3445*b1cdbd2cSJim Jagielski 							sDecoded += '\\';
3446*b1cdbd2cSJim Jagielski 							break;
3447*b1cdbd2cSJim Jagielski 					}
3448*b1cdbd2cSJim Jagielski 					sDecoded += *pTextPtr;
3449*b1cdbd2cSJim Jagielski 				}
3450*b1cdbd2cSJim Jagielski 				sDecoded += '"';
3451*b1cdbd2cSJim Jagielski 			}
3452*b1cdbd2cSJim Jagielski 			else
3453*b1cdbd2cSJim Jagielski 				sDecoded += sEncodedText;
3454*b1cdbd2cSJim Jagielski 			sEncodedText.Erase();
3455*b1cdbd2cSJim Jagielski 			bQuotedEncodedText = false;
3456*b1cdbd2cSJim Jagielski 		}
3457*b1cdbd2cSJim Jagielski 
3458*b1cdbd2cSJim Jagielski 		if (p == pEnd)
3459*b1cdbd2cSJim Jagielski 			break;
3460*b1cdbd2cSJim Jagielski 
3461*b1cdbd2cSJim Jagielski 		switch (*p++)
3462*b1cdbd2cSJim Jagielski 		{
3463*b1cdbd2cSJim Jagielski //			case '\t':
3464*b1cdbd2cSJim Jagielski //			case ' ':
3465*b1cdbd2cSJim Jagielski //			case ',':
3466*b1cdbd2cSJim Jagielski //			case '.':
3467*b1cdbd2cSJim Jagielski //			case '=':
3468*b1cdbd2cSJim Jagielski //				bStartEncodedWord = true;
3469*b1cdbd2cSJim Jagielski //				break;
3470*b1cdbd2cSJim Jagielski 
3471*b1cdbd2cSJim Jagielski 			case '"':
3472*b1cdbd2cSJim Jagielski 				if (eType != HEADER_FIELD_TEXT && nCommentLevel == 0)
3473*b1cdbd2cSJim Jagielski 				{
3474*b1cdbd2cSJim Jagielski 					const sal_Char * pQuotedStringEnd
3475*b1cdbd2cSJim Jagielski 						= skipQuotedString(p - 1, pEnd);
3476*b1cdbd2cSJim Jagielski 					p = pQuotedStringEnd == p - 1 ? pEnd : pQuotedStringEnd;
3477*b1cdbd2cSJim Jagielski 				}
3478*b1cdbd2cSJim Jagielski 				/* bStartEncodedWord = true; */
3479*b1cdbd2cSJim Jagielski 				break;
3480*b1cdbd2cSJim Jagielski 
3481*b1cdbd2cSJim Jagielski 			case '(':
3482*b1cdbd2cSJim Jagielski 				if (eType != HEADER_FIELD_TEXT)
3483*b1cdbd2cSJim Jagielski 					++nCommentLevel;
3484*b1cdbd2cSJim Jagielski 				/* bStartEncodedWord = true; */
3485*b1cdbd2cSJim Jagielski 				break;
3486*b1cdbd2cSJim Jagielski 
3487*b1cdbd2cSJim Jagielski 			case ')':
3488*b1cdbd2cSJim Jagielski 				if (nCommentLevel > 0)
3489*b1cdbd2cSJim Jagielski 					--nCommentLevel;
3490*b1cdbd2cSJim Jagielski 				/* bStartEncodedWord = false; */
3491*b1cdbd2cSJim Jagielski 				break;
3492*b1cdbd2cSJim Jagielski 
3493*b1cdbd2cSJim Jagielski 			default:
3494*b1cdbd2cSJim Jagielski 			{
3495*b1cdbd2cSJim Jagielski 				const sal_Char * pUTF8Begin = p - 1;
3496*b1cdbd2cSJim Jagielski 				const sal_Char * pUTF8End = pUTF8Begin;
3497*b1cdbd2cSJim Jagielski 				sal_uInt32 nCharacter;
3498*b1cdbd2cSJim Jagielski 				if (translateUTF8Char(pUTF8End, pEnd, RTL_TEXTENCODING_UCS4,
3499*b1cdbd2cSJim Jagielski 									  nCharacter))
3500*b1cdbd2cSJim Jagielski 				{
3501*b1cdbd2cSJim Jagielski 					appendISO88591(sDecoded, pCopyBegin, p - 1);
3502*b1cdbd2cSJim Jagielski 					sal_Unicode aUTF16Buf[2];
3503*b1cdbd2cSJim Jagielski 					xub_StrLen nUTF16Len = static_cast< xub_StrLen >(
3504*b1cdbd2cSJim Jagielski                         putUTF32Character(aUTF16Buf, nCharacter) - aUTF16Buf);
3505*b1cdbd2cSJim Jagielski 					sDecoded.Append(aUTF16Buf, nUTF16Len);
3506*b1cdbd2cSJim Jagielski 					p = pUTF8End;
3507*b1cdbd2cSJim Jagielski 					pCopyBegin = p;
3508*b1cdbd2cSJim Jagielski 				}
3509*b1cdbd2cSJim Jagielski 				/* bStartEncodedWord = false; */
3510*b1cdbd2cSJim Jagielski 				break;
3511*b1cdbd2cSJim Jagielski 			}
3512*b1cdbd2cSJim Jagielski 		}
3513*b1cdbd2cSJim Jagielski 		pWSPBegin = p;
3514*b1cdbd2cSJim Jagielski 	}
3515*b1cdbd2cSJim Jagielski 
3516*b1cdbd2cSJim Jagielski 	appendISO88591(sDecoded, pCopyBegin, pEnd);
3517*b1cdbd2cSJim Jagielski 	return sDecoded;
3518*b1cdbd2cSJim Jagielski }
3519*b1cdbd2cSJim Jagielski 
3520*b1cdbd2cSJim Jagielski //============================================================================
3521*b1cdbd2cSJim Jagielski //
3522*b1cdbd2cSJim Jagielski //  INetMIMEOutputSink
3523*b1cdbd2cSJim Jagielski //
3524*b1cdbd2cSJim Jagielski //============================================================================
3525*b1cdbd2cSJim Jagielski 
3526*b1cdbd2cSJim Jagielski // virtual
writeSequence(const sal_Char * pSequence)3527*b1cdbd2cSJim Jagielski sal_Size INetMIMEOutputSink::writeSequence(const sal_Char * pSequence)
3528*b1cdbd2cSJim Jagielski {
3529*b1cdbd2cSJim Jagielski 	sal_Size nLength = rtl_str_getLength(pSequence);
3530*b1cdbd2cSJim Jagielski 	writeSequence(pSequence, pSequence + nLength);
3531*b1cdbd2cSJim Jagielski 	return nLength;
3532*b1cdbd2cSJim Jagielski }
3533*b1cdbd2cSJim Jagielski 
3534*b1cdbd2cSJim Jagielski //============================================================================
3535*b1cdbd2cSJim Jagielski // virtual
writeSequence(const sal_uInt32 * pBegin,const sal_uInt32 * pEnd)3536*b1cdbd2cSJim Jagielski void INetMIMEOutputSink::writeSequence(const sal_uInt32 * pBegin,
3537*b1cdbd2cSJim Jagielski 									   const sal_uInt32 * pEnd)
3538*b1cdbd2cSJim Jagielski {
3539*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
3540*b1cdbd2cSJim Jagielski 			   "INetMIMEOutputSink::writeSequence(): Bad sequence");
3541*b1cdbd2cSJim Jagielski 
3542*b1cdbd2cSJim Jagielski 	sal_Char * pBufferBegin = new sal_Char[pEnd - pBegin];
3543*b1cdbd2cSJim Jagielski 	sal_Char * pBufferEnd = pBufferBegin;
3544*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd)
3545*b1cdbd2cSJim Jagielski 	{
3546*b1cdbd2cSJim Jagielski 		DBG_ASSERT(*pBegin < 256,
3547*b1cdbd2cSJim Jagielski 				   "INetMIMEOutputSink::writeSequence(): Bad octet");
3548*b1cdbd2cSJim Jagielski 		*pBufferEnd++ = sal_Char(*pBegin++);
3549*b1cdbd2cSJim Jagielski 	}
3550*b1cdbd2cSJim Jagielski 	writeSequence(pBufferBegin, pBufferEnd);
3551*b1cdbd2cSJim Jagielski 	delete[] pBufferBegin;
3552*b1cdbd2cSJim Jagielski }
3553*b1cdbd2cSJim Jagielski 
3554*b1cdbd2cSJim Jagielski //============================================================================
3555*b1cdbd2cSJim Jagielski // virtual
writeSequence(const sal_Unicode * pBegin,const sal_Unicode * pEnd)3556*b1cdbd2cSJim Jagielski void INetMIMEOutputSink::writeSequence(const sal_Unicode * pBegin,
3557*b1cdbd2cSJim Jagielski 									   const sal_Unicode * pEnd)
3558*b1cdbd2cSJim Jagielski {
3559*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
3560*b1cdbd2cSJim Jagielski 			   "INetMIMEOutputSink::writeSequence(): Bad sequence");
3561*b1cdbd2cSJim Jagielski 
3562*b1cdbd2cSJim Jagielski 	sal_Char * pBufferBegin = new sal_Char[pEnd - pBegin];
3563*b1cdbd2cSJim Jagielski 	sal_Char * pBufferEnd = pBufferBegin;
3564*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd)
3565*b1cdbd2cSJim Jagielski 	{
3566*b1cdbd2cSJim Jagielski 		DBG_ASSERT(*pBegin < 256,
3567*b1cdbd2cSJim Jagielski 				   "INetMIMEOutputSink::writeSequence(): Bad octet");
3568*b1cdbd2cSJim Jagielski 		*pBufferEnd++ = sal_Char(*pBegin++);
3569*b1cdbd2cSJim Jagielski 	}
3570*b1cdbd2cSJim Jagielski 	writeSequence(pBufferBegin, pBufferEnd);
3571*b1cdbd2cSJim Jagielski 	delete[] pBufferBegin;
3572*b1cdbd2cSJim Jagielski }
3573*b1cdbd2cSJim Jagielski 
3574*b1cdbd2cSJim Jagielski //============================================================================
3575*b1cdbd2cSJim Jagielski // virtual
getError() const3576*b1cdbd2cSJim Jagielski ErrCode INetMIMEOutputSink::getError() const
3577*b1cdbd2cSJim Jagielski {
3578*b1cdbd2cSJim Jagielski 	return ERRCODE_NONE;
3579*b1cdbd2cSJim Jagielski }
3580*b1cdbd2cSJim Jagielski 
3581*b1cdbd2cSJim Jagielski //============================================================================
writeLineEnd()3582*b1cdbd2cSJim Jagielski void INetMIMEOutputSink::writeLineEnd()
3583*b1cdbd2cSJim Jagielski {
3584*b1cdbd2cSJim Jagielski 	static const sal_Char aCRLF[2] = { 0x0D, 0x0A };
3585*b1cdbd2cSJim Jagielski 	writeSequence(aCRLF, aCRLF + 2);
3586*b1cdbd2cSJim Jagielski 	m_nColumn = 0;
3587*b1cdbd2cSJim Jagielski }
3588*b1cdbd2cSJim Jagielski 
3589*b1cdbd2cSJim Jagielski //============================================================================
3590*b1cdbd2cSJim Jagielski //
3591*b1cdbd2cSJim Jagielski //  INetMIMEStringOutputSink
3592*b1cdbd2cSJim Jagielski //
3593*b1cdbd2cSJim Jagielski //============================================================================
3594*b1cdbd2cSJim Jagielski 
3595*b1cdbd2cSJim Jagielski // virtual
writeSequence(const sal_Char * pBegin,const sal_Char * pEnd)3596*b1cdbd2cSJim Jagielski void INetMIMEStringOutputSink::writeSequence(const sal_Char * pBegin,
3597*b1cdbd2cSJim Jagielski 											 const sal_Char * pEnd)
3598*b1cdbd2cSJim Jagielski {
3599*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
3600*b1cdbd2cSJim Jagielski 			   "INetMIMEStringOutputSink::writeSequence(): Bad sequence");
3601*b1cdbd2cSJim Jagielski 
3602*b1cdbd2cSJim Jagielski 	m_bOverflow = m_bOverflow
3603*b1cdbd2cSJim Jagielski 		          || pEnd - pBegin > STRING_MAXLEN - m_aBuffer.Len();
3604*b1cdbd2cSJim Jagielski 	if (!m_bOverflow)
3605*b1cdbd2cSJim Jagielski 		m_aBuffer.Append(pBegin, static_cast< xub_StrLen >(pEnd - pBegin));
3606*b1cdbd2cSJim Jagielski }
3607*b1cdbd2cSJim Jagielski 
3608*b1cdbd2cSJim Jagielski //============================================================================
3609*b1cdbd2cSJim Jagielski // virtual
getError() const3610*b1cdbd2cSJim Jagielski ErrCode INetMIMEStringOutputSink::getError() const
3611*b1cdbd2cSJim Jagielski {
3612*b1cdbd2cSJim Jagielski 	return m_bOverflow ? ERRCODE_IO_OUTOFMEMORY : ERRCODE_NONE;
3613*b1cdbd2cSJim Jagielski }
3614*b1cdbd2cSJim Jagielski 
3615*b1cdbd2cSJim Jagielski //============================================================================
3616*b1cdbd2cSJim Jagielski //
3617*b1cdbd2cSJim Jagielski //  INetMIMEUnicodeOutputSink
3618*b1cdbd2cSJim Jagielski //
3619*b1cdbd2cSJim Jagielski //============================================================================
3620*b1cdbd2cSJim Jagielski 
3621*b1cdbd2cSJim Jagielski // virtual
writeSequence(const sal_Char * pBegin,const sal_Char * pEnd)3622*b1cdbd2cSJim Jagielski void INetMIMEUnicodeOutputSink::writeSequence(const sal_Char * pBegin,
3623*b1cdbd2cSJim Jagielski 											  const sal_Char * pEnd)
3624*b1cdbd2cSJim Jagielski {
3625*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
3626*b1cdbd2cSJim Jagielski 			   "INetMIMEUnicodeOutputSink::writeSequence(): Bad sequence");
3627*b1cdbd2cSJim Jagielski 
3628*b1cdbd2cSJim Jagielski 	sal_Unicode * pBufferBegin = new sal_Unicode[pEnd - pBegin];
3629*b1cdbd2cSJim Jagielski 	sal_Unicode * pBufferEnd = pBufferBegin;
3630*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd)
3631*b1cdbd2cSJim Jagielski 		*pBufferEnd++ = sal_uChar(*pBegin++);
3632*b1cdbd2cSJim Jagielski 	writeSequence(pBufferBegin, pBufferEnd);
3633*b1cdbd2cSJim Jagielski 	delete[] pBufferBegin;
3634*b1cdbd2cSJim Jagielski }
3635*b1cdbd2cSJim Jagielski 
3636*b1cdbd2cSJim Jagielski //============================================================================
3637*b1cdbd2cSJim Jagielski // virtual
writeSequence(const sal_uInt32 * pBegin,const sal_uInt32 * pEnd)3638*b1cdbd2cSJim Jagielski void INetMIMEUnicodeOutputSink::writeSequence(const sal_uInt32 * pBegin,
3639*b1cdbd2cSJim Jagielski 											  const sal_uInt32 * pEnd)
3640*b1cdbd2cSJim Jagielski {
3641*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
3642*b1cdbd2cSJim Jagielski 			   "INetMIMEUnicodeOutputSink::writeSequence(): Bad sequence");
3643*b1cdbd2cSJim Jagielski 
3644*b1cdbd2cSJim Jagielski 	sal_Unicode * pBufferBegin = new sal_Unicode[pEnd - pBegin];
3645*b1cdbd2cSJim Jagielski 	sal_Unicode * pBufferEnd = pBufferBegin;
3646*b1cdbd2cSJim Jagielski 	while (pBegin != pEnd)
3647*b1cdbd2cSJim Jagielski 	{
3648*b1cdbd2cSJim Jagielski 		DBG_ASSERT(*pBegin < 256,
3649*b1cdbd2cSJim Jagielski 				   "INetMIMEOutputSink::writeSequence(): Bad octet");
3650*b1cdbd2cSJim Jagielski 		*pBufferEnd++ = sal_Unicode(*pBegin++);
3651*b1cdbd2cSJim Jagielski 	}
3652*b1cdbd2cSJim Jagielski 	writeSequence(pBufferBegin, pBufferEnd);
3653*b1cdbd2cSJim Jagielski 	delete[] pBufferBegin;
3654*b1cdbd2cSJim Jagielski }
3655*b1cdbd2cSJim Jagielski 
3656*b1cdbd2cSJim Jagielski //============================================================================
3657*b1cdbd2cSJim Jagielski // virtual
writeSequence(const sal_Unicode * pBegin,const sal_Unicode * pEnd)3658*b1cdbd2cSJim Jagielski void INetMIMEUnicodeOutputSink::writeSequence(const sal_Unicode * pBegin,
3659*b1cdbd2cSJim Jagielski 											  const sal_Unicode * pEnd)
3660*b1cdbd2cSJim Jagielski {
3661*b1cdbd2cSJim Jagielski 	DBG_ASSERT(pBegin && pBegin <= pEnd,
3662*b1cdbd2cSJim Jagielski 			   "INetMIMEUnicodeOutputSink::writeSequence(): Bad sequence");
3663*b1cdbd2cSJim Jagielski 
3664*b1cdbd2cSJim Jagielski 	m_bOverflow = m_bOverflow
3665*b1cdbd2cSJim Jagielski 		          || pEnd - pBegin > STRING_MAXLEN - m_aBuffer.Len();
3666*b1cdbd2cSJim Jagielski 	if (!m_bOverflow)
3667*b1cdbd2cSJim Jagielski 		m_aBuffer.Append(pBegin, static_cast< xub_StrLen >(pEnd - pBegin));
3668*b1cdbd2cSJim Jagielski }
3669*b1cdbd2cSJim Jagielski 
3670*b1cdbd2cSJim Jagielski //============================================================================
3671*b1cdbd2cSJim Jagielski // virtual
getError() const3672*b1cdbd2cSJim Jagielski ErrCode INetMIMEUnicodeOutputSink::getError() const
3673*b1cdbd2cSJim Jagielski {
3674*b1cdbd2cSJim Jagielski 	return m_bOverflow ? ERRCODE_IO_OUTOFMEMORY : ERRCODE_NONE;
3675*b1cdbd2cSJim Jagielski }
3676*b1cdbd2cSJim Jagielski 
3677*b1cdbd2cSJim Jagielski //============================================================================
3678*b1cdbd2cSJim Jagielski //
3679*b1cdbd2cSJim Jagielski //  INetMIMEEncodedWordOutputSink
3680*b1cdbd2cSJim Jagielski //
3681*b1cdbd2cSJim Jagielski //============================================================================
3682*b1cdbd2cSJim Jagielski 
3683*b1cdbd2cSJim Jagielski static const sal_Char aEscape[128]
3684*b1cdbd2cSJim Jagielski 	= { INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x00
3685*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x01
3686*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x02
3687*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x03
3688*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x04
3689*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x05
3690*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x06
3691*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x07
3692*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x08
3693*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x09
3694*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x0A
3695*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x0B
3696*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x0C
3697*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x0D
3698*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x0E
3699*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x0F
3700*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x10
3701*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x11
3702*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x12
3703*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x13
3704*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x14
3705*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x15
3706*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x16
3707*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x17
3708*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x18
3709*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x19
3710*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x1A
3711*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x1B
3712*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x1C
3713*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x1D
3714*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x1E
3715*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // 0x1F
3716*b1cdbd2cSJim Jagielski 		0,   // ' '
3717*b1cdbd2cSJim Jagielski 		0,   // '!'
3718*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '"'
3719*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '#'
3720*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '$'
3721*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '%'
3722*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '&'
3723*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '''
3724*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '('
3725*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // ')'
3726*b1cdbd2cSJim Jagielski 		0,   // '*'
3727*b1cdbd2cSJim Jagielski 		0,   // '+'
3728*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // ','
3729*b1cdbd2cSJim Jagielski 		0,   // '-'
3730*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '.'
3731*b1cdbd2cSJim Jagielski 		0,   // '/'
3732*b1cdbd2cSJim Jagielski 		0,   // '0'
3733*b1cdbd2cSJim Jagielski 		0,   // '1'
3734*b1cdbd2cSJim Jagielski 		0,   // '2'
3735*b1cdbd2cSJim Jagielski 		0,   // '3'
3736*b1cdbd2cSJim Jagielski 		0,   // '4'
3737*b1cdbd2cSJim Jagielski 		0,   // '5'
3738*b1cdbd2cSJim Jagielski 		0,   // '6'
3739*b1cdbd2cSJim Jagielski 		0,   // '7'
3740*b1cdbd2cSJim Jagielski 		0,   // '8'
3741*b1cdbd2cSJim Jagielski 		0,   // '9'
3742*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // ':'
3743*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // ';'
3744*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '<'
3745*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '='
3746*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '>'
3747*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '?'
3748*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '@'
3749*b1cdbd2cSJim Jagielski 		0,   // 'A'
3750*b1cdbd2cSJim Jagielski 		0,   // 'B'
3751*b1cdbd2cSJim Jagielski 		0,   // 'C'
3752*b1cdbd2cSJim Jagielski 		0,   // 'D'
3753*b1cdbd2cSJim Jagielski 		0,   // 'E'
3754*b1cdbd2cSJim Jagielski 		0,   // 'F'
3755*b1cdbd2cSJim Jagielski 		0,   // 'G'
3756*b1cdbd2cSJim Jagielski 		0,   // 'H'
3757*b1cdbd2cSJim Jagielski 		0,   // 'I'
3758*b1cdbd2cSJim Jagielski 		0,   // 'J'
3759*b1cdbd2cSJim Jagielski 		0,   // 'K'
3760*b1cdbd2cSJim Jagielski 		0,   // 'L'
3761*b1cdbd2cSJim Jagielski 		0,   // 'M'
3762*b1cdbd2cSJim Jagielski 		0,   // 'N'
3763*b1cdbd2cSJim Jagielski 		0,   // 'O'
3764*b1cdbd2cSJim Jagielski 		0,   // 'P'
3765*b1cdbd2cSJim Jagielski 		0,   // 'Q'
3766*b1cdbd2cSJim Jagielski 		0,   // 'R'
3767*b1cdbd2cSJim Jagielski 		0,   // 'S'
3768*b1cdbd2cSJim Jagielski 		0,   // 'T'
3769*b1cdbd2cSJim Jagielski 		0,   // 'U'
3770*b1cdbd2cSJim Jagielski 		0,   // 'V'
3771*b1cdbd2cSJim Jagielski 		0,   // 'W'
3772*b1cdbd2cSJim Jagielski 		0,   // 'X'
3773*b1cdbd2cSJim Jagielski 		0,   // 'Y'
3774*b1cdbd2cSJim Jagielski 		0,   // 'Z'
3775*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '['
3776*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '\'
3777*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // ']'
3778*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '^'
3779*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '_'
3780*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '`'
3781*b1cdbd2cSJim Jagielski 		0,   // 'a'
3782*b1cdbd2cSJim Jagielski 		0,   // 'b'
3783*b1cdbd2cSJim Jagielski 		0,   // 'c'
3784*b1cdbd2cSJim Jagielski 		0,   // 'd'
3785*b1cdbd2cSJim Jagielski 		0,   // 'e'
3786*b1cdbd2cSJim Jagielski 		0,   // 'f'
3787*b1cdbd2cSJim Jagielski 		0,   // 'g'
3788*b1cdbd2cSJim Jagielski 		0,   // 'h'
3789*b1cdbd2cSJim Jagielski 		0,   // 'i'
3790*b1cdbd2cSJim Jagielski 		0,   // 'j'
3791*b1cdbd2cSJim Jagielski 		0,   // 'k'
3792*b1cdbd2cSJim Jagielski 		0,   // 'l'
3793*b1cdbd2cSJim Jagielski 		0,   // 'm'
3794*b1cdbd2cSJim Jagielski 		0,   // 'n'
3795*b1cdbd2cSJim Jagielski 		0,   // 'o'
3796*b1cdbd2cSJim Jagielski 		0,   // 'p'
3797*b1cdbd2cSJim Jagielski 		0,   // 'q'
3798*b1cdbd2cSJim Jagielski 		0,   // 'r'
3799*b1cdbd2cSJim Jagielski 		0,   // 's'
3800*b1cdbd2cSJim Jagielski 		0,   // 't'
3801*b1cdbd2cSJim Jagielski 		0,   // 'u'
3802*b1cdbd2cSJim Jagielski 		0,   // 'v'
3803*b1cdbd2cSJim Jagielski 		0,   // 'w'
3804*b1cdbd2cSJim Jagielski 		0,   // 'x'
3805*b1cdbd2cSJim Jagielski 		0,   // 'y'
3806*b1cdbd2cSJim Jagielski 		0,   // 'z'
3807*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '{'
3808*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '|'
3809*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '}'
3810*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE,   // '~'
3811*b1cdbd2cSJim Jagielski 		INetMIMEEncodedWordOutputSink::CONTEXT_TEXT | INetMIMEEncodedWordOutputSink::CONTEXT_COMMENT | INetMIMEEncodedWordOutputSink::CONTEXT_PHRASE }; // DEL
3812*b1cdbd2cSJim Jagielski 
3813*b1cdbd2cSJim Jagielski inline bool
needsEncodedWordEscape(sal_uInt32 nChar) const3814*b1cdbd2cSJim Jagielski INetMIMEEncodedWordOutputSink::needsEncodedWordEscape(sal_uInt32 nChar) const
3815*b1cdbd2cSJim Jagielski {
3816*b1cdbd2cSJim Jagielski 	return !INetMIME::isUSASCII(nChar) || aEscape[nChar] & m_eContext;
3817*b1cdbd2cSJim Jagielski }
3818*b1cdbd2cSJim Jagielski 
3819*b1cdbd2cSJim Jagielski //============================================================================
finish(bool bWriteTrailer)3820*b1cdbd2cSJim Jagielski void INetMIMEEncodedWordOutputSink::finish(bool bWriteTrailer)
3821*b1cdbd2cSJim Jagielski {
3822*b1cdbd2cSJim Jagielski 	if (m_eInitialSpace == SPACE_ALWAYS && m_nExtraSpaces == 0)
3823*b1cdbd2cSJim Jagielski 		m_nExtraSpaces = 1;
3824*b1cdbd2cSJim Jagielski 
3825*b1cdbd2cSJim Jagielski 	if (m_eEncodedWordState == STATE_SECOND_EQUALS)
3826*b1cdbd2cSJim Jagielski 	{
3827*b1cdbd2cSJim Jagielski 		// If the text is already an encoded word, copy it verbatim:
3828*b1cdbd2cSJim Jagielski 		sal_uInt32 nSize = m_pBufferEnd - m_pBuffer;
3829*b1cdbd2cSJim Jagielski 		switch (m_ePrevCoding)
3830*b1cdbd2cSJim Jagielski 		{
3831*b1cdbd2cSJim Jagielski 			case CODING_QUOTED:
3832*b1cdbd2cSJim Jagielski 				m_rSink << '"';
3833*b1cdbd2cSJim Jagielski 			case CODING_NONE:
3834*b1cdbd2cSJim Jagielski 				if (m_eInitialSpace == SPACE_ENCODED && m_nExtraSpaces == 0)
3835*b1cdbd2cSJim Jagielski 					m_nExtraSpaces = 1;
3836*b1cdbd2cSJim Jagielski 				for (; m_nExtraSpaces > 1; --m_nExtraSpaces)
3837*b1cdbd2cSJim Jagielski 				{
3838*b1cdbd2cSJim Jagielski 					if (m_rSink.getColumn() >= m_rSink.getLineLengthLimit())
3839*b1cdbd2cSJim Jagielski 						m_rSink << INetMIMEOutputSink::endl;
3840*b1cdbd2cSJim Jagielski 					m_rSink << ' ';
3841*b1cdbd2cSJim Jagielski 				}
3842*b1cdbd2cSJim Jagielski 				if (m_nExtraSpaces == 1)
3843*b1cdbd2cSJim Jagielski 				{
3844*b1cdbd2cSJim Jagielski 					if (m_rSink.getColumn() + nSize
3845*b1cdbd2cSJim Jagielski 						    >= m_rSink.getLineLengthLimit())
3846*b1cdbd2cSJim Jagielski 						m_rSink << INetMIMEOutputSink::endl;
3847*b1cdbd2cSJim Jagielski 					m_rSink << ' ';
3848*b1cdbd2cSJim Jagielski 				}
3849*b1cdbd2cSJim Jagielski 				break;
3850*b1cdbd2cSJim Jagielski 
3851*b1cdbd2cSJim Jagielski 			case CODING_ENCODED:
3852*b1cdbd2cSJim Jagielski 			{
3853*b1cdbd2cSJim Jagielski 				const sal_Char * pCharsetName
3854*b1cdbd2cSJim Jagielski 				 = INetMIME::getCharsetName(m_ePrevMIMEEncoding);
3855*b1cdbd2cSJim Jagielski 				while (m_nExtraSpaces-- > 0)
3856*b1cdbd2cSJim Jagielski 				{
3857*b1cdbd2cSJim Jagielski 					if (m_rSink.getColumn()
3858*b1cdbd2cSJim Jagielski 						    > m_rSink.getLineLengthLimit() - 3)
3859*b1cdbd2cSJim Jagielski 						m_rSink << "?=" << INetMIMEOutputSink::endl << " =?"
3860*b1cdbd2cSJim Jagielski 								<< pCharsetName << "?Q?";
3861*b1cdbd2cSJim Jagielski 					m_rSink << '_';
3862*b1cdbd2cSJim Jagielski 				}
3863*b1cdbd2cSJim Jagielski 				m_rSink << "?=";
3864*b1cdbd2cSJim Jagielski 			}
3865*b1cdbd2cSJim Jagielski 			case CODING_ENCODED_TERMINATED:
3866*b1cdbd2cSJim Jagielski 				if (m_rSink.getColumn() + nSize
3867*b1cdbd2cSJim Jagielski 					    > m_rSink.getLineLengthLimit() - 1)
3868*b1cdbd2cSJim Jagielski 					m_rSink << INetMIMEOutputSink::endl;
3869*b1cdbd2cSJim Jagielski 				m_rSink << ' ';
3870*b1cdbd2cSJim Jagielski 				break;
3871*b1cdbd2cSJim Jagielski 		}
3872*b1cdbd2cSJim Jagielski 		m_rSink.write(m_pBuffer, m_pBufferEnd);
3873*b1cdbd2cSJim Jagielski 		m_eCoding = CODING_ENCODED_TERMINATED;
3874*b1cdbd2cSJim Jagielski 	}
3875*b1cdbd2cSJim Jagielski 	else
3876*b1cdbd2cSJim Jagielski 	{
3877*b1cdbd2cSJim Jagielski 		// If the text itself is too long to fit into a single line, make it
3878*b1cdbd2cSJim Jagielski 		// into multiple encoded words:
3879*b1cdbd2cSJim Jagielski 		switch (m_eCoding)
3880*b1cdbd2cSJim Jagielski 		{
3881*b1cdbd2cSJim Jagielski 			case CODING_NONE:
3882*b1cdbd2cSJim Jagielski 				if (m_nExtraSpaces == 0)
3883*b1cdbd2cSJim Jagielski 				{
3884*b1cdbd2cSJim Jagielski 					DBG_ASSERT(m_ePrevCoding == CODING_NONE
3885*b1cdbd2cSJim Jagielski 							   || m_pBuffer == m_pBufferEnd,
3886*b1cdbd2cSJim Jagielski 							   "INetMIMEEncodedWordOutputSink::finish():"
3887*b1cdbd2cSJim Jagielski 							       " Bad state");
3888*b1cdbd2cSJim Jagielski 					if (m_rSink.getColumn() + (m_pBufferEnd - m_pBuffer)
3889*b1cdbd2cSJim Jagielski 						    > m_rSink.getLineLengthLimit())
3890*b1cdbd2cSJim Jagielski 						m_eCoding = CODING_ENCODED;
3891*b1cdbd2cSJim Jagielski 				}
3892*b1cdbd2cSJim Jagielski 				else
3893*b1cdbd2cSJim Jagielski                 {
3894*b1cdbd2cSJim Jagielski                     OSL_ASSERT(m_pBufferEnd >= m_pBuffer);
3895*b1cdbd2cSJim Jagielski                     if (static_cast< std::size_t >(m_pBufferEnd - m_pBuffer)
3896*b1cdbd2cSJim Jagielski                         > m_rSink.getLineLengthLimit() - 1)
3897*b1cdbd2cSJim Jagielski                     {
3898*b1cdbd2cSJim Jagielski                         m_eCoding = CODING_ENCODED;
3899*b1cdbd2cSJim Jagielski                     }
3900*b1cdbd2cSJim Jagielski                 }
3901*b1cdbd2cSJim Jagielski 				break;
3902*b1cdbd2cSJim Jagielski 
3903*b1cdbd2cSJim Jagielski 			case CODING_QUOTED:
3904*b1cdbd2cSJim Jagielski 				if (m_nExtraSpaces == 0)
3905*b1cdbd2cSJim Jagielski 				{
3906*b1cdbd2cSJim Jagielski 					DBG_ASSERT(m_ePrevCoding == CODING_NONE,
3907*b1cdbd2cSJim Jagielski 							   "INetMIMEEncodedWordOutputSink::finish():"
3908*b1cdbd2cSJim Jagielski 							       " Bad state");
3909*b1cdbd2cSJim Jagielski 					if (m_rSink.getColumn() + (m_pBufferEnd - m_pBuffer)
3910*b1cdbd2cSJim Jagielski 						        + m_nQuotedEscaped
3911*b1cdbd2cSJim Jagielski 						    > m_rSink.getLineLengthLimit() - 2)
3912*b1cdbd2cSJim Jagielski 						m_eCoding = CODING_ENCODED;
3913*b1cdbd2cSJim Jagielski 				}
3914*b1cdbd2cSJim Jagielski 				else if ((m_pBufferEnd - m_pBuffer) + m_nQuotedEscaped
3915*b1cdbd2cSJim Jagielski 						     > m_rSink.getLineLengthLimit() - 3)
3916*b1cdbd2cSJim Jagielski 					m_eCoding = CODING_ENCODED;
3917*b1cdbd2cSJim Jagielski 				break;
3918*b1cdbd2cSJim Jagielski 
3919*b1cdbd2cSJim Jagielski             default:
3920*b1cdbd2cSJim Jagielski                 break;
3921*b1cdbd2cSJim Jagielski 		}
3922*b1cdbd2cSJim Jagielski 
3923*b1cdbd2cSJim Jagielski 		switch (m_eCoding)
3924*b1cdbd2cSJim Jagielski 		{
3925*b1cdbd2cSJim Jagielski 			case CODING_NONE:
3926*b1cdbd2cSJim Jagielski 				switch (m_ePrevCoding)
3927*b1cdbd2cSJim Jagielski 				{
3928*b1cdbd2cSJim Jagielski 					case CODING_QUOTED:
3929*b1cdbd2cSJim Jagielski 						if (m_rSink.getColumn() + m_nExtraSpaces
3930*b1cdbd2cSJim Jagielski 							        + (m_pBufferEnd - m_pBuffer)
3931*b1cdbd2cSJim Jagielski 							    < m_rSink.getLineLengthLimit())
3932*b1cdbd2cSJim Jagielski 							m_eCoding = CODING_QUOTED;
3933*b1cdbd2cSJim Jagielski 						else
3934*b1cdbd2cSJim Jagielski 							m_rSink << '"';
3935*b1cdbd2cSJim Jagielski 						break;
3936*b1cdbd2cSJim Jagielski 
3937*b1cdbd2cSJim Jagielski 					case CODING_ENCODED:
3938*b1cdbd2cSJim Jagielski 						m_rSink << "?=";
3939*b1cdbd2cSJim Jagielski 						break;
3940*b1cdbd2cSJim Jagielski 
3941*b1cdbd2cSJim Jagielski                     default:
3942*b1cdbd2cSJim Jagielski                         break;
3943*b1cdbd2cSJim Jagielski 				}
3944*b1cdbd2cSJim Jagielski 				for (; m_nExtraSpaces > 1; --m_nExtraSpaces)
3945*b1cdbd2cSJim Jagielski 				{
3946*b1cdbd2cSJim Jagielski 					if (m_rSink.getColumn() >= m_rSink.getLineLengthLimit())
3947*b1cdbd2cSJim Jagielski 						m_rSink << INetMIMEOutputSink::endl;
3948*b1cdbd2cSJim Jagielski 					m_rSink << ' ';
3949*b1cdbd2cSJim Jagielski 				}
3950*b1cdbd2cSJim Jagielski 				if (m_nExtraSpaces == 1)
3951*b1cdbd2cSJim Jagielski 				{
3952*b1cdbd2cSJim Jagielski 					if (m_rSink.getColumn() + (m_pBufferEnd - m_pBuffer)
3953*b1cdbd2cSJim Jagielski 						    >= m_rSink.getLineLengthLimit())
3954*b1cdbd2cSJim Jagielski 						m_rSink << INetMIMEOutputSink::endl;
3955*b1cdbd2cSJim Jagielski 					m_rSink << ' ';
3956*b1cdbd2cSJim Jagielski 				}
3957*b1cdbd2cSJim Jagielski 				m_rSink.write(m_pBuffer, m_pBufferEnd);
3958*b1cdbd2cSJim Jagielski 				if (m_eCoding == CODING_QUOTED && bWriteTrailer)
3959*b1cdbd2cSJim Jagielski 				{
3960*b1cdbd2cSJim Jagielski 					m_rSink << '"';
3961*b1cdbd2cSJim Jagielski 					m_eCoding = CODING_NONE;
3962*b1cdbd2cSJim Jagielski 				}
3963*b1cdbd2cSJim Jagielski 				break;
3964*b1cdbd2cSJim Jagielski 
3965*b1cdbd2cSJim Jagielski 			case CODING_QUOTED:
3966*b1cdbd2cSJim Jagielski 			{
3967*b1cdbd2cSJim Jagielski 				bool bInsertLeadingQuote = true;
3968*b1cdbd2cSJim Jagielski 				sal_uInt32 nSize = (m_pBufferEnd - m_pBuffer)
3969*b1cdbd2cSJim Jagielski 					                   + m_nQuotedEscaped + 2;
3970*b1cdbd2cSJim Jagielski 				switch (m_ePrevCoding)
3971*b1cdbd2cSJim Jagielski 				{
3972*b1cdbd2cSJim Jagielski 					case CODING_QUOTED:
3973*b1cdbd2cSJim Jagielski 						if (m_rSink.getColumn() + m_nExtraSpaces + nSize - 1
3974*b1cdbd2cSJim Jagielski 							    < m_rSink.getLineLengthLimit())
3975*b1cdbd2cSJim Jagielski 						{
3976*b1cdbd2cSJim Jagielski 							bInsertLeadingQuote = false;
3977*b1cdbd2cSJim Jagielski 							--nSize;
3978*b1cdbd2cSJim Jagielski 						}
3979*b1cdbd2cSJim Jagielski 						else
3980*b1cdbd2cSJim Jagielski 							m_rSink << '"';
3981*b1cdbd2cSJim Jagielski 						break;
3982*b1cdbd2cSJim Jagielski 
3983*b1cdbd2cSJim Jagielski 					case CODING_ENCODED:
3984*b1cdbd2cSJim Jagielski 						m_rSink << "?=";
3985*b1cdbd2cSJim Jagielski 						break;
3986*b1cdbd2cSJim Jagielski 
3987*b1cdbd2cSJim Jagielski                     default:
3988*b1cdbd2cSJim Jagielski                         break;
3989*b1cdbd2cSJim Jagielski 				}
3990*b1cdbd2cSJim Jagielski 				for (; m_nExtraSpaces > 1; --m_nExtraSpaces)
3991*b1cdbd2cSJim Jagielski 				{
3992*b1cdbd2cSJim Jagielski 					if (m_rSink.getColumn() >= m_rSink.getLineLengthLimit())
3993*b1cdbd2cSJim Jagielski 						m_rSink << INetMIMEOutputSink::endl;
3994*b1cdbd2cSJim Jagielski 					m_rSink << ' ';
3995*b1cdbd2cSJim Jagielski 				}
3996*b1cdbd2cSJim Jagielski 				if (m_nExtraSpaces == 1)
3997*b1cdbd2cSJim Jagielski 				{
3998*b1cdbd2cSJim Jagielski 					if (m_rSink.getColumn() + nSize
3999*b1cdbd2cSJim Jagielski 						    >= m_rSink.getLineLengthLimit())
4000*b1cdbd2cSJim Jagielski 						m_rSink << INetMIMEOutputSink::endl;
4001*b1cdbd2cSJim Jagielski 					m_rSink << ' ';
4002*b1cdbd2cSJim Jagielski 				}
4003*b1cdbd2cSJim Jagielski 				if (bInsertLeadingQuote)
4004*b1cdbd2cSJim Jagielski 					m_rSink << '"';
4005*b1cdbd2cSJim Jagielski 				for (const sal_Unicode * p = m_pBuffer; p != m_pBufferEnd;
4006*b1cdbd2cSJim Jagielski 					 ++p)
4007*b1cdbd2cSJim Jagielski 				{
4008*b1cdbd2cSJim Jagielski 					if (INetMIME::needsQuotedStringEscape(*p))
4009*b1cdbd2cSJim Jagielski 						m_rSink << '\\';
4010*b1cdbd2cSJim Jagielski 					m_rSink << sal_Char(*p);
4011*b1cdbd2cSJim Jagielski 				}
4012*b1cdbd2cSJim Jagielski 				if (bWriteTrailer)
4013*b1cdbd2cSJim Jagielski 				{
4014*b1cdbd2cSJim Jagielski 					m_rSink << '"';
4015*b1cdbd2cSJim Jagielski 					m_eCoding = CODING_NONE;
4016*b1cdbd2cSJim Jagielski 				}
4017*b1cdbd2cSJim Jagielski 				break;
4018*b1cdbd2cSJim Jagielski 			}
4019*b1cdbd2cSJim Jagielski 
4020*b1cdbd2cSJim Jagielski 			case CODING_ENCODED:
4021*b1cdbd2cSJim Jagielski 			{
4022*b1cdbd2cSJim Jagielski 				rtl_TextEncoding eCharsetEncoding
4023*b1cdbd2cSJim Jagielski 					= m_pEncodingList->
4024*b1cdbd2cSJim Jagielski 					      getPreferredEncoding(RTL_TEXTENCODING_UTF8);
4025*b1cdbd2cSJim Jagielski 				rtl_TextEncoding eMIMEEncoding
4026*b1cdbd2cSJim Jagielski 					= INetMIME::translateToMIME(eCharsetEncoding);
4027*b1cdbd2cSJim Jagielski 
4028*b1cdbd2cSJim Jagielski 				// The non UTF-8 code will only work for stateless single byte
4029*b1cdbd2cSJim Jagielski 				// character encodings (see also below):
4030*b1cdbd2cSJim Jagielski 				sal_Char * pTargetBuffer = NULL;
4031*b1cdbd2cSJim Jagielski 				sal_Size nTargetSize = 0;
4032*b1cdbd2cSJim Jagielski 				sal_uInt32 nSize;
4033*b1cdbd2cSJim Jagielski 				if (eMIMEEncoding == RTL_TEXTENCODING_UTF8)
4034*b1cdbd2cSJim Jagielski 				{
4035*b1cdbd2cSJim Jagielski 					nSize = 0;
4036*b1cdbd2cSJim Jagielski 					for (sal_Unicode const * p = m_pBuffer;
4037*b1cdbd2cSJim Jagielski 						 p != m_pBufferEnd;)
4038*b1cdbd2cSJim Jagielski 					{
4039*b1cdbd2cSJim Jagielski 						sal_uInt32 nUTF32
4040*b1cdbd2cSJim Jagielski 							= INetMIME::getUTF32Character(p, m_pBufferEnd);
4041*b1cdbd2cSJim Jagielski 						nSize += needsEncodedWordEscape(nUTF32) ?
4042*b1cdbd2cSJim Jagielski 							         3 * INetMIME::getUTF8OctetCount(nUTF32) :
4043*b1cdbd2cSJim Jagielski 							         1;
4044*b1cdbd2cSJim Jagielski 							// only US-ASCII characters (that are converted to
4045*b1cdbd2cSJim Jagielski 							// a single byte by UTF-8) need no encoded word
4046*b1cdbd2cSJim Jagielski 							// escapes...
4047*b1cdbd2cSJim Jagielski 					}
4048*b1cdbd2cSJim Jagielski 				}
4049*b1cdbd2cSJim Jagielski 				else
4050*b1cdbd2cSJim Jagielski 				{
4051*b1cdbd2cSJim Jagielski 					rtl_UnicodeToTextConverter hConverter
4052*b1cdbd2cSJim Jagielski 						= rtl_createUnicodeToTextConverter(eCharsetEncoding);
4053*b1cdbd2cSJim Jagielski 					rtl_UnicodeToTextContext hContext
4054*b1cdbd2cSJim Jagielski 						= rtl_createUnicodeToTextContext(hConverter);
4055*b1cdbd2cSJim Jagielski 					for (sal_Size nBufferSize = m_pBufferEnd - m_pBuffer;;
4056*b1cdbd2cSJim Jagielski 						 nBufferSize += nBufferSize / 3 + 1)
4057*b1cdbd2cSJim Jagielski 					{
4058*b1cdbd2cSJim Jagielski 						pTargetBuffer = new sal_Char[nBufferSize];
4059*b1cdbd2cSJim Jagielski 						sal_uInt32 nInfo;
4060*b1cdbd2cSJim Jagielski 						sal_Size nSrcCvtBytes;
4061*b1cdbd2cSJim Jagielski 						nTargetSize
4062*b1cdbd2cSJim Jagielski 							= rtl_convertUnicodeToText(
4063*b1cdbd2cSJim Jagielski 								  hConverter, hContext, m_pBuffer,
4064*b1cdbd2cSJim Jagielski 								  m_pBufferEnd - m_pBuffer, pTargetBuffer,
4065*b1cdbd2cSJim Jagielski 								  nBufferSize,
4066*b1cdbd2cSJim Jagielski 								  RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE
4067*b1cdbd2cSJim Jagielski 							         | RTL_UNICODETOTEXT_FLAGS_INVALID_IGNORE,
4068*b1cdbd2cSJim Jagielski 								  &nInfo, &nSrcCvtBytes);
4069*b1cdbd2cSJim Jagielski 						if (!(nInfo
4070*b1cdbd2cSJim Jagielski 							      & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
4071*b1cdbd2cSJim Jagielski 							break;
4072*b1cdbd2cSJim Jagielski 						delete[] pTargetBuffer;
4073*b1cdbd2cSJim Jagielski 						pTargetBuffer = NULL;
4074*b1cdbd2cSJim Jagielski 						rtl_resetUnicodeToTextContext(hConverter, hContext);
4075*b1cdbd2cSJim Jagielski 					}
4076*b1cdbd2cSJim Jagielski 					rtl_destroyUnicodeToTextContext(hConverter, hContext);
4077*b1cdbd2cSJim Jagielski 					rtl_destroyUnicodeToTextConverter(hConverter);
4078*b1cdbd2cSJim Jagielski 
4079*b1cdbd2cSJim Jagielski 					nSize = nTargetSize;
4080*b1cdbd2cSJim Jagielski 					for (sal_Size k = 0; k < nTargetSize; ++k)
4081*b1cdbd2cSJim Jagielski 						if (needsEncodedWordEscape(sal_uChar(
4082*b1cdbd2cSJim Jagielski 							                           pTargetBuffer[k])))
4083*b1cdbd2cSJim Jagielski 							nSize += 2;
4084*b1cdbd2cSJim Jagielski 				}
4085*b1cdbd2cSJim Jagielski 
4086*b1cdbd2cSJim Jagielski 				const sal_Char * pCharsetName
4087*b1cdbd2cSJim Jagielski 					= INetMIME::getCharsetName(eMIMEEncoding);
4088*b1cdbd2cSJim Jagielski 				sal_uInt32 nWrapperSize = rtl_str_getLength(pCharsetName) + 7;
4089*b1cdbd2cSJim Jagielski 					// '=?', '?Q?', '?='
4090*b1cdbd2cSJim Jagielski 
4091*b1cdbd2cSJim Jagielski 				switch (m_ePrevCoding)
4092*b1cdbd2cSJim Jagielski 				{
4093*b1cdbd2cSJim Jagielski 					case CODING_QUOTED:
4094*b1cdbd2cSJim Jagielski 						m_rSink << '"';
4095*b1cdbd2cSJim Jagielski 					case CODING_NONE:
4096*b1cdbd2cSJim Jagielski 						if (m_eInitialSpace == SPACE_ENCODED
4097*b1cdbd2cSJim Jagielski 							&& m_nExtraSpaces == 0)
4098*b1cdbd2cSJim Jagielski 							m_nExtraSpaces = 1;
4099*b1cdbd2cSJim Jagielski 						nSize += nWrapperSize;
4100*b1cdbd2cSJim Jagielski 						for (; m_nExtraSpaces > 1; --m_nExtraSpaces)
4101*b1cdbd2cSJim Jagielski 						{
4102*b1cdbd2cSJim Jagielski 							if (m_rSink.getColumn()
4103*b1cdbd2cSJim Jagielski 								    >= m_rSink.getLineLengthLimit())
4104*b1cdbd2cSJim Jagielski 								m_rSink << INetMIMEOutputSink::endl;
4105*b1cdbd2cSJim Jagielski 							m_rSink << ' ';
4106*b1cdbd2cSJim Jagielski 						}
4107*b1cdbd2cSJim Jagielski 						if (m_nExtraSpaces == 1)
4108*b1cdbd2cSJim Jagielski 						{
4109*b1cdbd2cSJim Jagielski 							if (m_rSink.getColumn() + nSize
4110*b1cdbd2cSJim Jagielski 								    >= m_rSink.getLineLengthLimit())
4111*b1cdbd2cSJim Jagielski 							m_rSink << INetMIMEOutputSink::endl;
4112*b1cdbd2cSJim Jagielski 							m_rSink << ' ';
4113*b1cdbd2cSJim Jagielski 						}
4114*b1cdbd2cSJim Jagielski 						m_rSink << "=?" << pCharsetName << "?Q?";
4115*b1cdbd2cSJim Jagielski 						break;
4116*b1cdbd2cSJim Jagielski 
4117*b1cdbd2cSJim Jagielski 					case CODING_ENCODED:
4118*b1cdbd2cSJim Jagielski 						if (m_ePrevMIMEEncoding != eMIMEEncoding
4119*b1cdbd2cSJim Jagielski 							|| m_rSink.getColumn() + m_nExtraSpaces + nSize
4120*b1cdbd2cSJim Jagielski 							       > m_rSink.getLineLengthLimit() - 2)
4121*b1cdbd2cSJim Jagielski 						{
4122*b1cdbd2cSJim Jagielski 							m_rSink << "?=";
4123*b1cdbd2cSJim Jagielski 							if (m_rSink.getColumn() + nWrapperSize
4124*b1cdbd2cSJim Jagielski 								        + m_nExtraSpaces + nSize
4125*b1cdbd2cSJim Jagielski 								    > m_rSink.getLineLengthLimit() - 1)
4126*b1cdbd2cSJim Jagielski 								m_rSink << INetMIMEOutputSink::endl;
4127*b1cdbd2cSJim Jagielski 							m_rSink << " =?" << pCharsetName << "?Q?";
4128*b1cdbd2cSJim Jagielski 						}
4129*b1cdbd2cSJim Jagielski 						while (m_nExtraSpaces-- > 0)
4130*b1cdbd2cSJim Jagielski 						{
4131*b1cdbd2cSJim Jagielski 							if (m_rSink.getColumn()
4132*b1cdbd2cSJim Jagielski 								    > m_rSink.getLineLengthLimit() - 3)
4133*b1cdbd2cSJim Jagielski 								m_rSink << "?=" << INetMIMEOutputSink::endl
4134*b1cdbd2cSJim Jagielski 										<< " =?" << pCharsetName << "?Q?";
4135*b1cdbd2cSJim Jagielski 							m_rSink << '_';
4136*b1cdbd2cSJim Jagielski 						}
4137*b1cdbd2cSJim Jagielski 						break;
4138*b1cdbd2cSJim Jagielski 
4139*b1cdbd2cSJim Jagielski 					case CODING_ENCODED_TERMINATED:
4140*b1cdbd2cSJim Jagielski 						if (m_rSink.getColumn() + nWrapperSize
4141*b1cdbd2cSJim Jagielski 							        + m_nExtraSpaces + nSize
4142*b1cdbd2cSJim Jagielski 							    > m_rSink.getLineLengthLimit() - 1)
4143*b1cdbd2cSJim Jagielski 							m_rSink << INetMIMEOutputSink::endl;
4144*b1cdbd2cSJim Jagielski 						m_rSink << " =?" << pCharsetName << "?Q?";
4145*b1cdbd2cSJim Jagielski 						while (m_nExtraSpaces-- > 0)
4146*b1cdbd2cSJim Jagielski 						{
4147*b1cdbd2cSJim Jagielski 							if (m_rSink.getColumn()
4148*b1cdbd2cSJim Jagielski 								    > m_rSink.getLineLengthLimit() - 3)
4149*b1cdbd2cSJim Jagielski 								m_rSink << "?=" << INetMIMEOutputSink::endl
4150*b1cdbd2cSJim Jagielski 										<< " =?" << pCharsetName << "?Q?";
4151*b1cdbd2cSJim Jagielski 							m_rSink << '_';
4152*b1cdbd2cSJim Jagielski 						}
4153*b1cdbd2cSJim Jagielski 						break;
4154*b1cdbd2cSJim Jagielski 				}
4155*b1cdbd2cSJim Jagielski 
4156*b1cdbd2cSJim Jagielski 				// The non UTF-8 code will only work for stateless single byte
4157*b1cdbd2cSJim Jagielski 				// character encodings (see also above):
4158*b1cdbd2cSJim Jagielski 				if (eMIMEEncoding == RTL_TEXTENCODING_UTF8)
4159*b1cdbd2cSJim Jagielski 				{
4160*b1cdbd2cSJim Jagielski 					bool bInitial = true;
4161*b1cdbd2cSJim Jagielski 					for (sal_Unicode const * p = m_pBuffer;
4162*b1cdbd2cSJim Jagielski 						 p != m_pBufferEnd;)
4163*b1cdbd2cSJim Jagielski 					{
4164*b1cdbd2cSJim Jagielski 						sal_uInt32 nUTF32
4165*b1cdbd2cSJim Jagielski 							= INetMIME::getUTF32Character(p, m_pBufferEnd);
4166*b1cdbd2cSJim Jagielski 						bool bEscape = needsEncodedWordEscape(nUTF32);
4167*b1cdbd2cSJim Jagielski 						sal_uInt32 nWidth
4168*b1cdbd2cSJim Jagielski 							= bEscape ?
4169*b1cdbd2cSJim Jagielski 							      3 * INetMIME::getUTF8OctetCount(nUTF32) : 1;
4170*b1cdbd2cSJim Jagielski 							// only US-ASCII characters (that are converted to
4171*b1cdbd2cSJim Jagielski 							// a single byte by UTF-8) need no encoded word
4172*b1cdbd2cSJim Jagielski 							// escapes...
4173*b1cdbd2cSJim Jagielski 						if (!bInitial
4174*b1cdbd2cSJim Jagielski 							&& m_rSink.getColumn() + nWidth + 2
4175*b1cdbd2cSJim Jagielski 							       > m_rSink.getLineLengthLimit())
4176*b1cdbd2cSJim Jagielski 							m_rSink << "?=" << INetMIMEOutputSink::endl
4177*b1cdbd2cSJim Jagielski 									<< " =?" << pCharsetName << "?Q?";
4178*b1cdbd2cSJim Jagielski 						if (bEscape)
4179*b1cdbd2cSJim Jagielski 						{
4180*b1cdbd2cSJim Jagielski 							DBG_ASSERT(
4181*b1cdbd2cSJim Jagielski 								nUTF32 < 0x10FFFF,
4182*b1cdbd2cSJim Jagielski 								"INetMIMEEncodedWordOutputSink::finish():"
4183*b1cdbd2cSJim Jagielski 								    " Bad char");
4184*b1cdbd2cSJim Jagielski 							if (nUTF32 < 0x80)
4185*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4186*b1cdbd2cSJim Jagielski 															  nUTF32);
4187*b1cdbd2cSJim Jagielski 							else if (nUTF32 < 0x800)
4188*b1cdbd2cSJim Jagielski 							{
4189*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4190*b1cdbd2cSJim Jagielski 															  (nUTF32 >> 6)
4191*b1cdbd2cSJim Jagielski 															      | 0xC0);
4192*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4193*b1cdbd2cSJim Jagielski 															  (nUTF32 & 0x3F)
4194*b1cdbd2cSJim Jagielski 															      | 0x80);
4195*b1cdbd2cSJim Jagielski 							}
4196*b1cdbd2cSJim Jagielski 							else if (nUTF32 < 0x10000)
4197*b1cdbd2cSJim Jagielski 							{
4198*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4199*b1cdbd2cSJim Jagielski 															  (nUTF32 >> 12)
4200*b1cdbd2cSJim Jagielski 															      | 0xE0);
4201*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4202*b1cdbd2cSJim Jagielski 															  ((nUTF32 >> 6)
4203*b1cdbd2cSJim Jagielski 															          & 0x3F)
4204*b1cdbd2cSJim Jagielski 															      | 0x80);
4205*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4206*b1cdbd2cSJim Jagielski 															  (nUTF32 & 0x3F)
4207*b1cdbd2cSJim Jagielski 															      | 0x80);
4208*b1cdbd2cSJim Jagielski 							}
4209*b1cdbd2cSJim Jagielski 							else
4210*b1cdbd2cSJim Jagielski 							{
4211*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4212*b1cdbd2cSJim Jagielski 															  (nUTF32 >> 18)
4213*b1cdbd2cSJim Jagielski 															      | 0xF0);
4214*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4215*b1cdbd2cSJim Jagielski 															  ((nUTF32 >> 12)
4216*b1cdbd2cSJim Jagielski 															          & 0x3F)
4217*b1cdbd2cSJim Jagielski 															      | 0x80);
4218*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4219*b1cdbd2cSJim Jagielski 															  ((nUTF32 >> 6)
4220*b1cdbd2cSJim Jagielski 															          & 0x3F)
4221*b1cdbd2cSJim Jagielski 															      | 0x80);
4222*b1cdbd2cSJim Jagielski 								INetMIME::writeEscapeSequence(m_rSink,
4223*b1cdbd2cSJim Jagielski 															  (nUTF32 & 0x3F)
4224*b1cdbd2cSJim Jagielski 															      | 0x80);
4225*b1cdbd2cSJim Jagielski 							}
4226*b1cdbd2cSJim Jagielski 						}
4227*b1cdbd2cSJim Jagielski 						else
4228*b1cdbd2cSJim Jagielski 							m_rSink << sal_Char(nUTF32);
4229*b1cdbd2cSJim Jagielski 						bInitial = false;
4230*b1cdbd2cSJim Jagielski 					}
4231*b1cdbd2cSJim Jagielski 				}
4232*b1cdbd2cSJim Jagielski 				else
4233*b1cdbd2cSJim Jagielski 				{
4234*b1cdbd2cSJim Jagielski 					for (sal_Size k = 0; k < nTargetSize; ++k)
4235*b1cdbd2cSJim Jagielski 					{
4236*b1cdbd2cSJim Jagielski 						sal_uInt32 nUCS4 = sal_uChar(pTargetBuffer[k]);
4237*b1cdbd2cSJim Jagielski 						bool bEscape = needsEncodedWordEscape(nUCS4);
4238*b1cdbd2cSJim Jagielski 						if (k > 0
4239*b1cdbd2cSJim Jagielski 							&& m_rSink.getColumn() + (bEscape ? 5 : 3)
4240*b1cdbd2cSJim Jagielski 							       > m_rSink.getLineLengthLimit())
4241*b1cdbd2cSJim Jagielski 							m_rSink << "?=" << INetMIMEOutputSink::endl
4242*b1cdbd2cSJim Jagielski 									<< " =?" << pCharsetName << "?Q?";
4243*b1cdbd2cSJim Jagielski 						if (bEscape)
4244*b1cdbd2cSJim Jagielski 							INetMIME::writeEscapeSequence(m_rSink, nUCS4);
4245*b1cdbd2cSJim Jagielski 						else
4246*b1cdbd2cSJim Jagielski 							m_rSink << sal_Char(nUCS4);
4247*b1cdbd2cSJim Jagielski 					}
4248*b1cdbd2cSJim Jagielski 					delete[] pTargetBuffer;
4249*b1cdbd2cSJim Jagielski 				}
4250*b1cdbd2cSJim Jagielski 
4251*b1cdbd2cSJim Jagielski 				if (bWriteTrailer)
4252*b1cdbd2cSJim Jagielski 				{
4253*b1cdbd2cSJim Jagielski 					m_rSink << "?=";
4254*b1cdbd2cSJim Jagielski 					m_eCoding = CODING_ENCODED_TERMINATED;
4255*b1cdbd2cSJim Jagielski 				}
4256*b1cdbd2cSJim Jagielski 
4257*b1cdbd2cSJim Jagielski 				m_ePrevMIMEEncoding = eMIMEEncoding;
4258*b1cdbd2cSJim Jagielski 				break;
4259*b1cdbd2cSJim Jagielski 			}
4260*b1cdbd2cSJim Jagielski 
4261*b1cdbd2cSJim Jagielski             default:
4262*b1cdbd2cSJim Jagielski                 OSL_ASSERT(false);
4263*b1cdbd2cSJim Jagielski                 break;
4264*b1cdbd2cSJim Jagielski 		}
4265*b1cdbd2cSJim Jagielski 	}
4266*b1cdbd2cSJim Jagielski 
4267*b1cdbd2cSJim Jagielski 	m_eInitialSpace = SPACE_NO;
4268*b1cdbd2cSJim Jagielski 	m_nExtraSpaces = 0;
4269*b1cdbd2cSJim Jagielski 	m_pEncodingList->reset();
4270*b1cdbd2cSJim Jagielski 	m_pBufferEnd = m_pBuffer;
4271*b1cdbd2cSJim Jagielski 	m_ePrevCoding = m_eCoding;
4272*b1cdbd2cSJim Jagielski 	m_eCoding = CODING_NONE;
4273*b1cdbd2cSJim Jagielski 	m_nQuotedEscaped = 0;
4274*b1cdbd2cSJim Jagielski 	m_eEncodedWordState = STATE_INITIAL;
4275*b1cdbd2cSJim Jagielski }
4276*b1cdbd2cSJim Jagielski 
4277*b1cdbd2cSJim Jagielski //============================================================================
~INetMIMEEncodedWordOutputSink()4278*b1cdbd2cSJim Jagielski INetMIMEEncodedWordOutputSink::~INetMIMEEncodedWordOutputSink()
4279*b1cdbd2cSJim Jagielski {
4280*b1cdbd2cSJim Jagielski 	rtl_freeMemory(m_pBuffer);
4281*b1cdbd2cSJim Jagielski 	delete m_pEncodingList;
4282*b1cdbd2cSJim Jagielski }
4283*b1cdbd2cSJim Jagielski 
4284*b1cdbd2cSJim Jagielski //============================================================================
4285*b1cdbd2cSJim Jagielski INetMIMEEncodedWordOutputSink &
operator <<(sal_uInt32 nChar)4286*b1cdbd2cSJim Jagielski INetMIMEEncodedWordOutputSink::operator <<(sal_uInt32 nChar)
4287*b1cdbd2cSJim Jagielski {
4288*b1cdbd2cSJim Jagielski 	if (nChar == ' ')
4289*b1cdbd2cSJim Jagielski 	{
4290*b1cdbd2cSJim Jagielski 		if (m_pBufferEnd != m_pBuffer)
4291*b1cdbd2cSJim Jagielski 			finish(false);
4292*b1cdbd2cSJim Jagielski 		++m_nExtraSpaces;
4293*b1cdbd2cSJim Jagielski 	}
4294*b1cdbd2cSJim Jagielski 	else
4295*b1cdbd2cSJim Jagielski 	{
4296*b1cdbd2cSJim Jagielski 		// Check for an already encoded word:
4297*b1cdbd2cSJim Jagielski 		switch (m_eEncodedWordState)
4298*b1cdbd2cSJim Jagielski 		{
4299*b1cdbd2cSJim Jagielski 			case STATE_INITIAL:
4300*b1cdbd2cSJim Jagielski 				if (nChar == '=')
4301*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_FIRST_EQUALS;
4302*b1cdbd2cSJim Jagielski 				else
4303*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_BAD;
4304*b1cdbd2cSJim Jagielski 				break;
4305*b1cdbd2cSJim Jagielski 
4306*b1cdbd2cSJim Jagielski 			case STATE_FIRST_EQUALS:
4307*b1cdbd2cSJim Jagielski 				if (nChar == '?')
4308*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_FIRST_EQUALS;
4309*b1cdbd2cSJim Jagielski 				else
4310*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_BAD;
4311*b1cdbd2cSJim Jagielski 				break;
4312*b1cdbd2cSJim Jagielski 
4313*b1cdbd2cSJim Jagielski 			case STATE_FIRST_QUESTION:
4314*b1cdbd2cSJim Jagielski 				if (INetMIME::isEncodedWordTokenChar(nChar))
4315*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_CHARSET;
4316*b1cdbd2cSJim Jagielski 				else
4317*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_BAD;
4318*b1cdbd2cSJim Jagielski 				break;
4319*b1cdbd2cSJim Jagielski 
4320*b1cdbd2cSJim Jagielski 			case STATE_CHARSET:
4321*b1cdbd2cSJim Jagielski 				if (nChar == '?')
4322*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_SECOND_QUESTION;
4323*b1cdbd2cSJim Jagielski 				else if (!INetMIME::isEncodedWordTokenChar(nChar))
4324*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_BAD;
4325*b1cdbd2cSJim Jagielski 				break;
4326*b1cdbd2cSJim Jagielski 
4327*b1cdbd2cSJim Jagielski 			case STATE_SECOND_QUESTION:
4328*b1cdbd2cSJim Jagielski 				if (nChar == 'B' || nChar == 'Q'
4329*b1cdbd2cSJim Jagielski 					|| nChar == 'b' || nChar == 'q')
4330*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_ENCODING;
4331*b1cdbd2cSJim Jagielski 				else
4332*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_BAD;
4333*b1cdbd2cSJim Jagielski 				break;
4334*b1cdbd2cSJim Jagielski 
4335*b1cdbd2cSJim Jagielski 			case STATE_ENCODING:
4336*b1cdbd2cSJim Jagielski 				if (nChar == '?')
4337*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_THIRD_QUESTION;
4338*b1cdbd2cSJim Jagielski 				else
4339*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_BAD;
4340*b1cdbd2cSJim Jagielski 				break;
4341*b1cdbd2cSJim Jagielski 
4342*b1cdbd2cSJim Jagielski 			case STATE_THIRD_QUESTION:
4343*b1cdbd2cSJim Jagielski 				if (INetMIME::isVisible(nChar) && nChar != '?')
4344*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_ENCODED_TEXT;
4345*b1cdbd2cSJim Jagielski 				else
4346*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_BAD;
4347*b1cdbd2cSJim Jagielski 				break;
4348*b1cdbd2cSJim Jagielski 
4349*b1cdbd2cSJim Jagielski 			case STATE_ENCODED_TEXT:
4350*b1cdbd2cSJim Jagielski 				if (nChar == '?')
4351*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_FOURTH_QUESTION;
4352*b1cdbd2cSJim Jagielski 				else if (!INetMIME::isVisible(nChar))
4353*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_BAD;
4354*b1cdbd2cSJim Jagielski 				break;
4355*b1cdbd2cSJim Jagielski 
4356*b1cdbd2cSJim Jagielski 			case STATE_FOURTH_QUESTION:
4357*b1cdbd2cSJim Jagielski 				if (nChar == '=')
4358*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_SECOND_EQUALS;
4359*b1cdbd2cSJim Jagielski 				else
4360*b1cdbd2cSJim Jagielski 					m_eEncodedWordState = STATE_BAD;
4361*b1cdbd2cSJim Jagielski 				break;
4362*b1cdbd2cSJim Jagielski 
4363*b1cdbd2cSJim Jagielski 			case STATE_SECOND_EQUALS:
4364*b1cdbd2cSJim Jagielski 				m_eEncodedWordState = STATE_BAD;
4365*b1cdbd2cSJim Jagielski 				break;
4366*b1cdbd2cSJim Jagielski 
4367*b1cdbd2cSJim Jagielski             case STATE_BAD:
4368*b1cdbd2cSJim Jagielski                 break;
4369*b1cdbd2cSJim Jagielski 		}
4370*b1cdbd2cSJim Jagielski 
4371*b1cdbd2cSJim Jagielski 		// Update encoding:
4372*b1cdbd2cSJim Jagielski 		m_pEncodingList->includes(nChar);
4373*b1cdbd2cSJim Jagielski 
4374*b1cdbd2cSJim Jagielski 		// Update coding:
4375*b1cdbd2cSJim Jagielski 		enum { TENQ = 1,   // CONTEXT_TEXT, CODING_ENCODED
4376*b1cdbd2cSJim Jagielski 			   CENQ = 2,   // CONTEXT_COMMENT, CODING_ENCODED
4377*b1cdbd2cSJim Jagielski 			   PQTD = 4,   // CONTEXT_PHRASE, CODING_QUOTED
4378*b1cdbd2cSJim Jagielski 			   PENQ = 8 }; // CONTEXT_PHRASE, CODING_ENCODED
4379*b1cdbd2cSJim Jagielski 		static const sal_Char aMinimal[128]
4380*b1cdbd2cSJim Jagielski 			= { TENQ | CENQ        | PENQ,   // 0x00
4381*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x01
4382*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x02
4383*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x03
4384*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x04
4385*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x05
4386*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x06
4387*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x07
4388*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x08
4389*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x09
4390*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x0A
4391*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x0B
4392*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x0C
4393*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x0D
4394*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x0E
4395*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x0F
4396*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x10
4397*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x11
4398*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x12
4399*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x13
4400*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x14
4401*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x15
4402*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x16
4403*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x17
4404*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x18
4405*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x19
4406*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x1A
4407*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x1B
4408*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x1C
4409*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x1D
4410*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x1E
4411*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ,   // 0x1F
4412*b1cdbd2cSJim Jagielski 										0,   // ' '
4413*b1cdbd2cSJim Jagielski 										0,   // '!'
4414*b1cdbd2cSJim Jagielski 							  PQTD       ,   // '"'
4415*b1cdbd2cSJim Jagielski 										0,   // '#'
4416*b1cdbd2cSJim Jagielski 										0,   // '$'
4417*b1cdbd2cSJim Jagielski 										0,   // '%'
4418*b1cdbd2cSJim Jagielski 										0,   // '&'
4419*b1cdbd2cSJim Jagielski 										0,   // '''
4420*b1cdbd2cSJim Jagielski 					   CENQ | PQTD       ,   // '('
4421*b1cdbd2cSJim Jagielski 					   CENQ | PQTD       ,   // ')'
4422*b1cdbd2cSJim Jagielski 										0,   // '*'
4423*b1cdbd2cSJim Jagielski 										0,   // '+'
4424*b1cdbd2cSJim Jagielski 							  PQTD       ,   // ','
4425*b1cdbd2cSJim Jagielski 										0,   // '-'
4426*b1cdbd2cSJim Jagielski 							  PQTD       ,   // '.'
4427*b1cdbd2cSJim Jagielski 										0,   // '/'
4428*b1cdbd2cSJim Jagielski 										0,   // '0'
4429*b1cdbd2cSJim Jagielski 										0,   // '1'
4430*b1cdbd2cSJim Jagielski 										0,   // '2'
4431*b1cdbd2cSJim Jagielski 										0,   // '3'
4432*b1cdbd2cSJim Jagielski 										0,   // '4'
4433*b1cdbd2cSJim Jagielski 										0,   // '5'
4434*b1cdbd2cSJim Jagielski 										0,   // '6'
4435*b1cdbd2cSJim Jagielski 										0,   // '7'
4436*b1cdbd2cSJim Jagielski 										0,   // '8'
4437*b1cdbd2cSJim Jagielski 										0,   // '9'
4438*b1cdbd2cSJim Jagielski 							  PQTD       ,   // ':'
4439*b1cdbd2cSJim Jagielski 							  PQTD       ,   // ';'
4440*b1cdbd2cSJim Jagielski 							  PQTD       ,   // '<'
4441*b1cdbd2cSJim Jagielski 										0,   // '='
4442*b1cdbd2cSJim Jagielski 							  PQTD       ,   // '>'
4443*b1cdbd2cSJim Jagielski 										0,   // '?'
4444*b1cdbd2cSJim Jagielski 							  PQTD       ,   // '@'
4445*b1cdbd2cSJim Jagielski 										0,   // 'A'
4446*b1cdbd2cSJim Jagielski 										0,   // 'B'
4447*b1cdbd2cSJim Jagielski 										0,   // 'C'
4448*b1cdbd2cSJim Jagielski 										0,   // 'D'
4449*b1cdbd2cSJim Jagielski 										0,   // 'E'
4450*b1cdbd2cSJim Jagielski 										0,   // 'F'
4451*b1cdbd2cSJim Jagielski 										0,   // 'G'
4452*b1cdbd2cSJim Jagielski 										0,   // 'H'
4453*b1cdbd2cSJim Jagielski 										0,   // 'I'
4454*b1cdbd2cSJim Jagielski 										0,   // 'J'
4455*b1cdbd2cSJim Jagielski 										0,   // 'K'
4456*b1cdbd2cSJim Jagielski 										0,   // 'L'
4457*b1cdbd2cSJim Jagielski 										0,   // 'M'
4458*b1cdbd2cSJim Jagielski 										0,   // 'N'
4459*b1cdbd2cSJim Jagielski 										0,   // 'O'
4460*b1cdbd2cSJim Jagielski 										0,   // 'P'
4461*b1cdbd2cSJim Jagielski 										0,   // 'Q'
4462*b1cdbd2cSJim Jagielski 										0,   // 'R'
4463*b1cdbd2cSJim Jagielski 										0,   // 'S'
4464*b1cdbd2cSJim Jagielski 										0,   // 'T'
4465*b1cdbd2cSJim Jagielski 										0,   // 'U'
4466*b1cdbd2cSJim Jagielski 										0,   // 'V'
4467*b1cdbd2cSJim Jagielski 										0,   // 'W'
4468*b1cdbd2cSJim Jagielski 										0,   // 'X'
4469*b1cdbd2cSJim Jagielski 										0,   // 'Y'
4470*b1cdbd2cSJim Jagielski 										0,   // 'Z'
4471*b1cdbd2cSJim Jagielski 							  PQTD       ,   // '['
4472*b1cdbd2cSJim Jagielski 					   CENQ | PQTD       ,   // '\'
4473*b1cdbd2cSJim Jagielski 							  PQTD       ,   // ']'
4474*b1cdbd2cSJim Jagielski 										0,   // '^'
4475*b1cdbd2cSJim Jagielski 										0,   // '_'
4476*b1cdbd2cSJim Jagielski 										0,   // '`'
4477*b1cdbd2cSJim Jagielski 										0,   // 'a'
4478*b1cdbd2cSJim Jagielski 										0,   // 'b'
4479*b1cdbd2cSJim Jagielski 										0,   // 'c'
4480*b1cdbd2cSJim Jagielski 										0,   // 'd'
4481*b1cdbd2cSJim Jagielski 										0,   // 'e'
4482*b1cdbd2cSJim Jagielski 										0,   // 'f'
4483*b1cdbd2cSJim Jagielski 										0,   // 'g'
4484*b1cdbd2cSJim Jagielski 										0,   // 'h'
4485*b1cdbd2cSJim Jagielski 										0,   // 'i'
4486*b1cdbd2cSJim Jagielski 										0,   // 'j'
4487*b1cdbd2cSJim Jagielski 										0,   // 'k'
4488*b1cdbd2cSJim Jagielski 										0,   // 'l'
4489*b1cdbd2cSJim Jagielski 										0,   // 'm'
4490*b1cdbd2cSJim Jagielski 										0,   // 'n'
4491*b1cdbd2cSJim Jagielski 										0,   // 'o'
4492*b1cdbd2cSJim Jagielski 										0,   // 'p'
4493*b1cdbd2cSJim Jagielski 										0,   // 'q'
4494*b1cdbd2cSJim Jagielski 										0,   // 'r'
4495*b1cdbd2cSJim Jagielski 										0,   // 's'
4496*b1cdbd2cSJim Jagielski 										0,   // 't'
4497*b1cdbd2cSJim Jagielski 										0,   // 'u'
4498*b1cdbd2cSJim Jagielski 										0,   // 'v'
4499*b1cdbd2cSJim Jagielski 										0,   // 'w'
4500*b1cdbd2cSJim Jagielski 										0,   // 'x'
4501*b1cdbd2cSJim Jagielski 										0,   // 'y'
4502*b1cdbd2cSJim Jagielski 										0,   // 'z'
4503*b1cdbd2cSJim Jagielski 										0,   // '{'
4504*b1cdbd2cSJim Jagielski 										0,   // '|'
4505*b1cdbd2cSJim Jagielski 										0,   // '}'
4506*b1cdbd2cSJim Jagielski 										0,   // '~'
4507*b1cdbd2cSJim Jagielski 				TENQ | CENQ        | PENQ }; // DEL
4508*b1cdbd2cSJim Jagielski 		Coding eNewCoding = !INetMIME::isUSASCII(nChar) ? CODING_ENCODED :
4509*b1cdbd2cSJim Jagielski 		                    m_eContext == CONTEXT_PHRASE ?
4510*b1cdbd2cSJim Jagielski 			                    Coding(aMinimal[nChar] >> 2) :
4511*b1cdbd2cSJim Jagielski 		                    aMinimal[nChar] & m_eContext ? CODING_ENCODED :
4512*b1cdbd2cSJim Jagielski 		                                                   CODING_NONE;
4513*b1cdbd2cSJim Jagielski 		if (eNewCoding > m_eCoding)
4514*b1cdbd2cSJim Jagielski 			m_eCoding = eNewCoding;
4515*b1cdbd2cSJim Jagielski 		if (m_eCoding == CODING_QUOTED
4516*b1cdbd2cSJim Jagielski 			&& INetMIME::needsQuotedStringEscape(nChar))
4517*b1cdbd2cSJim Jagielski 			++m_nQuotedEscaped;
4518*b1cdbd2cSJim Jagielski 
4519*b1cdbd2cSJim Jagielski 		// Append to buffer:
4520*b1cdbd2cSJim Jagielski 		if (sal_uInt32(m_pBufferEnd - m_pBuffer) == m_nBufferSize)
4521*b1cdbd2cSJim Jagielski 		{
4522*b1cdbd2cSJim Jagielski 			m_pBuffer
4523*b1cdbd2cSJim Jagielski 				= static_cast< sal_Unicode * >(
4524*b1cdbd2cSJim Jagielski 					  rtl_reallocateMemory(m_pBuffer,
4525*b1cdbd2cSJim Jagielski 										   (m_nBufferSize + BUFFER_SIZE)
4526*b1cdbd2cSJim Jagielski 										       * sizeof (sal_Unicode)));
4527*b1cdbd2cSJim Jagielski 			m_pBufferEnd = m_pBuffer + m_nBufferSize;
4528*b1cdbd2cSJim Jagielski 			m_nBufferSize += BUFFER_SIZE;
4529*b1cdbd2cSJim Jagielski 		}
4530*b1cdbd2cSJim Jagielski 		*m_pBufferEnd++ = sal_Unicode(nChar);
4531*b1cdbd2cSJim Jagielski 	}
4532*b1cdbd2cSJim Jagielski 	return *this;
4533*b1cdbd2cSJim Jagielski }
4534*b1cdbd2cSJim Jagielski 
4535*b1cdbd2cSJim Jagielski //============================================================================
4536*b1cdbd2cSJim Jagielski //
4537*b1cdbd2cSJim Jagielski //  INetContentTypeParameterList
4538*b1cdbd2cSJim Jagielski //
4539*b1cdbd2cSJim Jagielski //============================================================================
4540*b1cdbd2cSJim Jagielski 
Clear()4541*b1cdbd2cSJim Jagielski void INetContentTypeParameterList::Clear()
4542*b1cdbd2cSJim Jagielski {
4543*b1cdbd2cSJim Jagielski 	while (Count() > 0)
4544*b1cdbd2cSJim Jagielski 		delete static_cast< INetContentTypeParameter * >(Remove(Count() - 1));
4545*b1cdbd2cSJim Jagielski }
4546*b1cdbd2cSJim Jagielski 
4547*b1cdbd2cSJim Jagielski //============================================================================
4548*b1cdbd2cSJim Jagielski const INetContentTypeParameter *
find(const ByteString & rAttribute) const4549*b1cdbd2cSJim Jagielski INetContentTypeParameterList::find(const ByteString & rAttribute) const
4550*b1cdbd2cSJim Jagielski {
4551*b1cdbd2cSJim Jagielski 	for (sal_uIntPtr i = 0; i < Count(); ++i)
4552*b1cdbd2cSJim Jagielski 	{
4553*b1cdbd2cSJim Jagielski 		const INetContentTypeParameter * pParameter = GetObject(i);
4554*b1cdbd2cSJim Jagielski 		if (pParameter->m_sAttribute.EqualsIgnoreCaseAscii(rAttribute))
4555*b1cdbd2cSJim Jagielski 			return pParameter;
4556*b1cdbd2cSJim Jagielski 	}
4557*b1cdbd2cSJim Jagielski 	return 0;
4558*b1cdbd2cSJim Jagielski }
4559*b1cdbd2cSJim Jagielski 
4560