1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <rtl/alloc.h>
25 #include <com/sun/star/uno/Sequence.hxx>
27 #include <com/sun/star/uno/Exception.hpp>
29 using namespace ::com::sun::star::uno
;
31 #include "streamhelper.hxx"
35 void MemFIFO::write( const Sequence
< sal_Int8
> &seq
)
36 throw ( I_FIFO_OutOfMemoryException
,
37 I_FIFO_OutOfBoundsException
)
41 writeAt(getSize(), seq
);
43 catch( IRingBuffer_OutOfMemoryException
& )
45 throw I_FIFO_OutOfMemoryException();
47 catch( IRingBuffer_OutOfBoundsException
& )
49 throw I_FIFO_OutOfBoundsException();
53 void MemFIFO::read( Sequence
<sal_Int8
> &seq
, sal_Int32 nBufferLen
) throw (I_FIFO_OutOfBoundsException
)
57 readAt(0, seq
, nBufferLen
);
58 forgetFromStart( nBufferLen
);
60 catch ( IRingBuffer_OutOfBoundsException
& )
62 throw I_FIFO_OutOfBoundsException();
66 void MemFIFO::skip( sal_Int32 nBytesToSkip
) throw ( I_FIFO_OutOfBoundsException
)
70 forgetFromStart( nBytesToSkip
);
72 catch( IRingBuffer_OutOfBoundsException
& )
74 throw I_FIFO_OutOfBoundsException();
80 MemRingBuffer::MemRingBuffer()
85 m_nOccupiedBuffer
= 0;
88 MemRingBuffer::~MemRingBuffer()
91 rtl_freeMemory( m_p
);
95 void MemRingBuffer::resizeBuffer( sal_Int32 nMinSize
) throw( IRingBuffer_OutOfMemoryException
)
97 sal_Int32 nNewLen
= 1;
99 while( nMinSize
> nNewLen
) {
100 nNewLen
= nNewLen
<< 1;
103 // buffer never shrinks !
104 if( nNewLen
< m_nBufferLen
) {
105 nNewLen
= m_nBufferLen
;
108 if( nNewLen
!= m_nBufferLen
) {
109 m_p
= ( sal_Int8
* ) rtl_reallocateMemory( m_p
, nNewLen
);
111 throw IRingBuffer_OutOfMemoryException();
114 if( m_nStart
+ m_nOccupiedBuffer
> m_nBufferLen
) {
115 memmove( &( m_p
[m_nStart
+(nNewLen
-m_nBufferLen
)]) , &(m_p
[m_nStart
]) , m_nBufferLen
- m_nStart
);
116 m_nStart
+= nNewLen
- m_nBufferLen
;
118 m_nBufferLen
= nNewLen
;
123 void MemRingBuffer::readAt( sal_Int32 nPos
, Sequence
<sal_Int8
> &seq
, sal_Int32 nBytesToRead
) const
124 throw(IRingBuffer_OutOfBoundsException
)
126 if( nPos
+ nBytesToRead
> m_nOccupiedBuffer
) {
127 throw IRingBuffer_OutOfBoundsException();
130 sal_Int32 nStartReadingPos
= nPos
+ m_nStart
;
131 if( nStartReadingPos
>= m_nBufferLen
) {
132 nStartReadingPos
-= m_nBufferLen
;
135 seq
.realloc( nBytesToRead
);
137 if( nStartReadingPos
+ nBytesToRead
> m_nBufferLen
) {
138 sal_Int32 nDeltaLen
= m_nBufferLen
- nStartReadingPos
;
139 memcpy( seq
.getArray() , &(m_p
[nStartReadingPos
]) , nDeltaLen
);
140 memcpy( &(seq
.getArray()[nDeltaLen
]), m_p
, nBytesToRead
- nDeltaLen
);
143 memcpy( seq
.getArray() , &(m_p
[nStartReadingPos
]) , nBytesToRead
);
148 void MemRingBuffer::writeAt( sal_Int32 nPos
, const Sequence
<sal_Int8
> &seq
)
149 throw (IRingBuffer_OutOfBoundsException
,
150 IRingBuffer_OutOfMemoryException
)
153 sal_Int32 nLen
= seq
.getLength();
155 if( nPos
< 0 || nPos
> std::numeric_limits
< sal_Int32
>::max() - nLen
)
157 throw IRingBuffer_OutOfBoundsException();
160 if( nPos
+ nLen
- m_nOccupiedBuffer
> 0 ) {
161 resizeBuffer( nPos
+ seq
.getLength() );
164 sal_Int32 nStartWritingIndex
= m_nStart
+ nPos
;
165 if( nStartWritingIndex
>= m_nBufferLen
) {
166 nStartWritingIndex
-= m_nBufferLen
;
169 if( nLen
+ nStartWritingIndex
> m_nBufferLen
) {
171 memcpy( &(m_p
[nStartWritingIndex
]) , seq
.getConstArray(), m_nBufferLen
-nStartWritingIndex
);
172 memcpy( m_p
, &( seq
.getConstArray()[m_nBufferLen
-nStartWritingIndex
] ),
173 nLen
- (m_nBufferLen
-nStartWritingIndex
) );
178 memcpy( &( m_p
[nStartWritingIndex
]), seq
.getConstArray() , nLen
);
180 m_nOccupiedBuffer
= Max( nPos
+ seq
.getLength() , m_nOccupiedBuffer
);
185 sal_Int32
MemRingBuffer::getSize() const throw()
187 return m_nOccupiedBuffer
;
190 void MemRingBuffer::forgetFromStart( sal_Int32 nBytesToForget
) throw (IRingBuffer_OutOfBoundsException
)
193 if( nBytesToForget
> m_nOccupiedBuffer
) {
194 throw IRingBuffer_OutOfBoundsException();
196 m_nStart
+= nBytesToForget
;
197 if( m_nStart
>= m_nBufferLen
) {
198 m_nStart
= m_nStart
- m_nBufferLen
;
200 m_nOccupiedBuffer
-= nBytesToForget
;
205 void MemRingBuffer::forgetFromEnd( sal_Int32 nBytesToForget
) throw (IRingBuffer_OutOfBoundsException
)
208 if( nBytesToForget
> m_nOccupiedBuffer
) {
209 throw IRingBuffer_OutOfBoundsException();
211 m_nOccupiedBuffer
-= nBytesToForget
;
216 void MemRingBuffer::shrink() throw ()
220 // Up to now, only shrinking of while buffer works.
221 // No other shrinking supported up to now.
222 if( ! m_nOccupiedBuffer
) {
236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */