nss: upgrade to release 3.73
[LibreOffice.git] / io / source / TextOutputStream / TextOutputStream.cxx
blob2700ec1e415af195f476bf503ebe12d8199a4604
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
22 #include <cppuhelper/implbase.hxx>
23 #include <cppuhelper/supportsservice.hxx>
25 #include <rtl/textenc.h>
26 #include <rtl/tencinfo.h>
28 #include <com/sun/star/io/IOException.hpp>
29 #include <com/sun/star/io/XTextOutputStream2.hpp>
30 #include <com/sun/star/lang/XServiceInfo.hpp>
32 namespace com::sun::star::uno { class XComponentContext; }
34 #define IMPLEMENTATION_NAME "com.sun.star.comp.io.TextOutputStream"
35 #define SERVICE_NAME "com.sun.star.io.TextOutputStream"
37 using namespace ::osl;
38 using namespace ::cppu;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::lang;
41 using namespace ::com::sun::star::io;
43 // Implementation XTextOutputStream
45 namespace {
47 class OTextOutputStream : public WeakImplHelper< XTextOutputStream2, XServiceInfo >
49 Reference< XOutputStream > mxStream;
51 // Encoding
52 bool mbEncodingInitialized;
53 rtl_UnicodeToTextConverter mConvUnicode2Text;
54 rtl_UnicodeToTextContext mContextUnicode2Text;
56 Sequence<sal_Int8> implConvert( const OUString& rSource );
57 /// @throws IOException
58 void checkOutputStream() const;
60 public:
61 OTextOutputStream();
62 virtual ~OTextOutputStream() override;
64 // Methods XTextOutputStream
65 virtual void SAL_CALL writeString( const OUString& aString ) override;
66 virtual void SAL_CALL setEncoding( const OUString& Encoding ) override;
68 // Methods XOutputStream
69 virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& aData ) override;
70 virtual void SAL_CALL flush( ) override;
71 virtual void SAL_CALL closeOutput( ) override;
73 // Methods XActiveDataSource
74 virtual void SAL_CALL setOutputStream( const Reference< XOutputStream >& aStream ) override;
75 virtual Reference< XOutputStream > SAL_CALL getOutputStream( ) override;
77 // Methods XServiceInfo
78 virtual OUString SAL_CALL getImplementationName() override;
79 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
80 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
85 OTextOutputStream::OTextOutputStream()
86 : mbEncodingInitialized(false)
87 , mConvUnicode2Text(nullptr)
88 , mContextUnicode2Text(nullptr)
92 OTextOutputStream::~OTextOutputStream()
94 if( mbEncodingInitialized )
96 rtl_destroyUnicodeToTextContext( mConvUnicode2Text, mContextUnicode2Text );
97 rtl_destroyUnicodeToTextConverter( mConvUnicode2Text );
101 Sequence<sal_Int8> OTextOutputStream::implConvert( const OUString& rSource )
103 const sal_Unicode *puSource = rSource.getStr();
104 sal_Int32 nSourceSize = rSource.getLength();
106 sal_Size nTargetCount = 0;
107 sal_Size nSourceCount = 0;
109 sal_uInt32 uiInfo;
110 sal_Size nSrcCvtChars;
112 // take nSourceSize * 3 as preference
113 // this is an upper boundary for converting to utf8,
114 // which most often used as the target.
115 sal_Int32 nSeqSize = nSourceSize * 3;
117 Sequence<sal_Int8> seqText( nSeqSize );
118 char *pTarget = reinterpret_cast<char *>(seqText.getArray());
119 while( true )
121 nTargetCount += rtl_convertUnicodeToText(
122 mConvUnicode2Text,
123 mContextUnicode2Text,
124 &( puSource[nSourceCount] ),
125 nSourceSize - nSourceCount ,
126 &( pTarget[nTargetCount] ),
127 nSeqSize - nTargetCount,
128 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
129 RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT ,
130 &uiInfo,
131 &nSrcCvtChars);
132 nSourceCount += nSrcCvtChars;
134 if( uiInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
136 nSeqSize *= 2;
137 seqText.realloc( nSeqSize ); // double array size
138 pTarget = reinterpret_cast<char*>(seqText.getArray());
139 continue;
141 break;
144 // reduce the size of the buffer (fast, no copy necessary)
145 seqText.realloc( nTargetCount );
146 return seqText;
150 // XTextOutputStream
152 void OTextOutputStream::writeString( const OUString& aString )
154 checkOutputStream();
155 if( !mbEncodingInitialized )
157 setEncoding( "utf8" );
159 if( !mbEncodingInitialized )
160 return;
162 Sequence<sal_Int8> aByteSeq = implConvert( aString );
163 mxStream->writeBytes( aByteSeq );
166 void OTextOutputStream::setEncoding( const OUString& Encoding )
168 OString aOEncodingStr = OUStringToOString( Encoding, RTL_TEXTENCODING_ASCII_US );
169 rtl_TextEncoding encoding = rtl_getTextEncodingFromMimeCharset( aOEncodingStr.getStr() );
170 if( RTL_TEXTENCODING_DONTKNOW == encoding )
171 return;
173 mbEncodingInitialized = true;
174 mConvUnicode2Text = rtl_createUnicodeToTextConverter( encoding );
175 mContextUnicode2Text = rtl_createUnicodeToTextContext( mConvUnicode2Text );
179 // XOutputStream
180 void OTextOutputStream::writeBytes( const Sequence< sal_Int8 >& aData )
182 checkOutputStream();
183 mxStream->writeBytes( aData );
186 void OTextOutputStream::flush( )
188 checkOutputStream();
189 mxStream->flush();
192 void OTextOutputStream::closeOutput( )
194 checkOutputStream();
195 mxStream->closeOutput();
199 void OTextOutputStream::checkOutputStream() const
201 if (! mxStream.is() )
202 throw IOException("output stream is not initialized, you have to use setOutputStream first");
206 // XActiveDataSource
208 void OTextOutputStream::setOutputStream( const Reference< XOutputStream >& aStream )
210 mxStream = aStream;
213 Reference< XOutputStream > OTextOutputStream::getOutputStream()
215 return mxStream;
218 OUString OTextOutputStream::getImplementationName()
220 return IMPLEMENTATION_NAME;
223 sal_Bool OTextOutputStream::supportsService(const OUString& ServiceName)
225 return cppu::supportsService(this, ServiceName);
228 Sequence< OUString > OTextOutputStream::getSupportedServiceNames()
230 return { SERVICE_NAME };
235 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
236 io_OTextOutputStream_get_implementation(
237 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
239 return cppu::acquire(new OTextOutputStream());
242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */