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