xref: /trunk/main/oox/source/helper/textinputstream.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "oox/helper/textinputstream.hxx"
25 
26 #include <com/sun/star/io/XActiveDataSink.hpp>
27 #include <com/sun/star/io/XTextInputStream.hpp>
28 #include <cppuhelper/implbase1.hxx>
29 #include <rtl/tencinfo.h>
30 #include "oox/helper/binaryinputstream.hxx"
31 
32 namespace oox {
33 
34 // ============================================================================
35 
36 using namespace ::com::sun::star::io;
37 using namespace ::com::sun::star::lang;
38 using namespace ::com::sun::star::uno;
39 
40 using ::rtl::OUString;
41 
42 // ============================================================================
43 
44 namespace {
45 
46 typedef ::cppu::WeakImplHelper1< XInputStream > UnoBinaryInputStream_BASE;
47 
48 /** Implementation of a UNO input stream wrapping a binary input stream.
49  */
50 class UnoBinaryInputStream : public UnoBinaryInputStream_BASE
51 {
52 public:
53     explicit            UnoBinaryInputStream( BinaryInputStream& rInStrm );
54 
55     virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead );
56     virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead );
57     virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip );
58     virtual sal_Int32 SAL_CALL available();
59     virtual void SAL_CALL closeInput();
60 
61 private:
62     void                ensureConnected() const;
63 
64 private:
65     BinaryInputStream*  mpInStrm;
66 };
67 
68 // ----------------------------------------------------------------------------
69 
UnoBinaryInputStream(BinaryInputStream & rInStrm)70 UnoBinaryInputStream::UnoBinaryInputStream( BinaryInputStream& rInStrm ) :
71     mpInStrm( &rInStrm )
72 {
73 }
74 
readBytes(Sequence<sal_Int8> & rData,sal_Int32 nBytesToRead)75 sal_Int32 SAL_CALL UnoBinaryInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead )
76 {
77     ensureConnected();
78     return mpInStrm->readData( rData, nBytesToRead, 1 );
79 }
80 
readSomeBytes(Sequence<sal_Int8> & rData,sal_Int32 nMaxBytesToRead)81 sal_Int32 SAL_CALL UnoBinaryInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead )
82 {
83     ensureConnected();
84     return mpInStrm->readData( rData, nMaxBytesToRead, 1 );
85 }
86 
skipBytes(sal_Int32 nBytesToSkip)87 void SAL_CALL UnoBinaryInputStream::skipBytes( sal_Int32 nBytesToSkip )
88 {
89     ensureConnected();
90     mpInStrm->skip( nBytesToSkip, 1 );
91 }
92 
available()93 sal_Int32 SAL_CALL UnoBinaryInputStream::available()
94 {
95     ensureConnected();
96     throw RuntimeException( CREATE_OUSTRING( "Functionality not supported" ), Reference< XInputStream >() );
97 }
98 
closeInput()99 void SAL_CALL UnoBinaryInputStream::closeInput()
100 {
101     ensureConnected();
102     mpInStrm->close();
103     mpInStrm = 0;
104 }
105 
ensureConnected() const106 void UnoBinaryInputStream::ensureConnected() const
107 {
108     if( !mpInStrm )
109         throw NotConnectedException( CREATE_OUSTRING( "Stream closed" ), Reference< XInterface >() );
110 }
111 
112 } // namespace
113 
114 // ============================================================================
115 
TextInputStream(const Reference<XComponentContext> & rxContext,const Reference<XInputStream> & rxInStrm,rtl_TextEncoding eTextEnc)116 TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
117 {
118     init( rxContext, rxInStrm, eTextEnc );
119 }
120 
TextInputStream(const Reference<XComponentContext> & rxContext,BinaryInputStream & rInStrm,rtl_TextEncoding eTextEnc)121 TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc )
122 {
123     init( rxContext, new UnoBinaryInputStream( rInStrm ), eTextEnc );
124 }
125 
~TextInputStream()126 TextInputStream::~TextInputStream()
127 {
128 }
129 
isEof() const130 bool TextInputStream::isEof() const
131 {
132     if( mxTextStrm.is() ) try
133     {
134         return mxTextStrm->isEOF();
135     }
136     catch( Exception& )
137     {
138     }
139     return true;
140 }
141 
readLine()142 OUString TextInputStream::readLine()
143 {
144     if( mxTextStrm.is() ) try
145     {
146         /*  The function createFinalString() adds a character that may have
147             been buffered in the previous call of readToChar() (see below). */
148         return createFinalString( mxTextStrm->readLine() );
149     }
150     catch( Exception& )
151     {
152         mxTextStrm.clear();
153     }
154     return OUString();
155 }
156 
readToChar(sal_Unicode cChar,bool bIncludeChar)157 OUString TextInputStream::readToChar( sal_Unicode cChar, bool bIncludeChar )
158 {
159     if( mxTextStrm.is() ) try
160     {
161         Sequence< sal_Unicode > aDelimiters( 1 );
162         aDelimiters[ 0 ] = cChar;
163         /*  Always get the delimiter character from the UNO text input stream.
164             In difference to this implementation, it will not return it in the
165             next call but silently skip it. If caller specifies to exclude the
166             character in this call, it will be returned in the next call of one
167             of the own member functions. The function createFinalString() adds
168             a character that has been buffered in the previous call. */
169         OUString aString = createFinalString( mxTextStrm->readString( aDelimiters, sal_False ) );
170         // remove last character from string and remember it for next call
171         if( !bIncludeChar && (aString.getLength() > 0) && (aString[ aString.getLength() - 1 ] == cChar) )
172         {
173             mcPendingChar = cChar;
174             aString = aString.copy( 0, aString.getLength() - 1 );
175         }
176         return aString;
177     }
178     catch( Exception& )
179     {
180         mxTextStrm.clear();
181     }
182     return OUString();
183 }
184 
createXTextInputStream(const Reference<XComponentContext> & rxContext,const Reference<XInputStream> & rxInStrm,rtl_TextEncoding eTextEnc)185 /*static*/ Reference< XTextInputStream > TextInputStream::createXTextInputStream(
186         const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
187 {
188     Reference< XTextInputStream > xTextStrm;
189     const char* pcCharset = rtl_getBestMimeCharsetFromTextEncoding( eTextEnc);
190     OSL_ENSURE( pcCharset, "TextInputStream::createXTextInputStream - unsupported text encoding" );
191     if( rxContext.is() && rxInStrm.is() && pcCharset ) try
192     {
193         Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
194         Reference< XActiveDataSink > xDataSink( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW );
195         xDataSink->setInputStream( rxInStrm );
196         xTextStrm.set( xDataSink, UNO_QUERY_THROW );
197         xTextStrm->setEncoding( OUString::createFromAscii( pcCharset ) );
198     }
199     catch( Exception& )
200     {
201     }
202     return xTextStrm;
203 }
204 
205 // private --------------------------------------------------------------------
206 
createFinalString(const OUString & rString)207 OUString TextInputStream::createFinalString( const OUString& rString )
208 {
209     if( mcPendingChar == 0 )
210         return rString;
211 
212     OUString aString = OUString( mcPendingChar ) + rString;
213     mcPendingChar = 0;
214     return aString;
215 }
216 
init(const Reference<XComponentContext> & rxContext,const Reference<XInputStream> & rxInStrm,rtl_TextEncoding eTextEnc)217 void TextInputStream::init( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
218 {
219     mcPendingChar = 0;
220     mxTextStrm = createXTextInputStream( rxContext, rxInStrm, eTextEnc );
221 }
222 
223 // ============================================================================
224 
225 } // namespace oox
226