LibreOffice Module oox (master)  1
textinputstream.cxx
Go to the documentation of this file.
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 
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>
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 
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:
52  void ensureConnected() const;
53 
54 private:
55  BinaryInputStream* mpInStrm;
56 };
57 
58 UnoBinaryInputStream::UnoBinaryInputStream( BinaryInputStream& rInStrm ) :
59  mpInStrm( &rInStrm )
60 {
61 }
62 
63 sal_Int32 SAL_CALL UnoBinaryInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead )
64 {
65  ensureConnected();
66  return mpInStrm->readData( rData, nBytesToRead );
67 }
68 
69 sal_Int32 SAL_CALL UnoBinaryInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead )
70 {
71  ensureConnected();
72  return mpInStrm->readData( rData, nMaxBytesToRead );
73 }
74 
75 void SAL_CALL UnoBinaryInputStream::skipBytes( sal_Int32 nBytesToSkip )
76 {
77  ensureConnected();
78  mpInStrm->skip( nBytesToSkip );
79 }
80 
81 sal_Int32 SAL_CALL UnoBinaryInputStream::available()
82 {
83  ensureConnected();
84  throw RuntimeException( "Functionality not supported", Reference< XInputStream >() );
85 }
86 
87 void SAL_CALL UnoBinaryInputStream::closeInput()
88 {
89  ensureConnected();
90  mpInStrm->close();
91  mpInStrm = nullptr;
92 }
93 
94 void UnoBinaryInputStream::ensureConnected() const
95 {
96  if( !mpInStrm )
97  throw NotConnectedException( "Stream closed" );
98 }
99 
100 } // namespace
101 
102 TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
103 {
104  init( rxContext, rxInStrm, eTextEnc );
105 }
106 
107 TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc )
108 {
109  init( rxContext, new UnoBinaryInputStream( rInStrm ), eTextEnc );
110 }
111 
113 {
114 }
115 
117 {
118  if( mxTextStrm.is() ) try
119  {
120  return mxTextStrm->isEOF();
121  }
122  catch (const Exception&)
123  {
124  }
125  return true;
126 }
127 
129 {
130  if( mxTextStrm.is() ) try
131  {
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() );
135  }
136  catch (const Exception&)
137  {
138  mxTextStrm.clear();
139  }
140  return OUString();
141 }
142 
143 OUString TextInputStream::readToChar( sal_Unicode cChar, bool bIncludeChar )
144 {
145  if( mxTextStrm.is() ) try
146  {
147  Sequence< sal_Unicode > aDelimiters( 1 );
148  aDelimiters[ 0 ] = cChar;
149  /* Always get the delimiter character from the UNO text input stream.
150  In difference to this implementation, it will not return it in the
151  next call but silently skip it. If caller specifies to exclude the
152  character in this call, it will be returned in the next call of one
153  of the own member functions. The function createFinalString() adds
154  a character that has been buffered in the previous call. */
155  OUString aString = createFinalString( mxTextStrm->readString( aDelimiters, false ) );
156  // remove last character from string and remember it for next call
157  if( !bIncludeChar && !aString.isEmpty() && (aString[ aString.getLength() - 1 ] == cChar) )
158  {
159  mcPendingChar = cChar;
160  aString = aString.copy( 0, aString.getLength() - 1 );
161  }
162  return aString;
163  }
164  catch (const Exception&)
165  {
166  mxTextStrm.clear();
167  }
168  return OUString();
169 }
170 
171 Reference< XTextInputStream2 > TextInputStream::createXTextInputStream(
172  const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
173 {
174  Reference< XTextInputStream2 > xTextStrm;
175  const char* pcCharset = rtl_getBestMimeCharsetFromTextEncoding( eTextEnc );
176  OSL_ENSURE( pcCharset, "TextInputStream::createXTextInputStream - unsupported text encoding" );
177  if( rxContext.is() && rxInStrm.is() && pcCharset ) try
178  {
179  xTextStrm = css::io::TextInputStream::create( rxContext );
180  xTextStrm->setInputStream( rxInStrm );
181  xTextStrm->setEncoding( OUString::createFromAscii( pcCharset ) );
182  }
183  catch (const Exception&)
184  {
185  }
186  return xTextStrm;
187 }
188 
189 // private --------------------------------------------------------------------
190 
191 OUString TextInputStream::createFinalString( const OUString& rString )
192 {
193  if( mcPendingChar == 0 )
194  return rString;
195 
196  OUString aString = OUStringChar( mcPendingChar ) + rString;
197  mcPendingChar = 0;
198  return aString;
199 }
200 
201 void TextInputStream::init( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
202 {
203  mcPendingChar = 0;
204  mxTextStrm = createXTextInputStream( rxContext, rxInStrm, eTextEnc );
205 }
206 
207 } // namespace oox
208 
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString readToChar(sal_Unicode cChar, bool bIncludeChar)
Reads a text portion from the stream until the specified character is found.
OUString readLine()
Reads a text line from the stream.
sal_uInt16 sal_Unicode
TextInputStream(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::io::XInputStream > &rxInStrm, rtl_TextEncoding eTextEnc)
void init(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::io::XInputStream > &rxInStrm, rtl_TextEncoding eTextEnc)
static css::uno::Reference< css::io::XTextInputStream2 > createXTextInputStream(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::io::XInputStream > &rxInStrm, rtl_TextEncoding eTextEnc)
Creates a UNO text input stream object from the passed UNO input stream.
bool isEof() const
Returns true, if no more text is available in the stream.
OUString createFinalString(const OUString &rString)
Adds the pending character in front of the passed string, if existing.
FILE * init(int, char **)