xref: /aoo41x/main/svl/source/misc/strmadpt.cxx (revision 40df464e)
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
10*40df464eSAndrew Rist  *
11*40df464eSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*40df464eSAndrew Rist  *
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.
19*40df464eSAndrew Rist  *
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 }
1041cdf0e10cSrcweir 
1042