fix toolbar import
[ooovba.git] / tools / source / inet / inetmsg.cxx
blob00462e203666f12ea707c3b454d363d1fa62dd19
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: inetmsg.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
33 #include <sal/types.h>
34 #include <tools/datetime.hxx>
35 #ifndef _TOOLS_INETMIME_HXX
36 #include <tools/inetmime.hxx>
37 #endif
38 #include <tools/inetmsg.hxx>
39 #include <tools/inetstrm.hxx>
40 #include <rtl/instance.hxx>
42 #include <stdio.h>
44 //=======================================================================
46 inline sal_Bool ascii_isDigit( sal_Unicode ch )
48 return ((ch >= 0x0030) && (ch <= 0x0039));
51 inline sal_Bool ascii_isLetter( sal_Unicode ch )
53 return (( (ch >= 0x0041) && (ch <= 0x005A)) || ((ch >= 0x0061) && (ch <= 0x007A)));
56 inline sal_Unicode ascii_toLowerCase( sal_Unicode ch )
58 if ( (ch >= 0x0041) && (ch <= 0x005A) )
59 return ch + 0x20;
60 else
61 return ch;
64 /*=======================================================================
66 * INetMessage Implementation.
68 *=====================================================================*/
69 #define CONSTASCII_STRINGPARAM(a) (a), RTL_TEXTENCODING_ASCII_US
70 #define HEADERFIELD INetMessageHeader
73 * ~INetMessage.
75 INetMessage::~INetMessage (void)
77 ListCleanup_Impl();
81 * ListCleanup_Impl.
83 void INetMessage::ListCleanup_Impl (void)
85 // Cleanup.
86 ULONG i, n = m_aHeaderList.Count();
87 for (i = 0; i < n; i++)
88 delete ((HEADERFIELD*)(m_aHeaderList.GetObject(i)));
89 m_aHeaderList.Clear();
93 * ListCopy.
95 void INetMessage::ListCopy (const INetMessage &rMsg)
97 if (!(this == &rMsg))
99 // Cleanup.
100 ListCleanup_Impl();
102 // Copy.
103 ULONG i, n = rMsg.GetHeaderCount();
104 for (i = 0; i < n; i++)
106 HEADERFIELD *p = (HEADERFIELD*)(rMsg.m_aHeaderList.GetObject(i));
107 m_aHeaderList.Insert (new HEADERFIELD(*p), LIST_APPEND);
113 * SetHeaderField_Impl.
115 void INetMessage::SetHeaderField_Impl (
116 INetMIME::HeaderFieldType eType,
117 const ByteString &rName,
118 const UniString &rValue,
119 ULONG &rnIndex)
121 INetMIMEStringOutputSink aSink (0, STRING_MAXLEN);
122 INetMIME::writeHeaderFieldBody (
123 aSink, eType, rValue, gsl_getSystemTextEncoding(), false);
124 SetHeaderField_Impl (
125 INetMessageHeader (rName, aSink.takeBuffer()), rnIndex);
129 * SetHeaderField.
131 ULONG INetMessage::SetHeaderField (
132 const UniString& rName, const UniString& rValue, ULONG nIndex)
134 ULONG nResult = nIndex;
135 SetHeaderField_Impl (
136 INetMIME::HEADER_FIELD_TEXT,
137 ByteString (rName, RTL_TEXTENCODING_ASCII_US), rValue,
138 nResult);
139 return nResult;
143 * SetHeaderField.
145 ULONG INetMessage::SetHeaderField (
146 const INetMessageHeader &rHeader, ULONG nIndex)
148 ULONG nResult = nIndex;
149 SetHeaderField_Impl (rHeader, nResult);
150 return nResult;
155 * operator<<
157 SvStream& INetMessage::operator<< (SvStream& rStrm) const
159 rStrm << static_cast<sal_uInt32>(m_nDocSize);
160 rStrm.WriteByteString (m_aDocName, RTL_TEXTENCODING_UTF8);
162 ULONG i, n = m_aHeaderList.Count();
163 rStrm << static_cast<sal_uInt32>(n);
165 for (i = 0; i < n; i++)
166 rStrm << *((HEADERFIELD *)(m_aHeaderList.GetObject(i)));
168 return rStrm;
172 * operator>>
174 SvStream& INetMessage::operator>> (SvStream& rStrm)
176 // Cleanup.
177 m_nDocSize = 0;
178 m_xDocLB.Clear();
179 ListCleanup_Impl();
181 sal_uInt32 nTemp;
183 // Copy.
184 rStrm >> nTemp;
185 m_nDocSize = nTemp;
186 rStrm.ReadByteString (m_aDocName, RTL_TEXTENCODING_UTF8);
188 ULONG i, n = 0;
189 rStrm >> nTemp;
190 n = nTemp;
192 for (i = 0; i < n; i++)
194 HEADERFIELD *p = new HEADERFIELD();
195 rStrm >> *p;
196 m_aHeaderList.Insert (p, LIST_APPEND);
199 // Done.
200 return rStrm;
203 /*=======================================================================
205 * INetMessageHeaderIterator Implementation.
207 *=====================================================================*/
208 INetMessageHeaderIterator::INetMessageHeaderIterator (
209 const INetMessage& rMsg, const UniString& rHdrName)
211 ULONG i, n = rMsg.GetHeaderCount();
212 for (i = 0; i < n; i++)
214 if (rHdrName.CompareIgnoreCaseToAscii (rMsg.GetHeaderName(i)) == 0)
216 UniString *pValue = new UniString (rMsg.GetHeaderValue(i));
217 aValueList.Insert (pValue, LIST_APPEND);
220 nValueCount = aValueList.Count();
223 INetMessageHeaderIterator::~INetMessageHeaderIterator (void)
225 ULONG i, n = aValueList.Count();
226 for (i = 0; i < n; i++)
227 delete ((UniString*)(aValueList.GetObject(i)));
228 aValueList.Clear();
231 /*=======================================================================
233 * INetRFC822Message Implementation.
235 *=====================================================================*/
237 * ImplINetRFC822MessageHeaderData.
239 namespace
241 struct ImplINetRFC822MessageHeaderDataImpl
243 const ByteString* operator()()
245 static const ByteString _ImplINetRFC822MessageHeaderData[] =
247 ByteString ("BCC"),
248 ByteString ("CC"),
249 ByteString ("Comments"),
250 ByteString ("Date"),
251 ByteString ("From"),
252 ByteString ("In-Reply-To"),
253 ByteString ("Keywords"),
254 ByteString ("Message-ID"),
255 ByteString ("References"),
256 ByteString ("Reply-To"),
257 ByteString ("Return-Path"),
258 ByteString ("Subject"),
259 ByteString ("Sender"),
260 ByteString ("To"),
261 ByteString ("X-Mailer"),
262 ByteString ("Return-Receipt-To")
264 return &_ImplINetRFC822MessageHeaderData[0];
268 struct ImplINetRFC822MessageHeaderData
269 : public rtl::StaticAggregate< const ByteString, ImplINetRFC822MessageHeaderDataImpl > {};
272 #define HDR(n) ImplINetRFC822MessageHeaderData::get()[(n)]
275 * _ImplINetRFC822MessageHeaderState.
277 enum _ImplINetRFC822MessageHeaderState
279 INETMSG_RFC822_BEGIN,
280 INETMSG_RFC822_CHECK,
281 INETMSG_RFC822_OK,
282 INETMSG_RFC822_JUNK,
284 INETMSG_RFC822_TOKEN_RE,
285 INETMSG_RFC822_TOKEN_RETURNMINUS,
286 INETMSG_RFC822_TOKEN_XMINUS,
287 INETMSG_RFC822_LETTER_C,
288 INETMSG_RFC822_LETTER_S
292 * INetRFC822Message.
294 INetRFC822Message::INetRFC822Message (void)
295 : INetMessage()
297 for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
298 m_nIndex[i] = LIST_ENTRY_NOTFOUND;
301 INetRFC822Message::INetRFC822Message (const INetRFC822Message& rMsg)
302 : INetMessage (rMsg)
304 for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
305 m_nIndex[i] = rMsg.m_nIndex[i];
309 * operator=
311 INetRFC822Message& INetRFC822Message::operator= (const INetRFC822Message& rMsg)
313 if (this != &rMsg)
315 INetMessage::operator= (rMsg);
317 for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
318 m_nIndex[i] = rMsg.m_nIndex[i];
320 return *this;
324 * ~INetRFC822Message.
326 INetRFC822Message::~INetRFC822Message (void)
331 * <Generate|Parse>DateField and local helper functions.
333 * GenerateDateField.
334 * Generates a String from Date and Time objects in format:
335 * Wkd, 00 Mon 0000 00:00:00 [GMT] (rfc822, rfc1123)
337 * ParseDateField.
338 * Parses a String in (implied) GMT format into class Date and Time objects.
339 * Four formats are accepted:
341 * [Wkd,] 1*2DIGIT Mon 2*4DIGIT 00:00:00 [GMT] (rfc1123)
342 * [Wkd,] 00 Mon 0000 00:00:00 [GMT]) (rfc822, rfc1123)
343 * Weekday, 00-Mon-00 00:00:00 [GMT] (rfc850, rfc1036)
344 * Wkd Mon 00 00:00:00 0000 [GMT] (ctime)
345 * 1*DIGIT (delta seconds)
349 // Months and Weekdays.
350 static const sal_Char *months[12] =
352 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
353 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
356 static const sal_Char *wkdays[7] =
358 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
362 * GenerateDateField.
364 BOOL INetRFC822Message::GenerateDateField (
365 const DateTime& rDateTime, UniString& rDateFieldW)
367 // Check arguments.
368 if (!rDateTime.IsValid() ||
369 (rDateTime.GetSec() > 59) ||
370 (rDateTime.GetMin() > 59) ||
371 (rDateTime.GetHour() > 23) ) return FALSE;
373 // Prepare output string.
374 ByteString rDateField;
376 // Insert Date.
377 rDateField += wkdays[(USHORT)(rDateTime.GetDayOfWeek())];
378 rDateField += ", ";
380 USHORT nNum = rDateTime.GetDay();
381 if (nNum < 10) rDateField += '0';
382 rDateField += ByteString::CreateFromInt32(nNum);
383 rDateField += ' ';
385 rDateField += months[(USHORT)(rDateTime.GetMonth() - 1)];
386 rDateField += ' ';
388 rDateField += ByteString::CreateFromInt32(rDateTime.GetYear());
389 rDateField += ' ';
391 // Insert Time.
392 nNum = rDateTime.GetHour();
393 if (nNum < 10) rDateField += '0';
394 rDateField += ByteString::CreateFromInt32(nNum);
395 rDateField += ':';
397 nNum = rDateTime.GetMin();
398 if (nNum < 10) rDateField += '0';
399 rDateField += ByteString::CreateFromInt32(nNum);
400 rDateField += ':';
402 nNum = rDateTime.GetSec();
403 if (nNum < 10) rDateField += '0';
404 rDateField += ByteString::CreateFromInt32(nNum);
405 rDateField += " GMT";
407 // Done.
408 rDateFieldW = UniString (rDateField, RTL_TEXTENCODING_ASCII_US);
409 return TRUE;
413 * ParseDateField and local helper functions.
415 static USHORT ParseNumber (const ByteString& rStr, USHORT& nIndex)
417 USHORT n = nIndex;
418 while ((n < rStr.Len()) && ascii_isDigit(rStr.GetChar(n))) n++;
420 ByteString aNum (rStr.Copy (nIndex, (n - nIndex)));
421 nIndex = n;
423 return (USHORT)(aNum.ToInt32());
426 static USHORT ParseMonth (const ByteString& rStr, USHORT& nIndex)
428 USHORT n = nIndex;
429 while ((n < rStr.Len()) && ascii_isLetter(rStr.GetChar(n))) n++;
431 ByteString aMonth (rStr.Copy (nIndex, 3));
432 nIndex = n;
434 USHORT i;
435 for (i = 0; i < 12; i++)
436 if (aMonth.CompareIgnoreCaseToAscii (months[i]) == 0) break;
437 return (i + 1);
440 BOOL INetRFC822Message::ParseDateField (
441 const UniString& rDateFieldW, DateTime& rDateTime)
443 ByteString rDateField (rDateFieldW, RTL_TEXTENCODING_ASCII_US);
444 if (rDateField.Len() == 0) return FALSE;
446 if (rDateField.Search (':') != STRING_NOTFOUND)
448 // Some DateTime format.
449 USHORT nIndex = 0;
451 // Skip over <Wkd> or <Weekday>, leading and trailing space.
452 while ((nIndex < rDateField.Len()) &&
453 (rDateField.GetChar(nIndex) == ' '))
454 nIndex++;
456 while (
457 (nIndex < rDateField.Len()) &&
458 (ascii_isLetter (rDateField.GetChar(nIndex)) ||
459 (rDateField.GetChar(nIndex) == ',') ))
460 nIndex++;
462 while ((nIndex < rDateField.Len()) &&
463 (rDateField.GetChar(nIndex) == ' '))
464 nIndex++;
466 if (ascii_isLetter (rDateField.GetChar(nIndex)))
468 // Format: ctime().
469 if ((rDateField.Len() - nIndex) < 20) return FALSE;
471 rDateTime.SetMonth (ParseMonth (rDateField, nIndex)); nIndex++;
472 rDateTime.SetDay (ParseNumber (rDateField, nIndex)); nIndex++;
474 rDateTime.SetHour (ParseNumber (rDateField, nIndex)); nIndex++;
475 rDateTime.SetMin (ParseNumber (rDateField, nIndex)); nIndex++;
476 rDateTime.SetSec (ParseNumber (rDateField, nIndex)); nIndex++;
477 rDateTime.Set100Sec (0);
479 USHORT nYear = ParseNumber (rDateField, nIndex);
480 if (nYear < 100) nYear += 1900;
481 rDateTime.SetYear (nYear);
483 else
485 // Format: RFC1036 or RFC1123.
486 if ((rDateField.Len() - nIndex) < 17) return FALSE;
488 rDateTime.SetDay (ParseNumber (rDateField, nIndex)); nIndex++;
489 rDateTime.SetMonth (ParseMonth (rDateField, nIndex)); nIndex++;
491 USHORT nYear = ParseNumber (rDateField, nIndex); nIndex++;
492 if (nYear < 100) nYear += 1900;
493 rDateTime.SetYear (nYear);
495 rDateTime.SetHour (ParseNumber (rDateField, nIndex)); nIndex++;
496 rDateTime.SetMin (ParseNumber (rDateField, nIndex)); nIndex++;
497 rDateTime.SetSec (ParseNumber (rDateField, nIndex)); nIndex++;
498 rDateTime.Set100Sec (0);
500 if ((rDateField.GetChar(nIndex) == '+') ||
501 (rDateField.GetChar(nIndex) == '-') )
503 // Offset from GMT: "(+|-)HHMM".
504 BOOL bEast = (rDateField.GetChar(nIndex++) == '+');
505 USHORT nOffset = ParseNumber (rDateField, nIndex);
506 if (nOffset > 0)
508 Time aDiff;
509 aDiff.SetHour (nOffset / 100);
510 aDiff.SetMin (nOffset % 100);
511 aDiff.SetSec (0);
512 aDiff.Set100Sec (0);
514 if (bEast)
515 rDateTime -= aDiff;
516 else
517 rDateTime += aDiff;
522 else if (rDateField.IsNumericAscii())
524 // Format: delta seconds.
525 Time aDelta (0);
526 aDelta.SetTime (rDateField.ToInt32() * 100);
528 DateTime aNow;
529 aNow += aDelta;
530 aNow.ConvertToUTC();
532 rDateTime.SetDate (aNow.GetDate());
533 rDateTime.SetTime (aNow.GetTime());
535 else
537 // Junk.
538 return FALSE;
541 return (rDateTime.IsValid() &&
542 !((rDateTime.GetSec() > 59) ||
543 (rDateTime.GetMin() > 59) ||
544 (rDateTime.GetHour() > 23) ));
548 * SetHeaderField.
549 * (Header Field Parser).
551 ULONG INetRFC822Message::SetHeaderField (
552 const INetMessageHeader &rHeader, ULONG nNewIndex)
554 ByteString aName (rHeader.GetName());
555 const sal_Char *pData = aName.GetBuffer();
556 const sal_Char *pStop = pData + aName.Len() + 1;
557 const sal_Char *check = "";
559 ULONG nIdx = LIST_APPEND;
560 int eState = INETMSG_RFC822_BEGIN;
561 int eOkState = INETMSG_RFC822_OK;
563 while (pData < pStop)
565 switch (eState)
567 case INETMSG_RFC822_BEGIN:
568 eState = INETMSG_RFC822_CHECK;
569 eOkState = INETMSG_RFC822_OK;
571 switch (ascii_toLowerCase (*pData))
573 case 'b':
574 check = "cc";
575 nIdx = INETMSG_RFC822_BCC;
576 break;
578 case 'c':
579 eState = INETMSG_RFC822_LETTER_C;
580 break;
582 case 'd':
583 check = "ate";
584 nIdx = INETMSG_RFC822_DATE;
585 break;
587 case 'f':
588 check = "rom";
589 nIdx = INETMSG_RFC822_FROM;
590 break;
592 case 'i':
593 check = "n-reply-to";
594 nIdx = INETMSG_RFC822_IN_REPLY_TO;
595 break;
597 case 'k':
598 check = "eywords";
599 nIdx = INETMSG_RFC822_KEYWORDS;
600 break;
602 case 'm':
603 check = "essage-id";
604 nIdx = INETMSG_RFC822_MESSAGE_ID;
605 break;
607 case 'r':
608 check = "e";
609 eOkState = INETMSG_RFC822_TOKEN_RE;
610 break;
612 case 's':
613 eState = INETMSG_RFC822_LETTER_S;
614 break;
616 case 't':
617 check = "o";
618 nIdx = INETMSG_RFC822_TO;
619 break;
621 case 'x':
622 check = "-";
623 eOkState = INETMSG_RFC822_TOKEN_XMINUS;
624 break;
626 default:
627 eState = INETMSG_RFC822_JUNK;
628 break;
630 pData++;
631 break;
633 case INETMSG_RFC822_TOKEN_RE:
634 eState = INETMSG_RFC822_CHECK;
635 eOkState = INETMSG_RFC822_OK;
637 switch (ascii_toLowerCase (*pData))
639 case 'f':
640 check = "erences";
641 nIdx = INETMSG_RFC822_REFERENCES;
642 break;
644 case 'p':
645 check = "ly-to";
646 nIdx = INETMSG_RFC822_REPLY_TO;
647 break;
649 case 't':
650 check = "urn-";
651 eOkState = INETMSG_RFC822_TOKEN_RETURNMINUS;
652 break;
654 default:
655 eState = INETMSG_RFC822_JUNK;
656 break;
658 pData++;
659 break;
661 case INETMSG_RFC822_TOKEN_RETURNMINUS:
662 eState = INETMSG_RFC822_CHECK;
663 eOkState = INETMSG_RFC822_OK;
665 switch (ascii_toLowerCase (*pData))
667 case 'p':
668 check = "ath";
669 nIdx = INETMSG_RFC822_RETURN_PATH;
670 break;
672 case 'r':
673 check = "eceipt-to";
674 nIdx = INETMSG_RFC822_RETURN_RECEIPT_TO;
675 break;
677 default:
678 eState = INETMSG_RFC822_JUNK;
679 break;
681 pData++;
682 break;
684 case INETMSG_RFC822_TOKEN_XMINUS:
685 eState = INETMSG_RFC822_CHECK;
686 eOkState = INETMSG_RFC822_OK;
688 switch (ascii_toLowerCase (*pData))
690 case 'm':
691 check = "ailer";
692 nIdx = INETMSG_RFC822_X_MAILER;
693 break;
695 #if 0 /* NYI */
696 case 'p':
697 check = "riority";
698 eOkState = INETMSG_RFC822_X_PRIORITY;
699 break;
700 #endif /* NYI */
702 default:
703 eState = INETMSG_RFC822_JUNK;
704 break;
706 pData++;
707 break;
709 case INETMSG_RFC822_LETTER_C:
710 eState = INETMSG_RFC822_CHECK;
711 eOkState = INETMSG_RFC822_OK;
713 switch (ascii_toLowerCase (*pData))
715 case 'c':
716 check = "";
717 nIdx = INETMSG_RFC822_CC;
718 break;
720 case 'o':
721 check = "mments";
722 nIdx = INETMSG_RFC822_COMMENTS;
723 break;
725 default:
726 eState = INETMSG_RFC822_JUNK;
727 break;
729 pData++;
730 break;
732 case INETMSG_RFC822_LETTER_S:
733 eState = INETMSG_RFC822_CHECK;
734 eOkState = INETMSG_RFC822_OK;
736 switch (ascii_toLowerCase (*pData))
738 case 'e':
739 check = "nder";
740 nIdx = INETMSG_RFC822_SENDER;
741 break;
743 case 'u':
744 check = "bject";
745 nIdx = INETMSG_RFC822_SUBJECT;
746 break;
748 default:
749 eState = INETMSG_RFC822_JUNK;
750 break;
752 pData++;
753 break;
755 case INETMSG_RFC822_CHECK:
756 if (*check)
758 while (*pData && *check &&
759 (ascii_toLowerCase (*pData) == *check))
761 pData++;
762 check++;
765 else
767 check = pData;
769 eState = (*check == '\0') ? eOkState : INETMSG_RFC822_JUNK;
770 break;
772 case INETMSG_RFC822_OK:
773 pData = pStop;
774 SetHeaderField_Impl (
775 HEADERFIELD (HDR(nIdx), rHeader.GetValue()),
776 m_nIndex[nIdx]);
777 nNewIndex = m_nIndex[nIdx];
778 break;
780 default: // INETMSG_RFC822_JUNK
781 pData = pStop;
782 nNewIndex = INetMessage::SetHeaderField (rHeader, nNewIndex);
783 break;
786 return nNewIndex;
790 * Specific Set-Methods.
792 void INetRFC822Message::SetBCC (const UniString& rBCC)
794 SetHeaderField_Impl (
795 INetMIME::HEADER_FIELD_ADDRESS,
796 HDR(INETMSG_RFC822_BCC), rBCC,
797 m_nIndex[INETMSG_RFC822_BCC]);
800 void INetRFC822Message::SetCC (const UniString& rCC)
802 SetHeaderField_Impl (
803 INetMIME::HEADER_FIELD_ADDRESS,
804 HDR(INETMSG_RFC822_CC), rCC,
805 m_nIndex[INETMSG_RFC822_CC]);
808 void INetRFC822Message::SetComments (const UniString& rComments)
810 SetHeaderField_Impl (
811 INetMIME::HEADER_FIELD_TEXT,
812 HDR(INETMSG_RFC822_COMMENTS), rComments,
813 m_nIndex[INETMSG_RFC822_COMMENTS]);
816 void INetRFC822Message::SetDate (const UniString& rDate)
818 SetHeaderField_Impl (
819 INetMIME::HEADER_FIELD_STRUCTURED,
820 HDR(INETMSG_RFC822_DATE), rDate,
821 m_nIndex[INETMSG_RFC822_DATE]);
824 void INetRFC822Message::SetFrom (const UniString& rFrom)
826 SetHeaderField_Impl (
827 INetMIME::HEADER_FIELD_ADDRESS,
828 HDR(INETMSG_RFC822_FROM), rFrom,
829 m_nIndex[INETMSG_RFC822_FROM]);
832 void INetRFC822Message::SetInReplyTo (const UniString& rInReplyTo)
834 SetHeaderField_Impl (
835 INetMIME::HEADER_FIELD_ADDRESS, // ??? MESSAGE_ID ???
836 HDR(INETMSG_RFC822_IN_REPLY_TO), rInReplyTo,
837 m_nIndex[INETMSG_RFC822_IN_REPLY_TO]);
840 void INetRFC822Message::SetKeywords (const UniString& rKeywords)
842 SetHeaderField_Impl (
843 INetMIME::HEADER_FIELD_PHRASE,
844 HDR(INETMSG_RFC822_KEYWORDS), rKeywords,
845 m_nIndex[INETMSG_RFC822_KEYWORDS]);
848 void INetRFC822Message::SetMessageID (const UniString& rMessageID)
850 SetHeaderField_Impl (
851 INetMIME::HEADER_FIELD_MESSAGE_ID,
852 HDR(INETMSG_RFC822_MESSAGE_ID), rMessageID,
853 m_nIndex[INETMSG_RFC822_MESSAGE_ID]);
856 void INetRFC822Message::SetReferences (const UniString& rReferences)
858 SetHeaderField_Impl (
859 INetMIME::HEADER_FIELD_MESSAGE_ID,
860 HDR(INETMSG_RFC822_REFERENCES), rReferences,
861 m_nIndex[INETMSG_RFC822_REFERENCES]);
864 void INetRFC822Message::SetReplyTo (const UniString& rReplyTo)
866 SetHeaderField_Impl (
867 INetMIME::HEADER_FIELD_ADDRESS,
868 HDR(INETMSG_RFC822_REPLY_TO), rReplyTo,
869 m_nIndex[INETMSG_RFC822_REPLY_TO]);
872 void INetRFC822Message::SetReturnPath (const UniString& rReturnPath)
874 SetHeaderField_Impl (
875 INetMIME::HEADER_FIELD_ADDRESS,
876 HDR(INETMSG_RFC822_RETURN_PATH), rReturnPath,
877 m_nIndex[INETMSG_RFC822_RETURN_PATH]);
880 void INetRFC822Message::SetReturnReceiptTo (const UniString& rValue)
882 SetHeaderField_Impl (
883 INetMIME::HEADER_FIELD_ADDRESS,
884 HDR(INETMSG_RFC822_RETURN_RECEIPT_TO), rValue,
885 m_nIndex[INETMSG_RFC822_RETURN_RECEIPT_TO]);
888 void INetRFC822Message::SetSender (const UniString& rSender)
890 SetHeaderField_Impl (
891 INetMIME::HEADER_FIELD_ADDRESS,
892 HDR(INETMSG_RFC822_SENDER), rSender,
893 m_nIndex[INETMSG_RFC822_SENDER]);
896 void INetRFC822Message::SetSubject (const UniString& rSubject)
898 SetHeaderField_Impl (
899 INetMIME::HEADER_FIELD_TEXT,
900 HDR(INETMSG_RFC822_SUBJECT), rSubject,
901 m_nIndex[INETMSG_RFC822_SUBJECT]);
904 void INetRFC822Message::SetTo (const UniString& rTo)
906 SetHeaderField_Impl (
907 INetMIME::HEADER_FIELD_ADDRESS,
908 HDR(INETMSG_RFC822_TO), rTo,
909 m_nIndex[INETMSG_RFC822_TO]);
912 void INetRFC822Message::SetXMailer (const UniString& rXMailer)
914 SetHeaderField_Impl (
915 INetMIME::HEADER_FIELD_TEXT,
916 HDR(INETMSG_RFC822_X_MAILER), rXMailer,
917 m_nIndex[INETMSG_RFC822_X_MAILER]);
921 * operator<<
923 SvStream& INetRFC822Message::operator<< (SvStream& rStrm) const
925 INetMessage::operator<< (rStrm);
927 for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
928 rStrm << static_cast<sal_uInt32>(m_nIndex[i]);
930 return rStrm;
934 * operator>>
936 SvStream& INetRFC822Message::operator>> (SvStream& rStrm)
938 INetMessage::operator>> (rStrm);
940 sal_uInt32 nTemp;
941 for (USHORT i = 0; i < INETMSG_RFC822_NUMHDR; i++)
943 rStrm >> nTemp;
944 m_nIndex[i] = nTemp;
947 return rStrm;
950 /*=======================================================================
952 * INetMIMEMessage Implementation.
954 *=====================================================================*/
956 * _ImplINetMIMEMessageHeaderData.
958 namespace
960 struct ImplINetMIMEMessageHeaderDataImpl
962 const ByteString* operator()()
964 static const ByteString _ImplINetMIMEMessageHeaderData[] =
966 ByteString ("MIME-Version"),
967 ByteString ("Content-Description"),
968 ByteString ("Content-Disposition"),
969 ByteString ("Content-ID"),
970 ByteString ("Content-Type"),
971 ByteString ("Content-Transfer-Encoding")
973 return &_ImplINetMIMEMessageHeaderData[0];
977 struct ImplINetMIMEMessageHeaderData
978 : public rtl::StaticAggregate< const ByteString, ImplINetMIMEMessageHeaderDataImpl > {};
981 #define MIMEHDR(n) ImplINetMIMEMessageHeaderData::get()[(n)]
984 * _ImplINetMIMEMessageHeaderState.
986 enum _ImplINetMIMEMessageHeaderState
988 INETMSG_MIME_BEGIN,
989 INETMSG_MIME_CHECK,
990 INETMSG_MIME_OK,
991 INETMSG_MIME_JUNK,
993 INETMSG_MIME_TOKEN_CONTENT,
994 INETMSG_MIME_TOKEN_CONTENT_D,
995 INETMSG_MIME_TOKEN_CONTENT_T
999 * INetMIMEMessage.
1001 INetMIMEMessage::INetMIMEMessage (void)
1002 : INetRFC822Message (),
1003 pParent (NULL),
1004 nNumChildren (0),
1005 bHeaderParsed (FALSE)
1007 for (USHORT i = 0; i < INETMSG_MIME_NUMHDR; i++)
1008 m_nIndex[i] = LIST_ENTRY_NOTFOUND;
1011 INetMIMEMessage::INetMIMEMessage (const INetMIMEMessage& rMsg)
1012 : INetRFC822Message (rMsg)
1014 // Copy.
1015 CopyImp (rMsg);
1019 * operator=
1021 INetMIMEMessage& INetMIMEMessage::operator= (
1022 const INetMIMEMessage& rMsg)
1024 if (this != &rMsg)
1026 // Assign base.
1027 INetRFC822Message::operator= (rMsg);
1029 // Cleanup.
1030 CleanupImp();
1032 // Copy.
1033 CopyImp (rMsg);
1035 return *this;
1039 * ~INetMIMEMessage.
1041 INetMIMEMessage::~INetMIMEMessage (void)
1043 // Cleanup.
1044 CleanupImp();
1048 * CleanupImp.
1050 void INetMIMEMessage::CleanupImp (void)
1052 INetMIMEMessage *pChild = NULL;
1053 while ((pChild = (INetMIMEMessage *)(aChildren.Remove())) != NULL)
1054 if (pChild->pParent == this) delete pChild;
1058 * CopyImp.
1060 void INetMIMEMessage::CopyImp (const INetMIMEMessage& rMsg)
1062 bHeaderParsed = rMsg.bHeaderParsed;
1064 USHORT i;
1065 for (i = 0; i < INETMSG_MIME_NUMHDR; i++)
1066 m_nIndex[i] = rMsg.m_nIndex[i];
1068 m_aBoundary = rMsg.m_aBoundary;
1069 nNumChildren = rMsg.nNumChildren;
1071 for (i = 0; i < rMsg.aChildren.Count(); i++)
1073 INetMIMEMessage *pChild =
1074 (INetMIMEMessage *)(rMsg.aChildren.GetObject (i));
1076 if (pChild->pParent == &rMsg)
1078 pChild = pChild->CreateMessage (*pChild);
1079 pChild->pParent = this;
1081 aChildren.Insert (pChild, LIST_APPEND);
1086 * CreateMessage.
1088 INetMIMEMessage *INetMIMEMessage::CreateMessage (
1089 const INetMIMEMessage& rMsg) const
1091 return (new INetMIMEMessage (rMsg));
1095 * SetHeaderField.
1096 * (Header Field Parser).
1098 ULONG INetMIMEMessage::SetHeaderField (
1099 const INetMessageHeader &rHeader, ULONG nNewIndex)
1101 ByteString aName (rHeader.GetName());
1102 const sal_Char *pData = aName.GetBuffer();
1103 const sal_Char *pStop = pData + aName.Len() + 1;
1104 const sal_Char *check = "";
1106 ULONG nIdx = LIST_APPEND;
1107 int eState = INETMSG_MIME_BEGIN;
1108 int eOkState = INETMSG_MIME_OK;
1110 while (pData < pStop)
1112 switch (eState)
1114 case INETMSG_MIME_BEGIN:
1115 eState = INETMSG_MIME_CHECK;
1116 eOkState = INETMSG_MIME_OK;
1118 switch (ascii_toLowerCase (*pData))
1120 case 'c':
1121 check = "ontent-";
1122 eOkState = INETMSG_MIME_TOKEN_CONTENT;
1123 break;
1125 case 'm':
1126 check = "ime-version";
1127 nIdx = INETMSG_MIME_VERSION;
1128 break;
1130 default:
1131 eState = INETMSG_MIME_JUNK;
1132 break;
1134 pData++;
1135 break;
1137 case INETMSG_MIME_TOKEN_CONTENT:
1138 eState = INETMSG_MIME_CHECK;
1139 eOkState = INETMSG_MIME_OK;
1141 switch (ascii_toLowerCase (*pData))
1143 case 'd':
1144 eState = INETMSG_MIME_TOKEN_CONTENT_D;
1145 break;
1147 case 'i':
1148 check = "d";
1149 nIdx = INETMSG_MIME_CONTENT_ID;
1150 break;
1152 case 't':
1153 eState = INETMSG_MIME_TOKEN_CONTENT_T;
1154 break;
1156 default:
1157 eState = INETMSG_MIME_JUNK;
1158 break;
1160 pData++;
1161 break;
1163 case INETMSG_MIME_TOKEN_CONTENT_D:
1164 eState = INETMSG_MIME_CHECK;
1165 eOkState = INETMSG_MIME_OK;
1167 switch (ascii_toLowerCase (*pData))
1169 case 'e':
1170 check = "scription";
1171 nIdx = INETMSG_MIME_CONTENT_DESCRIPTION;
1172 break;
1174 case 'i':
1175 check = "sposition";
1176 nIdx = INETMSG_MIME_CONTENT_DISPOSITION;
1177 break;
1179 default:
1180 eState = INETMSG_MIME_JUNK;
1181 break;
1183 pData++;
1184 break;
1186 case INETMSG_MIME_TOKEN_CONTENT_T:
1187 eState = INETMSG_MIME_CHECK;
1188 eOkState = INETMSG_MIME_OK;
1190 switch (ascii_toLowerCase (*pData))
1192 case 'r':
1193 check = "ansfer-encoding";
1194 nIdx = INETMSG_MIME_CONTENT_TRANSFER_ENCODING;
1195 break;
1197 case 'y':
1198 check = "pe";
1199 nIdx = INETMSG_MIME_CONTENT_TYPE;
1200 break;
1202 default:
1203 eState = INETMSG_MIME_JUNK;
1204 break;
1206 pData++;
1207 break;
1209 case INETMSG_MIME_CHECK:
1210 if (*check)
1212 while (*pData && *check &&
1213 (ascii_toLowerCase (*pData) == *check))
1215 pData++;
1216 check++;
1219 else
1221 check = pData;
1223 eState = (*check == '\0') ? eOkState : INETMSG_MIME_JUNK;
1224 break;
1226 case INETMSG_MIME_OK:
1227 pData = pStop;
1228 SetHeaderField_Impl (
1229 HEADERFIELD (MIMEHDR(nIdx), rHeader.GetValue()),
1230 m_nIndex[nIdx]);
1231 nNewIndex = m_nIndex[nIdx];
1232 break;
1234 default: // INETMSG_MIME_JUNK
1235 pData = pStop;
1236 nNewIndex = INetRFC822Message::SetHeaderField (
1237 rHeader, nNewIndex);
1238 break;
1241 return nNewIndex;
1245 * Specific Set-Methods.
1247 void INetMIMEMessage::SetMIMEVersion (const UniString& rVersion)
1249 SetHeaderField_Impl (
1250 INetMIME::HEADER_FIELD_TEXT,
1251 MIMEHDR(INETMSG_MIME_VERSION), rVersion,
1252 m_nIndex[INETMSG_MIME_VERSION]);
1255 void INetMIMEMessage::SetContentDescription (const String& rDescription)
1257 SetHeaderField_Impl (
1258 INetMIME::HEADER_FIELD_TEXT,
1259 MIMEHDR(INETMSG_MIME_CONTENT_DESCRIPTION), rDescription,
1260 m_nIndex[INETMSG_MIME_CONTENT_DESCRIPTION]);
1263 void INetMIMEMessage::SetContentDisposition (const String& rDisposition)
1265 SetHeaderField_Impl (
1266 INetMIME::HEADER_FIELD_TEXT,
1267 MIMEHDR(INETMSG_MIME_CONTENT_DISPOSITION), rDisposition,
1268 m_nIndex[INETMSG_MIME_CONTENT_DISPOSITION]);
1271 void INetMIMEMessage::SetContentID (const String& rID)
1273 SetHeaderField_Impl (
1274 INetMIME::HEADER_FIELD_TEXT,
1275 MIMEHDR(INETMSG_MIME_CONTENT_ID), rID,
1276 m_nIndex[INETMSG_MIME_CONTENT_ID]);
1279 void INetMIMEMessage::SetContentType (const String& rType)
1281 SetHeaderField_Impl (
1282 INetMIME::HEADER_FIELD_TEXT,
1283 MIMEHDR(INETMSG_MIME_CONTENT_TYPE), rType,
1284 m_nIndex[INETMSG_MIME_CONTENT_TYPE]);
1287 void INetMIMEMessage::SetContentTransferEncoding (
1288 const String& rEncoding)
1290 SetHeaderField_Impl (
1291 INetMIME::HEADER_FIELD_TEXT,
1292 MIMEHDR(INETMSG_MIME_CONTENT_TRANSFER_ENCODING), rEncoding,
1293 m_nIndex[INETMSG_MIME_CONTENT_TRANSFER_ENCODING]);
1297 * GetDefaultContentType.
1299 void INetMIMEMessage::GetDefaultContentType (String& rContentType)
1301 String aDefaultCT (
1302 "text/plain; charset=us-ascii", RTL_TEXTENCODING_ASCII_US);
1303 if (pParent == NULL)
1305 rContentType = aDefaultCT;
1307 else
1309 String aParentCT (pParent->GetContentType());
1310 if (aParentCT.Len() == 0)
1311 pParent->GetDefaultContentType (aParentCT);
1313 if (aParentCT.CompareIgnoreCaseToAscii ("message/", 8) == 0)
1315 rContentType = aDefaultCT;
1317 else if (aParentCT.CompareIgnoreCaseToAscii ("multipart/", 10) == 0)
1319 if (aParentCT.CompareIgnoreCaseToAscii ("multipart/digest") == 0)
1320 rContentType.AssignAscii ("message/rfc822");
1321 else
1322 rContentType = aDefaultCT;
1324 else
1326 rContentType = aDefaultCT;
1332 * EnableAttachChild.
1334 BOOL INetMIMEMessage::EnableAttachChild (INetMessageContainerType eType)
1336 // Check context.
1337 if (IsContainer())
1338 return FALSE;
1340 // Setup Content-Type header field.
1341 ByteString aContentType;
1342 switch (eType)
1344 case INETMSG_MESSAGE_RFC822:
1345 aContentType = "message/rfc822";
1346 break;
1348 case INETMSG_MULTIPART_ALTERNATIVE:
1349 aContentType = "multipart/alternative";
1350 break;
1352 case INETMSG_MULTIPART_DIGEST:
1353 aContentType = "multipart/digest";
1354 break;
1356 case INETMSG_MULTIPART_PARALLEL:
1357 aContentType = "multipart/parallel";
1358 break;
1360 case INETMSG_MULTIPART_RELATED:
1361 aContentType = "multipart/related";
1362 break;
1364 case INETMSG_MULTIPART_FORM_DATA:
1365 aContentType = "multipart/form-data";
1366 break;
1368 default:
1369 aContentType = "multipart/mixed";
1370 break;
1373 // Setup boundary for multipart types.
1374 if (aContentType.CompareIgnoreCaseToAscii ("multipart/", 10) == 0)
1376 // Generate a unique boundary from current time.
1377 sal_Char sTail[16 + 1];
1378 Time aCurTime;
1379 sal_uInt64 nThis = reinterpret_cast< sal_uIntPtr >( this ); // we can be on a 64bit architecture
1380 nThis = ( ( nThis >> 32 ) ^ nThis ) & SAL_MAX_UINT32;
1381 sprintf (sTail, "%08X%08X",
1382 static_cast< unsigned int >(aCurTime.GetTime()),
1383 static_cast< unsigned int >(nThis));
1384 m_aBoundary = "------------_4D48";
1385 m_aBoundary += sTail;
1387 // Append boundary as ContentType parameter.
1388 aContentType += "; boundary=";
1389 aContentType += m_aBoundary;
1392 // Set header fields.
1393 SetMIMEVersion (String (CONSTASCII_STRINGPARAM("1.0")));
1394 SetContentType (String (aContentType, RTL_TEXTENCODING_ASCII_US));
1395 SetContentTransferEncoding (String (CONSTASCII_STRINGPARAM("7bit")));
1397 // Done.
1398 return TRUE;
1402 * AttachChild.
1404 BOOL INetMIMEMessage::AttachChild (
1405 INetMIMEMessage& rChildMsg, BOOL bOwner)
1407 if (IsContainer() /*&& rChildMsg.GetContentType().Len() */)
1409 if (bOwner) rChildMsg.pParent = this;
1410 aChildren.Insert (&rChildMsg, LIST_APPEND);
1411 nNumChildren = aChildren.Count();
1413 return TRUE;
1415 return FALSE;
1419 * DetachChild.
1421 BOOL INetMIMEMessage::DetachChild (
1422 ULONG nIndex, INetMIMEMessage& rChildMsg) const
1424 if (IsContainer())
1426 // Check document stream.
1427 if (GetDocumentLB() == NULL) return FALSE;
1428 SvStream *pDocStrm = new SvStream (GetDocumentLB());
1430 // Initialize message buffer.
1431 char pMsgBuffer[1024];
1432 char *pMsgRead, *pMsgWrite;
1433 pMsgRead = pMsgWrite = pMsgBuffer;
1435 // Initialize message parser stream.
1436 INetMIMEMessageStream *pMsgStrm = NULL;
1438 // Check for "multipart/uvw" or "message/xyz".
1439 if (IsMultipart())
1441 // Multipart message body. Initialize multipart delimiters.
1442 ByteString aDelim ("--");
1443 aDelim += GetMultipartBoundary();
1444 ByteString aClose = aDelim;
1445 aClose += "--";
1447 // Initialize line buffer.
1448 SvMemoryStream aLineBuf;
1450 // Initialize control variables.
1451 INetMessageStreamState eState = INETMSG_EOL_SCR;
1452 int nCurIndex = -1;
1454 // Go!
1455 while (nCurIndex < (int)(nIndex + 1))
1457 if ((pMsgRead - pMsgWrite) > 0)
1459 // Bytes still in buffer.
1460 if (eState == INETMSG_EOL_FCR)
1462 // Check for 2nd line break character.
1463 if ((*pMsgWrite == '\r') || (*pMsgWrite == '\n'))
1464 aLineBuf << *pMsgWrite++;
1466 // Check current index.
1467 if (nCurIndex == (int)nIndex)
1469 // Found requested part.
1470 if (pMsgStrm == NULL)
1472 // Create message parser stream.
1473 pMsgStrm = new INetMIMEMessageStream;
1474 pMsgStrm->SetTargetMessage (&rChildMsg);
1477 // Put message down-stream.
1478 int status = pMsgStrm->Write (
1479 (const sal_Char *) aLineBuf.GetData(), aLineBuf.Tell());
1480 if (status != INETSTREAM_STATUS_OK)
1482 // Cleanup.
1483 delete pDocStrm;
1484 delete pMsgStrm;
1486 // Finish.
1487 return (!(status == INETSTREAM_STATUS_OK));
1491 // Reset to <Begin-of-Line>.
1492 aLineBuf.Seek (STREAM_SEEK_TO_BEGIN);
1493 eState = INETMSG_EOL_SCR;
1495 else if ((*pMsgWrite == '\r') || (*pMsgWrite == '\n'))
1498 * Found any line break character.
1499 * Compare buffered line with part/close delimiter.
1500 * Increment current part index upon match.
1502 USHORT nLen = (USHORT)(aLineBuf.Tell() & 0xffff);
1503 if (nLen == aDelim.Len())
1505 if (aDelim.CompareTo ((const sal_Char *) aLineBuf.GetData(), nLen)
1506 == COMPARE_EQUAL) nCurIndex++;
1508 else if (nLen == aClose.Len())
1510 if (aClose.CompareTo ((const sal_Char *) aLineBuf.GetData(), nLen)
1511 == COMPARE_EQUAL) nCurIndex++;
1513 aLineBuf << *pMsgWrite++;
1514 eState = INETMSG_EOL_FCR;
1516 else
1518 // Insert into line buffer.
1519 aLineBuf << *pMsgWrite;
1522 else
1524 // Buffer empty. Reset to <Begin-of-Buffer>.
1525 pMsgRead = pMsgWrite = pMsgBuffer;
1527 // Read document stream.
1528 ULONG nRead = pDocStrm->Read (
1529 pMsgBuffer, sizeof (pMsgBuffer));
1530 if (nRead > 0)
1532 // Set read pointer.
1533 pMsgRead += nRead;
1535 else
1537 // Premature end.
1538 if (pMsgStrm)
1540 // Assume end of requested part.
1541 nCurIndex++;
1543 else
1545 // Requested part not found.
1546 delete pDocStrm;
1547 return FALSE;
1551 } // while (nCurIndex < (nIndex + 1))
1553 else
1555 // Encapsulated message body. Create message parser stream.
1556 pMsgStrm = new INetMIMEMessageStream;
1557 pMsgStrm->SetTargetMessage (&rChildMsg);
1559 // Initialize control variables.
1560 INetMessageStreamState eState = INETMSG_EOL_BEGIN;
1562 // Go.
1563 while (eState == INETMSG_EOL_BEGIN)
1565 if ((pMsgRead - pMsgWrite) > 0)
1567 // Bytes still in buffer. Put message down-stream.
1568 int status = pMsgStrm->Write (
1569 pMsgBuffer, (pMsgRead - pMsgWrite));
1570 if (status != INETSTREAM_STATUS_OK)
1572 // Cleanup.
1573 delete pDocStrm;
1574 delete pMsgStrm;
1576 // Finish.
1577 return (!(status == INETSTREAM_STATUS_ERROR));
1579 pMsgWrite = pMsgBuffer + (pMsgRead - pMsgWrite);
1581 else
1583 // Buffer empty. Reset to <Begin-of-Buffer>.
1584 pMsgRead = pMsgWrite = pMsgBuffer;
1586 // Read document stream.
1587 ULONG nRead = pDocStrm->Read (
1588 pMsgBuffer, sizeof (pMsgBuffer));
1589 if (nRead > 0)
1591 // Set read pointer.
1592 pMsgRead += nRead;
1594 else
1596 // Mark we're done.
1597 eState = INETMSG_EOL_DONE;
1600 } // while (eState == INETMSG_EOL_BEGIN)
1603 // Done.
1604 if (pDocStrm) delete pDocStrm;
1605 if (pMsgStrm) delete pMsgStrm;
1606 return TRUE;
1608 return FALSE;
1612 * operator<<
1614 SvStream& INetMIMEMessage::operator<< (SvStream& rStrm) const
1616 INetRFC822Message::operator<< (rStrm);
1618 for (USHORT i = 0; i < INETMSG_MIME_NUMHDR; i++)
1619 rStrm << static_cast<sal_uInt32>(m_nIndex[i]);
1621 #ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
1622 rStrm << m_aBoundary;
1623 #else
1624 rStrm.WriteByteString (m_aBoundary);
1625 #endif
1626 rStrm << static_cast<sal_uInt32>(nNumChildren);
1628 return rStrm;
1632 * operator>>
1634 SvStream& INetMIMEMessage::operator>> (SvStream& rStrm)
1636 INetRFC822Message::operator>> (rStrm);
1638 sal_uInt32 nTemp;
1639 for (USHORT i = 0; i < INETMSG_MIME_NUMHDR; i++)
1641 rStrm >> nTemp;
1642 m_nIndex[i] = nTemp;
1645 #ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
1646 rStrm >> m_aBoundary;
1647 #else
1648 rStrm.ReadByteString (m_aBoundary);
1649 #endif
1650 rStrm >> nTemp;
1651 nNumChildren = nTemp;
1653 return rStrm;