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