/src/libreoffice/oox/source/helper/textinputstream.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <oox/helper/textinputstream.hxx> |
21 | | |
22 | | #include <com/sun/star/io/NotConnectedException.hpp> |
23 | | #include <com/sun/star/io/TextInputStream.hpp> |
24 | | #include <cppuhelper/implbase.hxx> |
25 | | #include <osl/diagnose.h> |
26 | | #include <rtl/tencinfo.h> |
27 | | #include <oox/helper/binaryinputstream.hxx> |
28 | | |
29 | | namespace oox { |
30 | | |
31 | | using namespace ::com::sun::star::io; |
32 | | using namespace ::com::sun::star::lang; |
33 | | using namespace ::com::sun::star::uno; |
34 | | |
35 | | namespace { |
36 | | |
37 | | /** Implementation of a UNO input stream wrapping a binary input stream. |
38 | | */ |
39 | | class UnoBinaryInputStream : public ::cppu::WeakImplHelper< XInputStream > |
40 | | { |
41 | | public: |
42 | | explicit UnoBinaryInputStream( BinaryInputStream& rInStrm ); |
43 | | |
44 | | virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) override; |
45 | | virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) override; |
46 | | virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) override; |
47 | | virtual sal_Int32 SAL_CALL available() override; |
48 | | virtual void SAL_CALL closeInput() override; |
49 | | |
50 | | private: |
51 | | /// @throws NotConnectedException |
52 | | void ensureConnected() const; |
53 | | |
54 | | private: |
55 | | BinaryInputStream* mpInStrm; |
56 | | }; |
57 | | |
58 | | UnoBinaryInputStream::UnoBinaryInputStream( BinaryInputStream& rInStrm ) : |
59 | 13 | mpInStrm( &rInStrm ) |
60 | 13 | { |
61 | 13 | } |
62 | | |
63 | | sal_Int32 SAL_CALL UnoBinaryInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) |
64 | 0 | { |
65 | 0 | ensureConnected(); |
66 | 0 | return mpInStrm->readData( rData, nBytesToRead ); |
67 | 0 | } |
68 | | |
69 | | sal_Int32 SAL_CALL UnoBinaryInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) |
70 | 32 | { |
71 | 32 | ensureConnected(); |
72 | 32 | return mpInStrm->readData( rData, nMaxBytesToRead ); |
73 | 32 | } |
74 | | |
75 | | void SAL_CALL UnoBinaryInputStream::skipBytes( sal_Int32 nBytesToSkip ) |
76 | 0 | { |
77 | 0 | ensureConnected(); |
78 | 0 | mpInStrm->skip( nBytesToSkip ); |
79 | 0 | } |
80 | | |
81 | | sal_Int32 SAL_CALL UnoBinaryInputStream::available() |
82 | 0 | { |
83 | 0 | ensureConnected(); |
84 | 0 | throw RuntimeException( u"Functionality not supported"_ustr, Reference< XInputStream >() ); |
85 | 0 | } |
86 | | |
87 | | void SAL_CALL UnoBinaryInputStream::closeInput() |
88 | 0 | { |
89 | 0 | ensureConnected(); |
90 | 0 | mpInStrm->close(); |
91 | 0 | mpInStrm = nullptr; |
92 | 0 | } |
93 | | |
94 | | void UnoBinaryInputStream::ensureConnected() const |
95 | 32 | { |
96 | 32 | if( !mpInStrm ) |
97 | 0 | throw NotConnectedException( u"Stream closed"_ustr ); |
98 | 32 | } |
99 | | |
100 | | } // namespace |
101 | | |
102 | | TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) |
103 | 0 | { |
104 | 0 | init( rxContext, rxInStrm, eTextEnc ); |
105 | 0 | } |
106 | | |
107 | | TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc ) |
108 | 13 | { |
109 | 13 | init( rxContext, new UnoBinaryInputStream( rInStrm ), eTextEnc ); |
110 | 13 | } |
111 | | |
112 | | TextInputStream::~TextInputStream() |
113 | 13 | { |
114 | 13 | } |
115 | | |
116 | | bool TextInputStream::isEof() const |
117 | 151 | { |
118 | 151 | if( mxTextStrm.is() ) try |
119 | 151 | { |
120 | 151 | return mxTextStrm->isEOF(); |
121 | 151 | } |
122 | 151 | catch (const Exception&) |
123 | 151 | { |
124 | 0 | } |
125 | 0 | return true; |
126 | 151 | } |
127 | | |
128 | | OUString TextInputStream::readLine() |
129 | 148 | { |
130 | 148 | if( mxTextStrm.is() ) try |
131 | 148 | { |
132 | | /* The function createFinalString() adds a character that may have |
133 | | been buffered in the previous call of readToChar() (see below). */ |
134 | 148 | return createFinalString( mxTextStrm->readLine() ); |
135 | 148 | } |
136 | 148 | catch (const Exception&) |
137 | 148 | { |
138 | 0 | mxTextStrm.clear(); |
139 | 0 | } |
140 | 0 | return OUString(); |
141 | 148 | } |
142 | | |
143 | | OUString TextInputStream::readToChar( sal_Unicode cChar, bool bIncludeChar ) |
144 | 0 | { |
145 | 0 | if( mxTextStrm.is() ) try |
146 | 0 | { |
147 | 0 | Sequence< sal_Unicode > aDelimiters{ cChar }; |
148 | | /* Always get the delimiter character from the UNO text input stream. |
149 | | In difference to this implementation, it will not return it in the |
150 | | next call but silently skip it. If caller specifies to exclude the |
151 | | character in this call, it will be returned in the next call of one |
152 | | of the own member functions. The function createFinalString() adds |
153 | | a character that has been buffered in the previous call. */ |
154 | 0 | OUString aString = createFinalString( mxTextStrm->readString( aDelimiters, false ) ); |
155 | | // remove last character from string and remember it for next call |
156 | 0 | if( !bIncludeChar && !aString.isEmpty() && (aString[ aString.getLength() - 1 ] == cChar) ) |
157 | 0 | { |
158 | 0 | mcPendingChar = cChar; |
159 | 0 | aString = aString.copy( 0, aString.getLength() - 1 ); |
160 | 0 | } |
161 | 0 | return aString; |
162 | 0 | } |
163 | 0 | catch (const Exception&) |
164 | 0 | { |
165 | 0 | mxTextStrm.clear(); |
166 | 0 | } |
167 | 0 | return OUString(); |
168 | 0 | } |
169 | | |
170 | | Reference< XTextInputStream2 > TextInputStream::createXTextInputStream( |
171 | | const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) |
172 | 448 | { |
173 | 448 | Reference< XTextInputStream2 > xTextStrm; |
174 | 448 | const char* pcCharset = rtl_getBestMimeCharsetFromTextEncoding( eTextEnc ); |
175 | 448 | OSL_ENSURE( pcCharset, "TextInputStream::createXTextInputStream - unsupported text encoding" ); |
176 | 448 | if( rxContext.is() && rxInStrm.is() && pcCharset ) try |
177 | 329 | { |
178 | 329 | xTextStrm = css::io::TextInputStream::create( rxContext ); |
179 | 329 | xTextStrm->setInputStream( rxInStrm ); |
180 | 329 | xTextStrm->setEncoding( OUString::createFromAscii( pcCharset ) ); |
181 | 329 | } |
182 | 329 | catch (const Exception&) |
183 | 329 | { |
184 | 0 | } |
185 | 448 | return xTextStrm; |
186 | 448 | } |
187 | | |
188 | | // private -------------------------------------------------------------------- |
189 | | |
190 | | OUString TextInputStream::createFinalString( const OUString& rString ) |
191 | 148 | { |
192 | 148 | if( mcPendingChar == 0 ) |
193 | 148 | return rString; |
194 | | |
195 | 0 | OUString aString = OUStringChar( mcPendingChar ) + rString; |
196 | 0 | mcPendingChar = 0; |
197 | 0 | return aString; |
198 | 148 | } |
199 | | |
200 | | void TextInputStream::init( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) |
201 | 13 | { |
202 | 13 | mcPendingChar = 0; |
203 | 13 | mxTextStrm = createXTextInputStream( rxContext, rxInStrm, eTextEnc ); |
204 | 13 | } |
205 | | |
206 | | } // namespace oox |
207 | | |
208 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |