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

Generated by: LCOV version 1.10