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
;
39 MemoryInputStream::MemoryInputStream(
40 const sal_Int8
* pData
, sal_Int32 nDataLength
)
41 : m_pMemoryData(pData
)
42 , m_nMemoryDataLength(nDataLength
)
47 // checks if closed, returns available size, not mutex-protected
49 inline sal_Int32
MemoryInputStream::avail()
52 throw NotConnectedException(OUString(), *this);
54 return m_nMemoryDataLength
- m_nPos
;
57 // css::io::XInputStream
59 sal_Int32 SAL_CALL
MemoryInputStream::readBytes( Sequence
<sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
62 throw BufferSizeExceededException(OUString(),*this);
64 std::scoped_lock
aGuard( m_aMutex
);
66 sal_Int32 nAvail
= avail();
68 if (nAvail
< nBytesToRead
)
69 nBytesToRead
= nAvail
;
71 aData
.realloc(nBytesToRead
);
72 memcpy(aData
.getArray(), m_pMemoryData
+ m_nPos
, nBytesToRead
);
73 m_nPos
+= nBytesToRead
;
78 sal_Int32
MemoryInputStream::readSomeBytes( sal_Int8
* pData
, sal_Int32 nBytesToRead
)
81 throw BufferSizeExceededException(OUString(),*this);
83 std::scoped_lock
aGuard( m_aMutex
);
85 sal_Int32 nAvail
= avail();
87 if (nAvail
< nBytesToRead
)
88 nBytesToRead
= nAvail
;
90 memcpy(pData
, m_pMemoryData
+ m_nPos
, nBytesToRead
);
91 m_nPos
+= nBytesToRead
;
96 sal_Int32 SAL_CALL
MemoryInputStream::readSomeBytes( Sequence
<sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
98 // all data is available at once
99 return readBytes(aData
, nMaxBytesToRead
);
103 void SAL_CALL
MemoryInputStream::skipBytes( sal_Int32 nBytesToSkip
)
105 if (nBytesToSkip
< 0)
106 throw BufferSizeExceededException(OUString(),*this);
108 std::scoped_lock
aGuard( m_aMutex
);
110 sal_Int32 nAvail
= avail();
112 if (nAvail
< nBytesToSkip
)
113 nBytesToSkip
= nAvail
;
115 m_nPos
+= nBytesToSkip
;
119 sal_Int32 SAL_CALL
MemoryInputStream::available( )
121 std::scoped_lock
aGuard( m_aMutex
);
127 void SAL_CALL
MemoryInputStream::closeInput( )
129 std::scoped_lock
aGuard( m_aMutex
);
132 throw NotConnectedException(OUString(), *this);
137 void SAL_CALL
MemoryInputStream::seek( sal_Int64 location
)
139 if ( location
> m_nMemoryDataLength
|| location
< 0 || location
> SAL_MAX_INT32
)
140 throw IllegalArgumentException("bad location", static_cast<cppu::OWeakObject
*>(this), 1);
141 std::scoped_lock
aGuard( m_aMutex
);
142 m_nPos
= static_cast<sal_Int32
>(location
);
145 sal_Int64 SAL_CALL
MemoryInputStream::getPosition()
147 std::scoped_lock
aGuard( m_aMutex
);
151 sal_Int64 SAL_CALL
MemoryInputStream::getLength( )
153 std::scoped_lock
aGuard( m_aMutex
);
154 return m_nMemoryDataLength
;
158 SequenceInputStream::SequenceInputStream(
159 css::uno::Sequence
<sal_Int8
> const & rData
)
160 : MemoryInputStream(rData
.getConstArray(), rData
.getLength())
166 OSequenceOutputStream::OSequenceOutputStream(Sequence
< sal_Int8
>& _rSeq
, double _nResizeFactor
, sal_Int32 _nMinimumResize
)
168 ,m_nResizeFactor(_nResizeFactor
)
169 ,m_nMinimumResize(_nMinimumResize
)
170 ,m_nSize(0) // starting at position 0
173 OSL_ENSURE(m_nResizeFactor
> 1, "OSequenceOutputStream::OSequenceOutputStream : invalid resize factor !");
175 if (m_nResizeFactor
<= 1)
176 m_nResizeFactor
= 1.3;
180 void SAL_CALL
OSequenceOutputStream::writeBytes( const Sequence
< sal_Int8
>& _rData
)
182 std::scoped_lock
aGuard(m_aMutex
);
184 throw NotConnectedException();
186 // ensure the sequence has enough space left
187 if (m_nSize
+ _rData
.getLength() > m_rSequence
.getLength())
189 sal_Int32 nCurrentLength
= m_rSequence
.getLength();
190 sal_Int32 nNewLength
= static_cast< sal_Int32
>(
191 nCurrentLength
* m_nResizeFactor
);
193 if (m_nMinimumResize
> nNewLength
- nCurrentLength
)
194 // we have a minimum so it's not too inefficient for small sequences and small write requests
195 nNewLength
= nCurrentLength
+ m_nMinimumResize
;
197 if (nNewLength
< m_nSize
+ _rData
.getLength())
198 { // it's not enough... the data would not fit
200 // let's take the double amount of the length of the data to be written, as the next write
201 // request could be as large as this one
202 sal_Int32 nNewGrowth
= _rData
.getLength() * 2;
203 nNewLength
= nCurrentLength
+ nNewGrowth
;
206 // round it off to the next multiple of 4...
207 nNewLength
= (nNewLength
+ 3) / 4 * 4;
209 m_rSequence
.realloc(nNewLength
);
212 OSL_ENSURE(m_rSequence
.getLength() >= m_nSize
+ _rData
.getLength(),
213 "ooops ... the realloc algorithm seems to be wrong :( !");
215 memcpy(m_rSequence
.getArray() + m_nSize
, _rData
.getConstArray(), _rData
.getLength());
216 m_nSize
+= _rData
.getLength();
220 void SAL_CALL
OSequenceOutputStream::flush( )
222 std::scoped_lock
aGuard(m_aMutex
);
224 throw NotConnectedException();
226 // cut the sequence to the real size
227 m_rSequence
.realloc(m_nSize
);
230 void OSequenceOutputStream::finalizeOutput()
232 // cut the sequence to the real size
233 m_rSequence
.realloc(m_nSize
);
234 // and don't allow any further accesses
235 m_bConnected
= false;
238 void SAL_CALL
OSequenceOutputStream::closeOutput()
240 std::scoped_lock
aGuard(m_aMutex
);
242 throw NotConnectedException();
247 } // namespace comphelper
249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */