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/textinputstream.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSink.hpp> 27cdf0e10cSrcweir #include <com/sun/star/io/XTextInputStream.hpp> 28cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx> 29cdf0e10cSrcweir #include <rtl/tencinfo.h> 30cdf0e10cSrcweir #include "oox/helper/binaryinputstream.hxx" 31cdf0e10cSrcweir 32cdf0e10cSrcweir namespace oox { 33cdf0e10cSrcweir 34cdf0e10cSrcweir // ============================================================================ 35cdf0e10cSrcweir 36cdf0e10cSrcweir using namespace ::com::sun::star::io; 37cdf0e10cSrcweir using namespace ::com::sun::star::lang; 38cdf0e10cSrcweir using namespace ::com::sun::star::uno; 39cdf0e10cSrcweir 40cdf0e10cSrcweir using ::rtl::OUString; 41cdf0e10cSrcweir 42cdf0e10cSrcweir // ============================================================================ 43cdf0e10cSrcweir 44cdf0e10cSrcweir namespace { 45cdf0e10cSrcweir 46cdf0e10cSrcweir typedef ::cppu::WeakImplHelper1< XInputStream > UnoBinaryInputStream_BASE; 47cdf0e10cSrcweir 48cdf0e10cSrcweir /** Implementation of a UNO input stream wrapping a binary input stream. 49cdf0e10cSrcweir */ 50cdf0e10cSrcweir class UnoBinaryInputStream : public UnoBinaryInputStream_BASE 51cdf0e10cSrcweir { 52cdf0e10cSrcweir public: 53cdf0e10cSrcweir explicit UnoBinaryInputStream( BinaryInputStream& rInStrm ); 54cdf0e10cSrcweir 55cdf0e10cSrcweir virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) 56cdf0e10cSrcweir throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); 57cdf0e10cSrcweir virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) 58cdf0e10cSrcweir throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); 59cdf0e10cSrcweir virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) 60cdf0e10cSrcweir throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); 61cdf0e10cSrcweir virtual sal_Int32 SAL_CALL available() 62cdf0e10cSrcweir throw (NotConnectedException, IOException, RuntimeException); 63cdf0e10cSrcweir virtual void SAL_CALL closeInput() 64cdf0e10cSrcweir throw (NotConnectedException, IOException, RuntimeException); 65cdf0e10cSrcweir 66cdf0e10cSrcweir private: 67cdf0e10cSrcweir void ensureConnected() const throw (NotConnectedException); 68cdf0e10cSrcweir 69cdf0e10cSrcweir private: 70cdf0e10cSrcweir BinaryInputStream* mpInStrm; 71cdf0e10cSrcweir }; 72cdf0e10cSrcweir 73cdf0e10cSrcweir // ---------------------------------------------------------------------------- 74cdf0e10cSrcweir 75cdf0e10cSrcweir UnoBinaryInputStream::UnoBinaryInputStream( BinaryInputStream& rInStrm ) : 76cdf0e10cSrcweir mpInStrm( &rInStrm ) 77cdf0e10cSrcweir { 78cdf0e10cSrcweir } 79cdf0e10cSrcweir 80cdf0e10cSrcweir sal_Int32 SAL_CALL UnoBinaryInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) 81cdf0e10cSrcweir throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 82cdf0e10cSrcweir { 83cdf0e10cSrcweir ensureConnected(); 84cdf0e10cSrcweir return mpInStrm->readData( rData, nBytesToRead, 1 ); 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 87cdf0e10cSrcweir sal_Int32 SAL_CALL UnoBinaryInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) 88cdf0e10cSrcweir throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 89cdf0e10cSrcweir { 90cdf0e10cSrcweir ensureConnected(); 91cdf0e10cSrcweir return mpInStrm->readData( rData, nMaxBytesToRead, 1 ); 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94cdf0e10cSrcweir void SAL_CALL UnoBinaryInputStream::skipBytes( sal_Int32 nBytesToSkip ) 95cdf0e10cSrcweir throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 96cdf0e10cSrcweir { 97cdf0e10cSrcweir ensureConnected(); 98cdf0e10cSrcweir mpInStrm->skip( nBytesToSkip, 1 ); 99cdf0e10cSrcweir } 100cdf0e10cSrcweir 101cdf0e10cSrcweir sal_Int32 SAL_CALL UnoBinaryInputStream::available() throw (NotConnectedException, IOException, RuntimeException) 102cdf0e10cSrcweir { 103cdf0e10cSrcweir ensureConnected(); 104cdf0e10cSrcweir throw RuntimeException( CREATE_OUSTRING( "Functionality not supported" ), Reference< XInputStream >() ); 105cdf0e10cSrcweir } 106cdf0e10cSrcweir 107cdf0e10cSrcweir void SAL_CALL UnoBinaryInputStream::closeInput() throw (NotConnectedException, IOException, RuntimeException) 108cdf0e10cSrcweir { 109cdf0e10cSrcweir ensureConnected(); 110cdf0e10cSrcweir mpInStrm->close(); 111cdf0e10cSrcweir mpInStrm = 0; 112cdf0e10cSrcweir } 113cdf0e10cSrcweir 114cdf0e10cSrcweir void UnoBinaryInputStream::ensureConnected() const throw (NotConnectedException) 115cdf0e10cSrcweir { 116cdf0e10cSrcweir if( !mpInStrm ) 117cdf0e10cSrcweir throw NotConnectedException( CREATE_OUSTRING( "Stream closed" ), Reference< XInterface >() ); 118cdf0e10cSrcweir } 119cdf0e10cSrcweir 120cdf0e10cSrcweir } // namespace 121cdf0e10cSrcweir 122cdf0e10cSrcweir // ============================================================================ 123cdf0e10cSrcweir 124cdf0e10cSrcweir TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) 125cdf0e10cSrcweir { 126cdf0e10cSrcweir init( rxContext, rxInStrm, eTextEnc ); 127cdf0e10cSrcweir } 128cdf0e10cSrcweir 129cdf0e10cSrcweir TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc ) 130cdf0e10cSrcweir { 131cdf0e10cSrcweir init( rxContext, new UnoBinaryInputStream( rInStrm ), eTextEnc ); 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir TextInputStream::~TextInputStream() 135cdf0e10cSrcweir { 136cdf0e10cSrcweir } 137cdf0e10cSrcweir 138cdf0e10cSrcweir bool TextInputStream::isEof() const 139cdf0e10cSrcweir { 140cdf0e10cSrcweir if( mxTextStrm.is() ) try 141cdf0e10cSrcweir { 142cdf0e10cSrcweir return mxTextStrm->isEOF(); 143cdf0e10cSrcweir } 144cdf0e10cSrcweir catch( Exception& ) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir } 147cdf0e10cSrcweir return true; 148cdf0e10cSrcweir } 149cdf0e10cSrcweir 150cdf0e10cSrcweir OUString TextInputStream::readLine() 151cdf0e10cSrcweir { 152cdf0e10cSrcweir if( mxTextStrm.is() ) try 153cdf0e10cSrcweir { 154cdf0e10cSrcweir /* The function createFinalString() adds a character that may have 155cdf0e10cSrcweir been buffered in the previous call of readToChar() (see below). */ 156cdf0e10cSrcweir return createFinalString( mxTextStrm->readLine() ); 157cdf0e10cSrcweir } 158cdf0e10cSrcweir catch( Exception& ) 159cdf0e10cSrcweir { 160cdf0e10cSrcweir mxTextStrm.clear(); 161cdf0e10cSrcweir } 162cdf0e10cSrcweir return OUString(); 163cdf0e10cSrcweir } 164cdf0e10cSrcweir 165cdf0e10cSrcweir OUString TextInputStream::readToChar( sal_Unicode cChar, bool bIncludeChar ) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir if( mxTextStrm.is() ) try 168cdf0e10cSrcweir { 169cdf0e10cSrcweir Sequence< sal_Unicode > aDelimiters( 1 ); 170cdf0e10cSrcweir aDelimiters[ 0 ] = cChar; 171cdf0e10cSrcweir /* Always get the delimiter character from the UNO text input stream. 172cdf0e10cSrcweir In difference to this implementation, it will not return it in the 173cdf0e10cSrcweir next call but silently skip it. If caller specifies to exclude the 174cdf0e10cSrcweir character in this call, it will be returned in the next call of one 175cdf0e10cSrcweir of the own member functions. The function createFinalString() adds 176cdf0e10cSrcweir a character that has been buffered in the previous call. */ 177cdf0e10cSrcweir OUString aString = createFinalString( mxTextStrm->readString( aDelimiters, sal_False ) ); 178cdf0e10cSrcweir // remove last character from string and remember it for next call 179cdf0e10cSrcweir if( !bIncludeChar && (aString.getLength() > 0) && (aString[ aString.getLength() - 1 ] == cChar) ) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir mcPendingChar = cChar; 182cdf0e10cSrcweir aString = aString.copy( 0, aString.getLength() - 1 ); 183cdf0e10cSrcweir } 184cdf0e10cSrcweir return aString; 185cdf0e10cSrcweir } 186cdf0e10cSrcweir catch( Exception& ) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir mxTextStrm.clear(); 189cdf0e10cSrcweir } 190cdf0e10cSrcweir return OUString(); 191cdf0e10cSrcweir } 192cdf0e10cSrcweir 193cdf0e10cSrcweir /*static*/ Reference< XTextInputStream > TextInputStream::createXTextInputStream( 194cdf0e10cSrcweir const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) 195cdf0e10cSrcweir { 196cdf0e10cSrcweir Reference< XTextInputStream > xTextStrm; 197cdf0e10cSrcweir const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc ); 198cdf0e10cSrcweir OSL_ENSURE( pcCharset, "TextInputStream::createXTextInputStream - unsupported text encoding" ); 199cdf0e10cSrcweir if( rxContext.is() && rxInStrm.is() && pcCharset ) try 200cdf0e10cSrcweir { 201cdf0e10cSrcweir Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); 202cdf0e10cSrcweir Reference< XActiveDataSink > xDataSink( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW ); 203cdf0e10cSrcweir xDataSink->setInputStream( rxInStrm ); 204cdf0e10cSrcweir xTextStrm.set( xDataSink, UNO_QUERY_THROW ); 205cdf0e10cSrcweir xTextStrm->setEncoding( OUString::createFromAscii( pcCharset ) ); 206cdf0e10cSrcweir } 207cdf0e10cSrcweir catch( Exception& ) 208cdf0e10cSrcweir { 209cdf0e10cSrcweir } 210cdf0e10cSrcweir return xTextStrm; 211cdf0e10cSrcweir } 212cdf0e10cSrcweir 213cdf0e10cSrcweir // private -------------------------------------------------------------------- 214cdf0e10cSrcweir 215cdf0e10cSrcweir OUString TextInputStream::createFinalString( const OUString& rString ) 216cdf0e10cSrcweir { 217cdf0e10cSrcweir if( mcPendingChar == 0 ) 218cdf0e10cSrcweir return rString; 219cdf0e10cSrcweir 220cdf0e10cSrcweir OUString aString = OUString( mcPendingChar ) + rString; 221cdf0e10cSrcweir mcPendingChar = 0; 222cdf0e10cSrcweir return aString; 223cdf0e10cSrcweir } 224cdf0e10cSrcweir 225cdf0e10cSrcweir void TextInputStream::init( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) 226cdf0e10cSrcweir { 227cdf0e10cSrcweir mcPendingChar = 0; 228cdf0e10cSrcweir mxTextStrm = createXTextInputStream( rxContext, rxInStrm, eTextEnc ); 229cdf0e10cSrcweir } 230cdf0e10cSrcweir 231cdf0e10cSrcweir // ============================================================================ 232cdf0e10cSrcweir 233cdf0e10cSrcweir } // namespace oox 234