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