LCOV - code coverage report
Current view: top level - tools/source/inet - inetstrm.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 0 614 0.0 %
Date: 2014-11-03 Functions: 0 44 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <comphelper/string.hxx>
      21             : #include <sal/types.h>
      22             : #include <rtl/strbuf.hxx>
      23             : #include <tools/inetmsg.hxx>
      24             : #include <tools/inetstrm.hxx>
      25             : 
      26             : #include <ctype.h>
      27             : 
      28           0 : inline bool SAL_CALL ascii_isWhitespace( sal_Unicode ch )
      29             : {
      30           0 :     return ((ch <= 0x20) && ch);
      31             : }
      32             : 
      33             : /** Quoted-Printable Encoding */
      34             : class INetMessageEncodeQPStream_Impl : public INetMessageIStream
      35             : {
      36             :     SvStream*               pMsgStrm;
      37             : 
      38             :     sal_uIntPtr             nMsgBufSiz;
      39             :     sal_Char*               pMsgBuffer;
      40             :     sal_Char*               pMsgRead;
      41             :     sal_Char*               pMsgWrite;
      42             : 
      43             :     sal_uIntPtr             nTokBufSiz;
      44             :     sal_Char*               pTokBuffer;
      45             :     sal_Char*               pTokRead;
      46             :     sal_Char*               pTokWrite;
      47             : 
      48             :     INetMessageStreamState  eState;
      49             :     bool                    bDone;
      50             : 
      51             :     virtual int GetMsgLine(sal_Char* pData, sal_uIntPtr nSize) SAL_OVERRIDE;
      52             : 
      53             : public:
      54             :     INetMessageEncodeQPStream_Impl(sal_uIntPtr nMsgBufferSize = 1024);
      55             :     virtual ~INetMessageEncodeQPStream_Impl(void);
      56             : };
      57             : 
      58             : /** Quoted-Printable Decoding */
      59             : class INetMessageDecodeQPStream_Impl : public INetMessageOStream
      60             : {
      61             :     INetMessageStreamState  eState;
      62             :     SvMemoryStream         *pMsgBuffer;
      63             : 
      64             :     sal_uIntPtr             nTokBufLen;
      65             :     sal_Char                pTokBuffer[4];
      66             : 
      67             :     virtual int PutMsgLine(const sal_Char* pData, sal_uIntPtr nSize) SAL_OVERRIDE;
      68             : 
      69             : public:
      70             :     INetMessageDecodeQPStream_Impl(void);
      71             :     virtual ~INetMessageDecodeQPStream_Impl(void);
      72             : };
      73             : 
      74             : /** Base64 Encoding */
      75             : class INetMessageEncode64Stream_Impl : public INetMessageIStream
      76             : {
      77             :     SvStream*    pMsgStrm;
      78             : 
      79             :     sal_uIntPtr  nMsgBufSiz;
      80             :     sal_uInt8*   pMsgBuffer;
      81             :     sal_uInt8*   pMsgRead;
      82             :     sal_uInt8*   pMsgWrite;
      83             : 
      84             :     sal_uIntPtr  nTokBufSiz;
      85             :     sal_Char*    pTokBuffer;
      86             :     sal_Char*    pTokRead;
      87             :     sal_Char*    pTokWrite;
      88             : 
      89             :     bool         bDone;
      90             : 
      91             :     virtual int GetMsgLine(sal_Char* pData, sal_uIntPtr nSize) SAL_OVERRIDE;
      92             : 
      93             : public:
      94             :     INetMessageEncode64Stream_Impl(sal_uIntPtr nMsgBufferSize = 2048);
      95             :     virtual ~INetMessageEncode64Stream_Impl(void);
      96             : };
      97             : 
      98             : /** Base64 Decoding */
      99             : class INetMessageDecode64Stream_Impl : public INetMessageOStream
     100             : {
     101             :     INetMessageStreamState  eState;
     102             : 
     103             :     sal_uIntPtr             nMsgBufSiz;
     104             :     sal_Char*               pMsgBuffer;
     105             :     sal_Char*               pMsgRead;
     106             :     sal_Char*               pMsgWrite;
     107             : 
     108             :     virtual int PutMsgLine(const sal_Char* pData, sal_uIntPtr nSize) SAL_OVERRIDE;
     109             : 
     110             : public:
     111             :     INetMessageDecode64Stream_Impl(sal_uIntPtr nMsgBufferSize = 128);
     112             :     virtual ~INetMessageDecode64Stream_Impl(void);
     113             : };
     114             : 
     115             : // INetIStream
     116             : 
     117           0 : INetIStream::INetIStream()
     118             : {
     119           0 : }
     120             : 
     121           0 : INetIStream::~INetIStream(void)
     122             : {
     123           0 : }
     124             : 
     125           0 : int INetIStream::Read(sal_Char* pData, sal_uIntPtr nSize)
     126             : {
     127           0 :     return GetData(pData, nSize);
     128             : }
     129             : 
     130             : // INetOStream
     131             : 
     132           0 : INetOStream::INetOStream()
     133             : {
     134           0 : }
     135             : 
     136           0 : INetOStream::~INetOStream(void)
     137             : {
     138           0 : }
     139             : 
     140           0 : int INetOStream::Write(const sal_Char* pData, sal_uIntPtr nSize)
     141             : {
     142           0 :     return PutData(pData, nSize);
     143             : }
     144             : 
     145             : // INetMessageIStream
     146             : 
     147           0 : INetMessageIStream::INetMessageIStream(sal_uIntPtr nBufferSize)
     148             :     : pSourceMsg(NULL)
     149             :     , bHeaderGenerated(false)
     150             :     , nBufSiz(nBufferSize)
     151             :     , pMsgStrm(NULL)
     152           0 :     , pMsgBuffer(new SvMemoryStream)
     153             :     , pMsgRead(NULL)
     154           0 :     , pMsgWrite(NULL)
     155             : {
     156           0 :     pMsgBuffer->SetStreamCharSet(RTL_TEXTENCODING_ASCII_US);
     157           0 :     pBuffer = new sal_Char[nBufSiz];
     158           0 :     pRead = pWrite = pBuffer;
     159           0 : }
     160             : 
     161           0 : INetMessageIStream::~INetMessageIStream(void)
     162             : {
     163           0 :     delete [] pBuffer;
     164           0 :     delete pMsgBuffer;
     165           0 :     delete pMsgStrm;
     166           0 : }
     167             : 
     168           0 : int INetMessageIStream::GetData(sal_Char* pData, sal_uIntPtr nSize)
     169             : {
     170           0 :     if (pSourceMsg == NULL) return INETSTREAM_STATUS_ERROR;
     171             : 
     172           0 :     sal_Char* pWBuf = pData;
     173           0 :     sal_Char* pWEnd = pData + nSize;
     174             : 
     175           0 :     while (pWBuf < pWEnd)
     176             :     {
     177             :         // Caller's buffer not yet filled.
     178           0 :         sal_uIntPtr n = pRead - pWrite;
     179           0 :         if (n > 0)
     180             :         {
     181             :             // Bytes still in buffer.
     182           0 :             sal_uIntPtr m = pWEnd - pWBuf;
     183           0 :             if (m < n) n = m;
     184           0 :             for (sal_uIntPtr i = 0; i < n; i++) *pWBuf++ = *pWrite++;
     185             :         }
     186             :         else
     187             :         {
     188             :             // Buffer empty. Reset to <Begin-of-Buffer>.
     189           0 :             pRead = pWrite = pBuffer;
     190             : 
     191             :             // Read next message line.
     192           0 :             int nRead = GetMsgLine(pBuffer, nBufSiz);
     193           0 :             if (nRead > 0)
     194             :             {
     195             :                 // Set read pointer.
     196           0 :                 pRead = pBuffer + nRead;
     197             :             }
     198             :             else
     199             :             {
     200           0 :                 if (!bHeaderGenerated)
     201             :                 {
     202             :                     // Header generated. Insert empty line.
     203           0 :                     bHeaderGenerated = true;
     204           0 :                     *pRead++ = '\r';
     205           0 :                     *pRead++ = '\n';
     206             :                 }
     207             :                 else
     208             :                 {
     209             :                     // Body generated.
     210           0 :                     return (pWBuf - pData);
     211             :                 }
     212             :             }
     213             :         }
     214             :     }
     215           0 :     return (pWBuf - pData);
     216             : }
     217             : 
     218           0 : int INetMessageIStream::GetMsgLine(sal_Char* pData, sal_uIntPtr nSize)
     219             : {
     220           0 :     if (pSourceMsg == NULL) return INETSTREAM_STATUS_ERROR;
     221             : 
     222           0 :     sal_Char* pWBuf = pData;
     223           0 :     sal_Char* pWEnd = pData + nSize;
     224             : 
     225           0 :     if (!bHeaderGenerated)
     226             :     {
     227             :         sal_uIntPtr i, n;
     228             : 
     229           0 :         if (pMsgBuffer->Tell() == 0)
     230             :         {
     231             :             // Insert formatted header into buffer.
     232           0 :             n = pSourceMsg->GetHeaderCount();
     233           0 :             for (i = 0; i < n; i++)
     234             :             {
     235           0 :                 INetMessageHeader aHeader (pSourceMsg->GetHeaderField(i));
     236           0 :                 if (aHeader.GetValue().getLength())
     237             :                 {
     238             :                     // NYI: Folding long lines.
     239           0 :                     pMsgBuffer->WriteCharPtr( aHeader.GetName().getStr() );
     240           0 :                     pMsgBuffer->WriteCharPtr( ": " );
     241           0 :                     pMsgBuffer->WriteCharPtr( aHeader.GetValue().getStr() );
     242           0 :                     pMsgBuffer->WriteCharPtr( "\r\n" );
     243             :                 }
     244           0 :             }
     245             : 
     246           0 :             pMsgWrite = (sal_Char*)(pMsgBuffer->GetData());
     247           0 :             pMsgRead  = pMsgWrite + pMsgBuffer->Tell();
     248             :         }
     249             : 
     250           0 :         n = pMsgRead - pMsgWrite;
     251           0 :         if (n > 0)
     252             :         {
     253             :             // Move to caller.
     254           0 :             if (nSize < n) n = nSize;
     255           0 :             for (i = 0; i < n; i++) *pWBuf++ = *pMsgWrite++;
     256             :         }
     257             :         else
     258             :         {
     259             :             // Reset buffer.
     260           0 :             pMsgBuffer->Seek(STREAM_SEEK_TO_BEGIN);
     261             :         }
     262             :     }
     263             :     else
     264             :     {
     265           0 :         if (pSourceMsg->GetDocumentLB())
     266             :         {
     267           0 :             if (pMsgStrm == NULL)
     268           0 :                 pMsgStrm = new SvStream (pSourceMsg->GetDocumentLB());
     269             : 
     270           0 :             sal_uIntPtr nRead = pMsgStrm->Read(pWBuf, (pWEnd - pWBuf));
     271           0 :             pWBuf += nRead;
     272             :         }
     273             :     }
     274           0 :     return (pWBuf - pData);
     275             : }
     276             : 
     277             : // INetMessageOStream
     278             : 
     279           0 : INetMessageOStream::INetMessageOStream(void)
     280             :     : pTargetMsg    (NULL),
     281             :       bHeaderParsed (false),
     282             :       eOState       (INETMSG_EOL_BEGIN),
     283           0 :       pMsgBuffer    (new SvMemoryStream)
     284             : {
     285           0 : }
     286             : 
     287           0 : INetMessageOStream::~INetMessageOStream(void)
     288             : {
     289           0 :     if (pMsgBuffer->Tell() > 0)
     290           0 :         PutMsgLine((const sal_Char*) pMsgBuffer->GetData(), pMsgBuffer->Tell());
     291           0 :     delete pMsgBuffer;
     292             : 
     293           0 :     if (pTargetMsg)
     294             :     {
     295           0 :         SvOpenLockBytes* pLB = PTR_CAST(SvOpenLockBytes, pTargetMsg->GetDocumentLB());
     296           0 :         if (pLB)
     297             :         {
     298           0 :             pLB->Flush();
     299           0 :             pLB->Terminate();
     300             :         }
     301             :     }
     302           0 : }
     303             : 
     304             : /// Simple Field Parsing (RFC822, Appendix B)
     305           0 : int INetMessageOStream::PutData(const sal_Char* pData, sal_uIntPtr nSize)
     306             : {
     307           0 :     if (pTargetMsg == NULL) return INETSTREAM_STATUS_ERROR;
     308             : 
     309           0 :     const sal_Char* pStop = (pData + nSize);
     310             : 
     311           0 :     while (!bHeaderParsed && (pData < pStop))
     312             :     {
     313           0 :         if (eOState == INETMSG_EOL_BEGIN)
     314             :         {
     315           0 :             if ((*pData == '\r') || (*pData == '\n'))
     316             :             {
     317             :                 /*
     318             :                  * Empty Line. Separates header fields from message body.
     319             :                  * Skip this and any 2nd line break character (if any).
     320             :                  */
     321           0 :                 pData++;
     322           0 :                 if ((pData < pStop) && ((*pData == '\r') || (*pData == '\n')))
     323           0 :                     pData++;
     324             : 
     325             :                 // Emit any buffered last header field.
     326           0 :                 if (pMsgBuffer->Tell() > 0)
     327             :                 {
     328           0 :                     pMsgBuffer->WriteChar( '\0' );
     329           0 :                     int status = PutMsgLine( (const sal_Char*) pMsgBuffer->GetData(),
     330           0 :                                              pMsgBuffer->Tell());
     331           0 :                     if (status != INETSTREAM_STATUS_OK) return status;
     332             :                 }
     333             : 
     334             :                 // Reset to begin.
     335           0 :                 eOState = INETMSG_EOL_BEGIN;
     336           0 :                 pMsgBuffer->Seek(STREAM_SEEK_TO_BEGIN);
     337             : 
     338             :                 // Mark header parsed.
     339           0 :                 bHeaderParsed = true;
     340             :             }
     341           0 :             else if ((*pData == ' ') || (*pData == '\t'))
     342             :             {
     343             :                 // Continuation line. Unfold multi-line field-body.
     344           0 :                 pMsgBuffer->WriteChar( ' ' );
     345           0 :                 pData++;
     346             :             }
     347             :             else
     348             :             {
     349             :                 // Begin of new header field.
     350           0 :                 if (pMsgBuffer->Tell() > 0)
     351             :                 {
     352             :                     // Emit buffered header field now.
     353           0 :                     pMsgBuffer->WriteChar( '\0' );
     354           0 :                     int status = PutMsgLine((const sal_Char*) pMsgBuffer->GetData(),
     355           0 :                                              pMsgBuffer->Tell());
     356           0 :                     if (status != INETSTREAM_STATUS_OK) return status;
     357             :                 }
     358             : 
     359             :                 // Reset to begin of buffer.
     360           0 :                 pMsgBuffer->Seek(STREAM_SEEK_TO_BEGIN);
     361             : 
     362             :                 // Insert current character into buffer.
     363           0 :                 pMsgBuffer->WriteChar( *pData++ );
     364             :             }
     365             : 
     366             :             // Search for next line break character.
     367           0 :             if (!bHeaderParsed) eOState = INETMSG_EOL_SCR;
     368             :         }
     369           0 :         else if (eOState == INETMSG_EOL_FCR)
     370             :         {
     371             :             // Skip line break character.
     372           0 :             pData++;
     373             : 
     374             :             // Mark begin of line.
     375           0 :             eOState = INETMSG_EOL_BEGIN;
     376             :         }
     377           0 :         else if ((*pData == '\r') || (*pData == '\n'))
     378             :         {
     379           0 :             if (*pData == '\r') pData++;
     380           0 :             eOState = INETMSG_EOL_FCR;
     381             :         }
     382           0 :         else if (ascii_isWhitespace(*pData & 0x7f))
     383             :         {
     384             :             // Any <LWS> is folded into a single <SP> character.
     385           0 :             sal_Char c = *((const sal_Char*) pMsgBuffer->GetData() + pMsgBuffer->Tell() - 1);
     386           0 :             if (!ascii_isWhitespace(c & 0x7f)) pMsgBuffer->WriteChar( ' ' );
     387             : 
     388             :             // Skip over this <LWS> character.
     389           0 :             pData++;
     390             :         }
     391             :         else
     392             :         {
     393             :             // Any other character is inserted into line buffer.
     394           0 :             pMsgBuffer->WriteChar( *pData++ );
     395             :         }
     396             :     }
     397             : 
     398           0 :     if (bHeaderParsed && (pData < pStop))
     399             :     {
     400             :         // Put message body down-stream.
     401           0 :         return PutMsgLine(pData, (pStop - pData));
     402             :     }
     403             : 
     404           0 :     return INETSTREAM_STATUS_OK;
     405             : }
     406             : 
     407           0 : int INetMessageOStream::PutMsgLine(const sal_Char* pData, sal_uIntPtr nSize)
     408             : {
     409             :     // Check for message container.
     410           0 :     if (pTargetMsg == NULL) return INETSTREAM_STATUS_ERROR;
     411             : 
     412             :     // Check for header or body.
     413           0 :     if (!IsHeaderParsed())
     414             :     {
     415           0 :         OString aField(pData);
     416           0 :         sal_Int32 nPos = aField.indexOf(':');
     417           0 :         if (nPos != -1)
     418             :         {
     419           0 :             OString aName( aField.copy(0, nPos));
     420           0 :             OString aValue( aField.copy(nPos + 1, aField.getLength() - nPos + 1));
     421           0 :             aValue = comphelper::string::stripStart(aValue, ' ');
     422             : 
     423           0 :             pTargetMsg->SetHeaderField( INetMessageHeader (aName, aValue));
     424           0 :         }
     425             :     }
     426             :     else
     427             :     {
     428           0 :         SvOpenLockBytes *pLB = PTR_CAST(SvOpenLockBytes, pTargetMsg->GetDocumentLB());
     429           0 :         if (pLB == NULL)
     430           0 :             return INETSTREAM_STATUS_WOULDBLOCK;
     431             : 
     432           0 :         sal_Size nDocSiz = pTargetMsg->GetDocumentSize();
     433           0 :         sal_Size nWrite  = 0;
     434             : 
     435           0 :         pLB->FillAppend((sal_Char*)pData, nSize, &nWrite);
     436           0 :         pTargetMsg->SetDocumentSize(nDocSiz + nWrite);
     437             : 
     438           0 :         if (nWrite < nSize) return INETSTREAM_STATUS_ERROR;
     439             :     }
     440           0 :     return INETSTREAM_STATUS_OK;
     441             : }
     442             : 
     443             : // INetMessageIOStream
     444             : 
     445           0 : INetMessageIOStream::INetMessageIOStream(sal_uIntPtr nBufferSize)
     446             :     : INetMessageIStream (nBufferSize),
     447           0 :       INetMessageOStream ()
     448             : {
     449           0 : }
     450             : 
     451           0 : INetMessageIOStream::~INetMessageIOStream(void)
     452             : {
     453           0 : }
     454             : 
     455             : // INetMessageEncodeQPStream_Impl
     456             : 
     457             : static const sal_Char hex2pr[16] = {
     458             :     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
     459             :     'A', 'B', 'C', 'D', 'E', 'F'
     460             : };
     461             : 
     462           0 : INetMessageEncodeQPStream_Impl::INetMessageEncodeQPStream_Impl( sal_uIntPtr nMsgBufferSize)
     463             :     : INetMessageIStream (),
     464             :       pMsgStrm   (NULL),
     465             :       nMsgBufSiz (nMsgBufferSize),
     466             :       nTokBufSiz (80),
     467             :       eState     (INETMSG_EOL_SCR),
     468           0 :       bDone      (false)
     469             : {
     470           0 :     GenerateHeader (false);
     471             : 
     472           0 :     pMsgBuffer = new sal_Char[nMsgBufSiz];
     473           0 :     pMsgRead = pMsgWrite = pMsgBuffer;
     474             : 
     475           0 :     pTokBuffer = new sal_Char[nTokBufSiz];
     476           0 :     pTokRead = pTokWrite = pTokBuffer;
     477           0 : }
     478             : 
     479           0 : INetMessageEncodeQPStream_Impl::~INetMessageEncodeQPStream_Impl(void)
     480             : {
     481           0 :     delete pMsgStrm;
     482           0 :     delete [] pMsgBuffer;
     483           0 :     delete [] pTokBuffer;
     484           0 : }
     485             : 
     486           0 : int INetMessageEncodeQPStream_Impl::GetMsgLine(sal_Char* pData, sal_uIntPtr nSize)
     487             : {
     488           0 :     INetMessage* pMsg = GetSourceMessage();
     489           0 :     if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
     490             : 
     491           0 :     if (pMsg->GetDocumentLB() == NULL) return 0;
     492           0 :     if (pMsgStrm == NULL) pMsgStrm = new SvStream(pMsg->GetDocumentLB());
     493             : 
     494           0 :     sal_Char* pWBuf = pData;
     495           0 :     while (pWBuf < (pData + nSize))
     496             :     {
     497             :         // Caller's buffer not yet filled.
     498           0 :         if ((pMsgRead - pMsgWrite) > 0)
     499             :         {
     500             :             // Bytes still in message buffer.
     501           0 :             if ((eState != INETMSG_EOL_BEGIN) &&
     502           0 :                 ((pTokRead - pTokBuffer) < 72))
     503             :             {
     504             :                 // Token buffer not yet filled.
     505           0 :                 if (eState == INETMSG_EOL_FCR)
     506             :                 {
     507           0 :                     eState = INETMSG_EOL_BEGIN;
     508           0 :                     if (*pMsgWrite != '\n')
     509             :                     {
     510             :                         // Convert orphant <CR> into <CR><LF> sequence.
     511           0 :                         *pTokRead++ = '\n';
     512             :                     }
     513           0 :                     *pTokRead++ = *pMsgWrite++;
     514             :                 }
     515           0 :                 else if ((*pMsgWrite == ' ') || (*pMsgWrite == '\t'))
     516             :                 {
     517           0 :                     eState = INETMSG_EOL_FSP;
     518           0 :                     *pTokRead++ = *pMsgWrite++;
     519             :                 }
     520           0 :                 else if (*pMsgWrite == '\r')
     521             :                 {
     522             :                     // Found <CR>.
     523           0 :                     if (eState == INETMSG_EOL_FSP)
     524             :                     {
     525             :                         // Encode last (trailing space) character.
     526           0 :                         sal_uInt8 c = (sal_uInt8)(*(--pTokRead));
     527           0 :                         *pTokRead++ = '=';
     528           0 :                         *pTokRead++ = hex2pr[((c & 0xf0) >> 4)];
     529           0 :                         *pTokRead++ = hex2pr[((c & 0x0f)     )];
     530             :                     }
     531           0 :                     eState = INETMSG_EOL_FCR;
     532           0 :                     *pTokRead++ = *pMsgWrite++;
     533             :                 }
     534           0 :                 else if (*pMsgWrite == '\n')
     535             :                 {
     536             :                     // Found <LF> only.
     537           0 :                     if (eState == INETMSG_EOL_FSP)
     538             :                     {
     539             :                         // Encode last (trailing space) character.
     540           0 :                         sal_uInt8 c = (sal_uInt8)(*(--pTokRead));
     541           0 :                         *pTokRead++ = '=';
     542           0 :                         *pTokRead++ = hex2pr[((c & 0xf0) >> 4)];
     543           0 :                         *pTokRead++ = hex2pr[((c & 0x0f)     )];
     544             :                     }
     545           0 :                     eState = INETMSG_EOL_BEGIN;
     546             : 
     547             :                     // Convert orphant <LF> into <CR><LF> sequence.
     548           0 :                     *pTokRead++ = '\r';
     549           0 :                     *pTokRead++ = *pMsgWrite++;
     550             :                 }
     551           0 :                 else if (*pMsgWrite == '=')
     552             :                 {
     553             :                     // Escape character itself MUST be encoded, of course.
     554           0 :                     sal_uInt8 c = (sal_uInt8)(*pMsgWrite++);
     555           0 :                     *pTokRead++ = '=';
     556           0 :                     *pTokRead++ = hex2pr[((c & 0xf0) >> 4)];
     557           0 :                     *pTokRead++ = hex2pr[((c & 0x0f)     )];
     558             : 
     559           0 :                     eState = INETMSG_EOL_SCR;
     560             :                 }
     561           0 :                 else if (((sal_uInt8)(*pMsgWrite) > 0x20) &&
     562           0 :                          ((sal_uInt8)(*pMsgWrite) < 0x7f)    )
     563             :                 {
     564             :                     /*
     565             :                      * Some printable ASCII character.
     566             :                      * (Encode EBCDIC special characters (NYI)).
     567             :                      */
     568           0 :                     *pTokRead++ = *pMsgWrite++;
     569           0 :                     eState = INETMSG_EOL_SCR;
     570             :                 }
     571             :                 else
     572             :                 {
     573             :                     // Encode any other character.
     574           0 :                     sal_uInt8 c = (sal_uInt8)(*pMsgWrite++);
     575           0 :                     *pTokRead++ = '=';
     576           0 :                     *pTokRead++ = hex2pr[((c & 0xf0) >> 4)];
     577           0 :                     *pTokRead++ = hex2pr[((c & 0x0f)     )];
     578             : 
     579           0 :                     eState = INETMSG_EOL_SCR;
     580           0 :                 }
     581             :             }
     582             :             else
     583             :             {
     584             :                 // Check for maximum line length.
     585           0 :                 if (eState != INETMSG_EOL_BEGIN)
     586             :                 {
     587             :                     // Insert soft line break.
     588           0 :                     *pTokRead++ = '=';
     589           0 :                     *pTokRead++ = '\r';
     590           0 :                     *pTokRead++ = '\n';
     591             : 
     592           0 :                     eState = INETMSG_EOL_BEGIN;
     593             :                 }
     594             : 
     595             :                 // Copy to caller's buffer.
     596           0 :                 if ((pTokRead - pTokWrite) > 0)
     597             :                 {
     598             :                     // Bytes still in token buffer.
     599           0 :                     *pWBuf++ = *pTokWrite++;
     600             :                 }
     601             :                 else
     602             :                 {
     603             :                     // Token buffer empty. Reset to <Begin-of-Buffer>.
     604           0 :                     pTokRead = pTokWrite = pTokBuffer;
     605           0 :                     eState = INETMSG_EOL_SCR;
     606             :                 }
     607             :             }
     608             :         }
     609             :         else
     610             :         {
     611             :             // Message buffer empty. Reset to <Begin-of-Buffer>.
     612           0 :             pMsgRead = pMsgWrite = pMsgBuffer;
     613             : 
     614             :             // Read next message block.
     615           0 :             sal_uIntPtr nRead = pMsgStrm->Read(pMsgBuffer, nMsgBufSiz);
     616           0 :             if (nRead > 0)
     617             :             {
     618             :                 // Set read pointer.
     619           0 :                 pMsgRead = (pMsgBuffer + nRead);
     620             :             }
     621             :             else
     622             :             {
     623             :                 // Nothing more ro read.
     624           0 :                 if (!bDone)
     625             :                 {
     626             :                     // Append final <CR><LF> and mark we're done.
     627           0 :                     *pTokRead++ = '\r';
     628           0 :                     *pTokRead++ = '\n';
     629             : 
     630           0 :                     bDone = true;
     631             :                 }
     632             :                 else
     633             :                 {
     634             :                     // Already done all encoding.
     635           0 :                     if ((pTokRead - pTokWrite) > 0)
     636             :                     {
     637             :                         // Bytes still in token buffer.
     638           0 :                         *pWBuf++ = *pTokWrite++;
     639             :                     }
     640             :                     else
     641             :                     {
     642             :                         // Token buffer empty. Reset to <Begin-of-Buffer>.
     643           0 :                         pTokRead = pTokWrite = pTokBuffer;
     644             : 
     645             :                         // Return.
     646           0 :                         return (pWBuf - pData);
     647             :                     }
     648             :                 }
     649             :             }
     650             :         }
     651             :     }
     652           0 :     return (pWBuf - pData);
     653             : }
     654             : 
     655             : // INetMessageDecodeQPStream_Impl
     656             : 
     657             : static const sal_uInt8 pr2hex[128] = {
     658             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     659             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     660             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     661             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     662             : 
     663             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     664             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     665             :     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     666             :     0x08, 0x09, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     667             : 
     668             :     0x10, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
     669             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     670             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     671             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     672             : 
     673             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     674             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     675             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
     676             :     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10
     677             : };
     678             : 
     679           0 : INetMessageDecodeQPStream_Impl::INetMessageDecodeQPStream_Impl(void)
     680             :     : INetMessageOStream(),
     681             :       eState     (INETMSG_EOL_BEGIN),
     682           0 :       pMsgBuffer (new SvMemoryStream),
     683           0 :       nTokBufLen (0)
     684             : {
     685           0 :     ParseHeader(false);
     686           0 : }
     687             : 
     688           0 : INetMessageDecodeQPStream_Impl::~INetMessageDecodeQPStream_Impl(void)
     689             : {
     690           0 :     delete pMsgBuffer;
     691           0 : }
     692             : 
     693           0 : int INetMessageDecodeQPStream_Impl::PutMsgLine( const sal_Char* pData,
     694             :                                                 sal_uIntPtr nSize)
     695             : {
     696           0 :     INetMessage* pMsg = GetTargetMessage();
     697           0 :     if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
     698             : 
     699           0 :     SvOpenLockBytes* pLB = PTR_CAST(SvOpenLockBytes, pMsg->GetDocumentLB());
     700           0 :     if (pLB == NULL) return INETSTREAM_STATUS_WOULDBLOCK;
     701             : 
     702           0 :     const sal_Char* pStop = pData + nSize;
     703           0 :     while (pData < pStop)
     704             :     {
     705           0 :         if (eState == INETMSG_EOL_FESC)
     706             :         {
     707           0 :             *(pTokBuffer + nTokBufLen++) = static_cast< char >(toupper(*pData));
     708           0 :             pData++;
     709           0 :             if (nTokBufLen == 2)
     710             :             {
     711           0 :                 if ((*pTokBuffer == '\r') || (*pTokBuffer == '\n'))
     712             :                 {
     713             :                     // Soft line break (=<CR><LF>). Emit buffer now.
     714           0 :                     eState = INETMSG_EOL_BEGIN;
     715             :                 }
     716             :                 else
     717             :                 {
     718             :                     // Decode token.
     719             :                     pMsgBuffer->WriteUChar( sal_uInt8 (
     720           0 :                         (pr2hex[(int)(pTokBuffer[0] & 0x7f)] << 4) |
     721           0 :                         (pr2hex[(int)(pTokBuffer[1] & 0x7f)] & 15)   ) );
     722             : 
     723             :                     // Search for next <CR>.
     724           0 :                     eState = INETMSG_EOL_SCR;
     725             :                 }
     726             : 
     727             :                 // Reset token buffer.
     728           0 :                 nTokBufLen = 0;
     729             :             }
     730             :         }
     731           0 :         else if (*pData == '=')
     732             :         {
     733             :             // Found escape character.
     734           0 :             pData++;
     735           0 :             eState = INETMSG_EOL_FESC;
     736             :         }
     737           0 :         else if (eState == INETMSG_EOL_FCR)
     738             :         {
     739           0 :             pMsgBuffer->WriteChar( *pData++ );
     740           0 :             eState = INETMSG_EOL_BEGIN;
     741             :         }
     742           0 :         else if (*pData == '\r')
     743             :         {
     744           0 :             pMsgBuffer->WriteChar( *pData++ );
     745           0 :             eState = INETMSG_EOL_FCR;
     746             :         }
     747             :         else
     748             :         {
     749           0 :             pMsgBuffer->WriteChar( *pData++ );
     750             :         }
     751             : 
     752           0 :         if (eState == INETMSG_EOL_BEGIN)
     753             :         {
     754           0 :             sal_Size nRead = pMsgBuffer->Tell();
     755           0 :             if (nRead > 0)
     756             :             {
     757             :                 // Emit buffer.
     758           0 :                 sal_Size nDocSiz = pMsg->GetDocumentSize();
     759           0 :                 sal_Size nWrite  = 0;
     760             : 
     761           0 :                 pLB->FillAppend((sal_Char*)(pMsgBuffer->GetData()), nRead, &nWrite);
     762           0 :                 pMsg->SetDocumentSize(nDocSiz + nWrite);
     763             : 
     764           0 :                 if (nWrite < nRead) return INETSTREAM_STATUS_ERROR;
     765             : 
     766           0 :                 pMsgBuffer->Seek(STREAM_SEEK_TO_BEGIN);
     767             :             }
     768           0 :             eState = INETMSG_EOL_SCR;
     769             :         }
     770             :     }
     771           0 :     return INETSTREAM_STATUS_OK;
     772             : }
     773             : 
     774             : // INetMessageEncode64Stream_Impl
     775             : 
     776             : static const sal_Char six2pr[64] = {
     777             :     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
     778             :     'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
     779             :     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
     780             :     'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
     781             :     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
     782             : };
     783             : 
     784           0 : INetMessageEncode64Stream_Impl::INetMessageEncode64Stream_Impl(
     785             :     sal_uIntPtr nMsgBufferSize)
     786             :     : INetMessageIStream(),
     787             :       pMsgStrm   (NULL),
     788             :       nMsgBufSiz (nMsgBufferSize),
     789             :       nTokBufSiz (80),
     790           0 :       bDone      (false)
     791             : {
     792           0 :     GenerateHeader(false);
     793             : 
     794           0 :     pMsgBuffer = new sal_uInt8[nMsgBufSiz];
     795           0 :     pMsgRead = pMsgWrite = pMsgBuffer;
     796             : 
     797           0 :     pTokBuffer = new sal_Char[nTokBufSiz];
     798           0 :     pTokRead = pTokWrite = pTokBuffer;
     799           0 : }
     800             : 
     801           0 : INetMessageEncode64Stream_Impl::~INetMessageEncode64Stream_Impl(void)
     802             : {
     803           0 :     delete pMsgStrm;
     804           0 :     delete [] pMsgBuffer;
     805           0 :     delete [] pTokBuffer;
     806           0 : }
     807             : 
     808           0 : int INetMessageEncode64Stream_Impl::GetMsgLine(sal_Char* pData, sal_uIntPtr nSize)
     809             : {
     810           0 :     INetMessage* pMsg = GetSourceMessage();
     811           0 :     if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
     812             : 
     813           0 :     if (pMsg->GetDocumentLB() == NULL) return 0;
     814           0 :     if (pMsgStrm == NULL) pMsgStrm = new SvStream(pMsg->GetDocumentLB());
     815             : 
     816           0 :     sal_Char* pWBuf = pData;
     817           0 :     while (pWBuf < (pData + nSize))
     818             :     {
     819             :         // Caller's buffer not yet filled.
     820           0 :         if ((pMsgRead - pMsgWrite) > 0)
     821             :         {
     822             :             // Bytes still in message buffer.
     823           0 :             if ((pTokRead - pTokBuffer) < 72)
     824             :             {
     825             :                 // Token buffer not yet filled.
     826           0 :                 switch ((pTokRead - pTokBuffer) % 4)
     827             :                 {
     828             :                 case 0:
     829           0 :                     *pTokRead++ = six2pr[(int)(*pMsgWrite >> 2)];
     830           0 :                     break;
     831             : 
     832             :                 case 1:
     833           0 :                     *pTokRead++ = six2pr[ (int)(((*pMsgWrite << 4) & 060) |
     834           0 :                                                 (((*(pMsgWrite + 1)) >> 4) & 017))];
     835           0 :                     pMsgWrite++;
     836           0 :                     break;
     837             : 
     838             :                 case 2:
     839           0 :                     *pTokRead++ = six2pr[ (int)(((*pMsgWrite << 2) & 074) |
     840           0 :                                                 (((*(pMsgWrite + 1)) >> 6) & 003))];
     841           0 :                     pMsgWrite++;
     842           0 :                     break;
     843             : 
     844             :                 default: // == case 3
     845           0 :                     *pTokRead++ = six2pr[(int)(*pMsgWrite & 077)];
     846           0 :                     pMsgWrite++;
     847           0 :                     break;
     848             :                 }
     849             :             }
     850           0 :             else if ((pTokRead - pTokBuffer) == 72)
     851             :             {
     852             :                 // Maximum line length. Append <CR><LF>.
     853           0 :                 *pTokRead++ = '\r';
     854           0 :                 *pTokRead++ = '\n';
     855             :             }
     856             :             else
     857             :             {
     858           0 :                 if ((pTokRead - pTokWrite) > 0)
     859             :                 {
     860             :                     // Bytes still in token buffer.
     861           0 :                     *pWBuf++ = *pTokWrite++;
     862             :                 }
     863             :                 else
     864             :                 {
     865             :                     // Token buffer empty. Reset to <Begin-of-Buffer>.
     866           0 :                     pTokRead = pTokWrite = pTokBuffer;
     867             :                 }
     868             :             }
     869             :         }
     870             :         else
     871             :         {
     872             :             // Message buffer empty. Reset to <Begin-of-Buffer>.
     873           0 :             pMsgRead = pMsgWrite = pMsgBuffer;
     874             : 
     875             :             // Read next message block.
     876           0 :             sal_uIntPtr nRead = pMsgStrm->Read(pMsgBuffer, nMsgBufSiz);
     877           0 :             if (nRead > 0)
     878             :             {
     879             :                 // Set read pointer.
     880           0 :                 pMsgRead = (pMsgBuffer + nRead);
     881             :             }
     882             :             else
     883             :             {
     884             :                 // Nothing more to read.
     885           0 :                 if (!bDone)
     886             :                 {
     887             :                     // Append pad character(s) and final <CR><LF>.
     888           0 :                     switch ((pTokRead - pTokBuffer) % 4)
     889             :                     {
     890             :                     case 2:
     891           0 :                         *pTokRead++ = '=';
     892             :                         // Fall through for 2nd pad character.
     893             :                     case 3:
     894           0 :                         *pTokRead++ = '=';
     895           0 :                         break;
     896             : 
     897             :                     default:
     898           0 :                         break;
     899             :                     }
     900           0 :                     *pTokRead++ = '\r';
     901           0 :                     *pTokRead++ = '\n';
     902             : 
     903             :                     // Mark we're done.
     904           0 :                     bDone = true;
     905             :                 }
     906             :                 else
     907             :                 {
     908             :                     // Already done all encoding.
     909           0 :                     if ((pTokRead - pTokWrite) > 0)
     910             :                     {
     911             :                         // Bytes still in token buffer.
     912           0 :                         *pWBuf++ = *pTokWrite++;
     913             :                     }
     914             :                     else
     915             :                     {
     916             :                         // Token buffer empty. Reset to <Begin-of-Buffer>.
     917           0 :                         pTokRead = pTokWrite = pTokBuffer;
     918             : 
     919             :                         // Reset done flag, if everything has been done.
     920             :                         // if (pWBuf == pData) bDone = false;
     921             : 
     922             :                         // Return.
     923           0 :                         return (pWBuf - pData);
     924             :                     }
     925             :                 }
     926             :             }
     927             :         }
     928             :     } // while (pWBuf < (pData + nSize))
     929           0 :     return (pWBuf - pData);
     930             : }
     931             : 
     932             : // INetMessageDecode64Stream_Impl
     933             : 
     934             : static const sal_uInt8 pr2six[256] = {
     935             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     936             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     937             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     938             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     939             : 
     940             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     941             :     0x40, 0x40, 0x40, 0x3E, 0x40, 0x40, 0x40, 0x3F,
     942             :     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
     943             :     0x3C, 0x3D, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     944             : 
     945             :     0x40, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
     946             :     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
     947             :     0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
     948             :     0x17, 0x18, 0x19, 0x40, 0x40, 0x40, 0x40, 0x40,
     949             : 
     950             :     0x40, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
     951             :     0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
     952             :     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
     953             :     0x31, 0x32, 0x33, 0x40, 0x40, 0x40, 0x40, 0x40,
     954             : 
     955             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     956             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     957             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     958             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     959             : 
     960             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     961             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     962             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     963             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     964             : 
     965             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     966             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     967             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     968             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     969             : 
     970             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     971             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     972             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
     973             :     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
     974             : };
     975             : 
     976           0 : INetMessageDecode64Stream_Impl::INetMessageDecode64Stream_Impl(
     977             :     sal_uIntPtr nMsgBufferSize)
     978             :     : INetMessageOStream(),
     979             :       eState     (INETMSG_EOL_SCR),
     980           0 :       nMsgBufSiz (nMsgBufferSize)
     981             : {
     982           0 :     ParseHeader(false);
     983             : 
     984           0 :     pMsgBuffer = new sal_Char[nMsgBufSiz];
     985           0 :     pMsgRead = pMsgWrite = pMsgBuffer;
     986           0 : }
     987             : 
     988           0 : INetMessageDecode64Stream_Impl::~INetMessageDecode64Stream_Impl(void)
     989             : {
     990           0 :     delete [] pMsgBuffer;
     991           0 : }
     992             : 
     993           0 : int INetMessageDecode64Stream_Impl::PutMsgLine(const sal_Char* pData,
     994             :                                                sal_uIntPtr nSize)
     995             : {
     996           0 :     INetMessage* pMsg = GetTargetMessage();
     997           0 :     if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
     998             : 
     999           0 :     SvOpenLockBytes* pLB = PTR_CAST(SvOpenLockBytes, pMsg->GetDocumentLB());
    1000           0 :     if (pLB == NULL) return INETSTREAM_STATUS_WOULDBLOCK;
    1001             : 
    1002           0 :     const sal_Char* pStop = (pData + nSize);
    1003           0 :     while (pData < pStop)
    1004             :     {
    1005           0 :         if (pr2six[(int)(*pData)] > 63)
    1006             :         {
    1007             :             /*
    1008             :              * Character not in base64 alphabet.
    1009             :              * Check for <End-of-Stream> or Junk.
    1010             :              */
    1011           0 :             if (*pData == '=')
    1012             :             {
    1013             :                 // Final pad character -> Done.
    1014           0 :                 sal_Size nDocSiz = pMsg->GetDocumentSize();
    1015           0 :                 sal_Size nRead   = pMsgWrite - pMsgBuffer;
    1016           0 :                 sal_Size nWrite  = 0;
    1017             : 
    1018           0 :                 pLB->FillAppend(pMsgBuffer, nRead, &nWrite);
    1019           0 :                 pMsg->SetDocumentSize(nDocSiz + nWrite);
    1020             : 
    1021           0 :                 if (nWrite < nRead)
    1022           0 :                     return INETSTREAM_STATUS_ERROR;
    1023             :                 else
    1024           0 :                     return INETSTREAM_STATUS_LOADED;
    1025             :             }
    1026           0 :             else if (eState == INETMSG_EOL_FCR)
    1027             :             {
    1028             :                 // Skip any line break character.
    1029           0 :                 if ((*pData == '\r') || (*pData == '\n')) pData++;
    1030             : 
    1031             :                 // Store decoded message buffer contents.
    1032           0 :                 sal_Size nDocSiz = pMsg->GetDocumentSize();
    1033           0 :                 sal_Size nRead   = pMsgWrite - pMsgBuffer;
    1034           0 :                 sal_Size nWrite  = 0;
    1035             : 
    1036           0 :                 pLB->FillAppend(pMsgBuffer, nRead, &nWrite);
    1037           0 :                 pMsg->SetDocumentSize(nDocSiz + nWrite);
    1038             : 
    1039           0 :                 if (nWrite < nRead) return INETSTREAM_STATUS_ERROR;
    1040             : 
    1041             :                 // Reset to <Begin-of-Buffer>.
    1042           0 :                 pMsgWrite = pMsgBuffer;
    1043           0 :                 eState = INETMSG_EOL_SCR;
    1044             :             }
    1045           0 :             else if ((*pData == '\r') || (*pData == '\n'))
    1046             :             {
    1047             :                 // Skip any line break character.
    1048           0 :                 pData++;
    1049           0 :                 eState = INETMSG_EOL_FCR;
    1050             :             }
    1051             :             else
    1052             :             {
    1053             :                 // Skip any junk character (may be transmission error).
    1054           0 :                 pData++;
    1055             :             }
    1056             :         }
    1057             :         else
    1058             :         {
    1059             :             // Decode any other character into message buffer.
    1060           0 :             switch ((pMsgRead - pMsgBuffer) % 4)
    1061             :             {
    1062             :             case 0:
    1063           0 :                 *pMsgWrite    = (pr2six[(int)(*pData++)] << 2);
    1064           0 :                 pMsgRead++;
    1065           0 :                 break;
    1066             : 
    1067             :             case 1:
    1068           0 :                 *pMsgWrite++ |= (pr2six[(int)(*pData  )] >> 4);
    1069           0 :                 *pMsgWrite    = (pr2six[(int)(*pData++)] << 4);
    1070           0 :                 pMsgRead++;
    1071           0 :                 break;
    1072             : 
    1073             :             case 2:
    1074           0 :                 *pMsgWrite++ |= (pr2six[(int)(*pData  )] >> 2);
    1075           0 :                 *pMsgWrite    = (pr2six[(int)(*pData++)] << 6);
    1076           0 :                 pMsgRead++;
    1077           0 :                 break;
    1078             : 
    1079             :             default: // == case 3
    1080           0 :                 *pMsgWrite++ |= (pr2six[(int)(*pData++)]);
    1081           0 :                 pMsgRead = pMsgBuffer;
    1082           0 :                 break;
    1083             :             } // switch ((pMsgRead - pMsgBuffer) % 4)
    1084             :         }
    1085             :     } // while (pData < pStop)
    1086           0 :     return INETSTREAM_STATUS_OK;
    1087             : }
    1088             : 
    1089             : // INetMIMEMessageStream
    1090             : 
    1091           0 : INetMIMEMessageStream::INetMIMEMessageStream(sal_uIntPtr nBufferSize)
    1092             :     : INetMessageIOStream(nBufferSize),
    1093             :       eState      (INETMSG_EOL_BEGIN),
    1094             :       nChildIndex (0),
    1095             :       pChildStrm  (NULL),
    1096             :       eEncoding   (INETMSG_ENCODING_BINARY),
    1097             :       pEncodeStrm (NULL),
    1098             :       pDecodeStrm (NULL),
    1099           0 :       pMsgBuffer  (NULL)
    1100             : {
    1101           0 : }
    1102             : 
    1103           0 : INetMIMEMessageStream::~INetMIMEMessageStream(void)
    1104             : {
    1105           0 :     delete pChildStrm;
    1106           0 :     delete pEncodeStrm;
    1107           0 :     delete pDecodeStrm;
    1108           0 :     delete pMsgBuffer;
    1109           0 : }
    1110             : 
    1111             : INetMessageEncoding
    1112           0 : INetMIMEMessageStream::GetMsgEncoding(const OUString& rContentType)
    1113             : {
    1114           0 :     if (rContentType.startsWithIgnoreAsciiCase("message") ||
    1115           0 :         rContentType.startsWithIgnoreAsciiCase("multipart"))
    1116             :     {
    1117           0 :         return INETMSG_ENCODING_7BIT;
    1118             :     }
    1119           0 :     if (rContentType.startsWithIgnoreAsciiCase("text"))
    1120             :     {
    1121           0 :         if (rContentType.startsWithIgnoreAsciiCase("text/plain"))
    1122             :         {
    1123           0 :             if (comphelper::string::getTokenCount(rContentType, '=') > 1)
    1124             :             {
    1125           0 :                 OUString aCharset(rContentType.getToken(1, '='));
    1126           0 :                 aCharset = comphelper::string::stripStart(aCharset, ' ');
    1127           0 :                 aCharset = comphelper::string::stripStart(aCharset, '"');
    1128             : 
    1129           0 :                 if (aCharset.startsWithIgnoreAsciiCase("us-ascii"))
    1130           0 :                     return INETMSG_ENCODING_7BIT;
    1131             :                 else
    1132           0 :                     return INETMSG_ENCODING_QUOTED;
    1133             :             }
    1134             :             else
    1135           0 :                 return INETMSG_ENCODING_7BIT;
    1136             :         }
    1137             :         else
    1138           0 :             return INETMSG_ENCODING_QUOTED;
    1139             :     }
    1140             : 
    1141           0 :     return INETMSG_ENCODING_BASE64;
    1142             : }
    1143             : 
    1144             : /// Message Generator
    1145           0 : int INetMIMEMessageStream::GetMsgLine(sal_Char* pData, sal_uIntPtr nSize)
    1146             : {
    1147             :     // Check for message container.
    1148           0 :     INetMIMEMessage* pMsg = GetSourceMessage();
    1149           0 :     if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
    1150             : 
    1151             :     // Check for header or body.
    1152           0 :     if (!IsHeaderGenerated())
    1153             :     {
    1154           0 :         if (eState == INETMSG_EOL_BEGIN)
    1155             :         {
    1156             :             // Prepare special header fields.
    1157           0 :             if (pMsg->GetParent())
    1158             :             {
    1159           0 :                 OUString aPCT(pMsg->GetParent()->GetContentType());
    1160           0 :                 if (aPCT.startsWithIgnoreAsciiCase("message/rfc822"))
    1161           0 :                     pMsg->SetMIMEVersion("1.0");
    1162             :                 else
    1163           0 :                     pMsg->SetMIMEVersion(OUString());
    1164             :             }
    1165             :             else
    1166             :             {
    1167           0 :                 pMsg->SetMIMEVersion("1.0");
    1168             :             }
    1169             : 
    1170             :             // Check ContentType.
    1171           0 :             OUString aContentType(pMsg->GetContentType());
    1172           0 :             if (!aContentType.isEmpty())
    1173             :             {
    1174             :                 // Determine default Content-Type.
    1175           0 :                 OUString aDefaultType = pMsg->GetDefaultContentType();
    1176             : 
    1177           0 :                 if (aDefaultType.equalsIgnoreAsciiCase(aContentType))
    1178             :                 {
    1179             :                     // No need to specify default.
    1180           0 :                     pMsg->SetContentType(OUString());
    1181           0 :                 }
    1182             :             }
    1183             : 
    1184             :             // Check Encoding.
    1185           0 :             OUString aEncoding(pMsg->GetContentTransferEncoding());
    1186           0 :             if (!aEncoding.isEmpty())
    1187             :             {
    1188             :                 // Use given Encoding.
    1189           0 :                 if (aEncoding.startsWithIgnoreAsciiCase("base64"))
    1190             :                 {
    1191           0 :                     eEncoding = INETMSG_ENCODING_BASE64;
    1192             :                 }
    1193           0 :                 else if (aEncoding.startsWithIgnoreAsciiCase("quoted-printable"))
    1194             :                 {
    1195           0 :                     eEncoding = INETMSG_ENCODING_QUOTED;
    1196             :                 }
    1197             :                 else
    1198             :                 {
    1199           0 :                     eEncoding = INETMSG_ENCODING_7BIT;
    1200             :                 }
    1201             :             }
    1202             :             else
    1203             :             {
    1204             :                 // Use default Encoding for (given|default) Content-Type.
    1205           0 :                 if (aContentType.isEmpty())
    1206             :                 {
    1207             :                     // Determine default Content-Type.
    1208           0 :                     aContentType = pMsg->GetDefaultContentType();
    1209             :                 }
    1210           0 :                 eEncoding = GetMsgEncoding(aContentType);
    1211             :             }
    1212             : 
    1213             :             // Set Content-Transfer-Encoding header.
    1214           0 :             if (eEncoding == INETMSG_ENCODING_BASE64)
    1215             :             {
    1216             :                 // Base64.
    1217           0 :                 pMsg->SetContentTransferEncoding("base64");
    1218             :             }
    1219           0 :             else if (eEncoding == INETMSG_ENCODING_QUOTED)
    1220             :             {
    1221             :                 // Quoted-Printable.
    1222           0 :                 pMsg->SetContentTransferEncoding("quoted-printable");
    1223             :             }
    1224             :             else
    1225             :             {
    1226             :                 // No need to specify default.
    1227           0 :                 pMsg->SetContentTransferEncoding(OUString());
    1228             :             }
    1229             : 
    1230             :             // Mark we're done.
    1231           0 :             eState = INETMSG_EOL_DONE;
    1232             :         }
    1233             : 
    1234             :         // Generate the message header.
    1235           0 :         int nRead = INetMessageIOStream::GetMsgLine(pData, nSize);
    1236           0 :         if (nRead <= 0)
    1237             :         {
    1238             :             // Reset state.
    1239           0 :             eState = INETMSG_EOL_BEGIN;
    1240             :         }
    1241           0 :         return nRead;
    1242             :     }
    1243             :     else
    1244             :     {
    1245             :         // Generate the message body.
    1246           0 :         if (pMsg->IsContainer())
    1247             :         {
    1248             :             // Encapsulated message body.
    1249           0 :             while (eState == INETMSG_EOL_BEGIN)
    1250             :             {
    1251           0 :                 if (pChildStrm == NULL)
    1252             :                 {
    1253           0 :                     INetMIMEMessage *pChild = pMsg->GetChild(nChildIndex);
    1254           0 :                     if (pChild)
    1255             :                     {
    1256             :                         // Increment child index.
    1257           0 :                         nChildIndex++;
    1258             : 
    1259             :                         // Create child stream.
    1260           0 :                         pChildStrm = new INetMIMEMessageStream;
    1261           0 :                         pChildStrm->SetSourceMessage(pChild);
    1262             : 
    1263           0 :                         if (pMsg->IsMultipart())
    1264             :                         {
    1265             :                             // Insert multipart delimiter.
    1266           0 :                             OStringBuffer aDelim("--");
    1267           0 :                             aDelim.append(pMsg->GetMultipartBoundary());
    1268           0 :                             aDelim.append("\r\n");
    1269             : 
    1270           0 :                             memcpy(pData, aDelim.getStr(),
    1271           0 :                                 aDelim.getLength());
    1272           0 :                             return aDelim.getLength();
    1273             :                         }
    1274             :                     }
    1275             :                     else
    1276             :                     {
    1277             :                         // No more parts. Mark we're done.
    1278           0 :                         eState = INETMSG_EOL_DONE;
    1279           0 :                         nChildIndex = 0;
    1280             : 
    1281           0 :                         if (pMsg->IsMultipart())
    1282             :                         {
    1283             :                             // Insert close delimiter.
    1284           0 :                             OStringBuffer aDelim("--");
    1285           0 :                             aDelim.append(pMsg->GetMultipartBoundary());
    1286           0 :                             aDelim.append("--\r\n");
    1287             : 
    1288           0 :                             memcpy(pData, aDelim.getStr(),
    1289           0 :                                 aDelim.getLength());
    1290           0 :                             return aDelim.getLength();
    1291             :                         }
    1292             :                     }
    1293             :                 }
    1294             :                 else
    1295             :                 {
    1296             :                     // Read current child stream.
    1297           0 :                     int nRead = pChildStrm->Read(pData, nSize);
    1298           0 :                     if (nRead > 0)
    1299             :                     {
    1300           0 :                         return nRead;
    1301             :                     }
    1302             :                     else
    1303             :                     {
    1304             :                         // Cleanup exhausted child stream.
    1305           0 :                         delete pChildStrm;
    1306           0 :                         pChildStrm = NULL;
    1307             :                     }
    1308             :                 }
    1309             :             }
    1310           0 :             return 0;
    1311             :         }
    1312             :         else
    1313             :         {
    1314             :             // Single part message body.
    1315           0 :             if (pMsg->GetDocumentLB() == NULL)
    1316             :             {
    1317             :                 // Empty message body.
    1318           0 :                 return 0;
    1319             :             }
    1320             : 
    1321             :             // Check whether message body needs to be encoded.
    1322           0 :             if (eEncoding == INETMSG_ENCODING_7BIT)
    1323             :             {
    1324             :                 // No Encoding.
    1325           0 :                 return INetMessageIOStream::GetMsgLine(pData, nSize);
    1326             :             }
    1327             : 
    1328             :             // Apply appropriate Encoding.
    1329           0 :             while (eState == INETMSG_EOL_BEGIN)
    1330             :             {
    1331           0 :                 if (pEncodeStrm == NULL)
    1332             :                 {
    1333             :                     // Create encoder stream.
    1334           0 :                     if (eEncoding == INETMSG_ENCODING_QUOTED)
    1335             :                     {
    1336             :                         // Quoted-Printable Encoding.
    1337           0 :                         pEncodeStrm = new INetMessageEncodeQPStream_Impl;
    1338             :                     }
    1339             :                     else
    1340             :                     {
    1341             :                         // Base64 Encoding.
    1342           0 :                         pEncodeStrm = new INetMessageEncode64Stream_Impl;
    1343             :                     }
    1344           0 :                     pEncodeStrm->SetSourceMessage(pMsg);
    1345             :                 }
    1346             : 
    1347             :                 // Read encoded message.
    1348           0 :                 int nRead = pEncodeStrm->Read(pData, nSize);
    1349           0 :                 if (nRead > 0)
    1350             :                 {
    1351           0 :                     return nRead;
    1352             :                 }
    1353             :                 else
    1354             :                 {
    1355             :                     // Cleanup exhausted encoder stream.
    1356           0 :                     delete pEncodeStrm;
    1357           0 :                     pEncodeStrm = NULL;
    1358             : 
    1359             :                     // Mark we're done.
    1360           0 :                     eState = INETMSG_EOL_DONE;
    1361             :                 }
    1362             :             }
    1363           0 :             return 0;
    1364             :         }
    1365             :     }
    1366             : }
    1367             : 
    1368             : /// Message Parser
    1369           0 : int INetMIMEMessageStream::PutMsgLine(const sal_Char* pData, sal_uIntPtr nSize)
    1370             : {
    1371             :     // Check for message container.
    1372           0 :     INetMIMEMessage* pMsg = GetTargetMessage();
    1373           0 :     if (pMsg == NULL) return INETSTREAM_STATUS_ERROR;
    1374             : 
    1375             :     // Check for header or body.
    1376           0 :     if (!IsHeaderParsed())
    1377             :     {
    1378             :         // Parse the message header.
    1379           0 :         int nRet = INetMessageIOStream::PutMsgLine(pData, nSize);
    1380           0 :         return nRet;
    1381             :     }
    1382             :     else
    1383             :     {
    1384           0 :         pMsg->SetHeaderParsed();
    1385             :         // Parse the message body.
    1386           0 :         if (pMsg->IsContainer())
    1387             :         {
    1388             : 
    1389             :             // Content-Transfer-Encoding MUST be "7bit" (RFC1521).
    1390           0 :             if (pMsg->IsMessage())
    1391             :             {
    1392           0 :                 if( !pChildStrm )
    1393             :                 {
    1394             :                     // Encapsulated message.
    1395           0 :                     INetMIMEMessage* pNewMessage = new INetMIMEMessage;
    1396           0 :                     pNewMessage->SetDocumentLB( new SvAsyncLockBytes(new SvMemoryStream(), false));
    1397           0 :                     pMsg->AttachChild( *pNewMessage, true );
    1398             : 
    1399             :                     // Encapsulated message body. Create message parser stream.
    1400           0 :                     pChildStrm = new INetMIMEMessageStream;
    1401           0 :                     pChildStrm->SetTargetMessage( pNewMessage );
    1402             : 
    1403             :                     // Initialize control variables.
    1404           0 :                     eState = INETMSG_EOL_BEGIN;
    1405             :                 }
    1406           0 :                 if ( nSize > 0)
    1407             :                 {
    1408             :                     // Bytes still in buffer. Put message down-stream.
    1409           0 :                     int status = pChildStrm->Write( pData, nSize );
    1410           0 :                     if (status != INETSTREAM_STATUS_OK)
    1411           0 :                         return status;
    1412             :                 }
    1413             : 
    1414           0 :                 return INetMessageIOStream::PutMsgLine(pData, nSize);
    1415             :             }
    1416             :             else
    1417             :             {
    1418             : 
    1419             :                 // Multipart message body. Initialize multipart delimiters.
    1420             :                 // Multipart message.
    1421           0 :                 if (pMsg->GetMultipartBoundary().getLength() == 0)
    1422             :                 {
    1423             :                     // Determine boundary.
    1424             :                     OString aType(OUStringToOString(
    1425           0 :                         pMsg->GetContentType(), RTL_TEXTENCODING_ASCII_US));
    1426           0 :                     OString aLowerType(aType.toAsciiLowerCase());
    1427             : 
    1428           0 :                     sal_Int32 nPos = aLowerType.indexOf("boundary=");
    1429           0 :                     OString aBoundary(aType.copy(nPos + 9));
    1430             : 
    1431           0 :                     aBoundary = comphelper::string::strip(aBoundary, ' ');
    1432           0 :                     aBoundary = comphelper::string::strip(aBoundary, '"');
    1433             : 
    1434             :                     // Save boundary.
    1435           0 :                     pMsg->SetMultipartBoundary(aBoundary);
    1436             :                 }
    1437             : 
    1438           0 :                 OString aPlainDelim(pMsg->GetMultipartBoundary());
    1439             :                 OString aDelim = OStringBuffer("--").
    1440           0 :                     append(aPlainDelim).
    1441           0 :                     makeStringAndClear();
    1442             :                 OString aPlainClose = OStringBuffer(
    1443             :                     aPlainDelim).
    1444           0 :                     append("--").
    1445           0 :                     makeStringAndClear();
    1446             :                 OString aClose = OStringBuffer(
    1447             :                     aDelim).
    1448           0 :                     append("--").
    1449           0 :                     makeStringAndClear();
    1450             : 
    1451           0 :                 if (pMsgBuffer == NULL) pMsgBuffer = new SvMemoryStream;
    1452           0 :                 pMsgBuffer->Write(pData, nSize);
    1453           0 :                 sal_uIntPtr nBufSize = pMsgBuffer->Tell();
    1454             : 
    1455             :                 const sal_Char* pChar;
    1456             :                 const sal_Char* pOldPos;
    1457             :                 int status;
    1458           0 :                 for( pOldPos = pChar = (const sal_Char*) pMsgBuffer->GetData(); nBufSize--;
    1459             :                      pChar++ )
    1460             :                 {
    1461           0 :                     if( *pChar == '\r' || *pChar == '\n' )
    1462             :                     {
    1463           0 :                         if( aDelim.compareTo(pOldPos, aDelim.getLength())
    1464           0 :                             != -1 &&
    1465           0 :                             aClose.compareTo(pOldPos, aClose.getLength())
    1466           0 :                             != -1 &&
    1467           0 :                             aPlainDelim.compareTo(pOldPos, aPlainDelim.getLength())
    1468           0 :                             != -1 &&
    1469           0 :                             aPlainClose.compareTo(pOldPos, aPlainClose.getLength())
    1470             :                             != -1 )
    1471             :                         {
    1472           0 :                             if( nBufSize &&
    1473           0 :                                 ( pChar[1] == '\r' || pChar[1] == '\n' ) )
    1474           0 :                                 nBufSize--, pChar++;
    1475           0 :                             if( pChildStrm )
    1476             :                             {
    1477             :                                 status = pChildStrm->Write(
    1478           0 :                                     pOldPos, pChar - pOldPos + 1 );
    1479           0 :                                 if( status != INETSTREAM_STATUS_OK )
    1480           0 :                                     return status;
    1481             :                             }
    1482             :                             else {
    1483             :                                 SAL_WARN( "tools.stream", "Boundary not found." );
    1484             :                             }
    1485             :                             status = INetMessageIOStream::PutMsgLine(
    1486           0 :                                 pOldPos, pChar - pOldPos + 1 );
    1487           0 :                             if( status != INETSTREAM_STATUS_OK )
    1488           0 :                                 return status;
    1489           0 :                             pOldPos = pChar + 1;
    1490             :                         }
    1491             :                         else
    1492             :                         {
    1493           0 :                             if( nBufSize &&
    1494           0 :                                 ( pChar[1] == '\r' || pChar[1] == '\n' ) )
    1495           0 :                                 nBufSize--, pChar++;
    1496           0 :                             pOldPos = pChar + 1;
    1497           0 :                             DELETEZ( pChildStrm );
    1498             : 
    1499           0 :                             if (aClose.compareTo(pOldPos, aClose.getLength())
    1500           0 :                                 != -1 &&
    1501           0 :                                 aPlainClose.compareTo(pOldPos, aClose.getLength())
    1502             :                                 != -1 )
    1503             :                             {
    1504             :                                 // Encapsulated message.
    1505             :                                 INetMIMEMessage* pNewMessage =
    1506           0 :                                     new INetMIMEMessage;
    1507             :                                 pNewMessage->SetDocumentLB(
    1508             :                                     new SvAsyncLockBytes(
    1509           0 :                                         new SvMemoryStream(), false));
    1510             : 
    1511           0 :                                 pMsg->AttachChild( *pNewMessage, true );
    1512             : 
    1513             :                                 // Encapsulated message body. Create message parser stream.
    1514           0 :                                 pChildStrm = new INetMIMEMessageStream;
    1515           0 :                                 pChildStrm->SetTargetMessage( pNewMessage );
    1516             : 
    1517             :                                 // Initialize control variables.
    1518             :                             }
    1519           0 :                             eState = INETMSG_EOL_BEGIN;
    1520             :                             status = INetMessageIOStream::PutMsgLine(
    1521           0 :                                 pOldPos, pChar - pOldPos + 1 );
    1522           0 :                             if( status != INETSTREAM_STATUS_OK )
    1523           0 :                                 return status;
    1524             :                         }
    1525             :                     }
    1526             :                 }
    1527           0 :                 if( pOldPos < pChar )
    1528             :                 {
    1529           0 :                     SvMemoryStream* pNewStream = new SvMemoryStream;
    1530           0 :                     pNewStream->Write( pOldPos, pChar - pOldPos );
    1531           0 :                     SvMemoryStream* pTmp = pMsgBuffer;
    1532           0 :                     pMsgBuffer = pNewStream;
    1533           0 :                     delete pTmp;
    1534             :                 }
    1535             :                 else
    1536             :                 {
    1537           0 :                     pMsgBuffer->Seek( 0L );
    1538           0 :                     pMsgBuffer->SetStreamSize( 0 );
    1539             :                 }
    1540           0 :                 return INETSTREAM_STATUS_OK;
    1541             :             }
    1542             :         }
    1543             :         else
    1544             :         {
    1545             :             /*
    1546             :              * Single part message.
    1547             :              * Remove any ContentTransferEncoding.
    1548             :              */
    1549           0 :             if (pMsg->GetContentType().isEmpty())
    1550             :             {
    1551           0 :                 pMsg->SetContentType(pMsg->GetDefaultContentType());
    1552             :             }
    1553             : 
    1554           0 :             if (eEncoding == INETMSG_ENCODING_BINARY)
    1555             :             {
    1556           0 :                 OUString aEncoding(pMsg->GetContentTransferEncoding());
    1557           0 :                 if (aEncoding.startsWithIgnoreAsciiCase("base64"))
    1558             :                 {
    1559           0 :                     eEncoding = INETMSG_ENCODING_BASE64;
    1560             :                 }
    1561           0 :                 else if (aEncoding.startsWithIgnoreAsciiCase("quoted-printable"))
    1562             :                 {
    1563           0 :                     eEncoding = INETMSG_ENCODING_QUOTED;
    1564             :                 }
    1565             :                 else
    1566             :                 {
    1567           0 :                     eEncoding = INETMSG_ENCODING_7BIT;
    1568           0 :                 }
    1569             :             }
    1570             : 
    1571           0 :             if (eEncoding == INETMSG_ENCODING_7BIT)
    1572             :             {
    1573             :                 // No decoding necessary.
    1574           0 :                 return INetMessageIOStream::PutMsgLine(pData, nSize);
    1575             :             }
    1576             :             else
    1577             :             {
    1578           0 :                 if (pDecodeStrm == NULL)
    1579             :                 {
    1580           0 :                     if (eEncoding == INETMSG_ENCODING_QUOTED)
    1581             :                     {
    1582           0 :                         pDecodeStrm = new INetMessageDecodeQPStream_Impl;
    1583             :                     }
    1584             :                     else
    1585             :                     {
    1586           0 :                         pDecodeStrm = new INetMessageDecode64Stream_Impl;
    1587             :                     }
    1588           0 :                     pDecodeStrm->SetTargetMessage(pMsg);
    1589             :                 }
    1590           0 :                 return pDecodeStrm->Write(pData, nSize);
    1591             :             }
    1592             :         }
    1593             :     }
    1594             : }
    1595             : 
    1596             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10