26#include <rtl/textenc.h>
27#include <rtl/tencinfo.h>
29#include <com/sun/star/io/BufferSizeExceededException.hpp>
30#include <com/sun/star/io/IOException.hpp>
31#include <com/sun/star/io/NotConnectedException.hpp>
32#include <com/sun/star/io/XTextInputStream2.hpp>
33#include <com/sun/star/lang/XServiceInfo.hpp>
40using namespace ::
cppu;
48#define INITIAL_UNICODE_BUFFER_CAPACITY 0x100
49#define READ_BYTE_COUNT 0x100
53class OTextInputStream :
public WeakImplHelper< XTextInputStream2, XServiceInfo >
55 Reference< XInputStream > mxStream;
58 bool mbEncodingInitialized;
59 rtl_TextToUnicodeConverter mConvText2Unicode;
60 rtl_TextToUnicodeContext mContextText2Unicode;
61 Sequence<sal_Int8> mSeqSource;
64 std::vector<sal_Unicode> mvBuffer;
65 sal_Int32 mnCharsInBuffer;
70 OUString implReadString(
const Sequence< sal_Unicode >& Delimiters,
71 bool bRemoveDelimiter,
bool bFindLineEnd );
74 sal_Int32 implReadNext();
80 virtual ~OTextInputStream()
override;
83 virtual OUString SAL_CALL
readLine( )
override;
84 virtual OUString SAL_CALL
readString(
const Sequence< sal_Unicode >& Delimiters,
sal_Bool bRemoveDelimiter )
override;
85 virtual sal_Bool SAL_CALL isEOF( )
override;
86 virtual void SAL_CALL setEncoding(
const OUString& Encoding )
override;
91 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
override;
92 virtual sal_Int32 SAL_CALL available( )
override;
93 virtual void SAL_CALL closeInput( )
override;
96 virtual void SAL_CALL setInputStream(
const Reference< XInputStream >& aStream )
override;
97 virtual Reference< XInputStream > SAL_CALL getInputStream()
override;
107OTextInputStream::OTextInputStream()
108 : mbEncodingInitialized(false)
109 , mConvText2Unicode(nullptr)
110 , mContextText2Unicode(nullptr)
114 , mbReachedEOF(false)
118OTextInputStream::~OTextInputStream()
120 if( mbEncodingInitialized )
122 rtl_destroyTextToUnicodeContext( mConvText2Unicode, mContextText2Unicode );
123 rtl_destroyTextToUnicodeConverter( mConvText2Unicode );
129void OTextInputStream::checkNull()
131 if (mxStream==
nullptr){
138OUString OTextInputStream::readLine( )
141 static Sequence< sal_Unicode > aDummySeq;
142 return implReadString( aDummySeq,
true,
true );
145OUString OTextInputStream::readString(
const Sequence< sal_Unicode >& Delimiters,
sal_Bool bRemoveDelimiter )
148 return implReadString( Delimiters, bRemoveDelimiter,
false );
155 if( mnCharsInBuffer == 0 && mbReachedEOF )
161OUString OTextInputStream::implReadString(
const Sequence< sal_Unicode >& Delimiters,
162 bool bRemoveDelimiter,
bool bFindLineEnd )
165 if( !mbEncodingInitialized )
167 setEncoding(
"utf8" );
169 if( !mbEncodingInitialized )
176 sal_Int32 nBufferReadPos = 0;
177 sal_Int32 nCopyLen = 0;
179 bool bFoundFirstLineEndChar =
false;
184 if( nBufferReadPos == mnCharsInBuffer )
191 if( !implReadNext() )
201 if( bFoundFirstLineEndChar )
204 nCopyLen = nBufferReadPos - 2;
205 if( c == cLineEndChar1 || c == cLineEndChar2 )
208 if( c == cFirstLineEndChar )
219 else if( c == cLineEndChar1 || c == cLineEndChar2 )
221 bFoundFirstLineEndChar =
true;
222 cFirstLineEndChar = c;
228 nCopyLen = nBufferReadPos;
229 if( bRemoveDelimiter )
235 if( !nCopyLen && !bFound && mbReachedEOF )
236 nCopyLen = nBufferReadPos;
240 aRetStr = OUString( mvBuffer.data(), nCopyLen );
243 memmove( mvBuffer.data(), mvBuffer.data() + nBufferReadPos,
244 (mnCharsInBuffer - nBufferReadPos) *
sizeof(
sal_Unicode ) );
245 mnCharsInBuffer -= nBufferReadPos;
251sal_Int32 OTextInputStream::implReadNext()
253 sal_Int32 nFreeBufferSize = mvBuffer.size() - mnCharsInBuffer;
255 mvBuffer.resize(mvBuffer.size() * 2);
256 nFreeBufferSize = mvBuffer.size() - mnCharsInBuffer;
260 sal_Int32 nRead = mxStream->readSomeBytes( mSeqSource,
READ_BYTE_COUNT );
261 sal_Int32 nTotalRead = nRead;
267 sal_Size nSrcCvtBytes = 0;
268 sal_Size nTargetCount = 0;
269 sal_Size nSourceCount = 0;
272 const sal_Int8 *pbSource = mSeqSource.getConstArray();
275 nTargetCount += rtl_convertTextToUnicode(
277 mContextText2Unicode,
278 reinterpret_cast<const char*
>(&( pbSource[nSourceCount] )),
279 nTotalRead - nSourceCount,
280 mvBuffer.data() + mnCharsInBuffer + nTargetCount,
281 nFreeBufferSize - nTargetCount,
282 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
283 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
284 RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT,
287 nSourceCount += nSrcCvtBytes;
290 if( uiInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL )
292 mvBuffer.resize(mvBuffer.size() * 2);
296 if( uiInfo & RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL )
300 nRead = mxStream->readSomeBytes( aOneByteSeq, 1 );
307 sal_Int32 nOldLen = mSeqSource.getLength();
309 if( nTotalRead > nOldLen )
311 mSeqSource.realloc( nTotalRead );
313 mSeqSource.getArray()[ nOldLen ] = aOneByteSeq.getConstArray()[ 0 ];
322 mnCharsInBuffer += nTargetCount;
325 catch( NotConnectedException& )
330 catch( BufferSizeExceededException& )
336void OTextInputStream::setEncoding(
const OUString& Encoding )
338 OString aOEncodingStr =
OUStringToOString( Encoding, RTL_TEXTENCODING_ASCII_US );
339 rtl_TextEncoding encoding = rtl_getTextEncodingFromMimeCharset( aOEncodingStr.getStr() );
340 if( RTL_TEXTENCODING_DONTKNOW == encoding )
343 mbEncodingInitialized =
true;
344 mConvText2Unicode = rtl_createTextToUnicodeConverter( encoding );
345 mContextText2Unicode = rtl_createTextToUnicodeContext( mConvText2Unicode );
354 return mxStream->readBytes( aData, nBytesToRead );
357sal_Int32 OTextInputStream::readSomeBytes(
Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
360 return mxStream->readSomeBytes( aData, nMaxBytesToRead );
363void OTextInputStream::skipBytes( sal_Int32 nBytesToSkip )
366 mxStream->skipBytes( nBytesToSkip );
369sal_Int32 OTextInputStream::available( )
372 return mxStream->available();
375void OTextInputStream::closeInput( )
378 mxStream->closeInput();
384void OTextInputStream::setInputStream(
const Reference< XInputStream >& aStream )
389Reference< XInputStream > OTextInputStream::getInputStream()
394OUString OTextInputStream::getImplementationName()
396 return "com.sun.star.comp.io.TextInputStream";
399sal_Bool OTextInputStream::supportsService(
const OUString& ServiceName)
404Sequence< OUString > OTextInputStream::getSupportedServiceNames()
406 return {
"com.sun.star.io.TextInputStream" };
409extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
411 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any>
const&)
413 return cppu::acquire(
new OTextInputStream());
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * io_OTextInputStream_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
#define INITIAL_UNICODE_BUFFER_CAPACITY
constexpr OUStringLiteral aData
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool readLine(OUString *res, std::u16string_view startingWith, ::ucbhelper::Content &ucb_content, rtl_TextEncoding textenc)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
sal_uInt32 readString(const sal_uInt8 *buffer, sal_Unicode *v, sal_uInt32 maxSize)