xref: /AOO41X/main/oox/source/helper/textinputstream.cxx (revision ca5ec2004b000a7d9aaa8381be8ac2853e3b1dc7)
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