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