1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <comphelper/seqstream.hxx>
32 #include <memory.h> // for memcpy
36 using namespace ::com::sun::star::lang
;
37 using namespace ::com::sun::star::io
;
38 using namespace ::com::sun::star::uno
;
39 using namespace ::osl
;
41 //---------------------------------------------------------------------------------------------
42 // class SequenceInputStream
43 //---------------------------------------------------------------------------------------------
45 //------------------------------------------------------------------
46 SequenceInputStream::SequenceInputStream(const ByteSequence
& rData
)
52 // checks if closed, returns available size, not mutex-protected
53 //------------------------------------------------------------------
54 inline sal_Int32
SequenceInputStream::avail()
57 throw NotConnectedException(::rtl::OUString(), *this);
59 return m_aData
.getLength() - m_nPos
;
62 // com::sun::star::io::XInputStream
63 //------------------------------------------------------------------
64 sal_Int32 SAL_CALL
SequenceInputStream::readBytes( Sequence
<sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
65 throw(NotConnectedException
, BufferSizeExceededException
,
66 IOException
, RuntimeException
)
68 ::osl::MutexGuard
aGuard( m_aMutex
);
70 sal_Int32 nAvail
= avail();
73 throw BufferSizeExceededException(::rtl::OUString(),*this);
75 if (nAvail
< nBytesToRead
)
76 nBytesToRead
= nAvail
;
78 aData
.realloc(nBytesToRead
);
79 memcpy(aData
.getArray(), m_aData
.getConstArray() + m_nPos
, nBytesToRead
);
80 m_nPos
+= nBytesToRead
;
85 //------------------------------------------------------------------
86 sal_Int32 SAL_CALL
SequenceInputStream::readSomeBytes( Sequence
<sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
87 throw(NotConnectedException
, BufferSizeExceededException
,
88 IOException
, RuntimeException
)
90 // all data is available at once
91 return readBytes(aData
, nMaxBytesToRead
);
94 //------------------------------------------------------------------
95 void SAL_CALL
SequenceInputStream::skipBytes( sal_Int32 nBytesToSkip
)
96 throw(NotConnectedException
, BufferSizeExceededException
,
97 IOException
, RuntimeException
)
99 ::osl::MutexGuard
aGuard( m_aMutex
);
101 sal_Int32 nAvail
= avail();
103 if (nBytesToSkip
< 0)
104 throw BufferSizeExceededException(::rtl::OUString(),*this);
106 if (nAvail
< nBytesToSkip
)
107 nBytesToSkip
= nAvail
;
109 m_nPos
+= nBytesToSkip
;
112 //------------------------------------------------------------------
113 sal_Int32 SAL_CALL
SequenceInputStream::available( )
114 throw(NotConnectedException
, IOException
, RuntimeException
)
116 ::osl::MutexGuard
aGuard( m_aMutex
);
121 //------------------------------------------------------------------
122 void SAL_CALL
SequenceInputStream::closeInput( )
123 throw(NotConnectedException
, IOException
, RuntimeException
)
126 throw NotConnectedException(::rtl::OUString(), *this);
131 void SAL_CALL
SequenceInputStream::seek( sal_Int64 location
) throw (IllegalArgumentException
, IOException
, RuntimeException
)
133 if ( location
> m_aData
.getLength() || location
< 0 || location
> SAL_MAX_INT32
)
134 throw IllegalArgumentException();
135 m_nPos
= (sal_Int32
) location
;
138 sal_Int64 SAL_CALL
SequenceInputStream::getPosition() throw (IOException
, RuntimeException
)
143 sal_Int64 SAL_CALL
SequenceInputStream::getLength( ) throw (IOException
, RuntimeException
)
145 return m_aData
.getLength();
148 //--------------------------------------------------------------------------
149 OSequenceOutputStream::OSequenceOutputStream(Sequence
< sal_Int8
>& _rSeq
, double _nResizeFactor
, sal_Int32 _nMinimumResize
, sal_Int32 _nMaximumResize
)
151 ,m_nResizeFactor(_nResizeFactor
)
152 ,m_nMinimumResize(_nMinimumResize
)
153 ,m_nMaximumResize(_nMaximumResize
)
154 ,m_nSize(0) // starting at position 0
155 ,m_bConnected(sal_True
)
157 OSL_ENSURE(m_nResizeFactor
> 1, "OSequenceOutputStream::OSequenceOutputStream : invalid resize factor !");
158 OSL_ENSURE((m_nMaximumResize
< 0) || (m_nMaximumResize
> m_nMinimumResize
),
159 "OSequenceOutputStream::OSequenceOutputStream : these limits don't make any sense !");
161 if (m_nResizeFactor
<= 1)
162 m_nResizeFactor
= 1.3;
163 if ((m_nMaximumResize
>= 0) && (m_nMaximumResize
<= m_nMinimumResize
))
164 m_nMaximumResize
= m_nMinimumResize
* 2;
165 // this heuristic is as good as any other ... supply better parameters if you don't like it :)
168 //--------------------------------------------------------------------------
169 void SAL_CALL
OSequenceOutputStream::writeBytes( const Sequence
< sal_Int8
>& _rData
) throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
171 MutexGuard
aGuard(m_aMutex
);
173 throw NotConnectedException();
175 // ensure the sequence has enoungh space left
176 if (m_nSize
+ _rData
.getLength() > m_rSequence
.getLength())
178 sal_Int32 nCurrentLength
= m_rSequence
.getLength();
179 sal_Int32 nNewLength
= static_cast< sal_Int32
>(
180 nCurrentLength
* m_nResizeFactor
);
182 if (m_nMinimumResize
> nNewLength
- nCurrentLength
)
183 // we have a minimum so it's not too inefficient for small sequences and small write requests
184 nNewLength
= nCurrentLength
+ m_nMinimumResize
;
186 if ((m_nMaximumResize
> 0) && (nNewLength
- nCurrentLength
> m_nMaximumResize
))
187 // such a large step is not allowed
188 nNewLength
= nCurrentLength
+ m_nMaximumResize
;
190 if (nNewLength
< m_nSize
+ _rData
.getLength())
191 { // it's not enough .... the data would not fit
193 // let's take the double amount of the length of the data to be written, as the next write
194 // request could be as large as this one
195 sal_Int32 nNewGrowth
= _rData
.getLength() * 2;
196 if ((m_nMaximumResize
> 0) && (nNewGrowth
> m_nMaximumResize
))
197 { // we came to the limit, again ...
198 nNewGrowth
= m_nMaximumResize
;
199 if (nNewGrowth
+ nCurrentLength
< m_nSize
+ _rData
.getLength())
200 // but it would not fit if we respect the limit
201 nNewGrowth
= m_nSize
+ _rData
.getLength() - nCurrentLength
;
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();
219 //--------------------------------------------------------------------------
220 void SAL_CALL
OSequenceOutputStream::flush( ) throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
222 MutexGuard
aGuard(m_aMutex
);
224 throw NotConnectedException();
226 // cut the sequence to the real size
227 m_rSequence
.realloc(m_nSize
);
230 //--------------------------------------------------------------------------
231 void SAL_CALL
OSequenceOutputStream::closeOutput( ) throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
233 MutexGuard
aGuard(m_aMutex
);
235 throw NotConnectedException();
237 // cut the sequence to the real size
238 m_rSequence
.realloc(m_nSize
);
239 // and don't allow any further accesses
240 m_bConnected
= sal_False
;
243 } // namespace comphelper