bump product version to 6.3.0.0.beta1
[LibreOffice.git] / comphelper / source / streaming / seqstream.cxx
blobe7bcad1103c164bc0cf27206e0a67896e489fbee
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
29 namespace comphelper
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)
42 : m_aData(rData)
43 , m_nPos(0)
47 // checks if closed, returns available size, not mutex-protected
49 inline sal_Int32 SequenceInputStream::avail()
51 if (m_nPos == -1)
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();
65 if (nBytesToRead < 0)
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;
75 return 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();
92 if (nBytesToSkip < 0)
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 );
106 return avail();
110 void SAL_CALL SequenceInputStream::closeInput( )
112 if (m_nPos == -1)
113 throw NotConnectedException(OUString(), *this);
115 m_nPos = -1;
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()
127 return m_nPos;
130 sal_Int64 SAL_CALL SequenceInputStream::getLength( )
132 return m_aData.getLength();
136 OSequenceOutputStream::OSequenceOutputStream(Sequence< sal_Int8 >& _rSeq, double _nResizeFactor, sal_Int32 _nMinimumResize)
137 :m_rSequence(_rSeq)
138 ,m_nResizeFactor(_nResizeFactor)
139 ,m_nMinimumResize(_nMinimumResize)
140 ,m_nSize(0) // starting at position 0
141 ,m_bConnected(true)
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);
153 if (!m_bConnected)
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);
193 if (!m_bConnected)
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);
213 if (!m_bConnected)
214 throw NotConnectedException();
216 finalizeOutput();
219 } // namespace comphelper
221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */