1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: seqstream.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_comphelper.hxx"
33 #include <comphelper/seqstream.hxx>
35 #include <memory.h> // for memcpy
39 using namespace ::com::sun::star::lang
;
40 using namespace ::com::sun::star::io
;
41 using namespace ::com::sun::star::uno
;
42 using namespace ::osl
;
44 //---------------------------------------------------------------------------------------------
45 // class SequenceInputStream
46 //---------------------------------------------------------------------------------------------
48 //------------------------------------------------------------------
49 SequenceInputStream::SequenceInputStream(const ByteSequence
& rData
)
55 // checks if closed, returns available size, not mutex-protected
56 //------------------------------------------------------------------
57 inline sal_Int32
SequenceInputStream::avail()
60 throw NotConnectedException(::rtl::OUString(), *this);
62 return m_aData
.getLength() - m_nPos
;
65 // com::sun::star::io::XInputStream
66 //------------------------------------------------------------------
67 sal_Int32 SAL_CALL
SequenceInputStream::readBytes( Sequence
<sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
68 throw(NotConnectedException
, BufferSizeExceededException
,
69 IOException
, RuntimeException
)
71 ::osl::MutexGuard
aGuard( m_aMutex
);
73 sal_Int32 nAvail
= avail();
76 throw BufferSizeExceededException(::rtl::OUString(),*this);
78 if (nAvail
< nBytesToRead
)
79 nBytesToRead
= nAvail
;
81 aData
.realloc(nBytesToRead
);
82 memcpy(aData
.getArray(), m_aData
.getConstArray() + m_nPos
, nBytesToRead
);
83 m_nPos
+= nBytesToRead
;
88 //------------------------------------------------------------------
89 sal_Int32 SAL_CALL
SequenceInputStream::readSomeBytes( Sequence
<sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
90 throw(NotConnectedException
, BufferSizeExceededException
,
91 IOException
, RuntimeException
)
93 // all data is available at once
94 return readBytes(aData
, nMaxBytesToRead
);
97 //------------------------------------------------------------------
98 void SAL_CALL
SequenceInputStream::skipBytes( sal_Int32 nBytesToSkip
)
99 throw(NotConnectedException
, BufferSizeExceededException
,
100 IOException
, RuntimeException
)
102 ::osl::MutexGuard
aGuard( m_aMutex
);
104 sal_Int32 nAvail
= avail();
106 if (nBytesToSkip
< 0)
107 throw BufferSizeExceededException(::rtl::OUString(),*this);
109 if (nAvail
< nBytesToSkip
)
110 nBytesToSkip
= nAvail
;
112 m_nPos
+= nBytesToSkip
;
115 //------------------------------------------------------------------
116 sal_Int32 SAL_CALL
SequenceInputStream::available( )
117 throw(NotConnectedException
, IOException
, RuntimeException
)
119 ::osl::MutexGuard
aGuard( m_aMutex
);
124 //------------------------------------------------------------------
125 void SAL_CALL
SequenceInputStream::closeInput( )
126 throw(NotConnectedException
, IOException
, RuntimeException
)
129 throw NotConnectedException(::rtl::OUString(), *this);
134 void SAL_CALL
SequenceInputStream::seek( sal_Int64 location
) throw (IllegalArgumentException
, IOException
, RuntimeException
)
136 if ( location
> m_aData
.getLength() || location
< 0 || location
> SAL_MAX_INT32
)
137 throw IllegalArgumentException();
138 m_nPos
= (sal_Int32
) location
;
141 sal_Int64 SAL_CALL
SequenceInputStream::getPosition() throw (IOException
, RuntimeException
)
146 sal_Int64 SAL_CALL
SequenceInputStream::getLength( ) throw (IOException
, RuntimeException
)
148 return m_aData
.getLength();
151 //--------------------------------------------------------------------------
152 OSequenceOutputStream::OSequenceOutputStream(Sequence
< sal_Int8
>& _rSeq
, double _nResizeFactor
, sal_Int32 _nMinimumResize
, sal_Int32 _nMaximumResize
)
154 ,m_nResizeFactor(_nResizeFactor
)
155 ,m_nMinimumResize(_nMinimumResize
)
156 ,m_nMaximumResize(_nMaximumResize
)
157 ,m_nSize(0) // starting at position 0
158 ,m_bConnected(sal_True
)
160 OSL_ENSURE(m_nResizeFactor
> 1, "OSequenceOutputStream::OSequenceOutputStream : invalid resize factor !");
161 OSL_ENSURE((m_nMaximumResize
< 0) || (m_nMaximumResize
> m_nMinimumResize
),
162 "OSequenceOutputStream::OSequenceOutputStream : these limits don't make any sense !");
164 if (m_nResizeFactor
<= 1)
165 m_nResizeFactor
= 1.3;
166 if ((m_nMaximumResize
>= 0) && (m_nMaximumResize
<= m_nMinimumResize
))
167 m_nMaximumResize
= m_nMinimumResize
* 2;
168 // this heuristic is as good as any other ... supply better parameters if you don't like it :)
171 //--------------------------------------------------------------------------
172 void SAL_CALL
OSequenceOutputStream::writeBytes( const Sequence
< sal_Int8
>& _rData
) throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
174 MutexGuard
aGuard(m_aMutex
);
176 throw NotConnectedException();
178 // ensure the sequence has enoungh space left
179 if (m_nSize
+ _rData
.getLength() > m_rSequence
.getLength())
181 sal_Int32 nCurrentLength
= m_rSequence
.getLength();
182 sal_Int32 nNewLength
= static_cast< sal_Int32
>(
183 nCurrentLength
* m_nResizeFactor
);
185 if (m_nMinimumResize
> nNewLength
- nCurrentLength
)
186 // we have a minimum so it's not too inefficient for small sequences and small write requests
187 nNewLength
= nCurrentLength
+ m_nMinimumResize
;
189 if ((m_nMaximumResize
> 0) && (nNewLength
- nCurrentLength
> m_nMaximumResize
))
190 // such a large step is not allowed
191 nNewLength
= nCurrentLength
+ m_nMaximumResize
;
193 if (nNewLength
< m_nSize
+ _rData
.getLength())
194 { // it's not enough .... the data would not fit
196 // let's take the double amount of the length of the data to be written, as the next write
197 // request could be as large as this one
198 sal_Int32 nNewGrowth
= _rData
.getLength() * 2;
199 if ((m_nMaximumResize
> 0) && (nNewGrowth
> m_nMaximumResize
))
200 { // we came to the limit, again ...
201 nNewGrowth
= m_nMaximumResize
;
202 if (nNewGrowth
+ nCurrentLength
< m_nSize
+ _rData
.getLength())
203 // but it would not fit if we respect the limit
204 nNewGrowth
= m_nSize
+ _rData
.getLength() - nCurrentLength
;
206 nNewLength
= nCurrentLength
+ nNewGrowth
;
209 // round it off to the next multiple of 4 ...
210 nNewLength
= (nNewLength
+ 3) / 4 * 4;
212 m_rSequence
.realloc(nNewLength
);
215 OSL_ENSURE(m_rSequence
.getLength() >= m_nSize
+ _rData
.getLength(),
216 "ooops ... the realloc algorithm seems to be wrong :( !");
218 memcpy(m_rSequence
.getArray() + m_nSize
, _rData
.getConstArray(), _rData
.getLength());
219 m_nSize
+= _rData
.getLength();
222 //--------------------------------------------------------------------------
223 void SAL_CALL
OSequenceOutputStream::flush( ) throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
225 MutexGuard
aGuard(m_aMutex
);
227 throw NotConnectedException();
229 // cut the sequence to the real size
230 m_rSequence
.realloc(m_nSize
);
233 //--------------------------------------------------------------------------
234 void SAL_CALL
OSequenceOutputStream::closeOutput( ) throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
236 MutexGuard
aGuard(m_aMutex
);
238 throw NotConnectedException();
240 // cut the sequence to the real size
241 m_rSequence
.realloc(m_nSize
);
242 // and don't allow any further accesses
243 m_bConnected
= sal_False
;
246 } // namespace comphelper