xref: /AOO41X/main/io/source/stm/streamhelper.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_io.hxx"
30*cdf0e10cSrcweir #include <rtl/alloc.h>
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include <limits>
33*cdf0e10cSrcweir #include <string.h>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <com/sun/star/uno/Exception.hpp>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #include "streamhelper.hxx"
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir namespace io_stm {
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir void MemFIFO::write( const Sequence< sal_Int8 > &seq )
46*cdf0e10cSrcweir 	throw ( IFIFO_OutOfMemoryException,
47*cdf0e10cSrcweir 			IFIFO_OutOfBoundsException )
48*cdf0e10cSrcweir {
49*cdf0e10cSrcweir 	try
50*cdf0e10cSrcweir 	{
51*cdf0e10cSrcweir 		writeAt(getSize(), seq );
52*cdf0e10cSrcweir 	}
53*cdf0e10cSrcweir 	catch( IRingBuffer_OutOfMemoryException & )
54*cdf0e10cSrcweir 	{
55*cdf0e10cSrcweir 		throw IFIFO_OutOfMemoryException();
56*cdf0e10cSrcweir 	}
57*cdf0e10cSrcweir 	catch( IRingBuffer_OutOfBoundsException & )
58*cdf0e10cSrcweir 	{
59*cdf0e10cSrcweir 		throw IFIFO_OutOfBoundsException();
60*cdf0e10cSrcweir 	}
61*cdf0e10cSrcweir }
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir void MemFIFO::read( Sequence<sal_Int8> &seq , sal_Int32 nBufferLen ) throw (IFIFO_OutOfBoundsException)
64*cdf0e10cSrcweir {
65*cdf0e10cSrcweir 	try
66*cdf0e10cSrcweir 	{
67*cdf0e10cSrcweir 		readAt(0, seq , nBufferLen);
68*cdf0e10cSrcweir 		forgetFromStart( nBufferLen );
69*cdf0e10cSrcweir 	}
70*cdf0e10cSrcweir 	catch ( IRingBuffer_OutOfBoundsException & )
71*cdf0e10cSrcweir 	{
72*cdf0e10cSrcweir 		throw IFIFO_OutOfBoundsException();
73*cdf0e10cSrcweir 	}
74*cdf0e10cSrcweir }
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir void MemFIFO::skip( sal_Int32 nBytesToSkip ) throw ( IFIFO_OutOfBoundsException )
77*cdf0e10cSrcweir {
78*cdf0e10cSrcweir 	try
79*cdf0e10cSrcweir 	{
80*cdf0e10cSrcweir 		forgetFromStart( nBytesToSkip );
81*cdf0e10cSrcweir 	}
82*cdf0e10cSrcweir 	catch( IRingBuffer_OutOfBoundsException & )
83*cdf0e10cSrcweir 	{
84*cdf0e10cSrcweir 		throw IFIFO_OutOfBoundsException();
85*cdf0e10cSrcweir 	}
86*cdf0e10cSrcweir }
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir MemRingBuffer::MemRingBuffer()
91*cdf0e10cSrcweir {
92*cdf0e10cSrcweir 	m_nBufferLen 			= 0;
93*cdf0e10cSrcweir 	m_p 					= 0;
94*cdf0e10cSrcweir 	m_nStart 				= 0;
95*cdf0e10cSrcweir 	m_nOccupiedBuffer		= 0;
96*cdf0e10cSrcweir }
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir MemRingBuffer::~MemRingBuffer()
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir 	if( m_p ) {
101*cdf0e10cSrcweir 		rtl_freeMemory( m_p );
102*cdf0e10cSrcweir 	}
103*cdf0e10cSrcweir }
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir void MemRingBuffer::resizeBuffer( sal_Int32 nMinSize ) throw( IRingBuffer_OutOfMemoryException)
106*cdf0e10cSrcweir {
107*cdf0e10cSrcweir 	sal_Int32 nNewLen = 1;
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir 	while( nMinSize > nNewLen ) {
110*cdf0e10cSrcweir 		nNewLen = nNewLen << 1;
111*cdf0e10cSrcweir 	}
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir 	// buffer never shrinks !
114*cdf0e10cSrcweir 	if( nNewLen < m_nBufferLen ) {
115*cdf0e10cSrcweir 		nNewLen = m_nBufferLen;
116*cdf0e10cSrcweir 	}
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir 	if( nNewLen != m_nBufferLen ) {
119*cdf0e10cSrcweir 		m_p = ( sal_Int8 * ) rtl_reallocateMemory( m_p , nNewLen );
120*cdf0e10cSrcweir 		if( !m_p ) {
121*cdf0e10cSrcweir 			throw IRingBuffer_OutOfMemoryException();
122*cdf0e10cSrcweir 		}
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir 		if( m_nStart + m_nOccupiedBuffer > m_nBufferLen ) {
125*cdf0e10cSrcweir 			memmove( &( m_p[m_nStart+(nNewLen-m_nBufferLen)]) , &(m_p[m_nStart]) , m_nBufferLen - m_nStart );
126*cdf0e10cSrcweir 			m_nStart += nNewLen - m_nBufferLen;
127*cdf0e10cSrcweir 		}
128*cdf0e10cSrcweir 		m_nBufferLen = nNewLen;
129*cdf0e10cSrcweir 	}
130*cdf0e10cSrcweir }
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir void MemRingBuffer::readAt( sal_Int32 nPos, Sequence<sal_Int8> &seq , sal_Int32 nBytesToRead ) const
134*cdf0e10cSrcweir 														throw(IRingBuffer_OutOfBoundsException)
135*cdf0e10cSrcweir {
136*cdf0e10cSrcweir 	if( nPos + nBytesToRead > m_nOccupiedBuffer ) {
137*cdf0e10cSrcweir 		throw IRingBuffer_OutOfBoundsException();
138*cdf0e10cSrcweir 	}
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir 	sal_Int32 nStartReadingPos = nPos + m_nStart;
141*cdf0e10cSrcweir 	if( nStartReadingPos >= m_nBufferLen ) {
142*cdf0e10cSrcweir 		nStartReadingPos -= m_nBufferLen;
143*cdf0e10cSrcweir 	}
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir 	seq.realloc( nBytesToRead );
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir 	if( nStartReadingPos + nBytesToRead > m_nBufferLen ) {
148*cdf0e10cSrcweir 		sal_Int32 nDeltaLen = m_nBufferLen - nStartReadingPos;
149*cdf0e10cSrcweir 		memcpy( seq.getArray() , &(m_p[nStartReadingPos]) , nDeltaLen );
150*cdf0e10cSrcweir 		memcpy( &(seq.getArray()[nDeltaLen]), m_p , nBytesToRead - nDeltaLen );
151*cdf0e10cSrcweir 	}
152*cdf0e10cSrcweir 	else {
153*cdf0e10cSrcweir 		memcpy( seq.getArray() , &(m_p[nStartReadingPos]) , nBytesToRead );
154*cdf0e10cSrcweir 	}
155*cdf0e10cSrcweir }
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir void MemRingBuffer::writeAt( sal_Int32 nPos, const Sequence<sal_Int8> &seq )
159*cdf0e10cSrcweir 														throw (IRingBuffer_OutOfBoundsException,
160*cdf0e10cSrcweir 																IRingBuffer_OutOfMemoryException )
161*cdf0e10cSrcweir {
162*cdf0e10cSrcweir 	checkInvariants();
163*cdf0e10cSrcweir 	sal_Int32 nLen = seq.getLength();
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir 	if( nPos < 0 || nPos > std::numeric_limits< sal_Int32 >::max() - nLen )
166*cdf0e10cSrcweir 	{
167*cdf0e10cSrcweir 		throw IRingBuffer_OutOfBoundsException();
168*cdf0e10cSrcweir 	}
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir 	if( nPos + nLen - m_nOccupiedBuffer > 0 ) {
171*cdf0e10cSrcweir 		resizeBuffer( nPos + seq.getLength() );
172*cdf0e10cSrcweir 	}
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 	sal_Int32 nStartWritingIndex = m_nStart + nPos;
175*cdf0e10cSrcweir 	if( nStartWritingIndex >= m_nBufferLen ) {
176*cdf0e10cSrcweir 		nStartWritingIndex -= m_nBufferLen;
177*cdf0e10cSrcweir 	}
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 	if( nLen + nStartWritingIndex > m_nBufferLen ) {
180*cdf0e10cSrcweir 		// two area copy
181*cdf0e10cSrcweir 		memcpy( &(m_p[nStartWritingIndex]) , seq.getConstArray(), m_nBufferLen-nStartWritingIndex );
182*cdf0e10cSrcweir 		memcpy( m_p , &( seq.getConstArray()[m_nBufferLen-nStartWritingIndex] ),
183*cdf0e10cSrcweir 										nLen - (m_nBufferLen-nStartWritingIndex) );
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir 	}
186*cdf0e10cSrcweir 	else {
187*cdf0e10cSrcweir 		// one area copy
188*cdf0e10cSrcweir 		memcpy( &( m_p[nStartWritingIndex]), seq.getConstArray() , nLen );
189*cdf0e10cSrcweir 	}
190*cdf0e10cSrcweir 	m_nOccupiedBuffer = Max( nPos + seq.getLength() , m_nOccupiedBuffer );
191*cdf0e10cSrcweir 	checkInvariants();
192*cdf0e10cSrcweir }
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir sal_Int32 MemRingBuffer::getSize()  const throw()
196*cdf0e10cSrcweir {
197*cdf0e10cSrcweir 	return m_nOccupiedBuffer;
198*cdf0e10cSrcweir }
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir void MemRingBuffer::forgetFromStart( sal_Int32 nBytesToForget ) throw (IRingBuffer_OutOfBoundsException)
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir 	checkInvariants();
203*cdf0e10cSrcweir 	if( nBytesToForget > m_nOccupiedBuffer ) {
204*cdf0e10cSrcweir 		throw IRingBuffer_OutOfBoundsException();
205*cdf0e10cSrcweir 	}
206*cdf0e10cSrcweir 	m_nStart += nBytesToForget;
207*cdf0e10cSrcweir 	if( m_nStart >= m_nBufferLen ) {
208*cdf0e10cSrcweir 		m_nStart = m_nStart - m_nBufferLen;
209*cdf0e10cSrcweir 	}
210*cdf0e10cSrcweir 	m_nOccupiedBuffer -= nBytesToForget;
211*cdf0e10cSrcweir 	checkInvariants();
212*cdf0e10cSrcweir }
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir void MemRingBuffer::forgetFromEnd( sal_Int32 nBytesToForget ) throw (IRingBuffer_OutOfBoundsException)
216*cdf0e10cSrcweir {
217*cdf0e10cSrcweir 	checkInvariants();
218*cdf0e10cSrcweir 	if( nBytesToForget > m_nOccupiedBuffer ) {
219*cdf0e10cSrcweir 		throw IRingBuffer_OutOfBoundsException();
220*cdf0e10cSrcweir 	}
221*cdf0e10cSrcweir 	m_nOccupiedBuffer -= nBytesToForget;
222*cdf0e10cSrcweir 	checkInvariants();
223*cdf0e10cSrcweir }
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir void MemRingBuffer::shrink() throw ()
227*cdf0e10cSrcweir {
228*cdf0e10cSrcweir 	checkInvariants();
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir 	// Up to now, only shrinking of while buffer works.
231*cdf0e10cSrcweir 	// No other shrinking supported up to now.
232*cdf0e10cSrcweir 	if( ! m_nOccupiedBuffer ) {
233*cdf0e10cSrcweir 		if( m_p ) {
234*cdf0e10cSrcweir 			free( m_p );
235*cdf0e10cSrcweir 		}
236*cdf0e10cSrcweir 		m_p = 0;
237*cdf0e10cSrcweir 		m_nBufferLen = 0;
238*cdf0e10cSrcweir 		m_nStart = 0;
239*cdf0e10cSrcweir 	}
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir 	checkInvariants();
242*cdf0e10cSrcweir }
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir }
245