tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / tools / source / inet / inetstrm.cxx
blob2feaad7f1167ff7772302bdfa27acbd8e8ece9ab
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <cassert>
24 #include <sal/types.h>
25 #include <tools/inetmsg.hxx>
26 #include <tools/inetstrm.hxx>
28 int INetMIMEMessageStream::GetHeaderLine(char* pData, sal_uInt32 nSize)
30 char* pWBuf = pData;
32 sal_uInt32 i, n;
34 if (maMsgBuffer.Tell() == 0)
36 // Insert formatted header into buffer.
37 n = pSourceMsg->GetHeaderCount();
38 for (i = 0; i < n; i++)
40 INetMessageHeader aHeader (pSourceMsg->GetHeaderField(i));
41 if (aHeader.GetValue().getLength())
43 // NYI: Folding long lines.
44 maMsgBuffer.WriteOString( aHeader.GetName() );
45 maMsgBuffer.WriteOString( ": " );
46 maMsgBuffer.WriteOString( aHeader.GetValue() );
47 maMsgBuffer.WriteOString( "\r\n" );
51 pMsgWrite = const_cast<char *>(static_cast<char const *>(maMsgBuffer.GetData()));
52 pMsgRead = pMsgWrite + maMsgBuffer.Tell();
55 n = pMsgRead - pMsgWrite;
56 if (n > 0)
58 // Move to caller.
59 if (nSize < n) n = nSize;
60 for (i = 0; i < n; i++) *pWBuf++ = *pMsgWrite++;
62 else
64 // Reset buffer.
65 maMsgBuffer.Seek(STREAM_SEEK_TO_BEGIN);
68 return (pWBuf - pData);
71 int INetMIMEMessageStream::GetBodyLine(char* pData, sal_uInt32 nSize)
73 char* pWBuf = pData;
74 char* pWEnd = pData + nSize;
76 if (pSourceMsg->GetDocumentLB())
78 sal_uInt32 nRead = pSourceMsg->GetDocumentLB()->ReadBytes(pWBuf, (pWEnd - pWBuf));
79 pWBuf += nRead;
82 return (pWBuf - pData);
85 int INetMIMEMessageStream::GetMsgLine(char* pData, sal_uInt32 nSize)
87 // Check for header or body.
88 if (!bHeaderGenerated)
90 if (!done)
92 // Prepare special header fields.
93 if (pSourceMsg->GetParent())
95 OUString aPCT(pSourceMsg->GetParent()->GetContentType());
96 if (aPCT.startsWithIgnoreAsciiCase("message/rfc822"))
97 pSourceMsg->SetMIMEVersion(u"1.0"_ustr);
98 else
99 pSourceMsg->SetMIMEVersion(OUString());
101 else
103 pSourceMsg->SetMIMEVersion(u"1.0"_ustr);
106 // Check ContentType.
107 OUString aContentType(pSourceMsg->GetContentType());
108 if (!aContentType.isEmpty())
110 // Determine default Content-Type.
111 OUString aDefaultType = pSourceMsg->GetDefaultContentType();
113 if (aDefaultType.equalsIgnoreAsciiCase(aContentType))
115 // No need to specify default.
116 pSourceMsg->SetContentType(OUString());
120 // No need to specify default.
121 pSourceMsg->SetContentTransferEncoding(OUString());
123 // Mark we're done.
124 done = true;
127 // Generate the message header.
128 int nRead = GetHeaderLine(pData, nSize);
129 if (nRead <= 0)
131 // Reset state.
132 done = false;
134 return nRead;
136 else
138 // Generate the message body.
139 if (pSourceMsg->IsContainer())
141 // Encapsulated message body.
142 while (!done)
144 if (pChildStrm == nullptr)
146 INetMIMEMessage *pChild = pSourceMsg->GetChild(nChildIndex);
147 if (pChild)
149 // Increment child index.
150 nChildIndex++;
152 // Create child stream.
153 pChildStrm.reset(new INetMIMEMessageStream(pChild, false));
155 if (pSourceMsg->IsMultipart())
157 // Insert multipart delimiter.
158 OString aDelim = "--" +
159 pSourceMsg->GetMultipartBoundary() +
160 "\r\n";
162 memcpy(pData, aDelim.getStr(),
163 aDelim.getLength());
164 return aDelim.getLength();
167 else
169 // No more parts. Mark we're done.
170 done = true;
171 nChildIndex = 0;
173 if (pSourceMsg->IsMultipart())
175 // Insert close delimiter.
176 OString aDelim = "--" +
177 pSourceMsg->GetMultipartBoundary() +
178 "--\r\n";
180 memcpy(pData, aDelim.getStr(),
181 aDelim.getLength());
182 return aDelim.getLength();
186 else
188 // Read current child stream.
189 int nRead = pChildStrm->Read(pData, nSize);
190 if (nRead > 0)
192 return nRead;
194 else
196 // Cleanup exhausted child stream.
197 pChildStrm.reset();
201 return 0;
203 else
205 // Single part message body.
206 if (pSourceMsg->GetDocumentLB() == nullptr)
208 // Empty message body.
209 return 0;
212 // No Encoding.
213 return GetBodyLine(pData, nSize);
218 namespace
221 const int BUFFER_SIZE = 2048;
225 INetMIMEMessageStream::INetMIMEMessageStream(
226 INetMIMEMessage *pMsg, bool headerGenerated):
227 pSourceMsg(pMsg),
228 bHeaderGenerated(headerGenerated),
229 mvBuffer(BUFFER_SIZE),
230 pMsgRead(nullptr),
231 pMsgWrite(nullptr),
232 done(false),
233 nChildIndex(0)
235 assert(pMsg != nullptr);
236 maMsgBuffer.SetStreamCharSet(RTL_TEXTENCODING_ASCII_US);
237 pRead = pWrite = mvBuffer.data();
240 INetMIMEMessageStream::~INetMIMEMessageStream()
242 pChildStrm.reset();
245 int INetMIMEMessageStream::Read(char* pData, sal_uInt32 nSize)
247 char* pWBuf = pData;
248 char* pWEnd = pData + nSize;
250 while (pWBuf < pWEnd)
252 // Caller's buffer not yet filled.
253 sal_uInt32 n = pRead - pWrite;
254 if (n > 0)
256 // Bytes still in buffer.
257 sal_uInt32 m = pWEnd - pWBuf;
258 if (m < n) n = m;
259 for (sal_uInt32 i = 0; i < n; i++) *pWBuf++ = *pWrite++;
261 else
263 // Buffer empty. Reset to <Begin-of-Buffer>.
264 pRead = pWrite = mvBuffer.data();
266 // Read next message line.
267 int nRead = GetMsgLine(mvBuffer.data(), mvBuffer.size());
268 if (nRead > 0)
270 // Set read pointer.
271 pRead = mvBuffer.data() + nRead;
273 else
275 if (!bHeaderGenerated)
277 // Header generated. Insert empty line.
278 bHeaderGenerated = true;
279 *pRead++ = '\r';
280 *pRead++ = '\n';
282 else
284 // Body generated.
285 return (pWBuf - pData);
290 return (pWBuf - pData);
293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */