xref: /trunk/main/xmlhelp/source/cxxhelp/provider/bufferedinputstream.cxx (revision 9d37da743abb7db0a497688391f6e55a19f27c44)
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 
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 
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 
96 BufferedInputStream::~BufferedInputStream()
97 {
98     delete[] m_pBuffer;
99 }
100 
101 
102 Any SAL_CALL BufferedInputStream::queryInterface( const Type& rType )
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 
112 void SAL_CALL BufferedInputStream::acquire( void ) throw()
113 {
114     OWeakObject::acquire();
115 }
116 
117 
118 void SAL_CALL BufferedInputStream::release( void ) throw()
119 {
120     OWeakObject::release();
121 }
122 
123 
124 
125 sal_Int32 SAL_CALL BufferedInputStream::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead )
126 {
127     osl::MutexGuard aGuard( m_aMutex );
128 
129     if( 0 > nBytesToRead )
130         throw BufferSizeExceededException();
131 
132     if( m_nBufferLocation + nBytesToRead > m_nBufferSize )
133         nBytesToRead = m_nBufferSize - m_nBufferLocation;
134 
135     if( aData.getLength() < nBytesToRead )
136         aData.realloc(nBytesToRead);
137 
138     rtl_copyMemory((void*)(aData.getArray()),
139                    (void*)(m_pBuffer+m_nBufferLocation),
140                    nBytesToRead);
141 
142     return nBytesToRead;
143 }
144 
145 
146 sal_Int32 SAL_CALL BufferedInputStream::readSomeBytes(
147     Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
148 {
149     return readBytes(aData,nMaxBytesToRead);
150 }
151 
152 
153 
154 void SAL_CALL BufferedInputStream::skipBytes( sal_Int32 nBytesToSkip )
155 {
156     try
157     {
158         seek(m_nBufferLocation+nBytesToSkip);
159     }
160     catch( const IllegalArgumentException& )
161     {
162         throw BufferSizeExceededException();
163     }
164 }
165 
166 
167 
168 sal_Int32 SAL_CALL BufferedInputStream::available( void )
169 {
170     osl::MutexGuard aGuard( m_aMutex );
171     return  m_nBufferSize-m_nBufferLocation;
172 }
173 
174 
175 
176 void SAL_CALL BufferedInputStream::closeInput( void )
177 {
178 }
179 
180 
181 void SAL_CALL BufferedInputStream::seek( sal_Int64 location )
182 {
183     if( 0 <= location && location < m_nBufferSize )
184     {
185         osl::MutexGuard aGuard( m_aMutex );
186         m_nBufferLocation = sal::static_int_cast<sal_Int32>( location );
187     }
188     else
189         throw IllegalArgumentException();
190 }
191 
192 
193 
194 sal_Int64 SAL_CALL BufferedInputStream::getPosition( void )
195 {
196     osl::MutexGuard aGuard( m_aMutex );
197     return m_nBufferLocation;
198 }
199 
200 
201 
202 sal_Int64 SAL_CALL BufferedInputStream::getLength( void )
203 {
204     osl::MutexGuard aGuard( m_aMutex );
205     return m_nBufferSize;
206 }
207