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