1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: streamhelper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_io.hxx"
33 #include <rtl/alloc.h>
38 #include <com/sun/star/uno/Sequence.hxx>
40 #include <com/sun/star/uno/Exception.hpp>
42 using namespace ::com::sun::star::uno
;
44 #include "streamhelper.hxx"
48 void MemFIFO::write( const Sequence
< sal_Int8
> &seq
)
49 throw ( IFIFO_OutOfMemoryException
,
50 IFIFO_OutOfBoundsException
)
54 writeAt(getSize(), seq
);
56 catch( IRingBuffer_OutOfMemoryException
& )
58 throw IFIFO_OutOfMemoryException();
60 catch( IRingBuffer_OutOfBoundsException
& )
62 throw IFIFO_OutOfBoundsException();
66 void MemFIFO::read( Sequence
<sal_Int8
> &seq
, sal_Int32 nBufferLen
) throw (IFIFO_OutOfBoundsException
)
70 readAt(0, seq
, nBufferLen
);
71 forgetFromStart( nBufferLen
);
73 catch ( IRingBuffer_OutOfBoundsException
& )
75 throw IFIFO_OutOfBoundsException();
79 void MemFIFO::skip( sal_Int32 nBytesToSkip
) throw ( IFIFO_OutOfBoundsException
)
83 forgetFromStart( nBytesToSkip
);
85 catch( IRingBuffer_OutOfBoundsException
& )
87 throw IFIFO_OutOfBoundsException();
93 MemRingBuffer::MemRingBuffer()
98 m_nOccupiedBuffer
= 0;
101 MemRingBuffer::~MemRingBuffer()
104 rtl_freeMemory( m_p
);
108 void MemRingBuffer::resizeBuffer( sal_Int32 nMinSize
) throw( IRingBuffer_OutOfMemoryException
)
110 sal_Int32 nNewLen
= 1;
112 while( nMinSize
> nNewLen
) {
113 nNewLen
= nNewLen
<< 1;
116 // buffer never shrinks !
117 if( nNewLen
< m_nBufferLen
) {
118 nNewLen
= m_nBufferLen
;
121 if( nNewLen
!= m_nBufferLen
) {
122 m_p
= ( sal_Int8
* ) rtl_reallocateMemory( m_p
, nNewLen
);
124 throw IRingBuffer_OutOfMemoryException();
127 if( m_nStart
+ m_nOccupiedBuffer
> m_nBufferLen
) {
128 memmove( &( m_p
[m_nStart
+(nNewLen
-m_nBufferLen
)]) , &(m_p
[m_nStart
]) , m_nBufferLen
- m_nStart
);
129 m_nStart
+= nNewLen
- m_nBufferLen
;
131 m_nBufferLen
= nNewLen
;
136 void MemRingBuffer::readAt( sal_Int32 nPos
, Sequence
<sal_Int8
> &seq
, sal_Int32 nBytesToRead
) const
137 throw(IRingBuffer_OutOfBoundsException
)
139 if( nPos
+ nBytesToRead
> m_nOccupiedBuffer
) {
140 throw IRingBuffer_OutOfBoundsException();
143 sal_Int32 nStartReadingPos
= nPos
+ m_nStart
;
144 if( nStartReadingPos
>= m_nBufferLen
) {
145 nStartReadingPos
-= m_nBufferLen
;
148 seq
.realloc( nBytesToRead
);
150 if( nStartReadingPos
+ nBytesToRead
> m_nBufferLen
) {
151 sal_Int32 nDeltaLen
= m_nBufferLen
- nStartReadingPos
;
152 memcpy( seq
.getArray() , &(m_p
[nStartReadingPos
]) , nDeltaLen
);
153 memcpy( &(seq
.getArray()[nDeltaLen
]), m_p
, nBytesToRead
- nDeltaLen
);
156 memcpy( seq
.getArray() , &(m_p
[nStartReadingPos
]) , nBytesToRead
);
161 void MemRingBuffer::writeAt( sal_Int32 nPos
, const Sequence
<sal_Int8
> &seq
)
162 throw (IRingBuffer_OutOfBoundsException
,
163 IRingBuffer_OutOfMemoryException
)
166 sal_Int32 nLen
= seq
.getLength();
168 if( nPos
< 0 || nPos
> std::numeric_limits
< sal_Int32
>::max() - nLen
)
170 throw IRingBuffer_OutOfBoundsException();
173 if( nPos
+ nLen
- m_nOccupiedBuffer
> 0 ) {
174 resizeBuffer( nPos
+ seq
.getLength() );
177 sal_Int32 nStartWritingIndex
= m_nStart
+ nPos
;
178 if( nStartWritingIndex
>= m_nBufferLen
) {
179 nStartWritingIndex
-= m_nBufferLen
;
182 if( nLen
+ nStartWritingIndex
> m_nBufferLen
) {
184 memcpy( &(m_p
[nStartWritingIndex
]) , seq
.getConstArray(), m_nBufferLen
-nStartWritingIndex
);
185 memcpy( m_p
, &( seq
.getConstArray()[m_nBufferLen
-nStartWritingIndex
] ),
186 nLen
- (m_nBufferLen
-nStartWritingIndex
) );
191 memcpy( &( m_p
[nStartWritingIndex
]), seq
.getConstArray() , nLen
);
193 m_nOccupiedBuffer
= Max( nPos
+ seq
.getLength() , m_nOccupiedBuffer
);
198 sal_Int32
MemRingBuffer::getSize() const throw()
200 return m_nOccupiedBuffer
;
203 void MemRingBuffer::forgetFromStart( sal_Int32 nBytesToForget
) throw (IRingBuffer_OutOfBoundsException
)
206 if( nBytesToForget
> m_nOccupiedBuffer
) {
207 throw IRingBuffer_OutOfBoundsException();
209 m_nStart
+= nBytesToForget
;
210 if( m_nStart
>= m_nBufferLen
) {
211 m_nStart
= m_nStart
- m_nBufferLen
;
213 m_nOccupiedBuffer
-= nBytesToForget
;
218 void MemRingBuffer::forgetFromEnd( sal_Int32 nBytesToForget
) throw (IRingBuffer_OutOfBoundsException
)
221 if( nBytesToForget
> m_nOccupiedBuffer
) {
222 throw IRingBuffer_OutOfBoundsException();
224 m_nOccupiedBuffer
-= nBytesToForget
;
229 void MemRingBuffer::shrink() throw ()
233 // Up to now, only shrinking of while buffer works.
234 // No other shrinking supported up to now.
235 if( ! m_nOccupiedBuffer
) {