1ca5ec200SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file
5ca5ec200SAndrew Rist * distributed with this work for additional information
6ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the
8ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance
9ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing,
14ca5ec200SAndrew Rist * software distributed under the License is distributed on an
15ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the
17ca5ec200SAndrew Rist * specific language governing permissions and limitations
18ca5ec200SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20ca5ec200SAndrew Rist *************************************************************/
21ca5ec200SAndrew Rist
22ca5ec200SAndrew 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
UnoBinaryInputStream(BinaryInputStream & rInStrm)75cdf0e10cSrcweir UnoBinaryInputStream::UnoBinaryInputStream( BinaryInputStream& rInStrm ) :
76cdf0e10cSrcweir mpInStrm( &rInStrm )
77cdf0e10cSrcweir {
78cdf0e10cSrcweir }
79cdf0e10cSrcweir
readBytes(Sequence<sal_Int8> & rData,sal_Int32 nBytesToRead)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
readSomeBytes(Sequence<sal_Int8> & rData,sal_Int32 nMaxBytesToRead)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
skipBytes(sal_Int32 nBytesToSkip)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
available()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
closeInput()107cdf0e10cSrcweir void SAL_CALL UnoBinaryInputStream::closeInput() throw (NotConnectedException, IOException, RuntimeException)
108cdf0e10cSrcweir {
109cdf0e10cSrcweir ensureConnected();
110cdf0e10cSrcweir mpInStrm->close();
111cdf0e10cSrcweir mpInStrm = 0;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir
ensureConnected() const114cdf0e10cSrcweir 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
TextInputStream(const Reference<XComponentContext> & rxContext,const Reference<XInputStream> & rxInStrm,rtl_TextEncoding eTextEnc)124cdf0e10cSrcweir TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
125cdf0e10cSrcweir {
126cdf0e10cSrcweir init( rxContext, rxInStrm, eTextEnc );
127cdf0e10cSrcweir }
128cdf0e10cSrcweir
TextInputStream(const Reference<XComponentContext> & rxContext,BinaryInputStream & rInStrm,rtl_TextEncoding eTextEnc)129cdf0e10cSrcweir TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir init( rxContext, new UnoBinaryInputStream( rInStrm ), eTextEnc );
132cdf0e10cSrcweir }
133cdf0e10cSrcweir
~TextInputStream()134cdf0e10cSrcweir TextInputStream::~TextInputStream()
135cdf0e10cSrcweir {
136cdf0e10cSrcweir }
137cdf0e10cSrcweir
isEof() const138cdf0e10cSrcweir 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
readLine()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
readToChar(sal_Unicode cChar,bool bIncludeChar)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
createXTextInputStream(const Reference<XComponentContext> & rxContext,const Reference<XInputStream> & rxInStrm,rtl_TextEncoding eTextEnc)193cdf0e10cSrcweir /*static*/ Reference< XTextInputStream > TextInputStream::createXTextInputStream(
194cdf0e10cSrcweir const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
195cdf0e10cSrcweir {
196cdf0e10cSrcweir Reference< XTextInputStream > xTextStrm;
197*0c336801SWang Lei const char* pcCharset = rtl_getBestMimeCharsetFromTextEncoding( 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
createFinalString(const OUString & rString)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
init(const Reference<XComponentContext> & rxContext,const Reference<XInputStream> & rxInStrm,rtl_TextEncoding eTextEnc)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