1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <oox/helper/textinputstream.hxx>
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>
31 using namespace ::com::sun::star::io
;
32 using namespace ::com::sun::star::lang
;
33 using namespace ::com::sun::star::uno
;
37 /** Implementation of a UNO input stream wrapping a binary input stream.
39 class UnoBinaryInputStream
: public ::cppu::WeakImplHelper
< XInputStream
>
42 explicit UnoBinaryInputStream( BinaryInputStream
& rInStrm
);
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
;
51 /// @throws NotConnectedException
52 void ensureConnected() const;
55 BinaryInputStream
* mpInStrm
;
58 UnoBinaryInputStream::UnoBinaryInputStream( BinaryInputStream
& rInStrm
) :
63 sal_Int32 SAL_CALL
UnoBinaryInputStream::readBytes( Sequence
< sal_Int8
>& rData
, sal_Int32 nBytesToRead
)
66 return mpInStrm
->readData( rData
, nBytesToRead
);
69 sal_Int32 SAL_CALL
UnoBinaryInputStream::readSomeBytes( Sequence
< sal_Int8
>& rData
, sal_Int32 nMaxBytesToRead
)
72 return mpInStrm
->readData( rData
, nMaxBytesToRead
);
75 void SAL_CALL
UnoBinaryInputStream::skipBytes( sal_Int32 nBytesToSkip
)
78 mpInStrm
->skip( nBytesToSkip
);
81 sal_Int32 SAL_CALL
UnoBinaryInputStream::available()
84 throw RuntimeException( "Functionality not supported", Reference
< XInputStream
>() );
87 void SAL_CALL
UnoBinaryInputStream::closeInput()
94 void UnoBinaryInputStream::ensureConnected() const
97 throw NotConnectedException( "Stream closed" );
102 TextInputStream::TextInputStream( const Reference
< XComponentContext
>& rxContext
, const Reference
< XInputStream
>& rxInStrm
, rtl_TextEncoding eTextEnc
)
104 init( rxContext
, rxInStrm
, eTextEnc
);
107 TextInputStream::TextInputStream( const Reference
< XComponentContext
>& rxContext
, BinaryInputStream
& rInStrm
, rtl_TextEncoding eTextEnc
)
109 init( rxContext
, new UnoBinaryInputStream( rInStrm
), eTextEnc
);
112 TextInputStream::~TextInputStream()
116 bool TextInputStream::isEof() const
118 if( mxTextStrm
.is() ) try
120 return mxTextStrm
->isEOF();
122 catch (const Exception
&)
128 OUString
TextInputStream::readLine()
130 if( mxTextStrm
.is() ) try
132 /* The function createFinalString() adds a character that may have
133 been buffered in the previous call of readToChar() (see below). */
134 return createFinalString( mxTextStrm
->readLine() );
136 catch (const Exception
&)
143 OUString
TextInputStream::readToChar( sal_Unicode cChar
, bool bIncludeChar
)
145 if( mxTextStrm
.is() ) try
147 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 OUString aString
= createFinalString( mxTextStrm
->readString( aDelimiters
, false ) );
155 // remove last character from string and remember it for next call
156 if( !bIncludeChar
&& !aString
.isEmpty() && (aString
[ aString
.getLength() - 1 ] == cChar
) )
158 mcPendingChar
= cChar
;
159 aString
= aString
.copy( 0, aString
.getLength() - 1 );
163 catch (const Exception
&)
170 Reference
< XTextInputStream2
> TextInputStream::createXTextInputStream(
171 const Reference
< XComponentContext
>& rxContext
, const Reference
< XInputStream
>& rxInStrm
, rtl_TextEncoding eTextEnc
)
173 Reference
< XTextInputStream2
> xTextStrm
;
174 const char* pcCharset
= rtl_getBestMimeCharsetFromTextEncoding( eTextEnc
);
175 OSL_ENSURE( pcCharset
, "TextInputStream::createXTextInputStream - unsupported text encoding" );
176 if( rxContext
.is() && rxInStrm
.is() && pcCharset
) try
178 xTextStrm
= css::io::TextInputStream::create( rxContext
);
179 xTextStrm
->setInputStream( rxInStrm
);
180 xTextStrm
->setEncoding( OUString::createFromAscii( pcCharset
) );
182 catch (const Exception
&)
188 // private --------------------------------------------------------------------
190 OUString
TextInputStream::createFinalString( const OUString
& rString
)
192 if( mcPendingChar
== 0 )
195 OUString aString
= OUStringChar( mcPendingChar
) + rString
;
200 void TextInputStream::init( const Reference
< XComponentContext
>& rxContext
, const Reference
< XInputStream
>& rxInStrm
, rtl_TextEncoding eTextEnc
)
203 mxTextStrm
= createXTextInputStream( rxContext
, rxInStrm
, eTextEnc
);
208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */