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 .
23 #include <com/sun/star/uno/Sequence.hxx>
25 #include <com/sun/star/io/BufferSizeExceededException.hpp>
27 using namespace ::com::sun::star::uno
;
29 #include "streamhelper.hxx"
33 void MemFIFO::write( const Sequence
< sal_Int8
> &seq
)
35 writeAt(getSize(), seq
);
38 void MemFIFO::read( Sequence
<sal_Int8
> &seq
, sal_Int32 nBufferLen
)
40 readAt(0, seq
, nBufferLen
);
41 forgetFromStart( nBufferLen
);
44 void MemFIFO::skip( sal_Int32 nBytesToSkip
)
46 forgetFromStart( nBytesToSkip
);
49 MemRingBuffer::MemRingBuffer()
54 m_nOccupiedBuffer
= 0;
57 MemRingBuffer::~MemRingBuffer()
62 void MemRingBuffer::resizeBuffer( sal_Int32 nMinSize
)
64 sal_Int32 nNewLen
= 1;
66 while( nMinSize
> nNewLen
) {
67 nNewLen
= nNewLen
<< 1;
70 // buffer never shrinks !
71 if( nNewLen
< m_nBufferLen
) {
72 nNewLen
= m_nBufferLen
;
75 if( nNewLen
!= m_nBufferLen
) {
76 if (auto p
= static_cast<sal_Int8
*>(std::realloc(m_p
, nNewLen
)))
80 throw css::io::BufferSizeExceededException(
81 "MemRingBuffer::resizeBuffer BufferSizeExceededException");
84 if( m_nStart
+ m_nOccupiedBuffer
> m_nBufferLen
) {
85 memmove( &( m_p
[m_nStart
+(nNewLen
-m_nBufferLen
)]) , &(m_p
[m_nStart
]) , m_nBufferLen
- m_nStart
);
86 m_nStart
+= nNewLen
- m_nBufferLen
;
88 m_nBufferLen
= nNewLen
;
93 void MemRingBuffer::readAt( sal_Int32 nPos
, Sequence
<sal_Int8
> &seq
, sal_Int32 nBytesToRead
) const
95 if( nPos
+ nBytesToRead
> m_nOccupiedBuffer
) {
96 throw css::io::BufferSizeExceededException(
97 "MemRingBuffer::readAt BufferSizeExceededException");
100 sal_Int32 nStartReadingPos
= nPos
+ m_nStart
;
101 if( nStartReadingPos
>= m_nBufferLen
) {
102 nStartReadingPos
-= m_nBufferLen
;
105 seq
.realloc( nBytesToRead
);
107 if( nStartReadingPos
+ nBytesToRead
> m_nBufferLen
) {
108 sal_Int32 nDeltaLen
= m_nBufferLen
- nStartReadingPos
;
109 memcpy( seq
.getArray() , &(m_p
[nStartReadingPos
]) , nDeltaLen
);
110 memcpy( &(seq
.getArray()[nDeltaLen
]), m_p
, nBytesToRead
- nDeltaLen
);
113 memcpy( seq
.getArray() , &(m_p
[nStartReadingPos
]) , nBytesToRead
);
118 void MemRingBuffer::writeAt( sal_Int32 nPos
, const Sequence
<sal_Int8
> &seq
)
121 const sal_Int32 nLen
= seq
.getLength();
123 if( nPos
< 0 || nPos
> std::numeric_limits
< sal_Int32
>::max() - nLen
)
125 throw css::io::BufferSizeExceededException(
126 "MemRingBuffer::writeAt BufferSizeExceededException");
129 if( nPos
+ nLen
- m_nOccupiedBuffer
> 0 ) {
130 resizeBuffer( nPos
+ nLen
);
131 m_nOccupiedBuffer
= nPos
+ nLen
;
134 sal_Int32 nStartWritingIndex
= m_nStart
+ nPos
;
135 if( nStartWritingIndex
>= m_nBufferLen
) {
136 nStartWritingIndex
-= m_nBufferLen
;
139 if( const sal_Int32 nBufferRestLen
= m_nBufferLen
-nStartWritingIndex
; nLen
> nBufferRestLen
) {
141 memcpy( &(m_p
[nStartWritingIndex
]) , seq
.getConstArray(), nBufferRestLen
);
142 memcpy( m_p
, &( seq
.getConstArray()[nBufferRestLen
] ), nLen
- nBufferRestLen
);
147 memcpy( &( m_p
[nStartWritingIndex
]), seq
.getConstArray() , nLen
);
153 sal_Int32
MemRingBuffer::getSize() const throw()
155 return m_nOccupiedBuffer
;
158 void MemRingBuffer::forgetFromStart( sal_Int32 nBytesToForget
)
161 if( nBytesToForget
> m_nOccupiedBuffer
) {
162 throw css::io::BufferSizeExceededException(
163 "MemRingBuffer::forgetFromStart BufferSizeExceededException");
165 m_nStart
+= nBytesToForget
;
166 if( m_nStart
>= m_nBufferLen
) {
167 m_nStart
= m_nStart
- m_nBufferLen
;
169 m_nOccupiedBuffer
-= nBytesToForget
;
176 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */