xref: /aoo41x/main/tools/source/inet/inetmsg.cxx (revision 89b56da7)
1*89b56da7SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*89b56da7SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*89b56da7SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*89b56da7SAndrew Rist  * distributed with this work for additional information
6*89b56da7SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*89b56da7SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*89b56da7SAndrew Rist  * "License"); you may not use this file except in compliance
9*89b56da7SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*89b56da7SAndrew Rist  *
11*89b56da7SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*89b56da7SAndrew Rist  *
13*89b56da7SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*89b56da7SAndrew Rist  * software distributed under the License is distributed on an
15*89b56da7SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*89b56da7SAndrew Rist  * KIND, either express or implied.  See the License for the
17*89b56da7SAndrew Rist  * specific language governing permissions and limitations
18*89b56da7SAndrew Rist  * under the License.
19*89b56da7SAndrew Rist  *
20*89b56da7SAndrew Rist  *************************************************************/
21*89b56da7SAndrew Rist 
22*89b56da7SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_tools.hxx"
26cdf0e10cSrcweir #include <sal/types.h>
27cdf0e10cSrcweir #include <tools/datetime.hxx>
28cdf0e10cSrcweir #ifndef _TOOLS_INETMIME_HXX
29cdf0e10cSrcweir #include <tools/inetmime.hxx>
30cdf0e10cSrcweir #endif
31cdf0e10cSrcweir #include <tools/inetmsg.hxx>
32cdf0e10cSrcweir #include <tools/inetstrm.hxx>
33cdf0e10cSrcweir #include <rtl/instance.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <stdio.h>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir //=======================================================================
38cdf0e10cSrcweir 
ascii_isDigit(sal_Unicode ch)39cdf0e10cSrcweir inline sal_Bool ascii_isDigit( sal_Unicode ch )
40cdf0e10cSrcweir {
41cdf0e10cSrcweir     return ((ch >= 0x0030) && (ch <= 0x0039));
42cdf0e10cSrcweir }
43cdf0e10cSrcweir 
ascii_isLetter(sal_Unicode ch)44cdf0e10cSrcweir inline sal_Bool ascii_isLetter( sal_Unicode ch )
45cdf0e10cSrcweir {
46cdf0e10cSrcweir     return (( (ch >= 0x0041) && (ch <= 0x005A)) || ((ch >= 0x0061) && (ch <= 0x007A)));
47cdf0e10cSrcweir }
48cdf0e10cSrcweir 
ascii_toLowerCase(sal_Unicode ch)49cdf0e10cSrcweir inline sal_Unicode ascii_toLowerCase( sal_Unicode ch )
50cdf0e10cSrcweir {
51cdf0e10cSrcweir     if ( (ch >= 0x0041) && (ch <= 0x005A) )
52cdf0e10cSrcweir         return ch + 0x20;
53cdf0e10cSrcweir     else
54cdf0e10cSrcweir         return ch;
55cdf0e10cSrcweir }
56cdf0e10cSrcweir 
57cdf0e10cSrcweir /*=======================================================================
58cdf0e10cSrcweir  *
59cdf0e10cSrcweir  * INetMessage Implementation.
60cdf0e10cSrcweir  *
61cdf0e10cSrcweir  *=====================================================================*/
62cdf0e10cSrcweir #define CONSTASCII_STRINGPARAM(a) (a), RTL_TEXTENCODING_ASCII_US
63cdf0e10cSrcweir #define HEADERFIELD INetMessageHeader
64cdf0e10cSrcweir 
65cdf0e10cSrcweir /*
66cdf0e10cSrcweir  * ~INetMessage.
67cdf0e10cSrcweir  */
~INetMessage(void)68cdf0e10cSrcweir INetMessage::~INetMessage (void)
69cdf0e10cSrcweir {
70cdf0e10cSrcweir     ListCleanup_Impl();
71cdf0e10cSrcweir }
72cdf0e10cSrcweir 
73cdf0e10cSrcweir /*
74cdf0e10cSrcweir  * ListCleanup_Impl.
75cdf0e10cSrcweir  */
ListCleanup_Impl(void)76cdf0e10cSrcweir void INetMessage::ListCleanup_Impl (void)
77cdf0e10cSrcweir {
78cdf0e10cSrcweir     // Cleanup.
79cdf0e10cSrcweir     sal_uIntPtr i, n = m_aHeaderList.Count();
80cdf0e10cSrcweir     for (i = 0; i < n; i++)
81cdf0e10cSrcweir         delete ((HEADERFIELD*)(m_aHeaderList.GetObject(i)));
82cdf0e10cSrcweir     m_aHeaderList.Clear();
83cdf0e10cSrcweir }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir /*
86cdf0e10cSrcweir  * ListCopy.
87cdf0e10cSrcweir  */
ListCopy(const INetMessage & rMsg)88cdf0e10cSrcweir void INetMessage::ListCopy (const INetMessage &rMsg)
89cdf0e10cSrcweir {
90cdf0e10cSrcweir     if (!(this == &rMsg))
91cdf0e10cSrcweir     {
92cdf0e10cSrcweir         // Cleanup.
93cdf0e10cSrcweir         ListCleanup_Impl();
94cdf0e10cSrcweir 
95cdf0e10cSrcweir         // Copy.
96cdf0e10cSrcweir         sal_uIntPtr i, n = rMsg.GetHeaderCount();
97cdf0e10cSrcweir         for (i = 0; i < n; i++)
98cdf0e10cSrcweir         {
99cdf0e10cSrcweir             HEADERFIELD *p = (HEADERFIELD*)(rMsg.m_aHeaderList.GetObject(i));
100cdf0e10cSrcweir             m_aHeaderList.Insert (new HEADERFIELD(*p), LIST_APPEND);
101cdf0e10cSrcweir         }
102cdf0e10cSrcweir     }
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir /*
106cdf0e10cSrcweir  * SetHeaderField_Impl.
107cdf0e10cSrcweir  */
SetHeaderField_Impl(INetMIME::HeaderFieldType eType,const ByteString & rName,const UniString & rValue,sal_uIntPtr & rnIndex)108cdf0e10cSrcweir void INetMessage::SetHeaderField_Impl (
109cdf0e10cSrcweir     INetMIME::HeaderFieldType  eType,
110cdf0e10cSrcweir     const ByteString          &rName,
111cdf0e10cSrcweir     const UniString           &rValue,
112cdf0e10cSrcweir     sal_uIntPtr                     &rnIndex)
113cdf0e10cSrcweir {
114cdf0e10cSrcweir     INetMIMEStringOutputSink aSink (0, STRING_MAXLEN);
115cdf0e10cSrcweir     INetMIME::writeHeaderFieldBody (
116cdf0e10cSrcweir         aSink, eType, rValue, gsl_getSystemTextEncoding(), false);
117cdf0e10cSrcweir     SetHeaderField_Impl (
118cdf0e10cSrcweir         INetMessageHeader (rName, aSink.takeBuffer()), rnIndex);
119cdf0e10cSrcweir }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir /*
122cdf0e10cSrcweir  * SetHeaderField.
123cdf0e10cSrcweir  */
SetHeaderField(const UniString & rName,const UniString & rValue,sal_uIntPtr nIndex)124cdf0e10cSrcweir sal_uIntPtr INetMessage::SetHeaderField (
125cdf0e10cSrcweir     const UniString& rName, const UniString& rValue, sal_uIntPtr nIndex)
126cdf0e10cSrcweir {
127cdf0e10cSrcweir     sal_uIntPtr nResult = nIndex;
128cdf0e10cSrcweir     SetHeaderField_Impl (
129cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
130cdf0e10cSrcweir         ByteString (rName, RTL_TEXTENCODING_ASCII_US), rValue,
131cdf0e10cSrcweir         nResult);
132cdf0e10cSrcweir     return nResult;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir /*
136cdf0e10cSrcweir  * SetHeaderField.
137cdf0e10cSrcweir  */
SetHeaderField(const INetMessageHeader & rHeader,sal_uIntPtr nIndex)138cdf0e10cSrcweir sal_uIntPtr INetMessage::SetHeaderField (
139cdf0e10cSrcweir     const INetMessageHeader &rHeader, sal_uIntPtr nIndex)
140cdf0e10cSrcweir {
141cdf0e10cSrcweir     sal_uIntPtr nResult = nIndex;
142cdf0e10cSrcweir     SetHeaderField_Impl (rHeader, nResult);
143cdf0e10cSrcweir     return nResult;
144cdf0e10cSrcweir }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 
147cdf0e10cSrcweir /*
148cdf0e10cSrcweir  * operator<<
149cdf0e10cSrcweir  */
operator <<(SvStream & rStrm) const150cdf0e10cSrcweir SvStream& INetMessage::operator<< (SvStream& rStrm) const
151cdf0e10cSrcweir {
152cdf0e10cSrcweir     rStrm << static_cast<sal_uInt32>(m_nDocSize);
153cdf0e10cSrcweir     rStrm.WriteByteString (m_aDocName, RTL_TEXTENCODING_UTF8);
154cdf0e10cSrcweir 
155cdf0e10cSrcweir     sal_uIntPtr i, n = m_aHeaderList.Count();
156cdf0e10cSrcweir     rStrm << static_cast<sal_uInt32>(n);
157cdf0e10cSrcweir 
158cdf0e10cSrcweir     for (i = 0; i < n; i++)
159cdf0e10cSrcweir         rStrm << *((HEADERFIELD *)(m_aHeaderList.GetObject(i)));
160cdf0e10cSrcweir 
161cdf0e10cSrcweir     return rStrm;
162cdf0e10cSrcweir }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir /*
165cdf0e10cSrcweir  * operator>>
166cdf0e10cSrcweir  */
operator >>(SvStream & rStrm)167cdf0e10cSrcweir SvStream& INetMessage::operator>> (SvStream& rStrm)
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     // Cleanup.
170cdf0e10cSrcweir     m_nDocSize = 0;
171cdf0e10cSrcweir     m_xDocLB.Clear();
172cdf0e10cSrcweir     ListCleanup_Impl();
173cdf0e10cSrcweir 
174cdf0e10cSrcweir     sal_uInt32 nTemp;
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     // Copy.
177cdf0e10cSrcweir     rStrm >> nTemp;
178cdf0e10cSrcweir     m_nDocSize = nTemp;
179cdf0e10cSrcweir     rStrm.ReadByteString (m_aDocName, RTL_TEXTENCODING_UTF8);
180cdf0e10cSrcweir 
181cdf0e10cSrcweir     sal_uIntPtr i, n = 0;
182cdf0e10cSrcweir     rStrm >> nTemp;
183cdf0e10cSrcweir     n = nTemp;
184cdf0e10cSrcweir 
185cdf0e10cSrcweir     for (i = 0; i < n; i++)
186cdf0e10cSrcweir     {
187cdf0e10cSrcweir         HEADERFIELD *p = new HEADERFIELD();
188cdf0e10cSrcweir         rStrm >> *p;
189cdf0e10cSrcweir         m_aHeaderList.Insert (p, LIST_APPEND);
190cdf0e10cSrcweir     }
191cdf0e10cSrcweir 
192cdf0e10cSrcweir     // Done.
193cdf0e10cSrcweir     return rStrm;
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir /*=======================================================================
197cdf0e10cSrcweir  *
198cdf0e10cSrcweir  * INetMessageHeaderIterator Implementation.
199cdf0e10cSrcweir  *
200cdf0e10cSrcweir  *=====================================================================*/
INetMessageHeaderIterator(const INetMessage & rMsg,const UniString & rHdrName)201cdf0e10cSrcweir INetMessageHeaderIterator::INetMessageHeaderIterator (
202cdf0e10cSrcweir     const INetMessage& rMsg, const UniString& rHdrName)
203cdf0e10cSrcweir {
204cdf0e10cSrcweir     sal_uIntPtr i, n = rMsg.GetHeaderCount();
205cdf0e10cSrcweir     for (i = 0; i < n; i++)
206cdf0e10cSrcweir     {
207cdf0e10cSrcweir         if (rHdrName.CompareIgnoreCaseToAscii (rMsg.GetHeaderName(i)) == 0)
208cdf0e10cSrcweir         {
209cdf0e10cSrcweir             UniString *pValue = new UniString (rMsg.GetHeaderValue(i));
210cdf0e10cSrcweir             aValueList.Insert (pValue, LIST_APPEND);
211cdf0e10cSrcweir         }
212cdf0e10cSrcweir     }
213cdf0e10cSrcweir     nValueCount = aValueList.Count();
214cdf0e10cSrcweir }
215cdf0e10cSrcweir 
~INetMessageHeaderIterator(void)216cdf0e10cSrcweir INetMessageHeaderIterator::~INetMessageHeaderIterator (void)
217cdf0e10cSrcweir {
218cdf0e10cSrcweir     sal_uIntPtr i, n = aValueList.Count();
219cdf0e10cSrcweir     for (i = 0; i < n; i++)
220cdf0e10cSrcweir         delete ((UniString*)(aValueList.GetObject(i)));
221cdf0e10cSrcweir     aValueList.Clear();
222cdf0e10cSrcweir }
223cdf0e10cSrcweir 
224cdf0e10cSrcweir /*=======================================================================
225cdf0e10cSrcweir  *
226cdf0e10cSrcweir  * INetRFC822Message Implementation.
227cdf0e10cSrcweir  *
228cdf0e10cSrcweir  *=====================================================================*/
229cdf0e10cSrcweir /*
230cdf0e10cSrcweir  * ImplINetRFC822MessageHeaderData.
231cdf0e10cSrcweir  */
232cdf0e10cSrcweir namespace
233cdf0e10cSrcweir {
234cdf0e10cSrcweir     struct ImplINetRFC822MessageHeaderDataImpl
235cdf0e10cSrcweir     {
operator ()__anon83da486d0111::ImplINetRFC822MessageHeaderDataImpl236cdf0e10cSrcweir         const ByteString* operator()()
237cdf0e10cSrcweir         {
238cdf0e10cSrcweir             static const ByteString _ImplINetRFC822MessageHeaderData[] =
239cdf0e10cSrcweir             {
240cdf0e10cSrcweir                 ByteString ("BCC"),
241cdf0e10cSrcweir                 ByteString ("CC"),
242cdf0e10cSrcweir                 ByteString ("Comments"),
243cdf0e10cSrcweir                 ByteString ("Date"),
244cdf0e10cSrcweir                 ByteString ("From"),
245cdf0e10cSrcweir                 ByteString ("In-Reply-To"),
246cdf0e10cSrcweir                 ByteString ("Keywords"),
247cdf0e10cSrcweir                 ByteString ("Message-ID"),
248cdf0e10cSrcweir                 ByteString ("References"),
249cdf0e10cSrcweir                 ByteString ("Reply-To"),
250cdf0e10cSrcweir                 ByteString ("Return-Path"),
251cdf0e10cSrcweir                 ByteString ("Subject"),
252cdf0e10cSrcweir                 ByteString ("Sender"),
253cdf0e10cSrcweir                 ByteString ("To"),
254cdf0e10cSrcweir                 ByteString ("X-Mailer"),
255cdf0e10cSrcweir                 ByteString ("Return-Receipt-To")
256cdf0e10cSrcweir             };
257cdf0e10cSrcweir             return &_ImplINetRFC822MessageHeaderData[0];
258cdf0e10cSrcweir         }
259cdf0e10cSrcweir     };
260cdf0e10cSrcweir 
261cdf0e10cSrcweir     struct ImplINetRFC822MessageHeaderData
262cdf0e10cSrcweir     	: public rtl::StaticAggregate< const ByteString, ImplINetRFC822MessageHeaderDataImpl > {};
263cdf0e10cSrcweir }
264cdf0e10cSrcweir 
265cdf0e10cSrcweir #define HDR(n) ImplINetRFC822MessageHeaderData::get()[(n)]
266cdf0e10cSrcweir 
267cdf0e10cSrcweir /*
268cdf0e10cSrcweir  * _ImplINetRFC822MessageHeaderState.
269cdf0e10cSrcweir  */
270cdf0e10cSrcweir enum _ImplINetRFC822MessageHeaderState
271cdf0e10cSrcweir {
272cdf0e10cSrcweir     INETMSG_RFC822_BEGIN,
273cdf0e10cSrcweir     INETMSG_RFC822_CHECK,
274cdf0e10cSrcweir     INETMSG_RFC822_OK,
275cdf0e10cSrcweir     INETMSG_RFC822_JUNK,
276cdf0e10cSrcweir 
277cdf0e10cSrcweir     INETMSG_RFC822_TOKEN_RE,
278cdf0e10cSrcweir     INETMSG_RFC822_TOKEN_RETURNMINUS,
279cdf0e10cSrcweir     INETMSG_RFC822_TOKEN_XMINUS,
280cdf0e10cSrcweir     INETMSG_RFC822_LETTER_C,
281cdf0e10cSrcweir     INETMSG_RFC822_LETTER_S
282cdf0e10cSrcweir };
283cdf0e10cSrcweir 
284cdf0e10cSrcweir /*
285cdf0e10cSrcweir  * INetRFC822Message.
286cdf0e10cSrcweir  */
INetRFC822Message(void)287cdf0e10cSrcweir INetRFC822Message::INetRFC822Message (void)
288cdf0e10cSrcweir     : INetMessage()
289cdf0e10cSrcweir {
290cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
291cdf0e10cSrcweir         m_nIndex[i] = LIST_ENTRY_NOTFOUND;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir 
INetRFC822Message(const INetRFC822Message & rMsg)294cdf0e10cSrcweir INetRFC822Message::INetRFC822Message (const INetRFC822Message& rMsg)
295cdf0e10cSrcweir     : INetMessage (rMsg)
296cdf0e10cSrcweir {
297cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
298cdf0e10cSrcweir         m_nIndex[i] = rMsg.m_nIndex[i];
299cdf0e10cSrcweir }
300cdf0e10cSrcweir 
301cdf0e10cSrcweir /*
302cdf0e10cSrcweir  * operator=
303cdf0e10cSrcweir  */
operator =(const INetRFC822Message & rMsg)304cdf0e10cSrcweir INetRFC822Message& INetRFC822Message::operator= (const INetRFC822Message& rMsg)
305cdf0e10cSrcweir {
306cdf0e10cSrcweir     if (this != &rMsg)
307cdf0e10cSrcweir     {
308cdf0e10cSrcweir         INetMessage::operator= (rMsg);
309cdf0e10cSrcweir 
310cdf0e10cSrcweir         for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
311cdf0e10cSrcweir             m_nIndex[i] = rMsg.m_nIndex[i];
312cdf0e10cSrcweir     }
313cdf0e10cSrcweir     return *this;
314cdf0e10cSrcweir }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir /*
317cdf0e10cSrcweir  * ~INetRFC822Message.
318cdf0e10cSrcweir  */
~INetRFC822Message(void)319cdf0e10cSrcweir INetRFC822Message::~INetRFC822Message (void)
320cdf0e10cSrcweir {
321cdf0e10cSrcweir }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir /*
324cdf0e10cSrcweir  * <Generate|Parse>DateField and local helper functions.
325cdf0e10cSrcweir  *
326cdf0e10cSrcweir  * GenerateDateField.
327cdf0e10cSrcweir  * Generates a String from Date and Time objects in format:
328cdf0e10cSrcweir  *   Wkd, 00 Mon 0000 00:00:00 [GMT]            (rfc822, rfc1123)
329cdf0e10cSrcweir  *
330cdf0e10cSrcweir  * ParseDateField.
331cdf0e10cSrcweir  * Parses a String in (implied) GMT format into class Date and Time objects.
332cdf0e10cSrcweir  * Four formats are accepted:
333cdf0e10cSrcweir  *
334cdf0e10cSrcweir  *  [Wkd,] 1*2DIGIT Mon 2*4DIGIT 00:00:00 [GMT]  (rfc1123)
335cdf0e10cSrcweir  *  [Wkd,] 00 Mon 0000 00:00:00 [GMT])           (rfc822, rfc1123)
336cdf0e10cSrcweir  *   Weekday, 00-Mon-00 00:00:00 [GMT]           (rfc850, rfc1036)
337cdf0e10cSrcweir  *   Wkd Mon 00 00:00:00 0000 [GMT]              (ctime)
338cdf0e10cSrcweir  *   1*DIGIT                                     (delta seconds)
339cdf0e10cSrcweir  *
340cdf0e10cSrcweir  */
341cdf0e10cSrcweir 
342cdf0e10cSrcweir // Months and Weekdays.
343cdf0e10cSrcweir static const sal_Char *months[12] =
344cdf0e10cSrcweir {
345cdf0e10cSrcweir     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
346cdf0e10cSrcweir     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
347cdf0e10cSrcweir };
348cdf0e10cSrcweir 
349cdf0e10cSrcweir static const sal_Char *wkdays[7] =
350cdf0e10cSrcweir {
351cdf0e10cSrcweir     "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
352cdf0e10cSrcweir };
353cdf0e10cSrcweir 
354cdf0e10cSrcweir /*
355cdf0e10cSrcweir  * GenerateDateField.
356cdf0e10cSrcweir  */
GenerateDateField(const DateTime & rDateTime,UniString & rDateFieldW)357cdf0e10cSrcweir sal_Bool INetRFC822Message::GenerateDateField (
358cdf0e10cSrcweir     const DateTime& rDateTime, UniString& rDateFieldW)
359cdf0e10cSrcweir {
360cdf0e10cSrcweir     // Check arguments.
361cdf0e10cSrcweir     if (!rDateTime.IsValid()       ||
362cdf0e10cSrcweir         (rDateTime.GetSec()  > 59) ||
363cdf0e10cSrcweir         (rDateTime.GetMin()  > 59) ||
364cdf0e10cSrcweir         (rDateTime.GetHour() > 23)    ) return sal_False;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir     // Prepare output string.
367cdf0e10cSrcweir     ByteString rDateField;
368cdf0e10cSrcweir 
369cdf0e10cSrcweir     // Insert Date.
370cdf0e10cSrcweir     rDateField += wkdays[(sal_uInt16)(rDateTime.GetDayOfWeek())];
371cdf0e10cSrcweir     rDateField += ", ";
372cdf0e10cSrcweir 
373cdf0e10cSrcweir     sal_uInt16 nNum = rDateTime.GetDay();
374cdf0e10cSrcweir     if (nNum < 10) rDateField += '0';
375cdf0e10cSrcweir     rDateField += ByteString::CreateFromInt32(nNum);
376cdf0e10cSrcweir     rDateField += ' ';
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     rDateField += months[(sal_uInt16)(rDateTime.GetMonth() - 1)];
379cdf0e10cSrcweir     rDateField += ' ';
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     rDateField += ByteString::CreateFromInt32(rDateTime.GetYear());
382cdf0e10cSrcweir     rDateField += ' ';
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     // Insert Time.
385cdf0e10cSrcweir     nNum = rDateTime.GetHour();
386cdf0e10cSrcweir     if (nNum < 10) rDateField += '0';
387cdf0e10cSrcweir     rDateField += ByteString::CreateFromInt32(nNum);
388cdf0e10cSrcweir     rDateField += ':';
389cdf0e10cSrcweir 
390cdf0e10cSrcweir     nNum = rDateTime.GetMin();
391cdf0e10cSrcweir     if (nNum < 10) rDateField += '0';
392cdf0e10cSrcweir     rDateField += ByteString::CreateFromInt32(nNum);
393cdf0e10cSrcweir     rDateField += ':';
394cdf0e10cSrcweir 
395cdf0e10cSrcweir     nNum = rDateTime.GetSec();
396cdf0e10cSrcweir     if (nNum < 10) rDateField += '0';
397cdf0e10cSrcweir     rDateField += ByteString::CreateFromInt32(nNum);
398cdf0e10cSrcweir     rDateField += " GMT";
399cdf0e10cSrcweir 
400cdf0e10cSrcweir     // Done.
401cdf0e10cSrcweir     rDateFieldW = UniString (rDateField, RTL_TEXTENCODING_ASCII_US);
402cdf0e10cSrcweir     return sal_True;
403cdf0e10cSrcweir }
404cdf0e10cSrcweir 
405cdf0e10cSrcweir /*
406cdf0e10cSrcweir  * ParseDateField and local helper functions.
407cdf0e10cSrcweir  */
ParseNumber(const ByteString & rStr,sal_uInt16 & nIndex)408cdf0e10cSrcweir static sal_uInt16 ParseNumber (const ByteString& rStr, sal_uInt16& nIndex)
409cdf0e10cSrcweir {
410cdf0e10cSrcweir     sal_uInt16 n = nIndex;
411cdf0e10cSrcweir     while ((n < rStr.Len()) && ascii_isDigit(rStr.GetChar(n))) n++;
412cdf0e10cSrcweir 
413cdf0e10cSrcweir     ByteString aNum (rStr.Copy (nIndex, (n - nIndex)));
414cdf0e10cSrcweir     nIndex = n;
415cdf0e10cSrcweir 
416cdf0e10cSrcweir     return (sal_uInt16)(aNum.ToInt32());
417cdf0e10cSrcweir }
418cdf0e10cSrcweir 
ParseMonth(const ByteString & rStr,sal_uInt16 & nIndex)419cdf0e10cSrcweir static sal_uInt16 ParseMonth (const ByteString& rStr, sal_uInt16& nIndex)
420cdf0e10cSrcweir {
421cdf0e10cSrcweir     sal_uInt16 n = nIndex;
422cdf0e10cSrcweir     while ((n < rStr.Len()) && ascii_isLetter(rStr.GetChar(n))) n++;
423cdf0e10cSrcweir 
424cdf0e10cSrcweir     ByteString aMonth (rStr.Copy (nIndex, 3));
425cdf0e10cSrcweir     nIndex = n;
426cdf0e10cSrcweir 
427cdf0e10cSrcweir     sal_uInt16 i;
428cdf0e10cSrcweir     for (i = 0; i < 12; i++)
429cdf0e10cSrcweir         if (aMonth.CompareIgnoreCaseToAscii (months[i]) == 0) break;
430cdf0e10cSrcweir     return (i + 1);
431cdf0e10cSrcweir }
432cdf0e10cSrcweir 
ParseDateField(const UniString & rDateFieldW,DateTime & rDateTime)433cdf0e10cSrcweir sal_Bool INetRFC822Message::ParseDateField (
434cdf0e10cSrcweir     const UniString& rDateFieldW, DateTime& rDateTime)
435cdf0e10cSrcweir {
436cdf0e10cSrcweir     ByteString rDateField (rDateFieldW, RTL_TEXTENCODING_ASCII_US);
437cdf0e10cSrcweir     if (rDateField.Len() == 0) return sal_False;
438cdf0e10cSrcweir 
439cdf0e10cSrcweir     if (rDateField.Search (':') != STRING_NOTFOUND)
440cdf0e10cSrcweir     {
441cdf0e10cSrcweir         // Some DateTime format.
442cdf0e10cSrcweir         sal_uInt16 nIndex = 0;
443cdf0e10cSrcweir 
444cdf0e10cSrcweir         // Skip over <Wkd> or <Weekday>, leading and trailing space.
445cdf0e10cSrcweir         while ((nIndex < rDateField.Len()) &&
446cdf0e10cSrcweir                (rDateField.GetChar(nIndex) == ' '))
447cdf0e10cSrcweir             nIndex++;
448cdf0e10cSrcweir 
449cdf0e10cSrcweir         while (
450cdf0e10cSrcweir             (nIndex < rDateField.Len()) &&
451cdf0e10cSrcweir             (ascii_isLetter (rDateField.GetChar(nIndex)) ||
452cdf0e10cSrcweir              (rDateField.GetChar(nIndex) == ',')     ))
453cdf0e10cSrcweir             nIndex++;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir         while ((nIndex < rDateField.Len()) &&
456cdf0e10cSrcweir                (rDateField.GetChar(nIndex) == ' '))
457cdf0e10cSrcweir             nIndex++;
458cdf0e10cSrcweir 
459cdf0e10cSrcweir         if (ascii_isLetter (rDateField.GetChar(nIndex)))
460cdf0e10cSrcweir         {
461cdf0e10cSrcweir             // Format: ctime().
462cdf0e10cSrcweir             if ((rDateField.Len() - nIndex) < 20) return sal_False;
463cdf0e10cSrcweir 
464cdf0e10cSrcweir             rDateTime.SetMonth  (ParseMonth  (rDateField, nIndex)); nIndex++;
465cdf0e10cSrcweir             rDateTime.SetDay    (ParseNumber (rDateField, nIndex)); nIndex++;
466cdf0e10cSrcweir 
467cdf0e10cSrcweir             rDateTime.SetHour   (ParseNumber (rDateField, nIndex)); nIndex++;
468cdf0e10cSrcweir             rDateTime.SetMin    (ParseNumber (rDateField, nIndex)); nIndex++;
469cdf0e10cSrcweir             rDateTime.SetSec    (ParseNumber (rDateField, nIndex)); nIndex++;
470cdf0e10cSrcweir             rDateTime.Set100Sec (0);
471cdf0e10cSrcweir 
472cdf0e10cSrcweir             sal_uInt16 nYear = ParseNumber (rDateField, nIndex);
473cdf0e10cSrcweir             if (nYear < 100) nYear += 1900;
474cdf0e10cSrcweir             rDateTime.SetYear   (nYear);
475cdf0e10cSrcweir         }
476cdf0e10cSrcweir         else
477cdf0e10cSrcweir         {
478cdf0e10cSrcweir             // Format: RFC1036 or RFC1123.
479cdf0e10cSrcweir             if ((rDateField.Len() - nIndex) < 17) return sal_False;
480cdf0e10cSrcweir 
481cdf0e10cSrcweir             rDateTime.SetDay    (ParseNumber (rDateField, nIndex)); nIndex++;
482cdf0e10cSrcweir             rDateTime.SetMonth  (ParseMonth  (rDateField, nIndex)); nIndex++;
483cdf0e10cSrcweir 
484cdf0e10cSrcweir             sal_uInt16 nYear  = ParseNumber (rDateField, nIndex);  nIndex++;
485cdf0e10cSrcweir             if (nYear < 100) nYear += 1900;
486cdf0e10cSrcweir             rDateTime.SetYear   (nYear);
487cdf0e10cSrcweir 
488cdf0e10cSrcweir             rDateTime.SetHour   (ParseNumber (rDateField, nIndex)); nIndex++;
489cdf0e10cSrcweir             rDateTime.SetMin    (ParseNumber (rDateField, nIndex)); nIndex++;
490cdf0e10cSrcweir             rDateTime.SetSec    (ParseNumber (rDateField, nIndex)); nIndex++;
491cdf0e10cSrcweir             rDateTime.Set100Sec (0);
492cdf0e10cSrcweir 
493cdf0e10cSrcweir             if ((rDateField.GetChar(nIndex) == '+') ||
494cdf0e10cSrcweir                 (rDateField.GetChar(nIndex) == '-')    )
495cdf0e10cSrcweir             {
496cdf0e10cSrcweir                 // Offset from GMT: "(+|-)HHMM".
497cdf0e10cSrcweir                 sal_Bool   bEast   = (rDateField.GetChar(nIndex++) == '+');
498cdf0e10cSrcweir                 sal_uInt16 nOffset = ParseNumber (rDateField, nIndex);
499cdf0e10cSrcweir                 if (nOffset > 0)
500cdf0e10cSrcweir                 {
501cdf0e10cSrcweir                     Time aDiff;
502cdf0e10cSrcweir                     aDiff.SetHour   (nOffset / 100);
503cdf0e10cSrcweir                     aDiff.SetMin    (nOffset % 100);
504cdf0e10cSrcweir                     aDiff.SetSec    (0);
505cdf0e10cSrcweir                     aDiff.Set100Sec (0);
506cdf0e10cSrcweir 
507cdf0e10cSrcweir                     if (bEast)
508cdf0e10cSrcweir                         rDateTime -= aDiff;
509cdf0e10cSrcweir                     else
510cdf0e10cSrcweir                         rDateTime += aDiff;
511cdf0e10cSrcweir                 }
512cdf0e10cSrcweir             }
513cdf0e10cSrcweir         }
514cdf0e10cSrcweir     }
515cdf0e10cSrcweir     else if (rDateField.IsNumericAscii())
516cdf0e10cSrcweir     {
517cdf0e10cSrcweir         // Format: delta seconds.
518cdf0e10cSrcweir         Time aDelta (0);
519cdf0e10cSrcweir         aDelta.SetTime (rDateField.ToInt32() * 100);
520cdf0e10cSrcweir 
521cdf0e10cSrcweir         DateTime aNow;
522cdf0e10cSrcweir         aNow += aDelta;
523cdf0e10cSrcweir         aNow.ConvertToUTC();
524cdf0e10cSrcweir 
525cdf0e10cSrcweir         rDateTime.SetDate (aNow.GetDate());
526cdf0e10cSrcweir         rDateTime.SetTime (aNow.GetTime());
527cdf0e10cSrcweir     }
528cdf0e10cSrcweir     else
529cdf0e10cSrcweir     {
530cdf0e10cSrcweir         // Junk.
531cdf0e10cSrcweir         return sal_False;
532cdf0e10cSrcweir     }
533cdf0e10cSrcweir 
534cdf0e10cSrcweir     return (rDateTime.IsValid() &&
535cdf0e10cSrcweir             !((rDateTime.GetSec()  > 59) ||
536cdf0e10cSrcweir               (rDateTime.GetMin()  > 59) ||
537cdf0e10cSrcweir               (rDateTime.GetHour() > 23)    ));
538cdf0e10cSrcweir }
539cdf0e10cSrcweir 
540cdf0e10cSrcweir /*
541cdf0e10cSrcweir  * SetHeaderField.
542cdf0e10cSrcweir  * (Header Field Parser).
543cdf0e10cSrcweir  */
SetHeaderField(const INetMessageHeader & rHeader,sal_uIntPtr nNewIndex)544cdf0e10cSrcweir sal_uIntPtr INetRFC822Message::SetHeaderField (
545cdf0e10cSrcweir     const INetMessageHeader &rHeader, sal_uIntPtr nNewIndex)
546cdf0e10cSrcweir {
547cdf0e10cSrcweir     ByteString aName (rHeader.GetName());
548cdf0e10cSrcweir     const sal_Char *pData = aName.GetBuffer();
549cdf0e10cSrcweir     const sal_Char *pStop = pData + aName.Len() + 1;
550cdf0e10cSrcweir     const sal_Char *check = "";
551cdf0e10cSrcweir 
552cdf0e10cSrcweir     sal_uIntPtr       nIdx     = LIST_APPEND;
553cdf0e10cSrcweir     int         eState   = INETMSG_RFC822_BEGIN;
554cdf0e10cSrcweir     int         eOkState = INETMSG_RFC822_OK;
555cdf0e10cSrcweir 
556cdf0e10cSrcweir     while (pData < pStop)
557cdf0e10cSrcweir     {
558cdf0e10cSrcweir         switch (eState)
559cdf0e10cSrcweir         {
560cdf0e10cSrcweir             case INETMSG_RFC822_BEGIN:
561cdf0e10cSrcweir                 eState = INETMSG_RFC822_CHECK;
562cdf0e10cSrcweir                 eOkState = INETMSG_RFC822_OK;
563cdf0e10cSrcweir 
564cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
565cdf0e10cSrcweir                 {
566cdf0e10cSrcweir                     case 'b':
567cdf0e10cSrcweir                         check = "cc";
568cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_BCC;
569cdf0e10cSrcweir                         break;
570cdf0e10cSrcweir 
571cdf0e10cSrcweir                     case 'c':
572cdf0e10cSrcweir                         eState = INETMSG_RFC822_LETTER_C;
573cdf0e10cSrcweir                         break;
574cdf0e10cSrcweir 
575cdf0e10cSrcweir                     case 'd':
576cdf0e10cSrcweir                         check = "ate";
577cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_DATE;
578cdf0e10cSrcweir                         break;
579cdf0e10cSrcweir 
580cdf0e10cSrcweir                     case 'f':
581cdf0e10cSrcweir                         check = "rom";
582cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_FROM;
583cdf0e10cSrcweir                         break;
584cdf0e10cSrcweir 
585cdf0e10cSrcweir                     case 'i':
586cdf0e10cSrcweir                         check = "n-reply-to";
587cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_IN_REPLY_TO;
588cdf0e10cSrcweir                         break;
589cdf0e10cSrcweir 
590cdf0e10cSrcweir                     case 'k':
591cdf0e10cSrcweir                         check = "eywords";
592cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_KEYWORDS;
593cdf0e10cSrcweir                         break;
594cdf0e10cSrcweir 
595cdf0e10cSrcweir                     case 'm':
596cdf0e10cSrcweir                         check = "essage-id";
597cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_MESSAGE_ID;
598cdf0e10cSrcweir                         break;
599cdf0e10cSrcweir 
600cdf0e10cSrcweir                     case 'r':
601cdf0e10cSrcweir                         check = "e";
602cdf0e10cSrcweir                         eOkState = INETMSG_RFC822_TOKEN_RE;
603cdf0e10cSrcweir                         break;
604cdf0e10cSrcweir 
605cdf0e10cSrcweir                     case 's':
606cdf0e10cSrcweir                         eState = INETMSG_RFC822_LETTER_S;
607cdf0e10cSrcweir                         break;
608cdf0e10cSrcweir 
609cdf0e10cSrcweir                     case 't':
610cdf0e10cSrcweir                         check = "o";
611cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_TO;
612cdf0e10cSrcweir                         break;
613cdf0e10cSrcweir 
614cdf0e10cSrcweir                     case 'x':
615cdf0e10cSrcweir                         check = "-";
616cdf0e10cSrcweir                         eOkState = INETMSG_RFC822_TOKEN_XMINUS;
617cdf0e10cSrcweir                         break;
618cdf0e10cSrcweir 
619cdf0e10cSrcweir                     default:
620cdf0e10cSrcweir                         eState = INETMSG_RFC822_JUNK;
621cdf0e10cSrcweir                         break;
622cdf0e10cSrcweir                 }
623cdf0e10cSrcweir                 pData++;
624cdf0e10cSrcweir                 break;
625cdf0e10cSrcweir 
626cdf0e10cSrcweir             case INETMSG_RFC822_TOKEN_RE:
627cdf0e10cSrcweir                 eState = INETMSG_RFC822_CHECK;
628cdf0e10cSrcweir                 eOkState = INETMSG_RFC822_OK;
629cdf0e10cSrcweir 
630cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
631cdf0e10cSrcweir                 {
632cdf0e10cSrcweir                     case 'f':
633cdf0e10cSrcweir                         check = "erences";
634cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_REFERENCES;
635cdf0e10cSrcweir                         break;
636cdf0e10cSrcweir 
637cdf0e10cSrcweir                     case 'p':
638cdf0e10cSrcweir                         check = "ly-to";
639cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_REPLY_TO;
640cdf0e10cSrcweir                         break;
641cdf0e10cSrcweir 
642cdf0e10cSrcweir                     case 't':
643cdf0e10cSrcweir                         check = "urn-";
644cdf0e10cSrcweir                         eOkState = INETMSG_RFC822_TOKEN_RETURNMINUS;
645cdf0e10cSrcweir                         break;
646cdf0e10cSrcweir 
647cdf0e10cSrcweir                     default:
648cdf0e10cSrcweir                         eState = INETMSG_RFC822_JUNK;
649cdf0e10cSrcweir                         break;
650cdf0e10cSrcweir                 }
651cdf0e10cSrcweir                 pData++;
652cdf0e10cSrcweir                 break;
653cdf0e10cSrcweir 
654cdf0e10cSrcweir             case INETMSG_RFC822_TOKEN_RETURNMINUS:
655cdf0e10cSrcweir                 eState = INETMSG_RFC822_CHECK;
656cdf0e10cSrcweir                 eOkState = INETMSG_RFC822_OK;
657cdf0e10cSrcweir 
658cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
659cdf0e10cSrcweir                 {
660cdf0e10cSrcweir                     case 'p':
661cdf0e10cSrcweir                         check = "ath";
662cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_RETURN_PATH;
663cdf0e10cSrcweir                         break;
664cdf0e10cSrcweir 
665cdf0e10cSrcweir                     case 'r':
666cdf0e10cSrcweir                         check = "eceipt-to";
667cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_RETURN_RECEIPT_TO;
668cdf0e10cSrcweir                         break;
669cdf0e10cSrcweir 
670cdf0e10cSrcweir                     default:
671cdf0e10cSrcweir                         eState = INETMSG_RFC822_JUNK;
672cdf0e10cSrcweir                         break;
673cdf0e10cSrcweir                 }
674cdf0e10cSrcweir                 pData++;
675cdf0e10cSrcweir                 break;
676cdf0e10cSrcweir 
677cdf0e10cSrcweir             case INETMSG_RFC822_TOKEN_XMINUS:
678cdf0e10cSrcweir                 eState = INETMSG_RFC822_CHECK;
679cdf0e10cSrcweir                 eOkState = INETMSG_RFC822_OK;
680cdf0e10cSrcweir 
681cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
682cdf0e10cSrcweir                 {
683cdf0e10cSrcweir                     case 'm':
684cdf0e10cSrcweir                         check = "ailer";
685cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_X_MAILER;
686cdf0e10cSrcweir                         break;
687cdf0e10cSrcweir 
688cdf0e10cSrcweir #if 0  /* NYI */
689cdf0e10cSrcweir                     case 'p':
690cdf0e10cSrcweir                         check = "riority";
691cdf0e10cSrcweir                         eOkState = INETMSG_RFC822_X_PRIORITY;
692cdf0e10cSrcweir                         break;
693cdf0e10cSrcweir #endif /* NYI */
694cdf0e10cSrcweir 
695cdf0e10cSrcweir                     default:
696cdf0e10cSrcweir                         eState = INETMSG_RFC822_JUNK;
697cdf0e10cSrcweir                         break;
698cdf0e10cSrcweir                 }
699cdf0e10cSrcweir                 pData++;
700cdf0e10cSrcweir                 break;
701cdf0e10cSrcweir 
702cdf0e10cSrcweir             case INETMSG_RFC822_LETTER_C:
703cdf0e10cSrcweir                 eState = INETMSG_RFC822_CHECK;
704cdf0e10cSrcweir                 eOkState = INETMSG_RFC822_OK;
705cdf0e10cSrcweir 
706cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
707cdf0e10cSrcweir                 {
708cdf0e10cSrcweir                     case 'c':
709cdf0e10cSrcweir                         check = "";
710cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_CC;
711cdf0e10cSrcweir                         break;
712cdf0e10cSrcweir 
713cdf0e10cSrcweir                     case 'o':
714cdf0e10cSrcweir                         check = "mments";
715cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_COMMENTS;
716cdf0e10cSrcweir                         break;
717cdf0e10cSrcweir 
718cdf0e10cSrcweir                     default:
719cdf0e10cSrcweir                         eState = INETMSG_RFC822_JUNK;
720cdf0e10cSrcweir                         break;
721cdf0e10cSrcweir                 }
722cdf0e10cSrcweir                 pData++;
723cdf0e10cSrcweir                 break;
724cdf0e10cSrcweir 
725cdf0e10cSrcweir             case INETMSG_RFC822_LETTER_S:
726cdf0e10cSrcweir                 eState = INETMSG_RFC822_CHECK;
727cdf0e10cSrcweir                 eOkState = INETMSG_RFC822_OK;
728cdf0e10cSrcweir 
729cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
730cdf0e10cSrcweir                 {
731cdf0e10cSrcweir                     case 'e':
732cdf0e10cSrcweir                         check = "nder";
733cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_SENDER;
734cdf0e10cSrcweir                         break;
735cdf0e10cSrcweir 
736cdf0e10cSrcweir                     case 'u':
737cdf0e10cSrcweir                         check = "bject";
738cdf0e10cSrcweir                         nIdx = INETMSG_RFC822_SUBJECT;
739cdf0e10cSrcweir                         break;
740cdf0e10cSrcweir 
741cdf0e10cSrcweir                     default:
742cdf0e10cSrcweir                         eState = INETMSG_RFC822_JUNK;
743cdf0e10cSrcweir                         break;
744cdf0e10cSrcweir                 }
745cdf0e10cSrcweir                 pData++;
746cdf0e10cSrcweir                 break;
747cdf0e10cSrcweir 
748cdf0e10cSrcweir             case INETMSG_RFC822_CHECK:
749cdf0e10cSrcweir                 if (*check)
750cdf0e10cSrcweir                 {
751cdf0e10cSrcweir                     while (*pData && *check &&
752cdf0e10cSrcweir                            (ascii_toLowerCase (*pData) == *check))
753cdf0e10cSrcweir                     {
754cdf0e10cSrcweir                         pData++;
755cdf0e10cSrcweir                         check++;
756cdf0e10cSrcweir                     }
757cdf0e10cSrcweir                 }
758cdf0e10cSrcweir                 else
759cdf0e10cSrcweir                 {
760cdf0e10cSrcweir                     check = pData;
761cdf0e10cSrcweir                 }
762cdf0e10cSrcweir                 eState = (*check == '\0') ? eOkState : INETMSG_RFC822_JUNK;
763cdf0e10cSrcweir                 break;
764cdf0e10cSrcweir 
765cdf0e10cSrcweir             case INETMSG_RFC822_OK:
766cdf0e10cSrcweir                 pData = pStop;
767cdf0e10cSrcweir                 SetHeaderField_Impl (
768cdf0e10cSrcweir                     HEADERFIELD (HDR(nIdx), rHeader.GetValue()),
769cdf0e10cSrcweir                     m_nIndex[nIdx]);
770cdf0e10cSrcweir                 nNewIndex = m_nIndex[nIdx];
771cdf0e10cSrcweir                 break;
772cdf0e10cSrcweir 
773cdf0e10cSrcweir             default: // INETMSG_RFC822_JUNK
774cdf0e10cSrcweir                 pData = pStop;
775cdf0e10cSrcweir                 nNewIndex = INetMessage::SetHeaderField (rHeader, nNewIndex);
776cdf0e10cSrcweir                 break;
777cdf0e10cSrcweir         }
778cdf0e10cSrcweir     }
779cdf0e10cSrcweir     return nNewIndex;
780cdf0e10cSrcweir }
781cdf0e10cSrcweir 
782cdf0e10cSrcweir /*
783cdf0e10cSrcweir  * Specific Set-Methods.
784cdf0e10cSrcweir  */
SetBCC(const UniString & rBCC)785cdf0e10cSrcweir void INetRFC822Message::SetBCC (const UniString& rBCC)
786cdf0e10cSrcweir {
787cdf0e10cSrcweir     SetHeaderField_Impl (
788cdf0e10cSrcweir         INetMIME::HEADER_FIELD_ADDRESS,
789cdf0e10cSrcweir         HDR(INETMSG_RFC822_BCC), rBCC,
790cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_BCC]);
791cdf0e10cSrcweir }
792cdf0e10cSrcweir 
SetCC(const UniString & rCC)793cdf0e10cSrcweir void INetRFC822Message::SetCC (const UniString& rCC)
794cdf0e10cSrcweir {
795cdf0e10cSrcweir     SetHeaderField_Impl (
796cdf0e10cSrcweir         INetMIME::HEADER_FIELD_ADDRESS,
797cdf0e10cSrcweir         HDR(INETMSG_RFC822_CC), rCC,
798cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_CC]);
799cdf0e10cSrcweir }
800cdf0e10cSrcweir 
SetComments(const UniString & rComments)801cdf0e10cSrcweir void INetRFC822Message::SetComments (const UniString& rComments)
802cdf0e10cSrcweir {
803cdf0e10cSrcweir     SetHeaderField_Impl (
804cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
805cdf0e10cSrcweir         HDR(INETMSG_RFC822_COMMENTS), rComments,
806cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_COMMENTS]);
807cdf0e10cSrcweir }
808cdf0e10cSrcweir 
SetDate(const UniString & rDate)809cdf0e10cSrcweir void INetRFC822Message::SetDate (const UniString& rDate)
810cdf0e10cSrcweir {
811cdf0e10cSrcweir     SetHeaderField_Impl (
812cdf0e10cSrcweir         INetMIME::HEADER_FIELD_STRUCTURED,
813cdf0e10cSrcweir         HDR(INETMSG_RFC822_DATE), rDate,
814cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_DATE]);
815cdf0e10cSrcweir }
816cdf0e10cSrcweir 
SetFrom(const UniString & rFrom)817cdf0e10cSrcweir void INetRFC822Message::SetFrom (const UniString& rFrom)
818cdf0e10cSrcweir {
819cdf0e10cSrcweir     SetHeaderField_Impl (
820cdf0e10cSrcweir         INetMIME::HEADER_FIELD_ADDRESS,
821cdf0e10cSrcweir         HDR(INETMSG_RFC822_FROM), rFrom,
822cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_FROM]);
823cdf0e10cSrcweir }
824cdf0e10cSrcweir 
SetInReplyTo(const UniString & rInReplyTo)825cdf0e10cSrcweir void INetRFC822Message::SetInReplyTo (const UniString& rInReplyTo)
826cdf0e10cSrcweir {
827cdf0e10cSrcweir     SetHeaderField_Impl (
828cdf0e10cSrcweir         INetMIME::HEADER_FIELD_ADDRESS, // ??? MESSAGE_ID ???
829cdf0e10cSrcweir         HDR(INETMSG_RFC822_IN_REPLY_TO), rInReplyTo,
830cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_IN_REPLY_TO]);
831cdf0e10cSrcweir }
832cdf0e10cSrcweir 
SetKeywords(const UniString & rKeywords)833cdf0e10cSrcweir void INetRFC822Message::SetKeywords (const UniString& rKeywords)
834cdf0e10cSrcweir {
835cdf0e10cSrcweir     SetHeaderField_Impl (
836cdf0e10cSrcweir         INetMIME::HEADER_FIELD_PHRASE,
837cdf0e10cSrcweir         HDR(INETMSG_RFC822_KEYWORDS), rKeywords,
838cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_KEYWORDS]);
839cdf0e10cSrcweir }
840cdf0e10cSrcweir 
SetMessageID(const UniString & rMessageID)841cdf0e10cSrcweir void INetRFC822Message::SetMessageID (const UniString& rMessageID)
842cdf0e10cSrcweir {
843cdf0e10cSrcweir     SetHeaderField_Impl (
844cdf0e10cSrcweir         INetMIME::HEADER_FIELD_MESSAGE_ID,
845cdf0e10cSrcweir         HDR(INETMSG_RFC822_MESSAGE_ID), rMessageID,
846cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_MESSAGE_ID]);
847cdf0e10cSrcweir }
848cdf0e10cSrcweir 
SetReferences(const UniString & rReferences)849cdf0e10cSrcweir void INetRFC822Message::SetReferences (const UniString& rReferences)
850cdf0e10cSrcweir {
851cdf0e10cSrcweir     SetHeaderField_Impl (
852cdf0e10cSrcweir         INetMIME::HEADER_FIELD_MESSAGE_ID,
853cdf0e10cSrcweir         HDR(INETMSG_RFC822_REFERENCES), rReferences,
854cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_REFERENCES]);
855cdf0e10cSrcweir }
856cdf0e10cSrcweir 
SetReplyTo(const UniString & rReplyTo)857cdf0e10cSrcweir void INetRFC822Message::SetReplyTo (const UniString& rReplyTo)
858cdf0e10cSrcweir {
859cdf0e10cSrcweir     SetHeaderField_Impl (
860cdf0e10cSrcweir         INetMIME::HEADER_FIELD_ADDRESS,
861cdf0e10cSrcweir         HDR(INETMSG_RFC822_REPLY_TO), rReplyTo,
862cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_REPLY_TO]);
863cdf0e10cSrcweir }
864cdf0e10cSrcweir 
SetReturnPath(const UniString & rReturnPath)865cdf0e10cSrcweir void INetRFC822Message::SetReturnPath (const UniString& rReturnPath)
866cdf0e10cSrcweir {
867cdf0e10cSrcweir     SetHeaderField_Impl (
868cdf0e10cSrcweir         INetMIME::HEADER_FIELD_ADDRESS,
869cdf0e10cSrcweir         HDR(INETMSG_RFC822_RETURN_PATH), rReturnPath,
870cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_RETURN_PATH]);
871cdf0e10cSrcweir }
872cdf0e10cSrcweir 
SetReturnReceiptTo(const UniString & rValue)873cdf0e10cSrcweir void INetRFC822Message::SetReturnReceiptTo (const UniString& rValue)
874cdf0e10cSrcweir {
875cdf0e10cSrcweir     SetHeaderField_Impl (
876cdf0e10cSrcweir         INetMIME::HEADER_FIELD_ADDRESS,
877cdf0e10cSrcweir         HDR(INETMSG_RFC822_RETURN_RECEIPT_TO), rValue,
878cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_RETURN_RECEIPT_TO]);
879cdf0e10cSrcweir }
880cdf0e10cSrcweir 
SetSender(const UniString & rSender)881cdf0e10cSrcweir void INetRFC822Message::SetSender (const UniString& rSender)
882cdf0e10cSrcweir {
883cdf0e10cSrcweir     SetHeaderField_Impl (
884cdf0e10cSrcweir         INetMIME::HEADER_FIELD_ADDRESS,
885cdf0e10cSrcweir         HDR(INETMSG_RFC822_SENDER), rSender,
886cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_SENDER]);
887cdf0e10cSrcweir }
888cdf0e10cSrcweir 
SetSubject(const UniString & rSubject)889cdf0e10cSrcweir void INetRFC822Message::SetSubject (const UniString& rSubject)
890cdf0e10cSrcweir {
891cdf0e10cSrcweir     SetHeaderField_Impl (
892cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
893cdf0e10cSrcweir         HDR(INETMSG_RFC822_SUBJECT), rSubject,
894cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_SUBJECT]);
895cdf0e10cSrcweir }
896cdf0e10cSrcweir 
SetTo(const UniString & rTo)897cdf0e10cSrcweir void INetRFC822Message::SetTo (const UniString& rTo)
898cdf0e10cSrcweir {
899cdf0e10cSrcweir     SetHeaderField_Impl (
900cdf0e10cSrcweir         INetMIME::HEADER_FIELD_ADDRESS,
901cdf0e10cSrcweir         HDR(INETMSG_RFC822_TO), rTo,
902cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_TO]);
903cdf0e10cSrcweir }
904cdf0e10cSrcweir 
SetXMailer(const UniString & rXMailer)905cdf0e10cSrcweir void INetRFC822Message::SetXMailer (const UniString& rXMailer)
906cdf0e10cSrcweir {
907cdf0e10cSrcweir     SetHeaderField_Impl (
908cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
909cdf0e10cSrcweir         HDR(INETMSG_RFC822_X_MAILER), rXMailer,
910cdf0e10cSrcweir         m_nIndex[INETMSG_RFC822_X_MAILER]);
911cdf0e10cSrcweir }
912cdf0e10cSrcweir 
913cdf0e10cSrcweir /*
914cdf0e10cSrcweir  * operator<<
915cdf0e10cSrcweir  */
operator <<(SvStream & rStrm) const916cdf0e10cSrcweir SvStream& INetRFC822Message::operator<< (SvStream& rStrm) const
917cdf0e10cSrcweir {
918cdf0e10cSrcweir     INetMessage::operator<< (rStrm);
919cdf0e10cSrcweir 
920cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
921cdf0e10cSrcweir         rStrm << static_cast<sal_uInt32>(m_nIndex[i]);
922cdf0e10cSrcweir 
923cdf0e10cSrcweir     return rStrm;
924cdf0e10cSrcweir }
925cdf0e10cSrcweir 
926cdf0e10cSrcweir /*
927cdf0e10cSrcweir  * operator>>
928cdf0e10cSrcweir  */
operator >>(SvStream & rStrm)929cdf0e10cSrcweir SvStream& INetRFC822Message::operator>> (SvStream& rStrm)
930cdf0e10cSrcweir {
931cdf0e10cSrcweir     INetMessage::operator>> (rStrm);
932cdf0e10cSrcweir 
933cdf0e10cSrcweir     sal_uInt32 nTemp;
934cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
935cdf0e10cSrcweir     {
936cdf0e10cSrcweir         rStrm >> nTemp;
937cdf0e10cSrcweir         m_nIndex[i] = nTemp;
938cdf0e10cSrcweir     }
939cdf0e10cSrcweir 
940cdf0e10cSrcweir     return rStrm;
941cdf0e10cSrcweir }
942cdf0e10cSrcweir 
943cdf0e10cSrcweir /*=======================================================================
944cdf0e10cSrcweir  *
945cdf0e10cSrcweir  * INetMIMEMessage Implementation.
946cdf0e10cSrcweir  *
947cdf0e10cSrcweir  *=====================================================================*/
948cdf0e10cSrcweir /*
949cdf0e10cSrcweir  * _ImplINetMIMEMessageHeaderData.
950cdf0e10cSrcweir  */
951cdf0e10cSrcweir namespace
952cdf0e10cSrcweir {
953cdf0e10cSrcweir     struct ImplINetMIMEMessageHeaderDataImpl
954cdf0e10cSrcweir     {
operator ()__anon83da486d0211::ImplINetMIMEMessageHeaderDataImpl955cdf0e10cSrcweir         const ByteString* operator()()
956cdf0e10cSrcweir         {
957cdf0e10cSrcweir             static const ByteString _ImplINetMIMEMessageHeaderData[] =
958cdf0e10cSrcweir             {
959cdf0e10cSrcweir                 ByteString ("MIME-Version"),
960cdf0e10cSrcweir                 ByteString ("Content-Description"),
961cdf0e10cSrcweir                 ByteString ("Content-Disposition"),
962cdf0e10cSrcweir                 ByteString ("Content-ID"),
963cdf0e10cSrcweir                 ByteString ("Content-Type"),
964cdf0e10cSrcweir                 ByteString ("Content-Transfer-Encoding")
965cdf0e10cSrcweir             };
966cdf0e10cSrcweir             return &_ImplINetMIMEMessageHeaderData[0];
967cdf0e10cSrcweir         }
968cdf0e10cSrcweir     };
969cdf0e10cSrcweir 
970cdf0e10cSrcweir     struct ImplINetMIMEMessageHeaderData
971cdf0e10cSrcweir         : public rtl::StaticAggregate< const ByteString, ImplINetMIMEMessageHeaderDataImpl > {};
972cdf0e10cSrcweir }
973cdf0e10cSrcweir 
974cdf0e10cSrcweir #define MIMEHDR(n) ImplINetMIMEMessageHeaderData::get()[(n)]
975cdf0e10cSrcweir 
976cdf0e10cSrcweir /*
977cdf0e10cSrcweir  * _ImplINetMIMEMessageHeaderState.
978cdf0e10cSrcweir  */
979cdf0e10cSrcweir enum _ImplINetMIMEMessageHeaderState
980cdf0e10cSrcweir {
981cdf0e10cSrcweir     INETMSG_MIME_BEGIN,
982cdf0e10cSrcweir     INETMSG_MIME_CHECK,
983cdf0e10cSrcweir     INETMSG_MIME_OK,
984cdf0e10cSrcweir     INETMSG_MIME_JUNK,
985cdf0e10cSrcweir 
986cdf0e10cSrcweir     INETMSG_MIME_TOKEN_CONTENT,
987cdf0e10cSrcweir     INETMSG_MIME_TOKEN_CONTENT_D,
988cdf0e10cSrcweir     INETMSG_MIME_TOKEN_CONTENT_T
989cdf0e10cSrcweir };
990cdf0e10cSrcweir 
991cdf0e10cSrcweir /*
992cdf0e10cSrcweir  * INetMIMEMessage.
993cdf0e10cSrcweir  */
INetMIMEMessage(void)994cdf0e10cSrcweir INetMIMEMessage::INetMIMEMessage (void)
995cdf0e10cSrcweir     : INetRFC822Message (),
996cdf0e10cSrcweir       pParent       (NULL),
997cdf0e10cSrcweir       nNumChildren  (0),
998cdf0e10cSrcweir       bHeaderParsed (sal_False)
999cdf0e10cSrcweir {
1000cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < INETMSG_MIME_NUMHDR; i++)
1001cdf0e10cSrcweir         m_nIndex[i] = LIST_ENTRY_NOTFOUND;
1002cdf0e10cSrcweir }
1003cdf0e10cSrcweir 
INetMIMEMessage(const INetMIMEMessage & rMsg)1004cdf0e10cSrcweir INetMIMEMessage::INetMIMEMessage (const INetMIMEMessage& rMsg)
1005cdf0e10cSrcweir     : INetRFC822Message (rMsg)
1006cdf0e10cSrcweir {
1007cdf0e10cSrcweir     // Copy.
1008cdf0e10cSrcweir     CopyImp (rMsg);
1009cdf0e10cSrcweir }
1010cdf0e10cSrcweir 
1011cdf0e10cSrcweir /*
1012cdf0e10cSrcweir  * operator=
1013cdf0e10cSrcweir  */
operator =(const INetMIMEMessage & rMsg)1014cdf0e10cSrcweir INetMIMEMessage& INetMIMEMessage::operator= (
1015cdf0e10cSrcweir     const INetMIMEMessage& rMsg)
1016cdf0e10cSrcweir {
1017cdf0e10cSrcweir     if (this != &rMsg)
1018cdf0e10cSrcweir     {
1019cdf0e10cSrcweir         // Assign base.
1020cdf0e10cSrcweir         INetRFC822Message::operator= (rMsg);
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir         // Cleanup.
1023cdf0e10cSrcweir         CleanupImp();
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir         // Copy.
1026cdf0e10cSrcweir         CopyImp (rMsg);
1027cdf0e10cSrcweir     }
1028cdf0e10cSrcweir     return *this;
1029cdf0e10cSrcweir }
1030cdf0e10cSrcweir 
1031cdf0e10cSrcweir /*
1032cdf0e10cSrcweir  * ~INetMIMEMessage.
1033cdf0e10cSrcweir  */
~INetMIMEMessage(void)1034cdf0e10cSrcweir INetMIMEMessage::~INetMIMEMessage (void)
1035cdf0e10cSrcweir {
1036cdf0e10cSrcweir     // Cleanup.
1037cdf0e10cSrcweir     CleanupImp();
1038cdf0e10cSrcweir }
1039cdf0e10cSrcweir 
1040cdf0e10cSrcweir /*
1041cdf0e10cSrcweir  * CleanupImp.
1042cdf0e10cSrcweir  */
CleanupImp(void)1043cdf0e10cSrcweir void INetMIMEMessage::CleanupImp (void)
1044cdf0e10cSrcweir {
1045cdf0e10cSrcweir     INetMIMEMessage *pChild = NULL;
1046cdf0e10cSrcweir     while ((pChild = (INetMIMEMessage *)(aChildren.Remove())) != NULL)
1047cdf0e10cSrcweir         if (pChild->pParent == this) delete pChild;
1048cdf0e10cSrcweir }
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir /*
1051cdf0e10cSrcweir  * CopyImp.
1052cdf0e10cSrcweir  */
CopyImp(const INetMIMEMessage & rMsg)1053cdf0e10cSrcweir void INetMIMEMessage::CopyImp (const INetMIMEMessage& rMsg)
1054cdf0e10cSrcweir {
1055cdf0e10cSrcweir     bHeaderParsed = rMsg.bHeaderParsed;
1056cdf0e10cSrcweir 
1057cdf0e10cSrcweir     sal_uInt16 i;
1058cdf0e10cSrcweir     for (i = 0; i < INETMSG_MIME_NUMHDR; i++)
1059cdf0e10cSrcweir         m_nIndex[i] = rMsg.m_nIndex[i];
1060cdf0e10cSrcweir 
1061cdf0e10cSrcweir     m_aBoundary = rMsg.m_aBoundary;
1062cdf0e10cSrcweir     nNumChildren = rMsg.nNumChildren;
1063cdf0e10cSrcweir 
1064cdf0e10cSrcweir     for (i = 0; i < rMsg.aChildren.Count(); i++)
1065cdf0e10cSrcweir     {
1066cdf0e10cSrcweir         INetMIMEMessage *pChild =
1067cdf0e10cSrcweir             (INetMIMEMessage *)(rMsg.aChildren.GetObject (i));
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir         if (pChild->pParent == &rMsg)
1070cdf0e10cSrcweir         {
1071cdf0e10cSrcweir             pChild = pChild->CreateMessage (*pChild);
1072cdf0e10cSrcweir             pChild->pParent = this;
1073cdf0e10cSrcweir         }
1074cdf0e10cSrcweir         aChildren.Insert (pChild, LIST_APPEND);
1075cdf0e10cSrcweir     }
1076cdf0e10cSrcweir }
1077cdf0e10cSrcweir 
1078cdf0e10cSrcweir /*
1079cdf0e10cSrcweir  * CreateMessage.
1080cdf0e10cSrcweir  */
CreateMessage(const INetMIMEMessage & rMsg) const1081cdf0e10cSrcweir INetMIMEMessage *INetMIMEMessage::CreateMessage (
1082cdf0e10cSrcweir     const INetMIMEMessage& rMsg) const
1083cdf0e10cSrcweir {
1084cdf0e10cSrcweir     return (new INetMIMEMessage (rMsg));
1085cdf0e10cSrcweir }
1086cdf0e10cSrcweir 
1087cdf0e10cSrcweir /*
1088cdf0e10cSrcweir  * SetHeaderField.
1089cdf0e10cSrcweir  * (Header Field Parser).
1090cdf0e10cSrcweir  */
SetHeaderField(const INetMessageHeader & rHeader,sal_uIntPtr nNewIndex)1091cdf0e10cSrcweir sal_uIntPtr INetMIMEMessage::SetHeaderField (
1092cdf0e10cSrcweir     const INetMessageHeader &rHeader, sal_uIntPtr nNewIndex)
1093cdf0e10cSrcweir {
1094cdf0e10cSrcweir     ByteString aName (rHeader.GetName());
1095cdf0e10cSrcweir     const sal_Char *pData = aName.GetBuffer();
1096cdf0e10cSrcweir     const sal_Char *pStop = pData + aName.Len() + 1;
1097cdf0e10cSrcweir     const sal_Char *check = "";
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir     sal_uIntPtr      nIdx     = LIST_APPEND;
1100cdf0e10cSrcweir     int        eState   = INETMSG_MIME_BEGIN;
1101cdf0e10cSrcweir     int        eOkState = INETMSG_MIME_OK;
1102cdf0e10cSrcweir 
1103cdf0e10cSrcweir     while (pData < pStop)
1104cdf0e10cSrcweir     {
1105cdf0e10cSrcweir         switch (eState)
1106cdf0e10cSrcweir         {
1107cdf0e10cSrcweir             case INETMSG_MIME_BEGIN:
1108cdf0e10cSrcweir                 eState = INETMSG_MIME_CHECK;
1109cdf0e10cSrcweir                 eOkState = INETMSG_MIME_OK;
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
1112cdf0e10cSrcweir                 {
1113cdf0e10cSrcweir                     case 'c':
1114cdf0e10cSrcweir                         check = "ontent-";
1115cdf0e10cSrcweir                         eOkState = INETMSG_MIME_TOKEN_CONTENT;
1116cdf0e10cSrcweir                         break;
1117cdf0e10cSrcweir 
1118cdf0e10cSrcweir                     case 'm':
1119cdf0e10cSrcweir                         check = "ime-version";
1120cdf0e10cSrcweir                         nIdx = INETMSG_MIME_VERSION;
1121cdf0e10cSrcweir                         break;
1122cdf0e10cSrcweir 
1123cdf0e10cSrcweir                     default:
1124cdf0e10cSrcweir                         eState = INETMSG_MIME_JUNK;
1125cdf0e10cSrcweir                         break;
1126cdf0e10cSrcweir                 }
1127cdf0e10cSrcweir                 pData++;
1128cdf0e10cSrcweir                 break;
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir             case INETMSG_MIME_TOKEN_CONTENT:
1131cdf0e10cSrcweir                 eState = INETMSG_MIME_CHECK;
1132cdf0e10cSrcweir                 eOkState = INETMSG_MIME_OK;
1133cdf0e10cSrcweir 
1134cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
1135cdf0e10cSrcweir                 {
1136cdf0e10cSrcweir                     case 'd':
1137cdf0e10cSrcweir                         eState = INETMSG_MIME_TOKEN_CONTENT_D;
1138cdf0e10cSrcweir                         break;
1139cdf0e10cSrcweir 
1140cdf0e10cSrcweir                     case 'i':
1141cdf0e10cSrcweir                         check = "d";
1142cdf0e10cSrcweir                         nIdx = INETMSG_MIME_CONTENT_ID;
1143cdf0e10cSrcweir                         break;
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir                     case 't':
1146cdf0e10cSrcweir                         eState = INETMSG_MIME_TOKEN_CONTENT_T;
1147cdf0e10cSrcweir                         break;
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir                     default:
1150cdf0e10cSrcweir                         eState = INETMSG_MIME_JUNK;
1151cdf0e10cSrcweir                         break;
1152cdf0e10cSrcweir                 }
1153cdf0e10cSrcweir                 pData++;
1154cdf0e10cSrcweir                 break;
1155cdf0e10cSrcweir 
1156cdf0e10cSrcweir             case INETMSG_MIME_TOKEN_CONTENT_D:
1157cdf0e10cSrcweir                 eState = INETMSG_MIME_CHECK;
1158cdf0e10cSrcweir                 eOkState = INETMSG_MIME_OK;
1159cdf0e10cSrcweir 
1160cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
1161cdf0e10cSrcweir                 {
1162cdf0e10cSrcweir                     case 'e':
1163cdf0e10cSrcweir                         check = "scription";
1164cdf0e10cSrcweir                         nIdx = INETMSG_MIME_CONTENT_DESCRIPTION;
1165cdf0e10cSrcweir                         break;
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir                     case 'i':
1168cdf0e10cSrcweir                         check = "sposition";
1169cdf0e10cSrcweir                         nIdx = INETMSG_MIME_CONTENT_DISPOSITION;
1170cdf0e10cSrcweir                         break;
1171cdf0e10cSrcweir 
1172cdf0e10cSrcweir                     default:
1173cdf0e10cSrcweir                         eState = INETMSG_MIME_JUNK;
1174cdf0e10cSrcweir                         break;
1175cdf0e10cSrcweir                 }
1176cdf0e10cSrcweir                 pData++;
1177cdf0e10cSrcweir                 break;
1178cdf0e10cSrcweir 
1179cdf0e10cSrcweir             case INETMSG_MIME_TOKEN_CONTENT_T:
1180cdf0e10cSrcweir                 eState = INETMSG_MIME_CHECK;
1181cdf0e10cSrcweir                 eOkState = INETMSG_MIME_OK;
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir                 switch (ascii_toLowerCase (*pData))
1184cdf0e10cSrcweir                 {
1185cdf0e10cSrcweir                     case 'r':
1186cdf0e10cSrcweir                         check = "ansfer-encoding";
1187cdf0e10cSrcweir                         nIdx = INETMSG_MIME_CONTENT_TRANSFER_ENCODING;
1188cdf0e10cSrcweir                         break;
1189cdf0e10cSrcweir 
1190cdf0e10cSrcweir                     case 'y':
1191cdf0e10cSrcweir                         check = "pe";
1192cdf0e10cSrcweir                         nIdx = INETMSG_MIME_CONTENT_TYPE;
1193cdf0e10cSrcweir                         break;
1194cdf0e10cSrcweir 
1195cdf0e10cSrcweir                     default:
1196cdf0e10cSrcweir                         eState = INETMSG_MIME_JUNK;
1197cdf0e10cSrcweir                         break;
1198cdf0e10cSrcweir                 }
1199cdf0e10cSrcweir                 pData++;
1200cdf0e10cSrcweir                 break;
1201cdf0e10cSrcweir 
1202cdf0e10cSrcweir             case INETMSG_MIME_CHECK:
1203cdf0e10cSrcweir                 if (*check)
1204cdf0e10cSrcweir                 {
1205cdf0e10cSrcweir                     while (*pData && *check &&
1206cdf0e10cSrcweir                            (ascii_toLowerCase (*pData) == *check))
1207cdf0e10cSrcweir                     {
1208cdf0e10cSrcweir                         pData++;
1209cdf0e10cSrcweir                         check++;
1210cdf0e10cSrcweir                     }
1211cdf0e10cSrcweir                 }
1212cdf0e10cSrcweir                 else
1213cdf0e10cSrcweir                 {
1214cdf0e10cSrcweir                     check = pData;
1215cdf0e10cSrcweir                 }
1216cdf0e10cSrcweir                 eState = (*check == '\0') ? eOkState : INETMSG_MIME_JUNK;
1217cdf0e10cSrcweir                 break;
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir             case INETMSG_MIME_OK:
1220cdf0e10cSrcweir                 pData = pStop;
1221cdf0e10cSrcweir                 SetHeaderField_Impl (
1222cdf0e10cSrcweir                     HEADERFIELD (MIMEHDR(nIdx), rHeader.GetValue()),
1223cdf0e10cSrcweir                     m_nIndex[nIdx]);
1224cdf0e10cSrcweir                 nNewIndex = m_nIndex[nIdx];
1225cdf0e10cSrcweir                 break;
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir             default: // INETMSG_MIME_JUNK
1228cdf0e10cSrcweir                 pData = pStop;
1229cdf0e10cSrcweir                 nNewIndex = INetRFC822Message::SetHeaderField (
1230cdf0e10cSrcweir                     rHeader, nNewIndex);
1231cdf0e10cSrcweir                 break;
1232cdf0e10cSrcweir         }
1233cdf0e10cSrcweir     }
1234cdf0e10cSrcweir     return nNewIndex;
1235cdf0e10cSrcweir }
1236cdf0e10cSrcweir 
1237cdf0e10cSrcweir /*
1238cdf0e10cSrcweir  * Specific Set-Methods.
1239cdf0e10cSrcweir  */
SetMIMEVersion(const UniString & rVersion)1240cdf0e10cSrcweir void INetMIMEMessage::SetMIMEVersion (const UniString& rVersion)
1241cdf0e10cSrcweir {
1242cdf0e10cSrcweir     SetHeaderField_Impl (
1243cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
1244cdf0e10cSrcweir         MIMEHDR(INETMSG_MIME_VERSION), rVersion,
1245cdf0e10cSrcweir         m_nIndex[INETMSG_MIME_VERSION]);
1246cdf0e10cSrcweir }
1247cdf0e10cSrcweir 
SetContentDescription(const String & rDescription)1248cdf0e10cSrcweir void INetMIMEMessage::SetContentDescription (const String& rDescription)
1249cdf0e10cSrcweir {
1250cdf0e10cSrcweir     SetHeaderField_Impl (
1251cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
1252cdf0e10cSrcweir         MIMEHDR(INETMSG_MIME_CONTENT_DESCRIPTION), rDescription,
1253cdf0e10cSrcweir         m_nIndex[INETMSG_MIME_CONTENT_DESCRIPTION]);
1254cdf0e10cSrcweir }
1255cdf0e10cSrcweir 
SetContentDisposition(const String & rDisposition)1256cdf0e10cSrcweir void INetMIMEMessage::SetContentDisposition (const String& rDisposition)
1257cdf0e10cSrcweir {
1258cdf0e10cSrcweir     SetHeaderField_Impl (
1259cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
1260cdf0e10cSrcweir         MIMEHDR(INETMSG_MIME_CONTENT_DISPOSITION), rDisposition,
1261cdf0e10cSrcweir         m_nIndex[INETMSG_MIME_CONTENT_DISPOSITION]);
1262cdf0e10cSrcweir }
1263cdf0e10cSrcweir 
SetContentID(const String & rID)1264cdf0e10cSrcweir void INetMIMEMessage::SetContentID (const String& rID)
1265cdf0e10cSrcweir {
1266cdf0e10cSrcweir     SetHeaderField_Impl (
1267cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
1268cdf0e10cSrcweir         MIMEHDR(INETMSG_MIME_CONTENT_ID), rID,
1269cdf0e10cSrcweir         m_nIndex[INETMSG_MIME_CONTENT_ID]);
1270cdf0e10cSrcweir }
1271cdf0e10cSrcweir 
SetContentType(const String & rType)1272cdf0e10cSrcweir void INetMIMEMessage::SetContentType (const String& rType)
1273cdf0e10cSrcweir {
1274cdf0e10cSrcweir     SetHeaderField_Impl (
1275cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
1276cdf0e10cSrcweir         MIMEHDR(INETMSG_MIME_CONTENT_TYPE), rType,
1277cdf0e10cSrcweir         m_nIndex[INETMSG_MIME_CONTENT_TYPE]);
1278cdf0e10cSrcweir }
1279cdf0e10cSrcweir 
SetContentTransferEncoding(const String & rEncoding)1280cdf0e10cSrcweir void INetMIMEMessage::SetContentTransferEncoding (
1281cdf0e10cSrcweir     const String& rEncoding)
1282cdf0e10cSrcweir {
1283cdf0e10cSrcweir     SetHeaderField_Impl (
1284cdf0e10cSrcweir         INetMIME::HEADER_FIELD_TEXT,
1285cdf0e10cSrcweir         MIMEHDR(INETMSG_MIME_CONTENT_TRANSFER_ENCODING), rEncoding,
1286cdf0e10cSrcweir         m_nIndex[INETMSG_MIME_CONTENT_TRANSFER_ENCODING]);
1287cdf0e10cSrcweir }
1288cdf0e10cSrcweir 
1289cdf0e10cSrcweir /*
1290cdf0e10cSrcweir  * GetDefaultContentType.
1291cdf0e10cSrcweir  */
GetDefaultContentType(String & rContentType)1292cdf0e10cSrcweir void INetMIMEMessage::GetDefaultContentType (String& rContentType)
1293cdf0e10cSrcweir {
1294cdf0e10cSrcweir     String aDefaultCT (
1295cdf0e10cSrcweir         "text/plain; charset=us-ascii", RTL_TEXTENCODING_ASCII_US);
1296cdf0e10cSrcweir     if (pParent == NULL)
1297cdf0e10cSrcweir     {
1298cdf0e10cSrcweir         rContentType = aDefaultCT;
1299cdf0e10cSrcweir     }
1300cdf0e10cSrcweir     else
1301cdf0e10cSrcweir     {
1302cdf0e10cSrcweir         String aParentCT (pParent->GetContentType());
1303cdf0e10cSrcweir         if (aParentCT.Len() == 0)
1304cdf0e10cSrcweir             pParent->GetDefaultContentType (aParentCT);
1305cdf0e10cSrcweir 
1306cdf0e10cSrcweir         if (aParentCT.CompareIgnoreCaseToAscii ("message/", 8) == 0)
1307cdf0e10cSrcweir         {
1308cdf0e10cSrcweir             rContentType = aDefaultCT;
1309cdf0e10cSrcweir         }
1310cdf0e10cSrcweir         else if (aParentCT.CompareIgnoreCaseToAscii ("multipart/", 10) == 0)
1311cdf0e10cSrcweir         {
1312cdf0e10cSrcweir             if (aParentCT.CompareIgnoreCaseToAscii ("multipart/digest") == 0)
1313cdf0e10cSrcweir                 rContentType.AssignAscii ("message/rfc822");
1314cdf0e10cSrcweir             else
1315cdf0e10cSrcweir                 rContentType = aDefaultCT;
1316cdf0e10cSrcweir         }
1317cdf0e10cSrcweir         else
1318cdf0e10cSrcweir         {
1319cdf0e10cSrcweir             rContentType = aDefaultCT;
1320cdf0e10cSrcweir         }
1321cdf0e10cSrcweir     }
1322cdf0e10cSrcweir }
1323cdf0e10cSrcweir 
1324cdf0e10cSrcweir /*
1325cdf0e10cSrcweir  * EnableAttachChild.
1326cdf0e10cSrcweir  */
EnableAttachChild(INetMessageContainerType eType)1327cdf0e10cSrcweir sal_Bool INetMIMEMessage::EnableAttachChild (INetMessageContainerType eType)
1328cdf0e10cSrcweir {
1329cdf0e10cSrcweir     // Check context.
1330cdf0e10cSrcweir     if (IsContainer())
1331cdf0e10cSrcweir         return sal_False;
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir     // Setup Content-Type header field.
1334cdf0e10cSrcweir     ByteString aContentType;
1335cdf0e10cSrcweir     switch (eType)
1336cdf0e10cSrcweir     {
1337cdf0e10cSrcweir         case INETMSG_MESSAGE_RFC822:
1338cdf0e10cSrcweir             aContentType = "message/rfc822";
1339cdf0e10cSrcweir             break;
1340cdf0e10cSrcweir 
1341cdf0e10cSrcweir         case INETMSG_MULTIPART_ALTERNATIVE:
1342cdf0e10cSrcweir             aContentType = "multipart/alternative";
1343cdf0e10cSrcweir             break;
1344cdf0e10cSrcweir 
1345cdf0e10cSrcweir         case INETMSG_MULTIPART_DIGEST:
1346cdf0e10cSrcweir             aContentType = "multipart/digest";
1347cdf0e10cSrcweir             break;
1348cdf0e10cSrcweir 
1349cdf0e10cSrcweir         case INETMSG_MULTIPART_PARALLEL:
1350cdf0e10cSrcweir             aContentType = "multipart/parallel";
1351cdf0e10cSrcweir             break;
1352cdf0e10cSrcweir 
1353cdf0e10cSrcweir         case INETMSG_MULTIPART_RELATED:
1354cdf0e10cSrcweir             aContentType = "multipart/related";
1355cdf0e10cSrcweir             break;
1356cdf0e10cSrcweir 
1357cdf0e10cSrcweir         case INETMSG_MULTIPART_FORM_DATA:
1358cdf0e10cSrcweir             aContentType = "multipart/form-data";
1359cdf0e10cSrcweir             break;
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir         default:
1362cdf0e10cSrcweir             aContentType = "multipart/mixed";
1363cdf0e10cSrcweir             break;
1364cdf0e10cSrcweir     }
1365cdf0e10cSrcweir 
1366cdf0e10cSrcweir     // Setup boundary for multipart types.
1367cdf0e10cSrcweir     if (aContentType.CompareIgnoreCaseToAscii ("multipart/", 10) == 0)
1368cdf0e10cSrcweir     {
1369cdf0e10cSrcweir         // Generate a unique boundary from current time.
1370cdf0e10cSrcweir         sal_Char sTail[16 + 1];
1371cdf0e10cSrcweir         Time aCurTime;
1372cdf0e10cSrcweir         sal_uInt64 nThis = reinterpret_cast< sal_uIntPtr >( this ); // we can be on a 64bit architecture
1373cdf0e10cSrcweir         nThis = ( ( nThis >> 32 ) ^ nThis ) & SAL_MAX_UINT32;
1374cdf0e10cSrcweir         sprintf (sTail, "%08X%08X",
1375cdf0e10cSrcweir                  static_cast< unsigned int >(aCurTime.GetTime()),
1376cdf0e10cSrcweir                  static_cast< unsigned int >(nThis));
1377cdf0e10cSrcweir         m_aBoundary = "------------_4D48";
1378cdf0e10cSrcweir         m_aBoundary += sTail;
1379cdf0e10cSrcweir 
1380cdf0e10cSrcweir         // Append boundary as ContentType parameter.
1381cdf0e10cSrcweir         aContentType += "; boundary=";
1382cdf0e10cSrcweir         aContentType += m_aBoundary;
1383cdf0e10cSrcweir     }
1384cdf0e10cSrcweir 
1385cdf0e10cSrcweir     // Set header fields.
1386cdf0e10cSrcweir     SetMIMEVersion (String (CONSTASCII_STRINGPARAM("1.0")));
1387cdf0e10cSrcweir     SetContentType (String (aContentType, RTL_TEXTENCODING_ASCII_US));
1388cdf0e10cSrcweir     SetContentTransferEncoding (String (CONSTASCII_STRINGPARAM("7bit")));
1389cdf0e10cSrcweir 
1390cdf0e10cSrcweir     // Done.
1391cdf0e10cSrcweir     return sal_True;
1392cdf0e10cSrcweir }
1393cdf0e10cSrcweir 
1394cdf0e10cSrcweir /*
1395cdf0e10cSrcweir  * AttachChild.
1396cdf0e10cSrcweir  */
AttachChild(INetMIMEMessage & rChildMsg,sal_Bool bOwner)1397cdf0e10cSrcweir sal_Bool INetMIMEMessage::AttachChild (
1398cdf0e10cSrcweir     INetMIMEMessage& rChildMsg, sal_Bool bOwner)
1399cdf0e10cSrcweir {
1400cdf0e10cSrcweir     if (IsContainer() /*&& rChildMsg.GetContentType().Len() */)
1401cdf0e10cSrcweir     {
1402cdf0e10cSrcweir         if (bOwner) rChildMsg.pParent = this;
1403cdf0e10cSrcweir         aChildren.Insert (&rChildMsg, LIST_APPEND);
1404cdf0e10cSrcweir         nNumChildren = aChildren.Count();
1405cdf0e10cSrcweir 
1406cdf0e10cSrcweir         return sal_True;
1407cdf0e10cSrcweir     }
1408cdf0e10cSrcweir     return sal_False;
1409cdf0e10cSrcweir }
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir /*
1412cdf0e10cSrcweir  * DetachChild.
1413cdf0e10cSrcweir  */
DetachChild(sal_uIntPtr nIndex,INetMIMEMessage & rChildMsg) const1414cdf0e10cSrcweir sal_Bool INetMIMEMessage::DetachChild (
1415cdf0e10cSrcweir     sal_uIntPtr nIndex, INetMIMEMessage& rChildMsg) const
1416cdf0e10cSrcweir {
1417cdf0e10cSrcweir     if (IsContainer())
1418cdf0e10cSrcweir     {
1419cdf0e10cSrcweir         // Check document stream.
1420cdf0e10cSrcweir         if (GetDocumentLB() == NULL) return sal_False;
1421cdf0e10cSrcweir         SvStream *pDocStrm = new SvStream (GetDocumentLB());
1422cdf0e10cSrcweir 
1423cdf0e10cSrcweir         // Initialize message buffer.
1424cdf0e10cSrcweir         char pMsgBuffer[1024];
1425cdf0e10cSrcweir         char *pMsgRead, *pMsgWrite;
1426cdf0e10cSrcweir         pMsgRead = pMsgWrite = pMsgBuffer;
1427cdf0e10cSrcweir 
1428cdf0e10cSrcweir         // Initialize message parser stream.
1429cdf0e10cSrcweir         INetMIMEMessageStream *pMsgStrm = NULL;
1430cdf0e10cSrcweir 
1431cdf0e10cSrcweir         // Check for "multipart/uvw" or "message/xyz".
1432cdf0e10cSrcweir         if (IsMultipart())
1433cdf0e10cSrcweir         {
1434cdf0e10cSrcweir             // Multipart message body. Initialize multipart delimiters.
1435cdf0e10cSrcweir             ByteString aDelim ("--");
1436cdf0e10cSrcweir             aDelim += GetMultipartBoundary();
1437cdf0e10cSrcweir             ByteString aClose = aDelim;
1438cdf0e10cSrcweir             aClose += "--";
1439cdf0e10cSrcweir 
1440cdf0e10cSrcweir             // Initialize line buffer.
1441cdf0e10cSrcweir             SvMemoryStream aLineBuf;
1442cdf0e10cSrcweir 
1443cdf0e10cSrcweir             // Initialize control variables.
1444cdf0e10cSrcweir             INetMessageStreamState eState = INETMSG_EOL_SCR;
1445cdf0e10cSrcweir             int nCurIndex = -1;
1446cdf0e10cSrcweir 
1447cdf0e10cSrcweir             // Go!
1448cdf0e10cSrcweir             while (nCurIndex < (int)(nIndex + 1))
1449cdf0e10cSrcweir             {
1450cdf0e10cSrcweir                 if ((pMsgRead - pMsgWrite) > 0)
1451cdf0e10cSrcweir                 {
1452cdf0e10cSrcweir                     // Bytes still in buffer.
1453cdf0e10cSrcweir                     if (eState == INETMSG_EOL_FCR)
1454cdf0e10cSrcweir                     {
1455cdf0e10cSrcweir                         // Check for 2nd line break character.
1456cdf0e10cSrcweir                         if ((*pMsgWrite == '\r') || (*pMsgWrite == '\n'))
1457cdf0e10cSrcweir                             aLineBuf << *pMsgWrite++;
1458cdf0e10cSrcweir 
1459cdf0e10cSrcweir                         // Check current index.
1460cdf0e10cSrcweir                         if (nCurIndex == (int)nIndex)
1461cdf0e10cSrcweir                         {
1462cdf0e10cSrcweir                             // Found requested part.
1463cdf0e10cSrcweir                             if (pMsgStrm == NULL)
1464cdf0e10cSrcweir                             {
1465cdf0e10cSrcweir                                 // Create message parser stream.
1466cdf0e10cSrcweir                                 pMsgStrm = new INetMIMEMessageStream;
1467cdf0e10cSrcweir                                 pMsgStrm->SetTargetMessage (&rChildMsg);
1468cdf0e10cSrcweir                             }
1469cdf0e10cSrcweir 
1470cdf0e10cSrcweir                             // Put message down-stream.
1471cdf0e10cSrcweir                             int status = pMsgStrm->Write (
1472cdf0e10cSrcweir                                 (const sal_Char *) aLineBuf.GetData(), aLineBuf.Tell());
1473cdf0e10cSrcweir                             if (status != INETSTREAM_STATUS_OK)
1474cdf0e10cSrcweir                             {
1475cdf0e10cSrcweir                                 // Cleanup.
1476cdf0e10cSrcweir                                 delete pDocStrm;
1477cdf0e10cSrcweir                                 delete pMsgStrm;
1478cdf0e10cSrcweir 
1479cdf0e10cSrcweir                                 // Finish.
1480cdf0e10cSrcweir                                 return (!(status == INETSTREAM_STATUS_OK));
1481cdf0e10cSrcweir                             }
1482cdf0e10cSrcweir                         }
1483cdf0e10cSrcweir 
1484cdf0e10cSrcweir                         // Reset to <Begin-of-Line>.
1485cdf0e10cSrcweir                         aLineBuf.Seek (STREAM_SEEK_TO_BEGIN);
1486cdf0e10cSrcweir                         eState = INETMSG_EOL_SCR;
1487cdf0e10cSrcweir                     }
1488cdf0e10cSrcweir                     else if ((*pMsgWrite == '\r') || (*pMsgWrite == '\n'))
1489cdf0e10cSrcweir                     {
1490cdf0e10cSrcweir                         /*
1491cdf0e10cSrcweir                          * Found any line break character.
1492cdf0e10cSrcweir                          * Compare buffered line with part/close delimiter.
1493cdf0e10cSrcweir                          * Increment current part index upon match.
1494cdf0e10cSrcweir                          */
1495cdf0e10cSrcweir                         sal_uInt16 nLen = (sal_uInt16)(aLineBuf.Tell() & 0xffff);
1496cdf0e10cSrcweir                         if (nLen == aDelim.Len())
1497cdf0e10cSrcweir                         {
1498cdf0e10cSrcweir                             if (aDelim.CompareTo ((const sal_Char *) aLineBuf.GetData(), nLen)
1499cdf0e10cSrcweir                                 == COMPARE_EQUAL) nCurIndex++;
1500cdf0e10cSrcweir                         }
1501cdf0e10cSrcweir                         else if (nLen == aClose.Len())
1502cdf0e10cSrcweir                         {
1503cdf0e10cSrcweir                             if (aClose.CompareTo ((const sal_Char *) aLineBuf.GetData(), nLen)
1504cdf0e10cSrcweir                                 == COMPARE_EQUAL) nCurIndex++;
1505cdf0e10cSrcweir                         }
1506cdf0e10cSrcweir                         aLineBuf << *pMsgWrite++;
1507cdf0e10cSrcweir                         eState = INETMSG_EOL_FCR;
1508cdf0e10cSrcweir                     }
1509cdf0e10cSrcweir                     else
1510cdf0e10cSrcweir                     {
1511cdf0e10cSrcweir                         // Insert into line buffer.
1512cdf0e10cSrcweir                         aLineBuf << *pMsgWrite;
1513cdf0e10cSrcweir                     }
1514cdf0e10cSrcweir                 }
1515cdf0e10cSrcweir                 else
1516cdf0e10cSrcweir                 {
1517cdf0e10cSrcweir                     // Buffer empty. Reset to <Begin-of-Buffer>.
1518cdf0e10cSrcweir                     pMsgRead = pMsgWrite = pMsgBuffer;
1519cdf0e10cSrcweir 
1520cdf0e10cSrcweir                     // Read document stream.
1521cdf0e10cSrcweir                     sal_uIntPtr nRead = pDocStrm->Read (
1522cdf0e10cSrcweir                         pMsgBuffer, sizeof (pMsgBuffer));
1523cdf0e10cSrcweir                     if (nRead > 0)
1524cdf0e10cSrcweir                     {
1525cdf0e10cSrcweir                         // Set read pointer.
1526cdf0e10cSrcweir                         pMsgRead += nRead;
1527cdf0e10cSrcweir                     }
1528cdf0e10cSrcweir                     else
1529cdf0e10cSrcweir                     {
1530cdf0e10cSrcweir                         // Premature end.
1531cdf0e10cSrcweir                         if (pMsgStrm)
1532cdf0e10cSrcweir                         {
1533cdf0e10cSrcweir                             // Assume end of requested part.
1534cdf0e10cSrcweir                             nCurIndex++;
1535cdf0e10cSrcweir                         }
1536cdf0e10cSrcweir                         else
1537cdf0e10cSrcweir                         {
1538cdf0e10cSrcweir                             // Requested part not found.
1539cdf0e10cSrcweir                             delete pDocStrm;
1540cdf0e10cSrcweir                             return sal_False;
1541cdf0e10cSrcweir                         }
1542cdf0e10cSrcweir                     }
1543cdf0e10cSrcweir                 }
1544cdf0e10cSrcweir             } // while (nCurIndex < (nIndex + 1))
1545cdf0e10cSrcweir         }
1546cdf0e10cSrcweir         else
1547cdf0e10cSrcweir         {
1548cdf0e10cSrcweir             // Encapsulated message body. Create message parser stream.
1549cdf0e10cSrcweir             pMsgStrm = new INetMIMEMessageStream;
1550cdf0e10cSrcweir             pMsgStrm->SetTargetMessage (&rChildMsg);
1551cdf0e10cSrcweir 
1552cdf0e10cSrcweir             // Initialize control variables.
1553cdf0e10cSrcweir             INetMessageStreamState eState = INETMSG_EOL_BEGIN;
1554cdf0e10cSrcweir 
1555cdf0e10cSrcweir             // Go.
1556cdf0e10cSrcweir             while (eState == INETMSG_EOL_BEGIN)
1557cdf0e10cSrcweir             {
1558cdf0e10cSrcweir                 if ((pMsgRead - pMsgWrite) > 0)
1559cdf0e10cSrcweir                 {
1560cdf0e10cSrcweir                     // Bytes still in buffer. Put message down-stream.
1561cdf0e10cSrcweir                     int status = pMsgStrm->Write (
1562cdf0e10cSrcweir                         pMsgBuffer, (pMsgRead - pMsgWrite));
1563cdf0e10cSrcweir                     if (status != INETSTREAM_STATUS_OK)
1564cdf0e10cSrcweir                     {
1565cdf0e10cSrcweir                         // Cleanup.
1566cdf0e10cSrcweir                         delete pDocStrm;
1567cdf0e10cSrcweir                         delete pMsgStrm;
1568cdf0e10cSrcweir 
1569cdf0e10cSrcweir                         // Finish.
1570cdf0e10cSrcweir                         return (!(status == INETSTREAM_STATUS_ERROR));
1571cdf0e10cSrcweir                     }
1572cdf0e10cSrcweir                     pMsgWrite = pMsgBuffer + (pMsgRead - pMsgWrite);
1573cdf0e10cSrcweir                 }
1574cdf0e10cSrcweir                 else
1575cdf0e10cSrcweir                 {
1576cdf0e10cSrcweir                     // Buffer empty. Reset to <Begin-of-Buffer>.
1577cdf0e10cSrcweir                     pMsgRead = pMsgWrite = pMsgBuffer;
1578cdf0e10cSrcweir 
1579cdf0e10cSrcweir                     // Read document stream.
1580cdf0e10cSrcweir                     sal_uIntPtr nRead = pDocStrm->Read (
1581cdf0e10cSrcweir                         pMsgBuffer, sizeof (pMsgBuffer));
1582cdf0e10cSrcweir                     if (nRead > 0)
1583cdf0e10cSrcweir                     {
1584cdf0e10cSrcweir                         // Set read pointer.
1585cdf0e10cSrcweir                         pMsgRead += nRead;
1586cdf0e10cSrcweir                     }
1587cdf0e10cSrcweir                     else
1588cdf0e10cSrcweir                     {
1589cdf0e10cSrcweir                         // Mark we're done.
1590cdf0e10cSrcweir                         eState = INETMSG_EOL_DONE;
1591cdf0e10cSrcweir                     }
1592cdf0e10cSrcweir                 }
1593cdf0e10cSrcweir             } // while (eState == INETMSG_EOL_BEGIN)
1594cdf0e10cSrcweir         }
1595cdf0e10cSrcweir 
1596cdf0e10cSrcweir         // Done.
1597cdf0e10cSrcweir         if (pDocStrm) delete pDocStrm;
1598cdf0e10cSrcweir         if (pMsgStrm) delete pMsgStrm;
1599cdf0e10cSrcweir         return sal_True;
1600cdf0e10cSrcweir     }
1601cdf0e10cSrcweir     return sal_False;
1602cdf0e10cSrcweir }
1603cdf0e10cSrcweir 
1604cdf0e10cSrcweir /*
1605cdf0e10cSrcweir  * operator<<
1606cdf0e10cSrcweir  */
operator <<(SvStream & rStrm) const1607cdf0e10cSrcweir SvStream& INetMIMEMessage::operator<< (SvStream& rStrm) const
1608cdf0e10cSrcweir {
1609cdf0e10cSrcweir     INetRFC822Message::operator<< (rStrm);
1610cdf0e10cSrcweir 
1611cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < INETMSG_MIME_NUMHDR; i++)
1612cdf0e10cSrcweir         rStrm << static_cast<sal_uInt32>(m_nIndex[i]);
1613cdf0e10cSrcweir 
1614cdf0e10cSrcweir #ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
1615cdf0e10cSrcweir     rStrm << m_aBoundary;
1616cdf0e10cSrcweir #else
1617cdf0e10cSrcweir     rStrm.WriteByteString (m_aBoundary);
1618cdf0e10cSrcweir #endif
1619cdf0e10cSrcweir     rStrm << static_cast<sal_uInt32>(nNumChildren);
1620cdf0e10cSrcweir 
1621cdf0e10cSrcweir     return rStrm;
1622cdf0e10cSrcweir }
1623cdf0e10cSrcweir 
1624cdf0e10cSrcweir /*
1625cdf0e10cSrcweir  * operator>>
1626cdf0e10cSrcweir  */
operator >>(SvStream & rStrm)1627cdf0e10cSrcweir SvStream& INetMIMEMessage::operator>> (SvStream& rStrm)
1628cdf0e10cSrcweir {
1629cdf0e10cSrcweir     INetRFC822Message::operator>> (rStrm);
1630cdf0e10cSrcweir 
1631cdf0e10cSrcweir     sal_uInt32 nTemp;
1632cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < INETMSG_MIME_NUMHDR; i++)
1633cdf0e10cSrcweir     {
1634cdf0e10cSrcweir         rStrm >> nTemp;
1635cdf0e10cSrcweir         m_nIndex[i] = nTemp;
1636cdf0e10cSrcweir     }
1637cdf0e10cSrcweir 
1638cdf0e10cSrcweir #ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
1639cdf0e10cSrcweir     rStrm >> m_aBoundary;
1640cdf0e10cSrcweir #else
1641cdf0e10cSrcweir     rStrm.ReadByteString (m_aBoundary);
1642cdf0e10cSrcweir #endif
1643cdf0e10cSrcweir     rStrm >> nTemp;
1644cdf0e10cSrcweir     nNumChildren = nTemp;
1645cdf0e10cSrcweir 
1646cdf0e10cSrcweir     return rStrm;
1647cdf0e10cSrcweir }
1648cdf0e10cSrcweir 
1649cdf0e10cSrcweir 
1650