bump product version to 4.1.6.2
[LibreOffice.git] / io / source / TextOutputStream / TextOutputStream.cxx
blob48db4a93fa0059687a01fd2180c71f3c9186f021
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 .
21 #include <osl/diagnose.h>
23 #include <uno/mapping.hxx>
25 #include <cppuhelper/factory.hxx>
26 #include <cppuhelper/implbase2.hxx>
27 #include <cppuhelper/implementationentry.hxx>
29 #include <rtl/textenc.h>
30 #include <rtl/tencinfo.h>
32 #include <com/sun/star/io/XTextOutputStream2.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
36 #define IMPLEMENTATION_NAME "com.sun.star.comp.io.TextOutputStream"
37 #define SERVICE_NAME "com.sun.star.io.TextOutputStream"
39 using namespace ::osl;
40 using namespace ::rtl;
41 using namespace ::cppu;
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::lang;
44 using namespace ::com::sun::star::io;
45 using namespace ::com::sun::star::registry;
47 namespace io_TextOutputStream
49 //===========================================================================
50 // Implementation XTextOutputStream
52 typedef WeakImplHelper2< XTextOutputStream2, XServiceInfo > TextOutputStreamHelper;
54 class OTextOutputStream : public TextOutputStreamHelper
56 Reference< XOutputStream > mxStream;
58 // Encoding
59 OUString mEncoding;
60 sal_Bool mbEncodingInitialized;
61 rtl_UnicodeToTextConverter mConvUnicode2Text;
62 rtl_UnicodeToTextContext mContextUnicode2Text;
64 Sequence<sal_Int8> implConvert( const OUString& rSource );
66 public:
67 OTextOutputStream();
68 ~OTextOutputStream();
70 // Methods XTextOutputStream
71 virtual void SAL_CALL writeString( const OUString& aString )
72 throw(IOException, RuntimeException);
73 virtual void SAL_CALL setEncoding( const OUString& Encoding )
74 throw(RuntimeException);
76 // Methods XOutputStream
77 virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& aData )
78 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
79 virtual void SAL_CALL flush( )
80 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
81 virtual void SAL_CALL closeOutput( )
82 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
84 // Methods XActiveDataSource
85 virtual void SAL_CALL setOutputStream( const Reference< XOutputStream >& aStream )
86 throw(RuntimeException);
87 virtual Reference< XOutputStream > SAL_CALL getOutputStream( )
88 throw(RuntimeException);
90 // Methods XServiceInfo
91 virtual OUString SAL_CALL getImplementationName() throw();
92 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
93 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
96 OTextOutputStream::OTextOutputStream()
98 mbEncodingInitialized = false;
101 OTextOutputStream::~OTextOutputStream()
103 if( mbEncodingInitialized )
105 rtl_destroyUnicodeToTextContext( mConvUnicode2Text, mContextUnicode2Text );
106 rtl_destroyUnicodeToTextConverter( mConvUnicode2Text );
110 Sequence<sal_Int8> OTextOutputStream::implConvert( const OUString& rSource )
112 const sal_Unicode *puSource = rSource.getStr();
113 sal_Int32 nSourceSize = rSource.getLength();
115 sal_Size nTargetCount = 0;
116 sal_Size nSourceCount = 0;
118 sal_uInt32 uiInfo;
119 sal_Size nSrcCvtChars;
121 // take nSourceSize * 3 as preference
122 // this is an upper boundary for converting to utf8,
123 // which most often used as the target.
124 sal_Int32 nSeqSize = nSourceSize * 3;
126 Sequence<sal_Int8> seqText( nSeqSize );
127 sal_Char *pTarget = (sal_Char *) seqText.getArray();
128 while( true )
130 nTargetCount += rtl_convertUnicodeToText(
131 mConvUnicode2Text,
132 mContextUnicode2Text,
133 &( puSource[nSourceCount] ),
134 nSourceSize - nSourceCount ,
135 &( pTarget[nTargetCount] ),
136 nSeqSize - nTargetCount,
137 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
138 RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT ,
139 &uiInfo,
140 &nSrcCvtChars);
141 nSourceCount += nSrcCvtChars;
143 if( uiInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
145 nSeqSize *= 2;
146 seqText.realloc( nSeqSize ); // double array size
147 pTarget = (sal_Char*) seqText.getArray();
148 continue;
150 break;
153 // reduce the size of the buffer (fast, no copy necessary)
154 seqText.realloc( nTargetCount );
155 return seqText;
159 //===========================================================================
160 // XTextOutputStream
162 void OTextOutputStream::writeString( const OUString& aString )
163 throw(IOException, RuntimeException)
165 if( !mbEncodingInitialized )
167 OUString aUtf8Str("utf8");
168 setEncoding( aUtf8Str );
170 if( !mbEncodingInitialized )
171 return;
173 Sequence<sal_Int8> aByteSeq = implConvert( aString );
174 mxStream->writeBytes( aByteSeq );
177 void OTextOutputStream::setEncoding( const OUString& Encoding )
178 throw(RuntimeException)
180 OString aOEncodingStr = OUStringToOString( Encoding, RTL_TEXTENCODING_ASCII_US );
181 rtl_TextEncoding encoding = rtl_getTextEncodingFromMimeCharset( aOEncodingStr.getStr() );
182 if( RTL_TEXTENCODING_DONTKNOW == encoding )
183 return;
185 mbEncodingInitialized = true;
186 mConvUnicode2Text = rtl_createUnicodeToTextConverter( encoding );
187 mContextUnicode2Text = rtl_createUnicodeToTextContext( mConvUnicode2Text );
188 mEncoding = Encoding;
191 //===========================================================================
192 // XOutputStream
193 void OTextOutputStream::writeBytes( const Sequence< sal_Int8 >& aData )
194 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
196 mxStream->writeBytes( aData );
199 void OTextOutputStream::flush( )
200 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
202 mxStream->flush();
205 void OTextOutputStream::closeOutput( )
206 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
208 mxStream->closeOutput();
212 //===========================================================================
213 // XActiveDataSource
215 void OTextOutputStream::setOutputStream( const Reference< XOutputStream >& aStream )
216 throw(RuntimeException)
218 mxStream = aStream;
221 Reference< XOutputStream > OTextOutputStream::getOutputStream()
222 throw(RuntimeException)
224 return mxStream;
228 Reference< XInterface > SAL_CALL TextOutputStream_CreateInstance(
229 SAL_UNUSED_PARAMETER const Reference< XComponentContext > &)
231 return Reference < XInterface >( ( OWeakObject * ) new OTextOutputStream() );
234 OUString TextOutputStream_getImplementationName() SAL_THROW( () )
236 return OUString( IMPLEMENTATION_NAME );
240 Sequence< OUString > TextOutputStream_getSupportedServiceNames()
242 Sequence< OUString > seqNames(1);
243 seqNames.getArray()[0] = SERVICE_NAME;
244 return seqNames;
247 OUString OTextOutputStream::getImplementationName() throw()
249 return TextOutputStream_getImplementationName();
252 sal_Bool OTextOutputStream::supportsService(const OUString& ServiceName) throw()
254 Sequence< OUString > aSNL = getSupportedServiceNames();
255 const OUString * pArray = aSNL.getConstArray();
257 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
258 if( pArray[i] == ServiceName )
259 return sal_True;
261 return sal_False;
264 Sequence< OUString > OTextOutputStream::getSupportedServiceNames(void) throw()
266 return TextOutputStream_getSupportedServiceNames();
272 using namespace io_TextOutputStream;
274 static struct ImplementationEntry g_entries[] =
277 TextOutputStream_CreateInstance, TextOutputStream_getImplementationName ,
278 TextOutputStream_getSupportedServiceNames, createSingleComponentFactory ,
279 0, 0
281 { 0, 0, 0, 0, 0, 0 }
284 extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL textoutstream_component_getFactory(
285 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
287 return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */