Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : #include <functional> // needed under Solaris when including <algorithm>...
22 : :
23 : : #include <algorithm>
24 : : #include <limits>
25 : : #include <set>
26 : : #include <rtl/alloc.h>
27 : : #include <rtl/memory.h>
28 : : #include <svl/instrm.hxx>
29 : : #include <svl/outstrm.hxx>
30 : : #include <svl/strmadpt.hxx>
31 : :
32 : : using namespace com::sun::star;
33 : :
34 : : //============================================================================
35 : : class SvDataPipe_Impl
36 : : {
37 : : public:
38 : : enum SeekResult { SEEK_BEFORE_MARKED, SEEK_OK, SEEK_PAST_END };
39 : :
40 : : private:
41 : : struct Page
42 : : {
43 : : Page * m_pPrev;
44 : : Page * m_pNext;
45 : : sal_Int8 * m_pStart;
46 : : sal_Int8 * m_pRead;
47 : : sal_Int8 * m_pEnd;
48 : : sal_uInt32 m_nOffset;
49 : : sal_Int8 m_aBuffer[1];
50 : : };
51 : :
52 : : std::multiset< sal_uInt32 > m_aMarks;
53 : : Page * m_pFirstPage;
54 : : Page * m_pReadPage;
55 : : Page * m_pWritePage;
56 : : sal_Int8 * m_pReadBuffer;
57 : : sal_uInt32 m_nReadBufferSize;
58 : : sal_uInt32 m_nReadBufferFilled;
59 : : sal_uInt32 m_nPageSize;
60 : : sal_uInt32 m_nMinPages;
61 : : sal_uInt32 m_nMaxPages;
62 : : sal_uInt32 m_nPages;
63 : : bool m_bEOF;
64 : :
65 : : bool remove(Page * pPage);
66 : :
67 : : public:
68 : : inline SvDataPipe_Impl(sal_uInt32 nThePageSize = 1000,
69 : : sal_uInt32 nTheMinPages = 100,
70 : : sal_uInt32 nTheMaxPages
71 : : = std::numeric_limits< sal_uInt32 >::max());
72 : :
73 : : ~SvDataPipe_Impl();
74 : :
75 : : inline void setReadBuffer(sal_Int8 * pBuffer, sal_uInt32 nSize);
76 : :
77 : : sal_uInt32 read();
78 : :
79 : 0 : void clearReadBuffer() { m_pReadBuffer = 0; }
80 : :
81 : : sal_uInt32 write(sal_Int8 const * pBuffer, sal_uInt32 nSize);
82 : :
83 : 0 : void setEOF() { m_bEOF = true; }
84 : :
85 : : inline bool isEOF() const;
86 : :
87 : : bool addMark(sal_uInt32 nPosition);
88 : : bool removeMark(sal_uInt32 nPosition);
89 : :
90 : : inline sal_uInt32 getReadPosition() const;
91 : :
92 : : SeekResult setReadPosition(sal_uInt32 nPosition);
93 : : };
94 : :
95 : 0 : SvDataPipe_Impl::SvDataPipe_Impl(sal_uInt32 nThePageSize,
96 : : sal_uInt32 nTheMinPages,
97 : : sal_uInt32 nTheMaxPages):
98 : : m_pFirstPage(0),
99 : : m_pReadPage(0),
100 : : m_pWritePage(0),
101 : : m_pReadBuffer(0),
102 : : m_nPageSize(std::min< sal_uInt32 >(
103 [ # # ]: 0 : std::max< sal_uInt32 >(nThePageSize, sal_uInt32(1)),
104 : 0 : sal_uInt32(std::numeric_limits< sal_uInt32 >::max()
105 [ # # ]: 0 : - sizeof (Page) + 1))),
106 [ # # ]: 0 : m_nMinPages(std::max< sal_uInt32 >(nTheMinPages, sal_uInt32(1))),
107 [ # # ]: 0 : m_nMaxPages(std::max< sal_uInt32 >(nTheMaxPages, sal_uInt32(1))),
108 : : m_nPages(0),
109 : 0 : m_bEOF(false)
110 : 0 : {}
111 : :
112 : 0 : inline void SvDataPipe_Impl::setReadBuffer(sal_Int8 * pBuffer,
113 : : sal_uInt32 nSize)
114 : : {
115 : 0 : m_pReadBuffer = pBuffer;
116 : 0 : m_nReadBufferSize = nSize;
117 : 0 : m_nReadBufferFilled = 0;
118 : 0 : }
119 : :
120 : 0 : inline bool SvDataPipe_Impl::isEOF() const
121 : : {
122 : : return m_bEOF && m_pReadPage == m_pWritePage
123 [ # # ][ # # ]: 0 : && (!m_pReadPage || m_pReadPage->m_pRead == m_pReadPage->m_pEnd);
[ # # ][ # # ]
124 : : }
125 : :
126 : : inline sal_uInt32 SvDataPipe_Impl::getReadPosition() const
127 : : {
128 : : return m_pReadPage == 0 ? 0 :
129 : : m_pReadPage->m_nOffset
130 : : + (m_pReadPage->m_pRead
131 : : - m_pReadPage->m_aBuffer);
132 : : }
133 : :
134 : : //============================================================================
135 : : //
136 : : // SvOutputStreamOpenLockBytes
137 : : //
138 : : //============================================================================
139 : :
140 [ # # ][ # # ]: 0 : TYPEINIT1(SvOutputStreamOpenLockBytes, SvOpenLockBytes)
141 : :
142 : : //============================================================================
143 : : // virtual
144 : 0 : ErrCode SvOutputStreamOpenLockBytes::ReadAt(sal_uLong, void *, sal_uLong, sal_uLong *)
145 : : const
146 : : {
147 : 0 : return ERRCODE_IO_CANTREAD;
148 : : }
149 : :
150 : : //============================================================================
151 : : // virtual
152 : 0 : ErrCode SvOutputStreamOpenLockBytes::WriteAt(sal_uLong nPos, void const * pBuffer,
153 : : sal_uLong nCount, sal_uLong * pWritten)
154 : : {
155 [ # # ]: 0 : if (nPos != m_nPosition)
156 : 0 : return ERRCODE_IO_CANTWRITE;
157 : 0 : return FillAppend(pBuffer, nCount, pWritten);
158 : : }
159 : :
160 : : //============================================================================
161 : : // virtual
162 : 0 : ErrCode SvOutputStreamOpenLockBytes::Flush() const
163 : : {
164 [ # # ]: 0 : if (!m_xOutputStream.is())
165 : 0 : return ERRCODE_IO_CANTWRITE;
166 : : try
167 : : {
168 [ # # ][ # # ]: 0 : m_xOutputStream->flush();
169 : : }
170 : 0 : catch (const io::IOException&)
171 : : {
172 : 0 : return ERRCODE_IO_CANTWRITE;
173 : : }
174 [ # # ]: 0 : return ERRCODE_NONE;
175 : : }
176 : :
177 : : //============================================================================
178 : : // virtual
179 : 0 : ErrCode SvOutputStreamOpenLockBytes::SetSize(sal_uLong)
180 : : {
181 : 0 : return ERRCODE_IO_NOTSUPPORTED;
182 : : }
183 : :
184 : : //============================================================================
185 : : // virtual
186 : 0 : ErrCode SvOutputStreamOpenLockBytes::Stat(SvLockBytesStat * pStat,
187 : : SvLockBytesStatFlag) const
188 : : {
189 [ # # ]: 0 : if (pStat)
190 : 0 : pStat->nSize = m_nPosition;
191 : 0 : return ERRCODE_NONE;
192 : : }
193 : :
194 : : //============================================================================
195 : : // virtual
196 : 0 : ErrCode SvOutputStreamOpenLockBytes::FillAppend(void const * pBuffer,
197 : : sal_uLong nCount,
198 : : sal_uLong * pWritten)
199 : : {
200 [ # # ]: 0 : if (!m_xOutputStream.is())
201 : 0 : return ERRCODE_IO_CANTWRITE;
202 [ # # # # ]: 0 : if (nCount > 0
[ # # ]
203 : 0 : && nCount > std::numeric_limits< sal_uLong >::max() - m_nPosition)
204 : : {
205 : 0 : nCount = std::numeric_limits< sal_uLong >::max() - m_nPosition;
206 [ # # ]: 0 : if (nCount == 0)
207 : 0 : return ERRCODE_IO_CANTWRITE;
208 : : }
209 : : try
210 : : {
211 [ # # ]: 0 : m_xOutputStream->
212 : : writeBytes(uno::Sequence< sal_Int8 >(
213 [ # # ][ # # ]: 0 : static_cast< sal_Int8 const * >(pBuffer), nCount));
[ # # # # ]
214 : : }
215 : 0 : catch (const io::IOException&)
216 : : {
217 : 0 : return ERRCODE_IO_CANTWRITE;
218 : : }
219 : 0 : m_nPosition += nCount;
220 [ # # ]: 0 : if (pWritten)
221 : 0 : *pWritten = nCount;
222 : 0 : return ERRCODE_NONE;
223 : : }
224 : :
225 : : //============================================================================
226 : : // virtual
227 : 0 : sal_uLong SvOutputStreamOpenLockBytes::Tell() const
228 : : {
229 : 0 : return m_nPosition;
230 : : }
231 : :
232 : : //============================================================================
233 : : // virtual
234 : 0 : sal_uLong SvOutputStreamOpenLockBytes::Seek(sal_uLong)
235 : : {
236 : 0 : return m_nPosition;
237 : : }
238 : :
239 : : //============================================================================
240 : : // virtual
241 : 0 : void SvOutputStreamOpenLockBytes::Terminate()
242 : : {
243 [ # # ]: 0 : if (m_xOutputStream.is())
244 : : {
245 : : try
246 : : {
247 [ # # ][ # # ]: 0 : m_xOutputStream->closeOutput();
248 : : }
249 : 0 : catch (const io::IOException&)
250 : : {
251 : : }
252 : : }
253 [ # # ]: 0 : }
254 : :
255 : : //============================================================================
256 : : //
257 : : // SvLockBytesInputStream
258 : : //
259 : : //============================================================================
260 : :
261 : : // virtual
262 : 0 : uno::Any SAL_CALL SvLockBytesInputStream::queryInterface(uno::Type const &
263 : : rType)
264 : : throw (uno::RuntimeException)
265 : : {
266 : : uno::Any
267 : : aReturn(cppu::queryInterface(rType,
268 : : static_cast< io::XInputStream * >(this),
269 [ # # ]: 0 : static_cast< io::XSeekable * >(this)));
270 [ # # ][ # # ]: 0 : return aReturn.hasValue() ? aReturn : OWeakObject::queryInterface(rType);
271 : : }
272 : :
273 : : //============================================================================
274 : : // virtual
275 : 0 : void SAL_CALL SvLockBytesInputStream::acquire() throw ()
276 : : {
277 : 0 : OWeakObject::acquire();
278 : 0 : }
279 : :
280 : : //============================================================================
281 : : // virtual
282 : 0 : void SAL_CALL SvLockBytesInputStream::release() throw ()
283 : : {
284 : 0 : OWeakObject::release();
285 : 0 : }
286 : :
287 : : //============================================================================
288 : : // virtual
289 : : sal_Int32 SAL_CALL
290 : 0 : SvLockBytesInputStream::readBytes(uno::Sequence< sal_Int8 > & rData,
291 : : sal_Int32 nBytesToRead)
292 : : throw (io::IOException, uno::RuntimeException)
293 : : {
294 : : OSL_ASSERT(m_nPosition >= 0);
295 [ # # ]: 0 : if (!m_xLockBytes.Is())
296 [ # # ]: 0 : throw io::NotConnectedException();
297 [ # # ][ # # ]: 0 : if (
[ # # ]
298 : : nBytesToRead < 0 ||
299 : : (
300 : : static_cast<sal_uInt64>(m_nPosition) > SAL_MAX_SIZE &&
301 : : nBytesToRead > 0
302 : : )
303 : : )
304 : : {
305 [ # # ]: 0 : throw io::IOException();
306 : : }
307 : 0 : rData.realloc(nBytesToRead);
308 : 0 : sal_Int32 nSize = 0;
309 [ # # ]: 0 : while (nSize < nBytesToRead)
310 : : {
311 : : sal_Size nCount;
312 : 0 : ErrCode nError = m_xLockBytes->ReadAt(static_cast<sal_Size>(
313 : : m_nPosition),
314 [ # # ]: 0 : rData.getArray() + nSize,
315 [ # # ]: 0 : nBytesToRead - nSize, &nCount);
316 [ # # ][ # # ]: 0 : if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING)
317 [ # # ]: 0 : throw io::IOException();
318 : 0 : m_nPosition += nCount;
319 : 0 : nSize += nCount;
320 [ # # ][ # # ]: 0 : if (nError == ERRCODE_NONE && nCount == 0)
321 : : break;
322 : : }
323 : 0 : rData.realloc(nSize);
324 : 0 : return nSize;
325 : : }
326 : :
327 : : //============================================================================
328 : : // virtual
329 : : sal_Int32 SAL_CALL
330 : 0 : SvLockBytesInputStream::readSomeBytes(uno::Sequence< sal_Int8 > & rData,
331 : : sal_Int32 nMaxBytesToRead)
332 : : throw (io::IOException, uno::RuntimeException)
333 : : {
334 : : OSL_ASSERT(m_nPosition >= 0);
335 [ # # ]: 0 : if (!m_xLockBytes.Is())
336 [ # # ]: 0 : throw io::NotConnectedException();
337 [ # # ][ # # ]: 0 : if (static_cast<sal_uInt64>(m_nPosition) > SAL_MAX_SIZE
338 : : && nMaxBytesToRead > 0)
339 [ # # ]: 0 : throw io::IOException();
340 [ # # ]: 0 : rData.realloc(nMaxBytesToRead);
341 : 0 : sal_Size nCount = 0;
342 [ # # ]: 0 : if (nMaxBytesToRead > 0)
343 : : {
344 : : ErrCode nError;
345 [ # # ][ # # ]: 0 : do
[ # # ]
346 : : {
347 : 0 : nError = m_xLockBytes->ReadAt(static_cast<sal_Size>(m_nPosition),
348 [ # # ]: 0 : rData.getArray(),
349 : : nMaxBytesToRead < 0 ?
350 : : 0 : nMaxBytesToRead,
351 [ # # ]: 0 : &nCount);
352 [ # # ][ # # ]: 0 : if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING)
353 [ # # ]: 0 : throw io::IOException();
354 : 0 : m_nPosition += nCount;
355 : : }
356 : : while (nCount == 0 && nError == ERRCODE_IO_PENDING);
357 : : }
358 [ # # ]: 0 : rData.realloc(sal_Int32(nCount));
359 : 0 : return sal_Int32(nCount);
360 : : }
361 : :
362 : : //============================================================================
363 : : // virtual
364 : 0 : void SAL_CALL SvLockBytesInputStream::skipBytes(sal_Int32 nBytesToSkip)
365 : : throw (io::IOException, uno::RuntimeException)
366 : : {
367 [ # # ]: 0 : if (!m_xLockBytes.Is())
368 [ # # ]: 0 : throw io::NotConnectedException();
369 [ # # ]: 0 : if (nBytesToSkip < 0)
370 [ # # ]: 0 : throw io::IOException();
371 [ # # ]: 0 : if (nBytesToSkip > SAL_MAX_INT64 - m_nPosition)
372 [ # # ]: 0 : throw io::BufferSizeExceededException();
373 : 0 : m_nPosition += nBytesToSkip;
374 : 0 : }
375 : :
376 : : //============================================================================
377 : : // virtual
378 : 0 : sal_Int32 SAL_CALL SvLockBytesInputStream::available()
379 : : throw (io::IOException, uno::RuntimeException)
380 : : {
381 : : OSL_ASSERT(m_nPosition >= 0);
382 [ # # ]: 0 : if (!m_xLockBytes.Is())
383 [ # # ]: 0 : throw io::NotConnectedException();
384 : 0 : SvLockBytesStat aStat;
385 [ # # ][ # # ]: 0 : if (m_xLockBytes->Stat(&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE)
386 [ # # ]: 0 : throw io::IOException();
387 : : return aStat.nSize <= static_cast<sal_uInt64>(m_nPosition) ?
388 : : 0 :
389 : : static_cast<sal_Size>(aStat.nSize - m_nPosition) <=
390 : : static_cast<sal_uInt32>(SAL_MAX_INT32) ?
391 : : static_cast<sal_Int32>(aStat.nSize - m_nPosition) :
392 [ # # ][ # # ]: 0 : SAL_MAX_INT32;
393 : : }
394 : :
395 : : //============================================================================
396 : : // virtual
397 : 0 : void SAL_CALL SvLockBytesInputStream::closeInput()
398 : : throw (io::IOException, uno::RuntimeException)
399 : : {
400 [ # # ]: 0 : if (!m_xLockBytes.Is())
401 [ # # ]: 0 : throw io::NotConnectedException();
402 : 0 : m_xLockBytes = 0;
403 : 0 : }
404 : :
405 : : //============================================================================
406 : : // virtual
407 : 0 : void SAL_CALL SvLockBytesInputStream::seek(sal_Int64 nLocation)
408 : : throw (lang::IllegalArgumentException, io::IOException,
409 : : uno::RuntimeException)
410 : : {
411 [ # # ]: 0 : if (nLocation < 0)
412 [ # # ]: 0 : throw lang::IllegalArgumentException();
413 [ # # ]: 0 : if (!m_xLockBytes.Is())
414 [ # # ]: 0 : throw io::NotConnectedException();
415 : 0 : m_nPosition = nLocation;
416 : 0 : }
417 : :
418 : : //============================================================================
419 : : // virtual
420 : 0 : sal_Int64 SAL_CALL SvLockBytesInputStream::getPosition()
421 : : throw (io::IOException, uno::RuntimeException)
422 : : {
423 [ # # ]: 0 : if (!m_xLockBytes.Is())
424 [ # # ]: 0 : throw io::NotConnectedException();
425 : 0 : return m_nPosition;
426 : : }
427 : :
428 : : //============================================================================
429 : : // virtual
430 : 0 : sal_Int64 SAL_CALL SvLockBytesInputStream::getLength()
431 : : throw (io::IOException, uno::RuntimeException)
432 : : {
433 [ # # ]: 0 : if (!m_xLockBytes.Is())
434 [ # # ]: 0 : throw io::NotConnectedException();
435 : 0 : SvLockBytesStat aStat;
436 [ # # ][ # # ]: 0 : if (m_xLockBytes->Stat(&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE)
437 [ # # ]: 0 : throw io::IOException();
438 : : #if SAL_TYPES_SIZEOFPOINTER > 4 // avoid warnings if sal_Size < sal_Int64
439 : : if (aStat.nSize > static_cast<sal_uInt64>(SAL_MAX_INT64))
440 : : throw io::IOException();
441 : : #endif
442 : 0 : return aStat.nSize;
443 : : }
444 : :
445 : : //============================================================================
446 : : //
447 : : // SvInputStream
448 : : //
449 : : //============================================================================
450 : :
451 : 0 : bool SvInputStream::open()
452 : : {
453 [ # # ]: 0 : if (GetError() != ERRCODE_NONE)
454 : 0 : return false;
455 [ # # ][ # # ]: 0 : if (!(m_xSeekable.is() || m_pPipe))
[ # # ]
456 : : {
457 [ # # ]: 0 : if (!m_xStream.is())
458 : : {
459 : 0 : SetError(ERRCODE_IO_INVALIDDEVICE);
460 : 0 : return false;
461 : : }
462 : : m_xSeekable
463 [ # # ]: 0 : = uno::Reference< io::XSeekable >(m_xStream, uno::UNO_QUERY);
464 [ # # ]: 0 : if (!m_xSeekable.is())
465 [ # # ]: 0 : m_pPipe = new SvDataPipe_Impl;
466 : : }
467 : 0 : return true;
468 : : }
469 : :
470 : : //============================================================================
471 : : // virtual
472 : 0 : sal_uLong SvInputStream::GetData(void * pData, sal_uLong nSize)
473 : : {
474 [ # # ]: 0 : if (!open())
475 : : {
476 : 0 : SetError(ERRCODE_IO_CANTREAD);
477 : 0 : return 0;
478 : : }
479 : 0 : sal_uInt32 nRead = 0;
480 [ # # ]: 0 : if (m_xSeekable.is())
481 : : {
482 [ # # ]: 0 : if (m_nSeekedFrom != STREAM_SEEK_TO_END)
483 : : {
484 : : try
485 : : {
486 [ # # ][ # # ]: 0 : m_xSeekable->seek(m_nSeekedFrom);
487 : : }
488 [ # # ]: 0 : catch (const io::IOException&)
489 : : {
490 [ # # ]: 0 : SetError(ERRCODE_IO_CANTREAD);
491 : 0 : return 0;
492 : : }
493 : 0 : m_nSeekedFrom = STREAM_SEEK_TO_END;
494 : : }
495 : 0 : for (;;)
496 : : {
497 : : sal_Int32 nRemain
498 : : = sal_Int32(
499 : : std::min(sal_uLong(nSize - nRead),
500 [ # # ]: 0 : sal_uLong(std::numeric_limits< sal_Int32 >::max())));
501 [ # # ]: 0 : if (nRemain == 0)
502 : : break;
503 [ # # ]: 0 : uno::Sequence< sal_Int8 > aBuffer;
504 : : sal_Int32 nCount;
505 : : try
506 : : {
507 [ # # ][ # # ]: 0 : nCount = m_xStream->readBytes(aBuffer, nRemain);
508 : : }
509 [ # # # # ]: 0 : catch (const io::IOException&)
510 : : {
511 [ # # ]: 0 : SetError(ERRCODE_IO_CANTREAD);
512 : 0 : return nRead;
513 : : }
514 : 0 : rtl_copyMemory(static_cast< sal_Int8 * >(pData) + nRead,
515 [ # # ]: 0 : aBuffer.getConstArray(), sal_uInt32(nCount));
516 : 0 : nRead += nCount;
517 [ # # ]: 0 : if (nCount < nRemain)
518 : : break;
519 [ # # ]: 0 : }
[ # # # ]
520 : : }
521 : : else
522 : : {
523 [ # # ]: 0 : if (m_nSeekedFrom != STREAM_SEEK_TO_END)
524 : : {
525 : 0 : SetError(ERRCODE_IO_CANTREAD);
526 : 0 : return 0;
527 : : }
528 : 0 : m_pPipe->setReadBuffer(static_cast< sal_Int8 * >(pData), nSize);
529 : 0 : nRead = m_pPipe->read();
530 [ # # ][ # # ]: 0 : if (nRead < nSize && !m_pPipe->isEOF())
[ # # ]
531 : 0 : for (;;)
532 : : {
533 : : sal_Int32 nRemain
534 : : = sal_Int32(
535 : : std::min(
536 : : sal_uLong(nSize - nRead),
537 [ # # ]: 0 : sal_uLong(std::numeric_limits< sal_Int32 >::max())));
538 [ # # ]: 0 : if (nRemain == 0)
539 : : break;
540 [ # # ]: 0 : uno::Sequence< sal_Int8 > aBuffer;
541 : : sal_Int32 nCount;
542 : : try
543 : : {
544 [ # # ][ # # ]: 0 : nCount = m_xStream->readBytes(aBuffer, nRemain);
545 : : }
546 [ # # # # ]: 0 : catch (const io::IOException&)
547 : : {
548 [ # # ]: 0 : SetError(ERRCODE_IO_CANTREAD);
549 : : break;
550 : : }
551 [ # # ]: 0 : m_pPipe->write(aBuffer.getConstArray(), sal_uInt32(nCount));
552 [ # # ]: 0 : nRead += m_pPipe->read();
553 [ # # ]: 0 : if (nCount < nRemain)
554 : : {
555 [ # # ][ # # ]: 0 : m_xStream->closeInput();
556 : 0 : m_pPipe->setEOF();
557 : : break;
558 : : }
559 [ # # ][ # # ]: 0 : }
560 : 0 : m_pPipe->clearReadBuffer();
561 : : }
562 : 0 : return nRead;
563 : : }
564 : :
565 : : //============================================================================
566 : : // virtual
567 : 0 : sal_uLong SvInputStream::PutData(void const *, sal_uLong)
568 : : {
569 : 0 : SetError(ERRCODE_IO_NOTSUPPORTED);
570 : 0 : return 0;
571 : : }
572 : :
573 : : //============================================================================
574 : : // virtual
575 : 0 : void SvInputStream::FlushData()
576 : 0 : {}
577 : :
578 : : //============================================================================
579 : : // virtual
580 : 0 : sal_uLong SvInputStream::SeekPos(sal_uLong nPos)
581 : : {
582 [ # # ]: 0 : if (open())
583 : : {
584 [ # # ]: 0 : if (nPos == STREAM_SEEK_TO_END)
585 : : {
586 [ # # ]: 0 : if (m_nSeekedFrom == STREAM_SEEK_TO_END)
587 : : {
588 [ # # ]: 0 : if (m_xSeekable.is())
589 : : try
590 : : {
591 [ # # ][ # # ]: 0 : sal_Int64 nLength = m_xSeekable->getLength();
592 : : OSL_ASSERT(nLength >= 0);
593 [ # # ]: 0 : if (static_cast<sal_uInt64>(nLength)
594 : : < STREAM_SEEK_TO_END)
595 : : {
596 : 0 : m_nSeekedFrom = Tell();
597 : 0 : return sal_uLong(nLength);
598 : : }
599 : : }
600 [ # # ]: 0 : catch (const io::IOException&)
601 : : {
602 : : }
603 : : else
604 : 0 : return Tell(); //@@@
605 : : }
606 : : else
607 : 0 : return Tell();
608 : : }
609 [ # # ]: 0 : else if (nPos == m_nSeekedFrom)
610 : : {
611 : 0 : m_nSeekedFrom = STREAM_SEEK_TO_END;
612 : 0 : return nPos;
613 : : }
614 [ # # ]: 0 : else if (m_xSeekable.is())
615 : : {
616 : : try
617 : : {
618 [ # # ][ # # ]: 0 : m_xSeekable->seek(nPos);
619 : 0 : m_nSeekedFrom = STREAM_SEEK_TO_END;
620 : 0 : return nPos;
621 : : }
622 : 0 : catch (const io::IOException&)
623 : : {
624 : : }
625 : : }
626 [ # # ]: 0 : else if (m_pPipe->setReadPosition(nPos) == SvDataPipe_Impl::SEEK_OK)
627 : : {
628 : 0 : m_nSeekedFrom = STREAM_SEEK_TO_END;
629 : 0 : return nPos;
630 : : }
631 [ # # ]: 0 : else if ( nPos > Tell() )
632 : : {
633 : : // Read out the bytes
634 : 0 : sal_Int32 nRead = nPos - Tell();
635 [ # # ]: 0 : uno::Sequence< sal_Int8 > aBuffer;
636 [ # # ][ # # ]: 0 : m_xStream->readBytes( aBuffer, nRead );
637 [ # # ]: 0 : return nPos;
638 : : }
639 [ # # ]: 0 : else if ( nPos == Tell() )
640 : 0 : return nPos;
641 : : }
642 : 0 : SetError(ERRCODE_IO_CANTSEEK);
643 [ # # ]: 0 : return Tell();
644 : : }
645 : :
646 : : //============================================================================
647 : : // virtual
648 : 0 : void SvInputStream::SetSize(sal_uLong)
649 : : {
650 : 0 : SetError(ERRCODE_IO_NOTSUPPORTED);
651 : 0 : }
652 : :
653 : : //============================================================================
654 : 0 : SvInputStream::SvInputStream(
655 : : com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
656 : : const &
657 : : rTheStream):
658 : : m_xStream(rTheStream),
659 : : m_pPipe(0),
660 : 0 : m_nSeekedFrom(STREAM_SEEK_TO_END)
661 : : {
662 [ # # ]: 0 : SetBufferSize(0);
663 : 0 : }
664 : :
665 : : //============================================================================
666 : : // virtual
667 : 0 : SvInputStream::~SvInputStream()
668 : : {
669 [ # # ]: 0 : if (m_xStream.is())
670 : : {
671 : : try
672 : : {
673 [ # # ][ # # ]: 0 : m_xStream->closeInput();
674 : : }
675 [ # # ]: 0 : catch (const io::IOException&)
676 : : {
677 : : }
678 : : }
679 [ # # ]: 0 : delete m_pPipe;
680 [ # # ][ # # ]: 0 : }
681 : :
682 : : //============================================================================
683 : : // virtual
684 : 0 : sal_uInt16 SvInputStream::IsA() const
685 : : {
686 : 0 : return 0;
687 : : }
688 : :
689 : : //============================================================================
690 : : // virtual
691 : 0 : void SvInputStream::AddMark(sal_uLong nPos)
692 : : {
693 [ # # ][ # # ]: 0 : if (open() && m_pPipe)
[ # # ]
694 : 0 : m_pPipe->addMark(nPos);
695 : 0 : }
696 : :
697 : : //============================================================================
698 : : // virtual
699 : 0 : void SvInputStream::RemoveMark(sal_uLong nPos)
700 : : {
701 [ # # ][ # # ]: 0 : if (open() && m_pPipe)
[ # # ]
702 : 0 : m_pPipe->removeMark(nPos);
703 : 0 : }
704 : :
705 : : //============================================================================
706 : : //
707 : : // SvOutputStream
708 : : //
709 : : //============================================================================
710 : :
711 : : // virtual
712 : 0 : sal_uLong SvOutputStream::GetData(void *, sal_uLong)
713 : : {
714 : 0 : SetError(ERRCODE_IO_NOTSUPPORTED);
715 : 0 : return 0;
716 : : }
717 : :
718 : : //============================================================================
719 : : // virtual
720 : 481 : sal_uLong SvOutputStream::PutData(void const * pData, sal_uLong nSize)
721 : : {
722 [ - + ]: 481 : if (!m_xStream.is())
723 : : {
724 : 0 : SetError(ERRCODE_IO_CANTWRITE);
725 : 0 : return 0;
726 : : }
727 : 481 : sal_uLong nWritten = 0;
728 : 481 : for (;;)
729 : : {
730 : : sal_Int32 nRemain
731 : : = sal_Int32(
732 : : std::min(sal_uLong(nSize - nWritten),
733 [ + - ]: 962 : sal_uLong(std::numeric_limits< sal_Int32 >::max())));
734 [ + + ]: 962 : if (nRemain == 0)
735 : 481 : break;
736 : : try
737 : : {
738 [ + - ]: 481 : m_xStream->writeBytes(uno::Sequence< sal_Int8 >(
739 : : static_cast<const sal_Int8 * >(pData)
740 : : + nWritten,
741 [ + - ][ + - ]: 481 : nRemain));
[ + - ]
742 : : }
743 [ # # ]: 0 : catch (const io::IOException&)
744 : : {
745 [ # # ]: 0 : SetError(ERRCODE_IO_CANTWRITE);
746 : : break;
747 : : }
748 : 481 : nWritten += nRemain;
749 : : }
750 : 481 : return nWritten;
751 : : }
752 : :
753 : : //============================================================================
754 : : // virtual
755 : 0 : sal_uLong SvOutputStream::SeekPos(sal_uLong)
756 : : {
757 : 0 : SetError(ERRCODE_IO_NOTSUPPORTED);
758 : 0 : return 0;
759 : : }
760 : :
761 : : //============================================================================
762 : : // virtual
763 : 0 : void SvOutputStream::FlushData()
764 : : {
765 [ # # ]: 0 : if (!m_xStream.is())
766 : : {
767 : 0 : SetError(ERRCODE_IO_INVALIDDEVICE);
768 [ # # ]: 0 : return;
769 : : }
770 : : try
771 : : {
772 [ # # ][ # # ]: 0 : m_xStream->flush();
773 : : }
774 : 0 : catch (const io::IOException&)
775 : : {
776 : : }
777 : : }
778 : :
779 : : //============================================================================
780 : : // virtual
781 : 0 : void SvOutputStream::SetSize(sal_uLong)
782 : : {
783 : 0 : SetError(ERRCODE_IO_NOTSUPPORTED);
784 : 0 : }
785 : :
786 : : //============================================================================
787 : 90 : SvOutputStream::SvOutputStream(uno::Reference< io::XOutputStream > const &
788 : : rTheStream):
789 : 90 : m_xStream(rTheStream)
790 : : {
791 [ + - ]: 90 : SetBufferSize(0);
792 : 90 : }
793 : :
794 : : //============================================================================
795 : : // virtual
796 : 90 : SvOutputStream::~SvOutputStream()
797 : : {
798 [ + - ]: 90 : if (m_xStream.is())
799 : : {
800 : : try
801 : : {
802 [ + - ][ + - ]: 90 : m_xStream->closeOutput();
803 : : }
804 [ # # ]: 0 : catch (const io::IOException&)
805 : : {
806 : : }
807 : : }
808 [ - + ][ # # ]: 90 : }
809 : :
810 : : //============================================================================
811 : : // virtual
812 : 0 : sal_uInt16 SvOutputStream::IsA() const
813 : : {
814 : 0 : return 0;
815 : : }
816 : :
817 : : //============================================================================
818 : : //
819 : : // SvDataPipe_Impl
820 : : //
821 : : //============================================================================
822 : :
823 : 0 : bool SvDataPipe_Impl::remove(Page * pPage)
824 : : {
825 [ # # ]: 0 : if (
[ # # # # ]
[ # # ][ # # ]
826 : : pPage != m_pFirstPage ||
827 : : m_pReadPage == m_pFirstPage ||
828 : : (
829 : 0 : !m_aMarks.empty() &&
830 [ # # ][ # # ]: 0 : *m_aMarks.begin() < m_pFirstPage->m_nOffset + m_nPageSize
[ # # ]
831 : : )
832 : : )
833 : : {
834 : 0 : return false;
835 : : }
836 : :
837 : 0 : m_pFirstPage = m_pFirstPage->m_pNext;
838 : :
839 [ # # ]: 0 : if (m_nPages <= m_nMinPages)
840 : 0 : return true;
841 : :
842 : 0 : pPage->m_pPrev->m_pNext = pPage->m_pNext;
843 : 0 : pPage->m_pNext->m_pPrev = pPage->m_pPrev;
844 : 0 : rtl_freeMemory(pPage);
845 : 0 : --m_nPages;
846 : :
847 : 0 : return true;
848 : : }
849 : :
850 : : //============================================================================
851 : 0 : SvDataPipe_Impl::~SvDataPipe_Impl()
852 : : {
853 [ # # ]: 0 : if (m_pFirstPage != 0)
854 : 0 : for (Page * pPage = m_pFirstPage;;)
855 : : {
856 : 0 : Page * pNext = pPage->m_pNext;
857 : 0 : rtl_freeMemory(pPage);
858 [ # # ]: 0 : if (pNext == m_pFirstPage)
859 : 0 : break;
860 : 0 : pPage = pNext;
861 : : }
862 : 0 : }
863 : :
864 : : //============================================================================
865 : 0 : sal_uInt32 SvDataPipe_Impl::read()
866 : : {
867 [ # # ][ # # ]: 0 : if (m_pReadBuffer == 0 || m_nReadBufferSize == 0 || m_pReadPage == 0)
[ # # ]
868 : 0 : return 0;
869 : :
870 : 0 : sal_uInt32 nSize = m_nReadBufferSize;
871 : 0 : sal_uInt32 nRemain = m_nReadBufferSize - m_nReadBufferFilled;
872 : :
873 : 0 : m_pReadBuffer += m_nReadBufferFilled;
874 : 0 : m_nReadBufferSize -= m_nReadBufferFilled;
875 : 0 : m_nReadBufferFilled = 0;
876 : :
877 [ # # ]: 0 : while (nRemain > 0)
878 : : {
879 : : sal_uInt32 nBlock = std::min(sal_uInt32(m_pReadPage->m_pEnd
880 : : - m_pReadPage->m_pRead),
881 [ # # ]: 0 : nRemain);
882 [ # # ]: 0 : rtl_copyMemory(m_pReadBuffer, m_pReadPage->m_pRead, nBlock);
883 : 0 : m_pReadPage->m_pRead += nBlock;
884 : 0 : m_pReadBuffer += nBlock;
885 : 0 : m_nReadBufferSize -= nBlock;
886 : 0 : m_nReadBufferFilled = 0;
887 : 0 : nRemain -= nBlock;
888 : :
889 [ # # ]: 0 : if (m_pReadPage == m_pWritePage)
890 : 0 : break;
891 : :
892 [ # # ]: 0 : if (m_pReadPage->m_pRead == m_pReadPage->m_pEnd)
893 : : {
894 : 0 : Page * pRemove = m_pReadPage;
895 : 0 : m_pReadPage = pRemove->m_pNext;
896 [ # # ]: 0 : remove(pRemove);
897 : : }
898 : : }
899 : :
900 : 0 : return nSize - nRemain;
901 : : }
902 : :
903 : : //============================================================================
904 : 0 : sal_uInt32 SvDataPipe_Impl::write(sal_Int8 const * pBuffer, sal_uInt32 nSize)
905 : : {
906 [ # # ]: 0 : if (nSize == 0)
907 : 0 : return 0;
908 : :
909 [ # # ]: 0 : if (m_pWritePage == 0)
910 : : {
911 : : m_pFirstPage
912 : : = static_cast< Page * >(rtl_allocateMemory(sizeof (Page)
913 : : + m_nPageSize
914 : 0 : - 1));
915 : 0 : m_pFirstPage->m_pPrev = m_pFirstPage;
916 : 0 : m_pFirstPage->m_pNext = m_pFirstPage;
917 : 0 : m_pFirstPage->m_pStart = m_pFirstPage->m_aBuffer;
918 : 0 : m_pFirstPage->m_pRead = m_pFirstPage->m_aBuffer;
919 : 0 : m_pFirstPage->m_pEnd = m_pFirstPage->m_aBuffer;
920 : 0 : m_pFirstPage->m_nOffset = 0;
921 : 0 : m_pReadPage = m_pFirstPage;
922 : 0 : m_pWritePage = m_pFirstPage;
923 : 0 : ++m_nPages;
924 : : }
925 : :
926 : 0 : sal_uInt32 nRemain = nSize;
927 : :
928 [ # # ][ # # ]: 0 : if (m_pReadBuffer != 0 && m_pReadPage == m_pWritePage
[ # # ]
929 : : && m_pReadPage->m_pRead == m_pWritePage->m_pEnd)
930 : : {
931 : : sal_uInt32 nBlock = std::min(nRemain,
932 : : sal_uInt32(m_nReadBufferSize
933 [ # # ]: 0 : - m_nReadBufferFilled));
934 : : sal_uInt32 nPosition = m_pWritePage->m_nOffset
935 : : + (m_pWritePage->m_pEnd
936 : 0 : - m_pWritePage->m_aBuffer);
937 [ # # ]: 0 : if (!m_aMarks.empty())
938 [ # # ]: 0 : nBlock = *m_aMarks.begin() > nPosition ?
939 [ # # ][ # # ]: 0 : std::min(nBlock, sal_uInt32(*m_aMarks.begin()
[ # # ]
940 [ # # ][ # # ]: 0 : - nPosition)) :
[ # # ]
941 [ # # ]: 0 : 0;
942 : :
943 [ # # ]: 0 : if (nBlock > 0)
944 : : {
945 : 0 : rtl_copyMemory(m_pReadBuffer + m_nReadBufferFilled, pBuffer,
946 [ # # ]: 0 : nBlock);
947 : 0 : m_nReadBufferFilled += nBlock;
948 : 0 : nRemain -= nBlock;
949 : :
950 : 0 : nPosition += nBlock;
951 : 0 : m_pWritePage->m_nOffset = (nPosition / m_nPageSize) * m_nPageSize;
952 : : m_pWritePage->m_pStart = m_pWritePage->m_aBuffer
953 : 0 : + nPosition % m_nPageSize;
954 : 0 : m_pWritePage->m_pRead = m_pWritePage->m_pStart;
955 : 0 : m_pWritePage->m_pEnd = m_pWritePage->m_pStart;
956 : : }
957 : : }
958 : :
959 [ # # ]: 0 : if (nRemain > 0)
960 : 0 : for (;;)
961 : : {
962 : : sal_uInt32 nBlock
963 : 0 : = std::min(sal_uInt32(m_pWritePage->m_aBuffer + m_nPageSize
964 : : - m_pWritePage->m_pEnd),
965 [ # # ]: 0 : nRemain);
966 [ # # ]: 0 : rtl_copyMemory(m_pWritePage->m_pEnd, pBuffer, nBlock);
967 : 0 : m_pWritePage->m_pEnd += nBlock;
968 : 0 : pBuffer += nBlock;
969 : 0 : nRemain -= nBlock;
970 : :
971 [ # # ]: 0 : if (nRemain == 0)
972 : 0 : break;
973 : :
974 [ # # ]: 0 : if (m_pWritePage->m_pNext == m_pFirstPage)
975 : : {
976 [ # # ]: 0 : if (m_nPages == m_nMaxPages)
977 : 0 : break;
978 : :
979 : : Page * pNew
980 : : = static_cast< Page * >(rtl_allocateMemory(
981 : : sizeof (Page) + m_nPageSize
982 : 0 : - 1));
983 : 0 : pNew->m_pPrev = m_pWritePage;
984 : 0 : pNew->m_pNext = m_pWritePage->m_pNext;
985 : :
986 : 0 : m_pWritePage->m_pNext->m_pPrev = pNew;
987 : 0 : m_pWritePage->m_pNext = pNew;
988 : 0 : ++m_nPages;
989 : : }
990 : :
991 : : m_pWritePage->m_pNext->m_nOffset = m_pWritePage->m_nOffset
992 : 0 : + m_nPageSize;
993 : 0 : m_pWritePage = m_pWritePage->m_pNext;
994 : 0 : m_pWritePage->m_pStart = m_pWritePage->m_aBuffer;
995 : 0 : m_pWritePage->m_pRead = m_pWritePage->m_aBuffer;
996 : 0 : m_pWritePage->m_pEnd = m_pWritePage->m_aBuffer;
997 : : }
998 : :
999 : 0 : return nSize - nRemain;
1000 : : }
1001 : :
1002 : : //============================================================================
1003 : 0 : bool SvDataPipe_Impl::addMark(sal_uInt32 nPosition)
1004 : : {
1005 [ # # ][ # # ]: 0 : if (m_pFirstPage != 0 && m_pFirstPage->m_nOffset > nPosition)
1006 : 0 : return false;
1007 : 0 : m_aMarks.insert(nPosition);
1008 : 0 : return true;
1009 : : }
1010 : :
1011 : : //============================================================================
1012 : 0 : bool SvDataPipe_Impl::removeMark(sal_uInt32 nPosition)
1013 : : {
1014 [ # # ]: 0 : std::multiset< sal_uInt32 >::iterator t = m_aMarks.find(nPosition);
1015 [ # # ][ # # ]: 0 : if (t == m_aMarks.end())
1016 : 0 : return false;
1017 [ # # ]: 0 : m_aMarks.erase(t);
1018 [ # # ][ # # ]: 0 : while (remove(m_pFirstPage)) ;
1019 : 0 : return true;
1020 : : }
1021 : :
1022 : : //============================================================================
1023 : 0 : SvDataPipe_Impl::SeekResult SvDataPipe_Impl::setReadPosition(sal_uInt32
1024 : : nPosition)
1025 : : {
1026 [ # # ]: 0 : if (m_pFirstPage == 0)
1027 [ # # ]: 0 : return nPosition == 0 ? SEEK_OK : SEEK_PAST_END;
1028 : :
1029 [ # # ]: 0 : if (nPosition
1030 : : <= m_pReadPage->m_nOffset
1031 : : + (m_pReadPage->m_pRead - m_pReadPage->m_aBuffer))
1032 : : {
1033 [ # # ]: 0 : if (nPosition
1034 : : < m_pFirstPage->m_nOffset
1035 : : + (m_pFirstPage->m_pStart - m_pFirstPage->m_aBuffer))
1036 : 0 : return SEEK_BEFORE_MARKED;
1037 : :
1038 [ # # ]: 0 : while (nPosition < m_pReadPage->m_nOffset)
1039 : : {
1040 : 0 : m_pReadPage->m_pRead = m_pReadPage->m_pStart;
1041 : 0 : m_pReadPage = m_pReadPage->m_pPrev;
1042 : : }
1043 : : }
1044 : : else
1045 : : {
1046 [ # # ]: 0 : if (nPosition
1047 : : > m_pWritePage->m_nOffset
1048 : : + (m_pWritePage->m_pEnd - m_pWritePage->m_aBuffer))
1049 : 0 : return SEEK_PAST_END;
1050 : :
1051 [ # # ][ # # ]: 0 : while (m_pReadPage != m_pWritePage
[ # # ]
1052 : : && nPosition >= m_pReadPage->m_nOffset + m_nPageSize)
1053 : : {
1054 : 0 : Page * pRemove = m_pReadPage;
1055 : 0 : m_pReadPage = pRemove->m_pNext;
1056 : 0 : remove(pRemove);
1057 : : }
1058 : : }
1059 : :
1060 : : m_pReadPage->m_pRead = m_pReadPage->m_aBuffer
1061 : 0 : + (nPosition - m_pReadPage->m_nOffset);
1062 : 0 : return SEEK_OK;
1063 : : }
1064 : :
1065 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|