1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 29 // MARKER(update_precomp.py): autogen include statement, do not remove 30 #include "precompiled_xmlhelp.hxx" 31 #include <rtl/memory.h> 32 #include "bufferedinputstream.hxx" 33 34 35 using namespace cppu; 36 using namespace com::sun::star::uno; 37 using namespace com::sun::star::lang; 38 using namespace com::sun::star::io; 39 using namespace chelp; 40 41 42 Reference<XInputStream> chelp::turnToSeekable(const Reference<XInputStream>& xInputStream) 43 { 44 if( ! xInputStream.is() ) 45 return xInputStream; 46 47 Reference<XSeekable> xSeekable(xInputStream,UNO_QUERY); 48 49 if( xSeekable.is() ) 50 return xInputStream; 51 52 return new BufferedInputStream(xInputStream); 53 } 54 55 56 57 BufferedInputStream::BufferedInputStream(const Reference<XInputStream>& xInputStream) 58 : m_nBufferLocation(0), 59 m_nBufferSize(0), 60 m_pBuffer(new sal_Int8[1]) // Initialize with one to avoid gcc compiler warnings 61 { 62 try 63 { 64 sal_Int32 num; 65 sal_Int8 *tmp; 66 Sequence< sal_Int8 > aData(4096); 67 do{ 68 num = xInputStream->readBytes(aData,4096); 69 if( num > 0 ) 70 { 71 tmp = m_pBuffer; 72 m_pBuffer = new sal_Int8[m_nBufferSize+num]; 73 rtl_copyMemory((void *)(m_pBuffer), 74 (void *)(tmp), 75 sal_uInt32(m_nBufferSize)); 76 rtl_copyMemory((void *)(m_pBuffer+m_nBufferSize), 77 (void *)(aData.getArray()), 78 sal_uInt32(num)); 79 m_nBufferSize += num; 80 delete[] tmp; 81 } 82 } while( num == 4096 ); 83 } 84 catch( const NotConnectedException&) 85 { 86 } 87 catch( const BufferSizeExceededException&) 88 { 89 } 90 catch( const IOException&) 91 { 92 } 93 catch( const RuntimeException&) 94 { 95 } 96 xInputStream->closeInput(); 97 } 98 99 100 BufferedInputStream::~BufferedInputStream() 101 { 102 delete[] m_pBuffer; 103 } 104 105 106 Any SAL_CALL BufferedInputStream::queryInterface( const Type& rType ) throw( RuntimeException ) 107 { 108 Any aRet = ::cppu::queryInterface( rType, 109 SAL_STATIC_CAST( XInputStream*,this ), 110 SAL_STATIC_CAST( XSeekable*,this ) ); 111 112 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); 113 } 114 115 116 void SAL_CALL BufferedInputStream::acquire( void ) throw() 117 { 118 OWeakObject::acquire(); 119 } 120 121 122 void SAL_CALL BufferedInputStream::release( void ) throw() 123 { 124 OWeakObject::release(); 125 } 126 127 128 129 sal_Int32 SAL_CALL BufferedInputStream::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) 130 throw( NotConnectedException, 131 BufferSizeExceededException, 132 IOException, 133 RuntimeException) 134 { 135 osl::MutexGuard aGuard( m_aMutex ); 136 137 if( 0 > nBytesToRead ) 138 throw BufferSizeExceededException(); 139 140 if( m_nBufferLocation + nBytesToRead > m_nBufferSize ) 141 nBytesToRead = m_nBufferSize - m_nBufferLocation; 142 143 if( aData.getLength() < nBytesToRead ) 144 aData.realloc(nBytesToRead); 145 146 rtl_copyMemory((void*)(aData.getArray()), 147 (void*)(m_pBuffer+m_nBufferLocation), 148 nBytesToRead); 149 150 return nBytesToRead; 151 } 152 153 154 sal_Int32 SAL_CALL BufferedInputStream::readSomeBytes( 155 Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) 156 throw( NotConnectedException, 157 BufferSizeExceededException, 158 IOException, 159 RuntimeException) 160 { 161 return readBytes(aData,nMaxBytesToRead); 162 } 163 164 165 166 void SAL_CALL BufferedInputStream::skipBytes( sal_Int32 nBytesToSkip ) 167 throw( NotConnectedException, 168 BufferSizeExceededException, 169 IOException, 170 RuntimeException ) 171 { 172 try 173 { 174 seek(m_nBufferLocation+nBytesToSkip); 175 } 176 catch( const IllegalArgumentException& ) 177 { 178 throw BufferSizeExceededException(); 179 } 180 } 181 182 183 184 sal_Int32 SAL_CALL BufferedInputStream::available( void ) 185 throw( NotConnectedException, 186 IOException, 187 RuntimeException ) 188 { 189 osl::MutexGuard aGuard( m_aMutex ); 190 return m_nBufferSize-m_nBufferLocation; 191 } 192 193 194 195 void SAL_CALL BufferedInputStream::closeInput( void ) 196 throw( NotConnectedException, 197 IOException, 198 RuntimeException ) 199 { 200 } 201 202 203 void SAL_CALL BufferedInputStream::seek( sal_Int64 location ) 204 throw( IllegalArgumentException, 205 IOException, 206 RuntimeException ) 207 { 208 if( 0 <= location && location < m_nBufferSize ) 209 { 210 osl::MutexGuard aGuard( m_aMutex ); 211 m_nBufferLocation = sal::static_int_cast<sal_Int32>( location ); 212 } 213 else 214 throw IllegalArgumentException(); 215 } 216 217 218 219 sal_Int64 SAL_CALL BufferedInputStream::getPosition( void ) 220 throw( IOException, 221 RuntimeException ) 222 { 223 osl::MutexGuard aGuard( m_aMutex ); 224 return m_nBufferLocation; 225 } 226 227 228 229 sal_Int64 SAL_CALL BufferedInputStream::getLength( void ) throw( IOException,RuntimeException ) 230 { 231 osl::MutexGuard aGuard( m_aMutex ); 232 return m_nBufferSize; 233 } 234