/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_tools.hxx"
#include <sal/types.h>
#include <tools/datetime.hxx>
#ifndef _TOOLS_INETMIME_HXX
#include <tools/inetmime.hxx>
#endif
#include <tools/inetmsg.hxx>
#include <tools/inetstrm.hxx>
#include <rtl/instance.hxx>

#include <stdio.h>

//=======================================================================

inline sal_Bool ascii_isDigit( sal_Unicode ch )
{
    return ((ch >= 0x0030) && (ch <= 0x0039));
}

inline sal_Bool ascii_isLetter( sal_Unicode ch )
{
    return (( (ch >= 0x0041) && (ch <= 0x005A)) || ((ch >= 0x0061) && (ch <= 0x007A)));
}

inline sal_Unicode ascii_toLowerCase( sal_Unicode ch )
{
    if ( (ch >= 0x0041) && (ch <= 0x005A) )
        return ch + 0x20;
    else
        return ch;
}

/*=======================================================================
 *
 * INetMessage Implementation.
 *
 *=====================================================================*/
#define CONSTASCII_STRINGPARAM(a) (a), RTL_TEXTENCODING_ASCII_US
#define HEADERFIELD INetMessageHeader

/*
 * ~INetMessage.
 */
INetMessage::~INetMessage (void)
{
    ListCleanup_Impl();
}

/*
 * ListCleanup_Impl.
 */
void INetMessage::ListCleanup_Impl (void)
{
    // Cleanup.
    sal_uIntPtr i, n = m_aHeaderList.Count();
    for (i = 0; i < n; i++)
        delete ((HEADERFIELD*)(m_aHeaderList.GetObject(i)));
    m_aHeaderList.Clear();
}

/*
 * ListCopy.
 */
void INetMessage::ListCopy (const INetMessage &rMsg)
{
    if (!(this == &rMsg))
    {
        // Cleanup.
        ListCleanup_Impl();

        // Copy.
        sal_uIntPtr i, n = rMsg.GetHeaderCount();
        for (i = 0; i < n; i++)
        {
            HEADERFIELD *p = (HEADERFIELD*)(rMsg.m_aHeaderList.GetObject(i));
            m_aHeaderList.Insert (new HEADERFIELD(*p), LIST_APPEND);
        }
    }
}

/*
 * SetHeaderField_Impl.
 */
void INetMessage::SetHeaderField_Impl (
    INetMIME::HeaderFieldType  eType,
    const ByteString          &rName,
    const UniString           &rValue,
    sal_uIntPtr                     &rnIndex)
{
    INetMIMEStringOutputSink aSink (0, STRING_MAXLEN);
    INetMIME::writeHeaderFieldBody (
        aSink, eType, rValue, gsl_getSystemTextEncoding(), false);
    SetHeaderField_Impl (
        INetMessageHeader (rName, aSink.takeBuffer()), rnIndex);
}

/*
 * SetHeaderField.
 */
sal_uIntPtr INetMessage::SetHeaderField (
    const UniString& rName, const UniString& rValue, sal_uIntPtr nIndex)
{
    sal_uIntPtr nResult = nIndex;
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        ByteString (rName, RTL_TEXTENCODING_ASCII_US), rValue,
        nResult);
    return nResult;
}

/*
 * SetHeaderField.
 */
sal_uIntPtr INetMessage::SetHeaderField (
    const INetMessageHeader &rHeader, sal_uIntPtr nIndex)
{
    sal_uIntPtr nResult = nIndex;
    SetHeaderField_Impl (rHeader, nResult);
    return nResult;
}


/*
 * operator<<
 */
SvStream& INetMessage::operator<< (SvStream& rStrm) const
{
    rStrm << static_cast<sal_uInt32>(m_nDocSize);
    rStrm.WriteByteString (m_aDocName, RTL_TEXTENCODING_UTF8);

    sal_uIntPtr i, n = m_aHeaderList.Count();
    rStrm << static_cast<sal_uInt32>(n);

    for (i = 0; i < n; i++)
        rStrm << *((HEADERFIELD *)(m_aHeaderList.GetObject(i)));

    return rStrm;
}

/*
 * operator>>
 */
SvStream& INetMessage::operator>> (SvStream& rStrm)
{
    // Cleanup.
    m_nDocSize = 0;
    m_xDocLB.Clear();
    ListCleanup_Impl();

    sal_uInt32 nTemp;

    // Copy.
    rStrm >> nTemp;
    m_nDocSize = nTemp;
    rStrm.ReadByteString (m_aDocName, RTL_TEXTENCODING_UTF8);

    sal_uIntPtr i, n = 0;
    rStrm >> nTemp;
    n = nTemp;

    for (i = 0; i < n; i++)
    {
        HEADERFIELD *p = new HEADERFIELD();
        rStrm >> *p;
        m_aHeaderList.Insert (p, LIST_APPEND);
    }

    // Done.
    return rStrm;
}

/*=======================================================================
 *
 * INetMessageHeaderIterator Implementation.
 *
 *=====================================================================*/
INetMessageHeaderIterator::INetMessageHeaderIterator (
    const INetMessage& rMsg, const UniString& rHdrName)
{
    sal_uIntPtr i, n = rMsg.GetHeaderCount();
    for (i = 0; i < n; i++)
    {
        if (rHdrName.CompareIgnoreCaseToAscii (rMsg.GetHeaderName(i)) == 0)
        {
            UniString *pValue = new UniString (rMsg.GetHeaderValue(i));
            aValueList.Insert (pValue, LIST_APPEND);
        }
    }
    nValueCount = aValueList.Count();
}

INetMessageHeaderIterator::~INetMessageHeaderIterator (void)
{
    sal_uIntPtr i, n = aValueList.Count();
    for (i = 0; i < n; i++)
        delete ((UniString*)(aValueList.GetObject(i)));
    aValueList.Clear();
}

/*=======================================================================
 *
 * INetRFC822Message Implementation.
 *
 *=====================================================================*/
/*
 * ImplINetRFC822MessageHeaderData.
 */
namespace
{
    struct ImplINetRFC822MessageHeaderDataImpl
    {
        const ByteString* operator()()
        {
            static const ByteString _ImplINetRFC822MessageHeaderData[] =
            {
                ByteString ("BCC"),
                ByteString ("CC"),
                ByteString ("Comments"),
                ByteString ("Date"),
                ByteString ("From"),
                ByteString ("In-Reply-To"),
                ByteString ("Keywords"),
                ByteString ("Message-ID"),
                ByteString ("References"),
                ByteString ("Reply-To"),
                ByteString ("Return-Path"),
                ByteString ("Subject"),
                ByteString ("Sender"),
                ByteString ("To"),
                ByteString ("X-Mailer"),
                ByteString ("Return-Receipt-To")
            };
            return &_ImplINetRFC822MessageHeaderData[0];
        }
    };

    struct ImplINetRFC822MessageHeaderData
    	: public rtl::StaticAggregate< const ByteString, ImplINetRFC822MessageHeaderDataImpl > {};
}

#define HDR(n) ImplINetRFC822MessageHeaderData::get()[(n)]

/*
 * _ImplINetRFC822MessageHeaderState.
 */
enum _ImplINetRFC822MessageHeaderState
{
    INETMSG_RFC822_BEGIN,
    INETMSG_RFC822_CHECK,
    INETMSG_RFC822_OK,
    INETMSG_RFC822_JUNK,

    INETMSG_RFC822_TOKEN_RE,
    INETMSG_RFC822_TOKEN_RETURNMINUS,
    INETMSG_RFC822_TOKEN_XMINUS,
    INETMSG_RFC822_LETTER_C,
    INETMSG_RFC822_LETTER_S
};

/*
 * INetRFC822Message.
 */
INetRFC822Message::INetRFC822Message (void)
    : INetMessage()
{
    for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
        m_nIndex[i] = LIST_ENTRY_NOTFOUND;
}

INetRFC822Message::INetRFC822Message (const INetRFC822Message& rMsg)
    : INetMessage (rMsg)
{
    for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
        m_nIndex[i] = rMsg.m_nIndex[i];
}

/*
 * operator=
 */
INetRFC822Message& INetRFC822Message::operator= (const INetRFC822Message& rMsg)
{
    if (this != &rMsg)
    {
        INetMessage::operator= (rMsg);

        for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
            m_nIndex[i] = rMsg.m_nIndex[i];
    }
    return *this;
}

/*
 * ~INetRFC822Message.
 */
INetRFC822Message::~INetRFC822Message (void)
{
}

/*
 * <Generate|Parse>DateField and local helper functions.
 *
 * GenerateDateField.
 * Generates a String from Date and Time objects in format:
 *   Wkd, 00 Mon 0000 00:00:00 [GMT]            (rfc822, rfc1123)
 *
 * ParseDateField.
 * Parses a String in (implied) GMT format into class Date and Time objects.
 * Four formats are accepted:
 *
 *  [Wkd,] 1*2DIGIT Mon 2*4DIGIT 00:00:00 [GMT]  (rfc1123)
 *  [Wkd,] 00 Mon 0000 00:00:00 [GMT])           (rfc822, rfc1123)
 *   Weekday, 00-Mon-00 00:00:00 [GMT]           (rfc850, rfc1036)
 *   Wkd Mon 00 00:00:00 0000 [GMT]              (ctime)
 *   1*DIGIT                                     (delta seconds)
 *
 */

// Months and Weekdays.
static const sal_Char *months[12] =
{
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

static const sal_Char *wkdays[7] =
{
    "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
};

/*
 * GenerateDateField.
 */
sal_Bool INetRFC822Message::GenerateDateField (
    const DateTime& rDateTime, UniString& rDateFieldW)
{
    // Check arguments.
    if (!rDateTime.IsValid()       ||
        (rDateTime.GetSec()  > 59) ||
        (rDateTime.GetMin()  > 59) ||
        (rDateTime.GetHour() > 23)    ) return sal_False;

    // Prepare output string.
    ByteString rDateField;

    // Insert Date.
    rDateField += wkdays[(sal_uInt16)(rDateTime.GetDayOfWeek())];
    rDateField += ", ";

    sal_uInt16 nNum = rDateTime.GetDay();
    if (nNum < 10) rDateField += '0';
    rDateField += ByteString::CreateFromInt32(nNum);
    rDateField += ' ';

    rDateField += months[(sal_uInt16)(rDateTime.GetMonth() - 1)];
    rDateField += ' ';

    rDateField += ByteString::CreateFromInt32(rDateTime.GetYear());
    rDateField += ' ';

    // Insert Time.
    nNum = rDateTime.GetHour();
    if (nNum < 10) rDateField += '0';
    rDateField += ByteString::CreateFromInt32(nNum);
    rDateField += ':';

    nNum = rDateTime.GetMin();
    if (nNum < 10) rDateField += '0';
    rDateField += ByteString::CreateFromInt32(nNum);
    rDateField += ':';

    nNum = rDateTime.GetSec();
    if (nNum < 10) rDateField += '0';
    rDateField += ByteString::CreateFromInt32(nNum);
    rDateField += " GMT";

    // Done.
    rDateFieldW = UniString (rDateField, RTL_TEXTENCODING_ASCII_US);
    return sal_True;
}

/*
 * ParseDateField and local helper functions.
 */
static sal_uInt16 ParseNumber (const ByteString& rStr, sal_uInt16& nIndex)
{
    sal_uInt16 n = nIndex;
    while ((n < rStr.Len()) && ascii_isDigit(rStr.GetChar(n))) n++;

    ByteString aNum (rStr.Copy (nIndex, (n - nIndex)));
    nIndex = n;

    return (sal_uInt16)(aNum.ToInt32());
}

static sal_uInt16 ParseMonth (const ByteString& rStr, sal_uInt16& nIndex)
{
    sal_uInt16 n = nIndex;
    while ((n < rStr.Len()) && ascii_isLetter(rStr.GetChar(n))) n++;

    ByteString aMonth (rStr.Copy (nIndex, 3));
    nIndex = n;

    sal_uInt16 i;
    for (i = 0; i < 12; i++)
        if (aMonth.CompareIgnoreCaseToAscii (months[i]) == 0) break;
    return (i + 1);
}

sal_Bool INetRFC822Message::ParseDateField (
    const UniString& rDateFieldW, DateTime& rDateTime)
{
    ByteString rDateField (rDateFieldW, RTL_TEXTENCODING_ASCII_US);
    if (rDateField.Len() == 0) return sal_False;

    if (rDateField.Search (':') != STRING_NOTFOUND)
    {
        // Some DateTime format.
        sal_uInt16 nIndex = 0;

        // Skip over <Wkd> or <Weekday>, leading and trailing space.
        while ((nIndex < rDateField.Len()) &&
               (rDateField.GetChar(nIndex) == ' '))
            nIndex++;

        while (
            (nIndex < rDateField.Len()) &&
            (ascii_isLetter (rDateField.GetChar(nIndex)) ||
             (rDateField.GetChar(nIndex) == ',')     ))
            nIndex++;

        while ((nIndex < rDateField.Len()) &&
               (rDateField.GetChar(nIndex) == ' '))
            nIndex++;

        if (ascii_isLetter (rDateField.GetChar(nIndex)))
        {
            // Format: ctime().
            if ((rDateField.Len() - nIndex) < 20) return sal_False;

            rDateTime.SetMonth  (ParseMonth  (rDateField, nIndex)); nIndex++;
            rDateTime.SetDay    (ParseNumber (rDateField, nIndex)); nIndex++;

            rDateTime.SetHour   (ParseNumber (rDateField, nIndex)); nIndex++;
            rDateTime.SetMin    (ParseNumber (rDateField, nIndex)); nIndex++;
            rDateTime.SetSec    (ParseNumber (rDateField, nIndex)); nIndex++;
            rDateTime.Set100Sec (0);

            sal_uInt16 nYear = ParseNumber (rDateField, nIndex);
            if (nYear < 100) nYear += 1900;
            rDateTime.SetYear   (nYear);
        }
        else
        {
            // Format: RFC1036 or RFC1123.
            if ((rDateField.Len() - nIndex) < 17) return sal_False;

            rDateTime.SetDay    (ParseNumber (rDateField, nIndex)); nIndex++;
            rDateTime.SetMonth  (ParseMonth  (rDateField, nIndex)); nIndex++;

            sal_uInt16 nYear  = ParseNumber (rDateField, nIndex);  nIndex++;
            if (nYear < 100) nYear += 1900;
            rDateTime.SetYear   (nYear);

            rDateTime.SetHour   (ParseNumber (rDateField, nIndex)); nIndex++;
            rDateTime.SetMin    (ParseNumber (rDateField, nIndex)); nIndex++;
            rDateTime.SetSec    (ParseNumber (rDateField, nIndex)); nIndex++;
            rDateTime.Set100Sec (0);

            if ((rDateField.GetChar(nIndex) == '+') ||
                (rDateField.GetChar(nIndex) == '-')    )
            {
                // Offset from GMT: "(+|-)HHMM".
                sal_Bool   bEast   = (rDateField.GetChar(nIndex++) == '+');
                sal_uInt16 nOffset = ParseNumber (rDateField, nIndex);
                if (nOffset > 0)
                {
                    Time aDiff;
                    aDiff.SetHour   (nOffset / 100);
                    aDiff.SetMin    (nOffset % 100);
                    aDiff.SetSec    (0);
                    aDiff.Set100Sec (0);

                    if (bEast)
                        rDateTime -= aDiff;
                    else
                        rDateTime += aDiff;
                }
            }
        }
    }
    else if (rDateField.IsNumericAscii())
    {
        // Format: delta seconds.
        Time aDelta (0);
        aDelta.SetTime (rDateField.ToInt32() * 100);

        DateTime aNow;
        aNow += aDelta;
        aNow.ConvertToUTC();

        rDateTime.SetDate (aNow.GetDate());
        rDateTime.SetTime (aNow.GetTime());
    }
    else
    {
        // Junk.
        return sal_False;
    }

    return (rDateTime.IsValid() &&
            !((rDateTime.GetSec()  > 59) ||
              (rDateTime.GetMin()  > 59) ||
              (rDateTime.GetHour() > 23)    ));
}

/*
 * SetHeaderField.
 * (Header Field Parser).
 */
sal_uIntPtr INetRFC822Message::SetHeaderField (
    const INetMessageHeader &rHeader, sal_uIntPtr nNewIndex)
{
    ByteString aName (rHeader.GetName());
    const sal_Char *pData = aName.GetBuffer();
    const sal_Char *pStop = pData + aName.Len() + 1;
    const sal_Char *check = "";

    sal_uIntPtr       nIdx     = LIST_APPEND;
    int         eState   = INETMSG_RFC822_BEGIN;
    int         eOkState = INETMSG_RFC822_OK;

    while (pData < pStop)
    {
        switch (eState)
        {
            case INETMSG_RFC822_BEGIN:
                eState = INETMSG_RFC822_CHECK;
                eOkState = INETMSG_RFC822_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'b':
                        check = "cc";
                        nIdx = INETMSG_RFC822_BCC;
                        break;

                    case 'c':
                        eState = INETMSG_RFC822_LETTER_C;
                        break;

                    case 'd':
                        check = "ate";
                        nIdx = INETMSG_RFC822_DATE;
                        break;

                    case 'f':
                        check = "rom";
                        nIdx = INETMSG_RFC822_FROM;
                        break;

                    case 'i':
                        check = "n-reply-to";
                        nIdx = INETMSG_RFC822_IN_REPLY_TO;
                        break;

                    case 'k':
                        check = "eywords";
                        nIdx = INETMSG_RFC822_KEYWORDS;
                        break;

                    case 'm':
                        check = "essage-id";
                        nIdx = INETMSG_RFC822_MESSAGE_ID;
                        break;

                    case 'r':
                        check = "e";
                        eOkState = INETMSG_RFC822_TOKEN_RE;
                        break;

                    case 's':
                        eState = INETMSG_RFC822_LETTER_S;
                        break;

                    case 't':
                        check = "o";
                        nIdx = INETMSG_RFC822_TO;
                        break;

                    case 'x':
                        check = "-";
                        eOkState = INETMSG_RFC822_TOKEN_XMINUS;
                        break;

                    default:
                        eState = INETMSG_RFC822_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_RFC822_TOKEN_RE:
                eState = INETMSG_RFC822_CHECK;
                eOkState = INETMSG_RFC822_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'f':
                        check = "erences";
                        nIdx = INETMSG_RFC822_REFERENCES;
                        break;

                    case 'p':
                        check = "ly-to";
                        nIdx = INETMSG_RFC822_REPLY_TO;
                        break;

                    case 't':
                        check = "urn-";
                        eOkState = INETMSG_RFC822_TOKEN_RETURNMINUS;
                        break;

                    default:
                        eState = INETMSG_RFC822_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_RFC822_TOKEN_RETURNMINUS:
                eState = INETMSG_RFC822_CHECK;
                eOkState = INETMSG_RFC822_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'p':
                        check = "ath";
                        nIdx = INETMSG_RFC822_RETURN_PATH;
                        break;

                    case 'r':
                        check = "eceipt-to";
                        nIdx = INETMSG_RFC822_RETURN_RECEIPT_TO;
                        break;

                    default:
                        eState = INETMSG_RFC822_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_RFC822_TOKEN_XMINUS:
                eState = INETMSG_RFC822_CHECK;
                eOkState = INETMSG_RFC822_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'm':
                        check = "ailer";
                        nIdx = INETMSG_RFC822_X_MAILER;
                        break;

#if 0  /* NYI */
                    case 'p':
                        check = "riority";
                        eOkState = INETMSG_RFC822_X_PRIORITY;
                        break;
#endif /* NYI */

                    default:
                        eState = INETMSG_RFC822_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_RFC822_LETTER_C:
                eState = INETMSG_RFC822_CHECK;
                eOkState = INETMSG_RFC822_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'c':
                        check = "";
                        nIdx = INETMSG_RFC822_CC;
                        break;

                    case 'o':
                        check = "mments";
                        nIdx = INETMSG_RFC822_COMMENTS;
                        break;

                    default:
                        eState = INETMSG_RFC822_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_RFC822_LETTER_S:
                eState = INETMSG_RFC822_CHECK;
                eOkState = INETMSG_RFC822_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'e':
                        check = "nder";
                        nIdx = INETMSG_RFC822_SENDER;
                        break;

                    case 'u':
                        check = "bject";
                        nIdx = INETMSG_RFC822_SUBJECT;
                        break;

                    default:
                        eState = INETMSG_RFC822_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_RFC822_CHECK:
                if (*check)
                {
                    while (*pData && *check &&
                           (ascii_toLowerCase (*pData) == *check))
                    {
                        pData++;
                        check++;
                    }
                }
                else
                {
                    check = pData;
                }
                eState = (*check == '\0') ? eOkState : INETMSG_RFC822_JUNK;
                break;

            case INETMSG_RFC822_OK:
                pData = pStop;
                SetHeaderField_Impl (
                    HEADERFIELD (HDR(nIdx), rHeader.GetValue()),
                    m_nIndex[nIdx]);
                nNewIndex = m_nIndex[nIdx];
                break;

            default: // INETMSG_RFC822_JUNK
                pData = pStop;
                nNewIndex = INetMessage::SetHeaderField (rHeader, nNewIndex);
                break;
        }
    }
    return nNewIndex;
}

/*
 * Specific Set-Methods.
 */
void INetRFC822Message::SetBCC (const UniString& rBCC)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_ADDRESS,
        HDR(INETMSG_RFC822_BCC), rBCC,
        m_nIndex[INETMSG_RFC822_BCC]);
}

void INetRFC822Message::SetCC (const UniString& rCC)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_ADDRESS,
        HDR(INETMSG_RFC822_CC), rCC,
        m_nIndex[INETMSG_RFC822_CC]);
}

void INetRFC822Message::SetComments (const UniString& rComments)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        HDR(INETMSG_RFC822_COMMENTS), rComments,
        m_nIndex[INETMSG_RFC822_COMMENTS]);
}

void INetRFC822Message::SetDate (const UniString& rDate)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_STRUCTURED,
        HDR(INETMSG_RFC822_DATE), rDate,
        m_nIndex[INETMSG_RFC822_DATE]);
}

void INetRFC822Message::SetFrom (const UniString& rFrom)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_ADDRESS,
        HDR(INETMSG_RFC822_FROM), rFrom,
        m_nIndex[INETMSG_RFC822_FROM]);
}

void INetRFC822Message::SetInReplyTo (const UniString& rInReplyTo)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_ADDRESS, // ??? MESSAGE_ID ???
        HDR(INETMSG_RFC822_IN_REPLY_TO), rInReplyTo,
        m_nIndex[INETMSG_RFC822_IN_REPLY_TO]);
}

void INetRFC822Message::SetKeywords (const UniString& rKeywords)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_PHRASE,
        HDR(INETMSG_RFC822_KEYWORDS), rKeywords,
        m_nIndex[INETMSG_RFC822_KEYWORDS]);
}

