1*ca5ec200SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*ca5ec200SAndrew Rist * distributed with this work for additional information 6*ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance 9*ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*ca5ec200SAndrew Rist * software distributed under the License is distributed on an 15*ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the 17*ca5ec200SAndrew Rist * specific language governing permissions and limitations 18*ca5ec200SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*ca5ec200SAndrew Rist *************************************************************/ 21*ca5ec200SAndrew Rist 22*ca5ec200SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "oox/helper/binaryinputstream.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include <com/sun/star/io/XInputStream.hpp> 27cdf0e10cSrcweir #include <com/sun/star/io/XSeekable.hpp> 28cdf0e10cSrcweir #include <string.h> 29cdf0e10cSrcweir #include <vector> 30cdf0e10cSrcweir #include <rtl/strbuf.hxx> 31cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 32cdf0e10cSrcweir #include "oox/helper/binaryoutputstream.hxx" 33cdf0e10cSrcweir 34cdf0e10cSrcweir namespace oox { 35cdf0e10cSrcweir 36cdf0e10cSrcweir // ============================================================================ 37cdf0e10cSrcweir 38cdf0e10cSrcweir using namespace ::com::sun::star::io; 39cdf0e10cSrcweir using namespace ::com::sun::star::uno; 40cdf0e10cSrcweir 41cdf0e10cSrcweir using ::rtl::OString; 42cdf0e10cSrcweir using ::rtl::OStringBuffer; 43cdf0e10cSrcweir using ::rtl::OStringToOUString; 44cdf0e10cSrcweir using ::rtl::OUString; 45cdf0e10cSrcweir using ::rtl::OUStringBuffer; 46cdf0e10cSrcweir 47cdf0e10cSrcweir namespace { 48cdf0e10cSrcweir 49cdf0e10cSrcweir const sal_Int32 INPUTSTREAM_BUFFERSIZE = 0x8000; 50cdf0e10cSrcweir 51cdf0e10cSrcweir } // namespace 52cdf0e10cSrcweir 53cdf0e10cSrcweir // ============================================================================ 54cdf0e10cSrcweir 55cdf0e10cSrcweir OString BinaryInputStream::readNulCharArray() 56cdf0e10cSrcweir { 57cdf0e10cSrcweir OStringBuffer aBuffer; 58cdf0e10cSrcweir for( sal_uInt8 nChar = readuInt8(); !mbEof && (nChar > 0); readValue( nChar ) ) 59cdf0e10cSrcweir aBuffer.append( static_cast< sal_Char >( nChar ) ); 60cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 61cdf0e10cSrcweir } 62cdf0e10cSrcweir 63cdf0e10cSrcweir OUString BinaryInputStream::readNulCharArrayUC( rtl_TextEncoding eTextEnc ) 64cdf0e10cSrcweir { 65cdf0e10cSrcweir return OStringToOUString( readNulCharArray(), eTextEnc ); 66cdf0e10cSrcweir } 67cdf0e10cSrcweir 68cdf0e10cSrcweir OUString BinaryInputStream::readNulUnicodeArray() 69cdf0e10cSrcweir { 70cdf0e10cSrcweir OUStringBuffer aBuffer; 71cdf0e10cSrcweir for( sal_uInt16 nChar = readuInt16(); !mbEof && (nChar > 0); readValue( nChar ) ) 72cdf0e10cSrcweir aBuffer.append( static_cast< sal_Unicode >( nChar ) ); 73cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 74cdf0e10cSrcweir } 75cdf0e10cSrcweir 76cdf0e10cSrcweir OString BinaryInputStream::readCharArray( sal_Int32 nChars, bool bAllowNulChars ) 77cdf0e10cSrcweir { 78cdf0e10cSrcweir if( nChars <= 0 ) 79cdf0e10cSrcweir return OString(); 80cdf0e10cSrcweir 81cdf0e10cSrcweir ::std::vector< sal_uInt8 > aBuffer; 82cdf0e10cSrcweir sal_Int32 nCharsRead = readArray( aBuffer, nChars ); 83cdf0e10cSrcweir if( nCharsRead <= 0 ) 84cdf0e10cSrcweir return OString(); 85cdf0e10cSrcweir 86cdf0e10cSrcweir aBuffer.resize( static_cast< size_t >( nCharsRead ) ); 87cdf0e10cSrcweir if( !bAllowNulChars ) 88cdf0e10cSrcweir ::std::replace( aBuffer.begin(), aBuffer.end(), '\0', '?' ); 89cdf0e10cSrcweir 90cdf0e10cSrcweir return OString( reinterpret_cast< sal_Char* >( &aBuffer.front() ), nCharsRead ); 91cdf0e10cSrcweir } 92cdf0e10cSrcweir 93cdf0e10cSrcweir OUString BinaryInputStream::readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars ) 94cdf0e10cSrcweir { 95cdf0e10cSrcweir return OStringToOUString( readCharArray( nChars, bAllowNulChars ), eTextEnc ); 96cdf0e10cSrcweir } 97cdf0e10cSrcweir 98cdf0e10cSrcweir OUString BinaryInputStream::readUnicodeArray( sal_Int32 nChars, bool bAllowNulChars ) 99cdf0e10cSrcweir { 100cdf0e10cSrcweir if( nChars <= 0 ) 101cdf0e10cSrcweir return OUString(); 102cdf0e10cSrcweir 103cdf0e10cSrcweir ::std::vector< sal_uInt16 > aBuffer; 104cdf0e10cSrcweir sal_Int32 nCharsRead = readArray( aBuffer, nChars ); 105cdf0e10cSrcweir if( nCharsRead <= 0 ) 106cdf0e10cSrcweir return OUString(); 107cdf0e10cSrcweir 108cdf0e10cSrcweir aBuffer.resize( static_cast< size_t >( nCharsRead ) ); 109cdf0e10cSrcweir if( !bAllowNulChars ) 110cdf0e10cSrcweir ::std::replace( aBuffer.begin(), aBuffer.begin() + nCharsRead, '\0', '?' ); 111cdf0e10cSrcweir 112cdf0e10cSrcweir OUStringBuffer aStringBuffer; 113cdf0e10cSrcweir aStringBuffer.ensureCapacity( nCharsRead ); 114cdf0e10cSrcweir for( ::std::vector< sal_uInt16 >::iterator aIt = aBuffer.begin(), aEnd = aBuffer.end(); aIt != aEnd; ++aIt ) 115cdf0e10cSrcweir aStringBuffer.append( static_cast< sal_Unicode >( *aIt ) ); 116cdf0e10cSrcweir return aStringBuffer.makeStringAndClear(); 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119cdf0e10cSrcweir OUString BinaryInputStream::readCompressedUnicodeArray( sal_Int32 nChars, bool bCompressed, bool bAllowNulChars ) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir return bCompressed ? 122cdf0e10cSrcweir // ISO-8859-1 maps all byte values 0xHH to the same Unicode code point U+00HH 123cdf0e10cSrcweir readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1, bAllowNulChars ) : 124cdf0e10cSrcweir readUnicodeArray( nChars, bAllowNulChars ); 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes, sal_Int32 nAtomSize ) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir if( nBytes > 0 ) 130cdf0e10cSrcweir { 131cdf0e10cSrcweir // make buffer size a multiple of the passed atom size 132cdf0e10cSrcweir sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, (INPUTSTREAM_BUFFERSIZE / nAtomSize) * nAtomSize ); 133cdf0e10cSrcweir StreamDataSequence aBuffer( nBufferSize ); 134cdf0e10cSrcweir while( nBytes > 0 ) 135cdf0e10cSrcweir { 136cdf0e10cSrcweir sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, nBufferSize ); 137cdf0e10cSrcweir sal_Int32 nBytesRead = readData( aBuffer, nReadSize, nAtomSize ); 138cdf0e10cSrcweir rOutStrm.writeData( aBuffer ); 139cdf0e10cSrcweir if( nReadSize == nBytesRead ) 140cdf0e10cSrcweir nBytes -= nReadSize; 141cdf0e10cSrcweir else 142cdf0e10cSrcweir nBytes = 0; 143cdf0e10cSrcweir } 144cdf0e10cSrcweir } 145cdf0e10cSrcweir } 146cdf0e10cSrcweir 147cdf0e10cSrcweir // ============================================================================ 148cdf0e10cSrcweir 149cdf0e10cSrcweir BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStrm, bool bAutoClose ) : 150cdf0e10cSrcweir BinaryStreamBase( Reference< XSeekable >( rxInStrm, UNO_QUERY ).is() ), 151cdf0e10cSrcweir BinaryXSeekableStream( Reference< XSeekable >( rxInStrm, UNO_QUERY ) ), 152cdf0e10cSrcweir maBuffer( INPUTSTREAM_BUFFERSIZE ), 153cdf0e10cSrcweir mxInStrm( rxInStrm ), 154cdf0e10cSrcweir mbAutoClose( bAutoClose && rxInStrm.is() ) 155cdf0e10cSrcweir { 156cdf0e10cSrcweir mbEof = !mxInStrm.is(); 157cdf0e10cSrcweir } 158cdf0e10cSrcweir 159cdf0e10cSrcweir BinaryXInputStream::~BinaryXInputStream() 160cdf0e10cSrcweir { 161cdf0e10cSrcweir close(); 162cdf0e10cSrcweir } 163cdf0e10cSrcweir 164cdf0e10cSrcweir void BinaryXInputStream::close() 165cdf0e10cSrcweir { 166cdf0e10cSrcweir OSL_ENSURE( !mbAutoClose || mxInStrm.is(), "BinaryXInputStream::close - invalid call" ); 167cdf0e10cSrcweir if( mbAutoClose && mxInStrm.is() ) try 168cdf0e10cSrcweir { 169cdf0e10cSrcweir mxInStrm->closeInput(); 170cdf0e10cSrcweir } 171cdf0e10cSrcweir catch( Exception& ) 172cdf0e10cSrcweir { 173cdf0e10cSrcweir OSL_ENSURE( false, "BinaryXInputStream::close - closing input stream failed" ); 174cdf0e10cSrcweir } 175cdf0e10cSrcweir mxInStrm.clear(); 176cdf0e10cSrcweir mbAutoClose = false; 177cdf0e10cSrcweir BinaryXSeekableStream::close(); 178cdf0e10cSrcweir } 179cdf0e10cSrcweir 180cdf0e10cSrcweir sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t /*nAtomSize*/ ) 181cdf0e10cSrcweir { 182cdf0e10cSrcweir sal_Int32 nRet = 0; 183cdf0e10cSrcweir if( !mbEof && (nBytes > 0) ) try 184cdf0e10cSrcweir { 185cdf0e10cSrcweir nRet = mxInStrm->readBytes( orData, nBytes ); 186cdf0e10cSrcweir mbEof = nRet != nBytes; 187cdf0e10cSrcweir } 188cdf0e10cSrcweir catch( Exception& ) 189cdf0e10cSrcweir { 190cdf0e10cSrcweir mbEof = true; 191cdf0e10cSrcweir } 192cdf0e10cSrcweir return nRet; 193cdf0e10cSrcweir } 194cdf0e10cSrcweir 195cdf0e10cSrcweir sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) 196cdf0e10cSrcweir { 197cdf0e10cSrcweir sal_Int32 nRet = 0; 198cdf0e10cSrcweir if( !mbEof && (nBytes > 0) ) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, INPUTSTREAM_BUFFERSIZE ); 201cdf0e10cSrcweir sal_uInt8* opnMem = reinterpret_cast< sal_uInt8* >( opMem ); 202cdf0e10cSrcweir while( !mbEof && (nBytes > 0) ) 203cdf0e10cSrcweir { 204cdf0e10cSrcweir sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize ); 205cdf0e10cSrcweir sal_Int32 nBytesRead = readData( maBuffer, nReadSize, nAtomSize ); 206cdf0e10cSrcweir if( nBytesRead > 0 ) 207cdf0e10cSrcweir memcpy( opnMem, maBuffer.getConstArray(), static_cast< size_t >( nBytesRead ) ); 208cdf0e10cSrcweir opnMem += nBytesRead; 209cdf0e10cSrcweir nBytes -= nBytesRead; 210cdf0e10cSrcweir nRet += nBytesRead; 211cdf0e10cSrcweir } 212cdf0e10cSrcweir } 213cdf0e10cSrcweir return nRet; 214cdf0e10cSrcweir } 215cdf0e10cSrcweir 216cdf0e10cSrcweir void BinaryXInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ ) 217cdf0e10cSrcweir { 218cdf0e10cSrcweir if( !mbEof ) try 219cdf0e10cSrcweir { 220cdf0e10cSrcweir mxInStrm->skipBytes( nBytes ); 221cdf0e10cSrcweir } 222cdf0e10cSrcweir catch( Exception& ) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir mbEof = true; 225cdf0e10cSrcweir } 226cdf0e10cSrcweir } 227cdf0e10cSrcweir 228cdf0e10cSrcweir // ============================================================================ 229cdf0e10cSrcweir 230cdf0e10cSrcweir SequenceInputStream::SequenceInputStream( const StreamDataSequence& rData ) : 231cdf0e10cSrcweir BinaryStreamBase( true ), 232cdf0e10cSrcweir SequenceSeekableStream( rData ) 233cdf0e10cSrcweir { 234cdf0e10cSrcweir } 235cdf0e10cSrcweir 236cdf0e10cSrcweir sal_Int32 SequenceInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t /*nAtomSize*/ ) 237cdf0e10cSrcweir { 238cdf0e10cSrcweir sal_Int32 nReadBytes = 0; 239cdf0e10cSrcweir if( !mbEof ) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir nReadBytes = getMaxBytes( nBytes ); 242cdf0e10cSrcweir orData.realloc( nReadBytes ); 243cdf0e10cSrcweir if( nReadBytes > 0 ) 244cdf0e10cSrcweir memcpy( orData.getArray(), mpData->getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); 245cdf0e10cSrcweir mnPos += nReadBytes; 246cdf0e10cSrcweir mbEof = nReadBytes < nBytes; 247cdf0e10cSrcweir } 248cdf0e10cSrcweir return nReadBytes; 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir sal_Int32 SequenceInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t /*nAtomSize*/ ) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir sal_Int32 nReadBytes = 0; 254cdf0e10cSrcweir if( !mbEof ) 255cdf0e10cSrcweir { 256cdf0e10cSrcweir nReadBytes = getMaxBytes( nBytes ); 257cdf0e10cSrcweir if( nReadBytes > 0 ) 258cdf0e10cSrcweir memcpy( opMem, mpData->getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); 259cdf0e10cSrcweir mnPos += nReadBytes; 260cdf0e10cSrcweir mbEof = nReadBytes < nBytes; 261cdf0e10cSrcweir } 262cdf0e10cSrcweir return nReadBytes; 263cdf0e10cSrcweir } 264cdf0e10cSrcweir 265cdf0e10cSrcweir void SequenceInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ ) 266cdf0e10cSrcweir { 267cdf0e10cSrcweir if( !mbEof ) 268cdf0e10cSrcweir { 269cdf0e10cSrcweir sal_Int32 nSkipBytes = getMaxBytes( nBytes ); 270cdf0e10cSrcweir mnPos += nSkipBytes; 271cdf0e10cSrcweir mbEof = nSkipBytes < nBytes; 272cdf0e10cSrcweir } 273cdf0e10cSrcweir } 274cdf0e10cSrcweir 275cdf0e10cSrcweir // ============================================================================ 276cdf0e10cSrcweir 277cdf0e10cSrcweir RelativeInputStream::RelativeInputStream( BinaryInputStream& rInStrm, sal_Int64 nSize ) : 278cdf0e10cSrcweir BinaryStreamBase( rInStrm.isSeekable() ), 279cdf0e10cSrcweir mpInStrm( &rInStrm ), 280cdf0e10cSrcweir mnStartPos( rInStrm.tell() ), 281cdf0e10cSrcweir mnRelPos( 0 ) 282cdf0e10cSrcweir { 283cdf0e10cSrcweir sal_Int64 nRemaining = rInStrm.getRemaining(); 284cdf0e10cSrcweir mnSize = (nRemaining >= 0) ? ::std::min( nSize, nRemaining ) : nSize; 285cdf0e10cSrcweir mbEof = mbEof || rInStrm.isEof() || (mnSize < 0); 286cdf0e10cSrcweir } 287cdf0e10cSrcweir 288cdf0e10cSrcweir sal_Int64 RelativeInputStream::size() const 289cdf0e10cSrcweir { 290cdf0e10cSrcweir return mpInStrm ? mnSize : -1; 291cdf0e10cSrcweir } 292cdf0e10cSrcweir 293cdf0e10cSrcweir sal_Int64 RelativeInputStream::tell() const 294cdf0e10cSrcweir { 295cdf0e10cSrcweir return mpInStrm ? mnRelPos : -1; 296cdf0e10cSrcweir } 297cdf0e10cSrcweir 298cdf0e10cSrcweir void RelativeInputStream::seek( sal_Int64 nPos ) 299cdf0e10cSrcweir { 300cdf0e10cSrcweir if( mpInStrm && isSeekable() && (mnStartPos >= 0) ) 301cdf0e10cSrcweir { 302cdf0e10cSrcweir mnRelPos = getLimitedValue< sal_Int64, sal_Int64 >( nPos, 0, mnSize ); 303cdf0e10cSrcweir mpInStrm->seek( mnStartPos + mnRelPos ); 304cdf0e10cSrcweir mbEof = (mnRelPos != nPos) || mpInStrm->isEof(); 305cdf0e10cSrcweir } 306cdf0e10cSrcweir } 307cdf0e10cSrcweir 308cdf0e10cSrcweir void RelativeInputStream::close() 309cdf0e10cSrcweir { 310cdf0e10cSrcweir mpInStrm = 0; 311cdf0e10cSrcweir mbEof = true; 312cdf0e10cSrcweir } 313cdf0e10cSrcweir 314cdf0e10cSrcweir sal_Int32 RelativeInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize ) 315cdf0e10cSrcweir { 316cdf0e10cSrcweir sal_Int32 nReadBytes = 0; 317cdf0e10cSrcweir if( !mbEof ) 318cdf0e10cSrcweir { 319cdf0e10cSrcweir sal_Int32 nMaxBytes = getMaxBytes( nBytes ); 320cdf0e10cSrcweir nReadBytes = mpInStrm->readData( orData, nMaxBytes, nAtomSize ); 321cdf0e10cSrcweir mnRelPos += nReadBytes; 322cdf0e10cSrcweir mbEof = (nMaxBytes < nBytes) || mpInStrm->isEof(); 323cdf0e10cSrcweir } 324cdf0e10cSrcweir return nReadBytes; 325cdf0e10cSrcweir } 326cdf0e10cSrcweir 327cdf0e10cSrcweir sal_Int32 RelativeInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) 328cdf0e10cSrcweir { 329cdf0e10cSrcweir sal_Int32 nReadBytes = 0; 330cdf0e10cSrcweir if( !mbEof ) 331cdf0e10cSrcweir { 332cdf0e10cSrcweir sal_Int32 nMaxBytes = getMaxBytes( nBytes ); 333cdf0e10cSrcweir nReadBytes = mpInStrm->readMemory( opMem, nMaxBytes, nAtomSize ); 334cdf0e10cSrcweir mnRelPos += nReadBytes; 335cdf0e10cSrcweir mbEof = (nMaxBytes < nBytes) || mpInStrm->isEof(); 336cdf0e10cSrcweir } 337cdf0e10cSrcweir return nReadBytes; 338cdf0e10cSrcweir } 339cdf0e10cSrcweir 340cdf0e10cSrcweir void RelativeInputStream::skip( sal_Int32 nBytes, size_t nAtomSize ) 341cdf0e10cSrcweir { 342cdf0e10cSrcweir if( !mbEof ) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir sal_Int32 nSkipBytes = getMaxBytes( nBytes ); 345cdf0e10cSrcweir mpInStrm->skip( nSkipBytes, nAtomSize ); 346cdf0e10cSrcweir mnRelPos += nSkipBytes; 347cdf0e10cSrcweir mbEof = nSkipBytes < nBytes; 348cdf0e10cSrcweir } 349cdf0e10cSrcweir } 350cdf0e10cSrcweir 351cdf0e10cSrcweir // ============================================================================ 352cdf0e10cSrcweir 353cdf0e10cSrcweir } // namespace oox 354