LibreOffice Module comphelper (master)  1
seqstream.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 
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>
26 
27 #include <osl/diagnose.h>
28 
29 namespace comphelper
30 {
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;
35 
36 
37 
38 
40  css::uno::Sequence<sal_Int8> const & rData)
41 : m_aData(rData)
42 , m_nPos(0)
43 {
44 }
45 
46 // checks if closed, returns available size, not mutex-protected
47 
48 inline sal_Int32 SequenceInputStream::avail()
49 {
50  if (m_nPos == -1)
51  throw NotConnectedException(OUString(), *this);
52 
53  return m_aData.getLength() - m_nPos;
54 }
55 
56 // css::io::XInputStream
57 
58 sal_Int32 SAL_CALL SequenceInputStream::readBytes( Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead )
59 {
60  ::osl::MutexGuard aGuard( m_aMutex );
61 
62  sal_Int32 nAvail = avail();
63 
64  if (nBytesToRead < 0)
65  throw BufferSizeExceededException(OUString(),*this);
66 
67  if (nAvail < nBytesToRead)
68  nBytesToRead = nAvail;
69 
70  aData.realloc(nBytesToRead);
71  memcpy(aData.getArray(), m_aData.getConstArray() + m_nPos, nBytesToRead);
72  m_nPos += nBytesToRead;
73 
74  return nBytesToRead;
75 }
76 
77 
78 sal_Int32 SAL_CALL SequenceInputStream::readSomeBytes( Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead )
79 {
80  // all data is available at once
81  return readBytes(aData, nMaxBytesToRead);
82 }
83 
84 
85 void SAL_CALL SequenceInputStream::skipBytes( sal_Int32 nBytesToSkip )
86 {
87  ::osl::MutexGuard aGuard( m_aMutex );
88 
89  sal_Int32 nAvail = avail();
90 
91  if (nBytesToSkip < 0)
92  throw BufferSizeExceededException(OUString(),*this);
93 
94  if (nAvail < nBytesToSkip)
95  nBytesToSkip = nAvail;
96 
97  m_nPos += nBytesToSkip;
98 }
99 
100 
101 sal_Int32 SAL_CALL SequenceInputStream::available( )
102 {
103  ::osl::MutexGuard aGuard( m_aMutex );
104 
105  return avail();
106 }
107 
108 
110 {
111  if (m_nPos == -1)
112  throw NotConnectedException(OUString(), *this);
113 
114  m_nPos = -1;
115 }
116 
117 void SAL_CALL SequenceInputStream::seek( sal_Int64 location )
118 {
119  if ( location > m_aData.getLength() || location < 0 || location > SAL_MAX_INT32 )
120  throw IllegalArgumentException();
121  m_nPos = static_cast<sal_Int32>(location);
122 }
123 
125 {
126  return m_nPos;
127 }
128 
129 sal_Int64 SAL_CALL SequenceInputStream::getLength( )
130 {
131  return m_aData.getLength();
132 }
133 
134 
135 OSequenceOutputStream::OSequenceOutputStream(Sequence< sal_Int8 >& _rSeq, double _nResizeFactor, sal_Int32 _nMinimumResize)
136  :m_rSequence(_rSeq)
137  ,m_nResizeFactor(_nResizeFactor)
138  ,m_nMinimumResize(_nMinimumResize)
139  ,m_nSize(0) // starting at position 0
140  ,m_bConnected(true)
141 {
142  OSL_ENSURE(m_nResizeFactor > 1, "OSequenceOutputStream::OSequenceOutputStream : invalid resize factor !");
143 
144  if (m_nResizeFactor <= 1)
145  m_nResizeFactor = 1.3;
146 }
147 
148 
149 void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rData )
150 {
151  MutexGuard aGuard(m_aMutex);
152  if (!m_bConnected)
153  throw NotConnectedException();
154 
155  // ensure the sequence has enough space left
156  if (m_nSize + _rData.getLength() > m_rSequence.getLength())
157  {
158  sal_Int32 nCurrentLength = m_rSequence.getLength();
159  sal_Int32 nNewLength = static_cast< sal_Int32 >(
160  nCurrentLength * m_nResizeFactor);
161 
162  if (m_nMinimumResize > nNewLength - nCurrentLength)
163  // we have a minimum so it's not too inefficient for small sequences and small write requests
164  nNewLength = nCurrentLength + m_nMinimumResize;
165 
166  if (nNewLength < m_nSize + _rData.getLength())
167  { // it's not enough... the data would not fit
168 
169  // let's take the double amount of the length of the data to be written, as the next write
170  // request could be as large as this one
171  sal_Int32 nNewGrowth = _rData.getLength() * 2;
172  nNewLength = nCurrentLength + nNewGrowth;
173  }
174 
175  // round it off to the next multiple of 4...
176  nNewLength = (nNewLength + 3) / 4 * 4;
177 
178  m_rSequence.realloc(nNewLength);
179  }
180 
181  OSL_ENSURE(m_rSequence.getLength() >= m_nSize + _rData.getLength(),
182  "ooops ... the realloc algorithm seems to be wrong :( !");
183 
184  memcpy(m_rSequence.getArray() + m_nSize, _rData.getConstArray(), _rData.getLength());
185  m_nSize += _rData.getLength();
186 }
187 
188 
189 void SAL_CALL OSequenceOutputStream::flush( )
190 {
191  MutexGuard aGuard(m_aMutex);
192  if (!m_bConnected)
193  throw NotConnectedException();
194 
195  // cut the sequence to the real size
196  m_rSequence.realloc(m_nSize);
197 }
198 
199 void OSequenceOutputStream::finalizeOutput()
200 {
201  MutexGuard aGuard(m_aMutex);
202 
203  // cut the sequence to the real size
204  m_rSequence.realloc(m_nSize);
205  // and don't allow any further accesses
206  m_bConnected = false;
207 }
208 
209 void SAL_CALL OSequenceOutputStream::closeOutput()
210 {
211  MutexGuard aGuard(m_aMutex);
212  if (!m_bConnected)
213  throw NotConnectedException();
214 
215  finalizeOutput();
216 }
217 
218 } // namespace comphelper
219 
220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
size_t m_nPos
::osl::Mutex m_aMutex
virtual void SAL_CALL seek(sal_Int64 location) override
Definition: seqstream.cxx:117
virtual sal_Int64 SAL_CALL getLength() override
Definition: seqstream.cxx:129
virtual sal_Int32 SAL_CALL available() override
Definition: seqstream.cxx:101
MapData m_aData
virtual sal_Int64 SAL_CALL getPosition() override
Definition: seqstream.cxx:124
SequenceInputStream(css::uno::Sequence< sal_Int8 > const &rData)
Definition: seqstream.cxx:39
#define SAL_MAX_INT32
virtual void SAL_CALL closeInput() override
Definition: seqstream.cxx:109
virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) override
Definition: seqstream.cxx:85
css::uno::Sequence< sal_Int8 > const m_aData
Definition: seqstream.hxx:43
virtual sal_Int32 SAL_CALL readBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nBytesToRead) override
virtual sal_Int32 SAL_CALL readSomeBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nMaxBytesToRead) override
sal_uInt32 m_nSize