merge the formfield patch from ooo-build
[ooovba.git] / io / source / TextOutputStream / TextOutputStream.cxx
blob06a5cf914b98ee9d788c2d44344a7c17eb3bd680
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: TextOutputStream.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_io.hxx"
35 #include <osl/mutex.hxx>
36 #include <osl/diagnose.h>
38 #include <uno/mapping.hxx>
40 #include <cppuhelper/factory.hxx>
41 #include <cppuhelper/implbase3.hxx>
42 #include <cppuhelper/implementationentry.hxx>
44 #include <rtl/textenc.h>
45 #include <rtl/tencinfo.h>
46 #include <rtl/unload.h>
48 #include <com/sun/star/io/XTextOutputStream.hpp>
49 #include <com/sun/star/io/XActiveDataSource.hpp>
50 #include <com/sun/star/lang/XServiceInfo.hpp>
53 #define IMPLEMENTATION_NAME "com.sun.star.comp.io.TextOutputStream"
54 #define SERVICE_NAME "com.sun.star.io.TextOutputStream"
56 using namespace ::osl;
57 using namespace ::rtl;
58 using namespace ::cppu;
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::lang;
61 using namespace ::com::sun::star::io;
62 using namespace ::com::sun::star::registry;
64 namespace io_TextOutputStream
66 rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
67 //===========================================================================
68 // Implementation XTextOutputStream
70 typedef WeakImplHelper3< XTextOutputStream, XActiveDataSource, XServiceInfo > TextOutputStreamHelper;
71 class OCommandEnvironment;
73 class OTextOutputStream : public TextOutputStreamHelper
75 Reference< XOutputStream > mxStream;
77 // Encoding
78 OUString mEncoding;
79 sal_Bool mbEncodingInitialized;
80 rtl_UnicodeToTextConverter mConvUnicode2Text;
81 rtl_UnicodeToTextContext mContextUnicode2Text;
83 Sequence<sal_Int8> implConvert( const OUString& rSource );
85 public:
86 OTextOutputStream();
87 ~OTextOutputStream();
89 // Methods XTextOutputStream
90 virtual void SAL_CALL writeString( const OUString& aString )
91 throw(IOException, RuntimeException);
92 virtual void SAL_CALL setEncoding( const OUString& Encoding )
93 throw(RuntimeException);
95 // Methods XOutputStream
96 virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& aData )
97 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
98 virtual void SAL_CALL flush( )
99 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
100 virtual void SAL_CALL closeOutput( )
101 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
103 // Methods XActiveDataSource
104 virtual void SAL_CALL setOutputStream( const Reference< XOutputStream >& aStream )
105 throw(RuntimeException);
106 virtual Reference< XOutputStream > SAL_CALL getOutputStream( )
107 throw(RuntimeException);
109 // Methods XServiceInfo
110 virtual OUString SAL_CALL getImplementationName() throw();
111 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
112 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
115 OTextOutputStream::OTextOutputStream()
117 mbEncodingInitialized = false;
120 OTextOutputStream::~OTextOutputStream()
122 if( mbEncodingInitialized )
124 rtl_destroyUnicodeToTextContext( mConvUnicode2Text, mContextUnicode2Text );
125 rtl_destroyUnicodeToTextConverter( mConvUnicode2Text );
129 Sequence<sal_Int8> OTextOutputStream::implConvert( const OUString& rSource )
131 const sal_Unicode *puSource = rSource.getStr();
132 sal_Int32 nSourceSize = rSource.getLength();
134 sal_Size nTargetCount = 0;
135 sal_Size nSourceCount = 0;
137 sal_uInt32 uiInfo;
138 sal_Size nSrcCvtChars;
140 // take nSourceSize * 3 as preference
141 // this is an upper boundary for converting to utf8,
142 // which most often used as the target.
143 sal_Int32 nSeqSize = nSourceSize * 3;
145 Sequence<sal_Int8> seqText( nSeqSize );
146 sal_Char *pTarget = (sal_Char *) seqText.getArray();
147 while( sal_True )
149 nTargetCount += rtl_convertUnicodeToText(
150 mConvUnicode2Text,
151 mContextUnicode2Text,
152 &( puSource[nSourceCount] ),
153 nSourceSize - nSourceCount ,
154 &( pTarget[nTargetCount] ),
155 nSeqSize - nTargetCount,
156 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
157 RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT ,
158 &uiInfo,
159 &nSrcCvtChars);
160 nSourceCount += nSrcCvtChars;
162 if( uiInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
164 nSeqSize *= 2;
165 seqText.realloc( nSeqSize ); // double array size
166 pTarget = (sal_Char*) seqText.getArray();
167 continue;
169 break;
172 // reduce the size of the buffer (fast, no copy necessary)
173 seqText.realloc( nTargetCount );
174 return seqText;
178 //===========================================================================
179 // XTextOutputStream
181 void OTextOutputStream::writeString( const OUString& aString )
182 throw(IOException, RuntimeException)
184 if( !mbEncodingInitialized )
186 OUString aUtf8Str( RTL_CONSTASCII_USTRINGPARAM("utf8") );
187 setEncoding( aUtf8Str );
189 if( !mbEncodingInitialized )
190 return;
192 Sequence<sal_Int8> aByteSeq = implConvert( aString );
193 mxStream->writeBytes( aByteSeq );
196 void OTextOutputStream::setEncoding( const OUString& Encoding )
197 throw(RuntimeException)
199 OString aOEncodingStr = OUStringToOString( Encoding, RTL_TEXTENCODING_ASCII_US );
200 rtl_TextEncoding encoding = rtl_getTextEncodingFromMimeCharset( aOEncodingStr.getStr() );
201 if( RTL_TEXTENCODING_DONTKNOW == encoding )
202 return;
204 mbEncodingInitialized = true;
205 mConvUnicode2Text = rtl_createUnicodeToTextConverter( encoding );
206 mContextUnicode2Text = rtl_createUnicodeToTextContext( mConvUnicode2Text );
207 mEncoding = Encoding;
210 //===========================================================================
211 // XOutputStream
212 void OTextOutputStream::writeBytes( const Sequence< sal_Int8 >& aData )
213 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
215 mxStream->writeBytes( aData );
218 void OTextOutputStream::flush( )
219 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
221 mxStream->flush();
224 void OTextOutputStream::closeOutput( )
225 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
227 mxStream->closeOutput();
231 //===========================================================================
232 // XActiveDataSource
234 void OTextOutputStream::setOutputStream( const Reference< XOutputStream >& aStream )
235 throw(RuntimeException)
237 mxStream = aStream;
240 Reference< XOutputStream > OTextOutputStream::getOutputStream()
241 throw(RuntimeException)
243 return mxStream;
247 Reference< XInterface > SAL_CALL TextOutputStream_CreateInstance( const Reference< XComponentContext > &)
249 return Reference < XInterface >( ( OWeakObject * ) new OTextOutputStream() );
252 OUString TextOutputStream_getImplementationName() SAL_THROW( () )
254 return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
258 Sequence< OUString > TextOutputStream_getSupportedServiceNames()
260 static Sequence < OUString > *pNames = 0;
261 if( ! pNames )
263 MutexGuard guard( Mutex::getGlobalMutex() );
264 if( !pNames )
266 static Sequence< OUString > seqNames(1);
267 seqNames.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) );
268 pNames = &seqNames;
271 return *pNames;
274 OUString OTextOutputStream::getImplementationName() throw()
276 return TextOutputStream_getImplementationName();
279 sal_Bool OTextOutputStream::supportsService(const OUString& ServiceName) throw()
281 Sequence< OUString > aSNL = getSupportedServiceNames();
282 const OUString * pArray = aSNL.getConstArray();
284 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
285 if( pArray[i] == ServiceName )
286 return sal_True;
288 return sal_False;
291 Sequence< OUString > OTextOutputStream::getSupportedServiceNames(void) throw()
293 return TextOutputStream_getSupportedServiceNames();
299 using namespace io_TextOutputStream;
301 static struct ImplementationEntry g_entries[] =
304 TextOutputStream_CreateInstance, TextOutputStream_getImplementationName ,
305 TextOutputStream_getSupportedServiceNames, createSingleComponentFactory ,
306 &g_moduleCount.modCnt , 0
308 { 0, 0, 0, 0, 0, 0 }
311 extern "C"
313 sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
315 return g_moduleCount.canUnload( &g_moduleCount , pTime );
318 //==================================================================================================
319 void SAL_CALL component_getImplementationEnvironment(
320 const sal_Char ** ppEnvTypeName, uno_Environment ** )
322 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
324 //==================================================================================================
325 sal_Bool SAL_CALL component_writeInfo(
326 void * pServiceManager, void * pRegistryKey )
328 return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
330 //==================================================================================================
331 void * SAL_CALL component_getFactory(
332 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
334 return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );