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 <sal/config.h>
22 #include <com/sun/star/io/BufferSizeExceededException.hpp>
23 #include <com/sun/star/io/NotConnectedException.hpp>
24 #include <com/sun/star/lang/IllegalArgumentException.hpp>
25 #include <comphelper/seqstream.hxx>
27 #include <osl/diagnose.h>
31 using namespace ::com::sun::star::lang
;
32 using namespace ::com::sun::star::io
;
33 using namespace ::com::sun::star::uno
;
34 using namespace ::osl
;
37 // class SequenceInputStream
40 SequenceInputStream::SequenceInputStream(
41 css::uno::Sequence
<sal_Int8
> const & rData
)
47 // checks if closed, returns available size, not mutex-protected
49 inline sal_Int32
SequenceInputStream::avail()
52 throw NotConnectedException(OUString(), *this);
54 return m_aData
.getLength() - m_nPos
;
57 // css::io::XInputStream
59 sal_Int32 SAL_CALL
SequenceInputStream::readBytes( Sequence
<sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
61 ::osl::MutexGuard
aGuard( m_aMutex
);
63 sal_Int32 nAvail
= avail();
66 throw BufferSizeExceededException(OUString(),*this);
68 if (nAvail
< nBytesToRead
)
69 nBytesToRead
= nAvail
;
71 aData
.realloc(nBytesToRead
);
72 memcpy(aData
.getArray(), m_aData
.getConstArray() + m_nPos
, nBytesToRead
);
73 m_nPos
+= nBytesToRead
;
79 sal_Int32 SAL_CALL
SequenceInputStream::readSomeBytes( Sequence
<sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
81 // all data is available at once
82 return readBytes(aData
, nMaxBytesToRead
);
86 void SAL_CALL
SequenceInputStream::skipBytes( sal_Int32 nBytesToSkip
)
88 ::osl::MutexGuard
aGuard( m_aMutex
);
90 sal_Int32 nAvail
= avail();
93 throw BufferSizeExceededException(OUString(),*this);
95 if (nAvail
< nBytesToSkip
)
96 nBytesToSkip
= nAvail
;
98 m_nPos
+= nBytesToSkip
;
102 sal_Int32 SAL_CALL
SequenceInputStream::available( )
104 ::osl::MutexGuard
aGuard( m_aMutex
);
110 void SAL_CALL
SequenceInputStream::closeInput( )
113 throw NotConnectedException(OUString(), *this);
118 void SAL_CALL
SequenceInputStream::seek( sal_Int64 location
)
120 if ( location
> m_aData
.getLength() || location
< 0 || location
> SAL_MAX_INT32
)
121 throw IllegalArgumentException();
122 m_nPos
= static_cast<sal_Int32
>(location
);
125 sal_Int64 SAL_CALL
SequenceInputStream::getPosition()
130 sal_Int64 SAL_CALL
SequenceInputStream::getLength( )
132 return m_aData
.getLength();
136 OSequenceOutputStream::OSequenceOutputStream(Sequence
< sal_Int8
>& _rSeq
, double _nResizeFactor
, sal_Int32 _nMinimumResize
)
138 ,m_nResizeFactor(_nResizeFactor
)
139 ,m_nMinimumResize(_nMinimumResize
)
140 ,m_nSize(0) // starting at position 0
143 OSL_ENSURE(m_nResizeFactor
> 1, "OSequenceOutputStream::OSequenceOutputStream : invalid resize factor !");
145 if (m_nResizeFactor
<= 1)
146 m_nResizeFactor
= 1.3;
150 void SAL_CALL
OSequenceOutputStream::writeBytes( const Sequence
< sal_Int8
>& _rData
)
152 MutexGuard
aGuard(m_aMutex
);
154 throw NotConnectedException();
156 // ensure the sequence has enough space left
157 if (m_nSize
+ _rData
.getLength() > m_rSequence
.getLength())
159 sal_Int32 nCurrentLength
= m_rSequence
.getLength();
160 sal_Int32 nNewLength
= static_cast< sal_Int32
>(
161 nCurrentLength
* m_nResizeFactor
);
163 if (m_nMinimumResize
> nNewLength
- nCurrentLength
)
164 // we have a minimum so it's not too inefficient for small sequences and small write requests
165 nNewLength
= nCurrentLength
+ m_nMinimumResize
;
167 if (nNewLength
< m_nSize
+ _rData
.getLength())
168 { // it's not enough .... the data would not fit
170 // let's take the double amount of the length of the data to be written, as the next write
171 // request could be as large as this one
172 sal_Int32 nNewGrowth
= _rData
.getLength() * 2;
173 nNewLength
= nCurrentLength
+ nNewGrowth
;
176 // round it off to the next multiple of 4 ...
177 nNewLength
= (nNewLength
+ 3) / 4 * 4;
179 m_rSequence
.realloc(nNewLength
);
182 OSL_ENSURE(m_rSequence
.getLength() >= m_nSize
+ _rData
.getLength(),
183 "ooops ... the realloc algorithm seems to be wrong :( !");
185 memcpy(m_rSequence
.getArray() + m_nSize
, _rData
.getConstArray(), _rData
.getLength());
186 m_nSize
+= _rData
.getLength();
190 void SAL_CALL
OSequenceOutputStream::flush( )
192 MutexGuard
aGuard(m_aMutex
);
194 throw NotConnectedException();
196 // cut the sequence to the real size
197 m_rSequence
.realloc(m_nSize
);
200 void OSequenceOutputStream::finalizeOutput()
202 MutexGuard
aGuard(m_aMutex
);
204 // cut the sequence to the real size
205 m_rSequence
.realloc(m_nSize
);
206 // and don't allow any further accesses
207 m_bConnected
= false;
210 void SAL_CALL
OSequenceOutputStream::closeOutput()
212 MutexGuard
aGuard(m_aMutex
);
214 throw NotConnectedException();
219 } // namespace comphelper
221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */