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