void INetRFC822Message::SetMessageID (const UniString& rMessageID)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_MESSAGE_ID,
        HDR(INETMSG_RFC822_MESSAGE_ID), rMessageID,
        m_nIndex[INETMSG_RFC822_MESSAGE_ID]);
}

void INetRFC822Message::SetReferences (const UniString& rReferences)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_MESSAGE_ID,
        HDR(INETMSG_RFC822_REFERENCES), rReferences,
        m_nIndex[INETMSG_RFC822_REFERENCES]);
}

void INetRFC822Message::SetReplyTo (const UniString& rReplyTo)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_ADDRESS,
        HDR(INETMSG_RFC822_REPLY_TO), rReplyTo,
        m_nIndex[INETMSG_RFC822_REPLY_TO]);
}

void INetRFC822Message::SetReturnPath (const UniString& rReturnPath)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_ADDRESS,
        HDR(INETMSG_RFC822_RETURN_PATH), rReturnPath,
        m_nIndex[INETMSG_RFC822_RETURN_PATH]);
}

void INetRFC822Message::SetReturnReceiptTo (const UniString& rValue)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_ADDRESS,
        HDR(INETMSG_RFC822_RETURN_RECEIPT_TO), rValue,
        m_nIndex[INETMSG_RFC822_RETURN_RECEIPT_TO]);
}

void INetRFC822Message::SetSender (const UniString& rSender)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_ADDRESS,
        HDR(INETMSG_RFC822_SENDER), rSender,
        m_nIndex[INETMSG_RFC822_SENDER]);
}

void INetRFC822Message::SetSubject (const UniString& rSubject)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        HDR(INETMSG_RFC822_SUBJECT), rSubject,
        m_nIndex[INETMSG_RFC822_SUBJECT]);
}

void INetRFC822Message::SetTo (const UniString& rTo)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_ADDRESS,
        HDR(INETMSG_RFC822_TO), rTo,
        m_nIndex[INETMSG_RFC822_TO]);
}

void INetRFC822Message::SetXMailer (const UniString& rXMailer)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        HDR(INETMSG_RFC822_X_MAILER), rXMailer,
        m_nIndex[INETMSG_RFC822_X_MAILER]);
}

/*
 * operator<<
 */
SvStream& INetRFC822Message::operator<< (SvStream& rStrm) const
{
    INetMessage::operator<< (rStrm);

    for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
        rStrm << static_cast<sal_uInt32>(m_nIndex[i]);

    return rStrm;
}

/*
 * operator>>
 */
SvStream& INetRFC822Message::operator>> (SvStream& rStrm)
{
    INetMessage::operator>> (rStrm);

    sal_uInt32 nTemp;
    for (sal_uInt16 i = 0; i < INETMSG_RFC822_NUMHDR; i++)
    {
        rStrm >> nTemp;
        m_nIndex[i] = nTemp;
    }

    return rStrm;
}

/*=======================================================================
 *
 * INetMIMEMessage Implementation.
 *
 *=====================================================================*/
/*
 * _ImplINetMIMEMessageHeaderData.
 */
namespace
{
    struct ImplINetMIMEMessageHeaderDataImpl
    {
        const ByteString* operator()()
        {
            static const ByteString _ImplINetMIMEMessageHeaderData[] =
            {
                ByteString ("MIME-Version"),
                ByteString ("Content-Description"),
                ByteString ("Content-Disposition"),
                ByteString ("Content-ID"),
                ByteString ("Content-Type"),
                ByteString ("Content-Transfer-Encoding")
            };
            return &_ImplINetMIMEMessageHeaderData[0];
        }
    };

    struct ImplINetMIMEMessageHeaderData
        : public rtl::StaticAggregate< const ByteString, ImplINetMIMEMessageHeaderDataImpl > {};
}

#define MIMEHDR(n) ImplINetMIMEMessageHeaderData::get()[(n)]

/*
 * _ImplINetMIMEMessageHeaderState.
 */
enum _ImplINetMIMEMessageHeaderState
{
    INETMSG_MIME_BEGIN,
    INETMSG_MIME_CHECK,
    INETMSG_MIME_OK,
    INETMSG_MIME_JUNK,

    INETMSG_MIME_TOKEN_CONTENT,
    INETMSG_MIME_TOKEN_CONTENT_D,
    INETMSG_MIME_TOKEN_CONTENT_T
};

/*
 * INetMIMEMessage.
 */
INetMIMEMessage::INetMIMEMessage (void)
    : INetRFC822Message (),
      pParent       (NULL),
      nNumChildren  (0),
      bHeaderParsed (sal_False)
{
    for (sal_uInt16 i = 0; i < INETMSG_MIME_NUMHDR; i++)
        m_nIndex[i] = LIST_ENTRY_NOTFOUND;
}

INetMIMEMessage::INetMIMEMessage (const INetMIMEMessage& rMsg)
    : INetRFC822Message (rMsg)
{
    // Copy.
    CopyImp (rMsg);
}

/*
 * operator=
 */
INetMIMEMessage& INetMIMEMessage::operator= (
    const INetMIMEMessage& rMsg)
{
    if (this != &rMsg)
    {
        // Assign base.
        INetRFC822Message::operator= (rMsg);

        // Cleanup.
        CleanupImp();

        // Copy.
        CopyImp (rMsg);
    }
    return *this;
}

/*
 * ~INetMIMEMessage.
 */
INetMIMEMessage::~INetMIMEMessage (void)
{
    // Cleanup.
    CleanupImp();
}

/*
 * CleanupImp.
 */
