1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24
25 // MARKER(update_precomp.py): autogen include statement, do not remove
26 #include "precompiled_xmlhelp.hxx"
27 #include <rtl/memory.h>
28 #include "bufferedinputstream.hxx"
29
30
31 using namespace cppu;
32 using namespace com::sun::star::uno;
33 using namespace com::sun::star::lang;
34 using namespace com::sun::star::io;
35 using namespace chelp;
36
37
turnToSeekable(const Reference<XInputStream> & xInputStream)38 Reference<XInputStream> chelp::turnToSeekable(const Reference<XInputStream>& xInputStream)
39 {
40 if( ! xInputStream.is() )
41 return xInputStream;
42
43 Reference<XSeekable> xSeekable(xInputStream,UNO_QUERY);
44
45 if( xSeekable.is() )
46 return xInputStream;
47
48 return new BufferedInputStream(xInputStream);
49 }
50
51
52
BufferedInputStream(const Reference<XInputStream> & xInputStream)53 BufferedInputStream::BufferedInputStream(const Reference<XInputStream>& xInputStream)
54 : m_nBufferLocation(0),
55 m_nBufferSize(0),
56 m_pBuffer(new sal_Int8[1]) // Initialize with one to avoid gcc compiler warnings
57 {
58 try
59 {
60 sal_Int32 num;
61 sal_Int8 *tmp;
62 Sequence< sal_Int8 > aData(4096);
63 do{
64 num = xInputStream->readBytes(aData,4096);
65 if( num > 0 )
66 {
67 tmp = m_pBuffer;
68 m_pBuffer = new sal_Int8[m_nBufferSize+num];
69 rtl_copyMemory((void *)(m_pBuffer),
70 (void *)(tmp),
71 sal_uInt32(m_nBufferSize));
72 rtl_copyMemory((void *)(m_pBuffer+m_nBufferSize),
73 (void *)(aData.getArray()),
74 sal_uInt32(num));
75 m_nBufferSize += num;
76 delete[] tmp;
77 }
78 } while( num == 4096 );
79 }
80 catch( const NotConnectedException&)
81 {
82 }
83 catch( const BufferSizeExceededException&)
84 {
85 }
86 catch( const IOException&)
87 {
88 }
89 catch( const RuntimeException&)
90 {
91 }
92 xInputStream->closeInput();
93 }
94
95
~BufferedInputStream()96 BufferedInputStream::~BufferedInputStream()
97 {
98 delete[] m_pBuffer;
99 }
100
101
queryInterface(const Type & rType)102 Any SAL_CALL BufferedInputStream::queryInterface( const Type& rType ) throw( RuntimeException )
103 {
104 Any aRet = ::cppu::queryInterface( rType,
105 SAL_STATIC_CAST( XInputStream*,this ),
106 SAL_STATIC_CAST( XSeekable*,this ) );
107
108 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
109 }
110
111
acquire(void)112 void SAL_CALL BufferedInputStream::acquire( void ) throw()
113 {
114 OWeakObject::acquire();
115 }
116
117
release(void)118 void SAL_CALL BufferedInputStream::release( void ) throw()
119 {
120 OWeakObject::release();
121 }
122
123
124
readBytes(Sequence<sal_Int8> & aData,sal_Int32 nBytesToRead)125 sal_Int32 SAL_CALL BufferedInputStream::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead )
126 throw( NotConnectedException,
127 BufferSizeExceededException,
128 IOException,
129 RuntimeException)
130 {
131 osl::MutexGuard aGuard( m_aMutex );
132
133 if( 0 > nBytesToRead )
134 throw BufferSizeExceededException();
135
136 if( m_nBufferLocation + nBytesToRead > m_nBufferSize )
137 nBytesToRead = m_nBufferSize - m_nBufferLocation;
138
139 if( aData.getLength() < nBytesToRead )
140 aData.realloc(nBytesToRead);
141
142 rtl_copyMemory((void*)(aData.getArray()),
143 (void*)(m_pBuffer+m_nBufferLocation),
144 nBytesToRead);
145
146 return nBytesToRead;
147 }
148
149
readSomeBytes(Sequence<sal_Int8> & aData,sal_Int32 nMaxBytesToRead)150 sal_Int32 SAL_CALL BufferedInputStream::readSomeBytes(
151 Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
152 throw( NotConnectedException,
153 BufferSizeExceededException,
154 IOException,
155 RuntimeException)
156 {
157 return readBytes(aData,nMaxBytesToRead);
158 }
159
160
161
skipBytes(sal_Int32 nBytesToSkip)162 void SAL_CALL BufferedInputStream::skipBytes( sal_Int32 nBytesToSkip )
163 throw( NotConnectedException,
164 BufferSizeExceededException,
165 IOException,
166 RuntimeException )
167 {
168 try
169 {
170 seek(m_nBufferLocation+nBytesToSkip);
171 }
172 catch( const IllegalArgumentException& )
173 {
174 throw BufferSizeExceededException();
175 }
176 }
177
178
179
available(void)180 sal_Int32 SAL_CALL BufferedInputStream::available( void )
181 throw( NotConnectedException,
182 IOException,
183 RuntimeException )
184 {
185 osl::MutexGuard aGuard( m_aMutex );
186 return m_nBufferSize-m_nBufferLocation;
187 }
188
189
190
closeInput(void)191 void SAL_CALL BufferedInputStream::closeInput( void )
192 throw( NotConnectedException,
193 IOException,
194 RuntimeException )
195 {
196 }
197
198
seek(sal_Int64 location)199 void SAL_CALL BufferedInputStream::seek( sal_Int64 location )
200 throw( IllegalArgumentException,
201 IOException,
202 RuntimeException )
203 {
204 if( 0 <= location && location < m_nBufferSize )
205 {
206 osl::MutexGuard aGuard( m_aMutex );
207 m_nBufferLocation = sal::static_int_cast<sal_Int32>( location );
208 }
209 else
210 throw IllegalArgumentException();
211 }
212
213
214
getPosition(void)215 sal_Int64 SAL_CALL BufferedInputStream::getPosition( void )
216 throw( IOException,
217 RuntimeException )
218 {
219 osl::MutexGuard aGuard( m_aMutex );
220 return m_nBufferLocation;
221 }
222
223
224
getLength(void)225 sal_Int64 SAL_CALL BufferedInputStream::getLength( void ) throw( IOException,RuntimeException )
226 {
227 osl::MutexGuard aGuard( m_aMutex );
228 return m_nBufferSize;
229 }
230