void INetMIMEMessage::CleanupImp (void)
{
    INetMIMEMessage *pChild = NULL;
    while ((pChild = (INetMIMEMessage *)(aChildren.Remove())) != NULL)
        if (pChild->pParent == this) delete pChild;
}

/*
 * CopyImp.
 */
void INetMIMEMessage::CopyImp (const INetMIMEMessage& rMsg)
{
    bHeaderParsed = rMsg.bHeaderParsed;

    sal_uInt16 i;
    for (i = 0; i < INETMSG_MIME_NUMHDR; i++)
        m_nIndex[i] = rMsg.m_nIndex[i];

    m_aBoundary = rMsg.m_aBoundary;
    nNumChildren = rMsg.nNumChildren;

    for (i = 0; i < rMsg.aChildren.Count(); i++)
    {
        INetMIMEMessage *pChild =
            (INetMIMEMessage *)(rMsg.aChildren.GetObject (i));

        if (pChild->pParent == &rMsg)
        {
            pChild = pChild->CreateMessage (*pChild);
            pChild->pParent = this;
        }
        aChildren.Insert (pChild, LIST_APPEND);
    }
}

/*
 * CreateMessage.
 */
INetMIMEMessage *INetMIMEMessage::CreateMessage (
    const INetMIMEMessage& rMsg) const
{
    return (new INetMIMEMessage (rMsg));
}

/*
 * SetHeaderField.
 * (Header Field Parser).
 */
sal_uIntPtr INetMIMEMessage::SetHeaderField (
    const INetMessageHeader &rHeader, sal_uIntPtr nNewIndex)
{
    ByteString aName (rHeader.GetName());
    const sal_Char *pData = aName.GetBuffer();
    const sal_Char *pStop = pData + aName.Len() + 1;
    const sal_Char *check = "";

    sal_uIntPtr      nIdx     = LIST_APPEND;
    int        eState   = INETMSG_MIME_BEGIN;
    int        eOkState = INETMSG_MIME_OK;

    while (pData < pStop)
    {
        switch (eState)
        {
            case INETMSG_MIME_BEGIN:
                eState = INETMSG_MIME_CHECK;
                eOkState = INETMSG_MIME_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'c':
                        check = "ontent-";
                        eOkState = INETMSG_MIME_TOKEN_CONTENT;
                        break;

                    case 'm':
                        check = "ime-version";
                        nIdx = INETMSG_MIME_VERSION;
                        break;

                    default:
                        eState = INETMSG_MIME_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_MIME_TOKEN_CONTENT:
                eState = INETMSG_MIME_CHECK;
                eOkState = INETMSG_MIME_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'd':
                        eState = INETMSG_MIME_TOKEN_CONTENT_D;
                        break;

                    case 'i':
                        check = "d";
                        nIdx = INETMSG_MIME_CONTENT_ID;
                        break;

                    case 't':
                        eState = INETMSG_MIME_TOKEN_CONTENT_T;
                        break;

                    default:
                        eState = INETMSG_MIME_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_MIME_TOKEN_CONTENT_D:
                eState = INETMSG_MIME_CHECK;
                eOkState = INETMSG_MIME_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'e':
                        check = "scription";
                        nIdx = INETMSG_MIME_CONTENT_DESCRIPTION;
                        break;

                    case 'i':
                        check = "sposition";
                        nIdx = INETMSG_MIME_CONTENT_DISPOSITION;
                        break;

                    default:
                        eState = INETMSG_MIME_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_MIME_TOKEN_CONTENT_T:
                eState = INETMSG_MIME_CHECK;
                eOkState = INETMSG_MIME_OK;

                switch (ascii_toLowerCase (*pData))
                {
                    case 'r':
                        check = "ansfer-encoding";
                        nIdx = INETMSG_MIME_CONTENT_TRANSFER_ENCODING;
                        break;

                    case 'y':
                        check = "pe";
                        nIdx = INETMSG_MIME_CONTENT_TYPE;
                        break;

                    default:
                        eState = INETMSG_MIME_JUNK;
                        break;
                }
                pData++;
                break;

            case INETMSG_MIME_CHECK:
                if (*check)
                {
                    while (*pData && *check &&
                           (ascii_toLowerCase (*pData) == *check))
                    {
                        pData++;
                        check++;
                    }
                }
                else
                {
                    check = pData;
                }
                eState = (*check == '\0') ? eOkState : INETMSG_MIME_JUNK;
                break;

            case INETMSG_MIME_OK:
                pData = pStop;
                SetHeaderField_Impl (
                    HEADERFIELD (MIMEHDR(nIdx), rHeader.GetValue()),
                    m_nIndex[nIdx]);
                nNewIndex = m_nIndex[nIdx];
                break;

            default: // INETMSG_MIME_JUNK
                pData = pStop;
                nNewIndex = INetRFC822Message::SetHeaderField (
                    rHeader, nNewIndex);
                break;
        }
    }
    return nNewIndex;
}

/*
 * Specific Set-Methods.
 */
void INetMIMEMessage::SetMIMEVersion (const UniString& rVersion)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        MIMEHDR(INETMSG_MIME_VERSION), rVersion,
        m_nIndex[INETMSG_MIME_VERSION]);
}

void INetMIMEMessage::SetContentDescription (const String& rDescription)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        MIMEHDR(INETMSG_MIME_CONTENT_DESCRIPTION), rDescription,
        m_nIndex[INETMSG_MIME_CONTENT_DESCRIPTION]);
}

void INetMIMEMessage::SetContentDisposition (const String& rDisposition)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        MIMEHDR(INETMSG_MIME_CONTENT_DISPOSITION), rDisposition,
        m_nIndex[INETMSG_MIME_CONTENT_DISPOSITION]);
}

void INetMIMEMessage::SetContentID (const String& rID)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        MIMEHDR(INETMSG_MIME_CONTENT_ID), rID,
        m_nIndex[INETMSG_MIME_CONTENT_ID]);
}

void INetMIMEMessage::SetContentType (const String& rType)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        MIMEHDR(INETMSG_MIME_CONTENT_TYPE), rType,
        m_nIndex[INETMSG_MIME_CONTENT_TYPE]);
}

void INetMIMEMessage::SetContentTransferEncoding (
    const String& rEncoding)
{
    SetHeaderField_Impl (
        INetMIME::HEADER_FIELD_TEXT,
        MIMEHDR(INETMSG_MIME_CONTENT_TRANSFER_ENCODING), rEncoding,
        m_nIndex[INETMSG_MIME_CONTENT_TRANSFER_ENCODING]);
}

/*
 * GetDefaultContentType.
 */
void INetMIMEMessage::GetDefaultContentType (String& rContentType)
{
    String aDefaultCT (
        "text/plain; charset=us-ascii", RTL_TEXTENCODING_ASCII_US);
    if (pParent == NULL)
    {
        rContentType = aDefaultCT;
    }
    else
    {
        String aParentCT (pParent->GetContentType());
        if (aParentCT.Len() == 0)
            pParent->GetDefaultContentType (aParentCT);

        if (aParentCT.CompareIgnoreCaseToAscii ("message/", 8) == 0)
        {
            rContentType = aDefaultCT;
        }
        else if (aParentCT.CompareIgnoreCaseToAscii ("multipart/", 10) == 0)
        {
            if (aParentCT.CompareIgnoreCaseToAscii ("multipart/digest") == 0)
                rContentType.AssignAscii ("message/rfc822");
            else
                rContentType = aDefaultCT;
        }
        else
        {
            rContentType = aDefaultCT;
        }
    }
}

/*
 * EnableAttachChild.
 */
sal_Bool INetMIMEMessage::EnableAttachChild (INetMessageContainerType eType)
{
    // Check context.
    if (IsContainer())
        return sal_False;

    // Setup Content-Type header field.
    ByteString aContentType;
    switch (eType)
    {
        case INETMSG_MESSAGE_RFC822:
            aContentType = "message/rfc822";
            break;

        case INETMSG_MULTIPART_ALTERNATIVE:
            aContentType = "multipart/alternative";
            break;

        case INETMSG_MULTIPART_DIGEST:
            aContentType = "multipart/digest";
            break;

        case INETMSG_MULTIPART_PARALLEL:
            aContentType = "multipart/parallel";
            break;

        case INETMSG_MULTIPART_RELATED:
            aContentType = "multipart/related";
            break;

        case INETMSG_MULTIPART_FORM_DATA:
            aContentType = "multipart/form-data";
            break;

        default:
            aContentType = "multipart/mixed";
            break;
    }

    // Setup boundary for multipart types.
    if (aContentType.CompareIgnoreCaseToAscii ("multipart/", 10) == 0)
    {
        // Generate a unique boundary from current time.
        sal_Char sTail[16 + 1];
        Time aCurTime;
        sal_uInt64 nThis = reinterpret_cast< sal_uIntPtr >( this ); // we can be on a 64bit architecture
        nThis = ( ( nThis >> 32 ) ^ nThis ) & SAL_MAX_UINT32;
        sprintf (sTail, "%08X%08X",
                 static_cast< unsigned int >(aCurTime.GetTime()),
                 static_cast< unsigned int >(nThis));
        m_aBoundary = "------------_4D48";
        m_aBoundary += sTail;

        // Append boundary as ContentType parameter.
        aContentType += "; boundary=";
        aContentType += m_aBoundary;
    }

    // Set header fields.
    SetMIMEVersion (String (CONSTASCII_STRINGPARAM("1.0")));
    SetContentType (String (aContentType, RTL_TEXTENCODING_ASCII_US));
    SetContentTransferEncoding (String (CONSTASCII_STRINGPARAM("7bit")));

    // Done.
    return sal_True;
}

/*
 * AttachChild.
 */
sal_Bool INetMIMEMessage::AttachChild (
    INetMIMEMessage& rChildMsg, sal_Bool bOwner)
{
    if (IsContainer() /*&& rChildMsg.GetContentType().Len() */)
    {
        if (bOwner) rChildMsg.pParent = this;
        aChildren.Insert (&rChildMsg, LIST_APPEND);
        nNumChildren = aChildren.Count();

        return sal_True;
    }
    return sal_False;
}

/*
 * DetachChild.
 */
sal_Bool INetMIMEMessage::DetachChild (
    sal_uIntPtr nIndex, INetMIMEMessage& rChildMsg) const
{
    if (IsContainer())
    {
        // Check document stream.
        if (GetDocumentLB() == NULL) return sal_False;
        SvStream *pDocStrm = new SvStream (GetDocumentLB());

        // Initialize message buffer.
        char pMsgBuffer[1024];
        char *pMsgRead, *pMsgWrite;
        pMsgRead = pMsgWrite = pMsgBuffer;

        // Initialize message parser stream.
        INetMIMEMessageStream *pMsgStrm = NULL;

        // Check for "multipart/uvw" or "message/xyz".
        if (IsMultipart())
        {
            // Multipart message body. Initialize multipart delimiters.
            ByteString aDelim ("--");
            aDelim += GetMultipartBoundary();
            ByteString aClose = aDelim;
            aClose += "--";

            // Initialize line buffer.
            SvMemoryStream aLineBuf;

            // Initialize control variables.
            INetMessageStreamState eState = INETMSG_EOL_SCR;
            int nCurIndex = -1;

            // Go!
            while (nCurIndex < (int)(nIndex + 1))
            {
                if ((pMsgRead - pMsgWrite) > 0)
                {
                    // Bytes still in buffer.
                    if (eState == INETMSG_EOL_FCR)
                    {
                        // Check for 2nd line break character.
                        if ((*pMsgWrite == '\r') || (*pMsgWrite == '\n'))
                            aLineBuf << *pMsgWrite++;

                        // Check current index.
                        if (nCurIndex == (int)nIndex)
                        {
                            // Found requested part.
                            if (pMsgStrm == NULL)
                            {
                                // Create message parser stream.
                                pMsgStrm = new INetMIMEMessageStream;
                                pMsgStrm->SetTargetMessage (&rChildMsg);
                            }

                            // Put message down-stream.
                            int status = pMsgStrm->Write (
                                (const sal_Char *) aLineBuf.GetData(), aLineBuf.Tell());
                            if (status != INETSTREAM_STATUS_OK)
                            {
                                // Cleanup.
                                delete pDocStrm;
                                delete pMsgStrm;

                                // Finish.
                                return (!(status == INETSTREAM_STATUS_OK));
                            }
                        }

                        // Reset to <Begin-of-Line>.
                        aLineBuf.Seek (STREAM_SEEK_TO_BEGIN);
                        eState = INETMSG_EOL_SCR;
                    }
                    else if ((*pMsgWrite == '\r') || (*pMsgWrite == '\n'))
                    {
                        /*
                         * Found any line break character.
                         * Compare buffered line with part/close delimiter.
                         * Increment current part index upon match.
                         */
                        sal_uInt16 nLen = (sal_uInt16)(aLineBuf.Tell() & 0xffff);
                        if (nLen == aDelim.Len())
                        {
                            if (aDelim.CompareTo ((const sal_Char *) aLineBuf.GetData(), nLen)
                                == COMPARE_EQUAL) nCurIndex++;
                        }
                        else if (nLen == aClose.Len())
                        {
                            if (aClose.CompareTo ((const sal_Char *) aLineBuf.GetData(), nLen)
                                == COMPARE_EQUAL) nCurIndex++;
                        }
                        aLineBuf << *pMsgWrite++;
                        eState = INETMSG_EOL_FCR;
                    }
                    else
                    {
                        // Insert into line buffer.
                        aLineBuf << *pMsgWrite;
                    }
                }
                else
                {
                    // Buffer empty. Reset to <Begin-of-Buffer>.
                    pMsgRead = pMsgWrite = pMsgBuffer;

                    // Read document stream.
                    sal_uIntPtr nRead = pDocStrm->Read (
                        pMsgBuffer, sizeof (pMsgBuffer));
                    if (nRead > 0)
                    {
                        // Set read pointer.
                        pMsgRead += nRead;
                    }
                    else
                    {
                        // Premature end.
                        if (pMsgStrm)
                        {
                            // Assume end of requested part.
                            nCurIndex++;
                        }
                        else
                        {
                            // Requested part not found.
                            delete pDocStrm;
                            return sal_False;
                        }
                    }
                }
            } // while (nCurIndex < (nIndex + 1))
        }
        else
        {
            // Encapsulated message body. Create message parser stream.
            pMsgStrm = new INetMIMEMessageStream;
            pMsgStrm->SetTargetMessage (&rChildMsg);

            // Initialize control variables.
            INetMessageStreamState eState = INETMSG_EOL_BEGIN;

            // Go.
            while (eState == INETMSG_EOL_BEGIN)
            {
                if ((pMsgRead - pMsgWrite) > 0)
                {
                    // Bytes still in buffer. Put message down-stream.
                    int status = pMsgStrm->Write (
                        pMsgBuffer, (pMsgRead - pMsgWrite));
                    if (status != INETSTREAM_STATUS_OK)
                    {
                        // Cleanup.
                        delete pDocStrm;
                        delete pMsgStrm;

                        // Finish.
                        return (!(status == INETSTREAM_STATUS_ERROR));
                    }
                    pMsgWrite = pMsgBuffer + (pMsgRead - pMsgWrite);
                }
                else
                {
                    // Buffer empty. Reset to <Begin-of-Buffer>.
                    pMsgRead = pMsgWrite = pMsgBuffer;

                    // Read document stream.
                    sal_uIntPtr nRead = pDocStrm->Read (
                        pMsgBuffer, sizeof (pMsgBuffer));
                    if (nRead > 0)
                    {
                        // Set read pointer.
                        pMsgRead += nRead;
                    }
                    else
                    {
                        // Mark we're done.
                        eState = INETMSG_EOL_DONE;
                    }
                }
            } // while (eState == INETMSG_EOL_BEGIN)
        }

        // Done.
        if (pDocStrm) delete pDocStrm;
        if (pMsgStrm) delete pMsgStrm;
        return sal_True;
    }
    return sal_False;
}

/*
 * operator<<
 */
SvStream& INetMIMEMessage::operator<< (SvStream& rStrm) const
{
    INetRFC822Message::operator<< (rStrm);

    for (sal_uInt16 i = 0; i < INETMSG_MIME_NUMHDR; i++)
        rStrm << static_cast<sal_uInt32>(m_nIndex[i]);

#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
    rStrm << m_aBoundary;
#else
    rStrm.WriteByteString (m_aBoundary);
#endif
    rStrm << static_cast<sal_uInt32>(nNumChildren);

    return rStrm;
}

/*
 * operator>>
 */
SvStream& INetMIMEMessage::operator>> (SvStream& rStrm)
{
    INetRFC822Message::operator>> (rStrm);

    sal_uInt32 nTemp;
    for (sal_uInt16 i = 0; i < INETMSG_MIME_NUMHDR; i++)
    {
        rStrm >> nTemp;
        m_nIndex[i] = nTemp;
    }

#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
    rStrm >> m_aBoundary;
#else
    rStrm.ReadByteString (m_aBoundary);
#endif
    rStrm >> nTemp;
    nNumChildren = nTemp;

    return rStrm;
}
