| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_cppuhelper.hxx" |
| |
| #include <string.h> |
| #include <vector> |
| |
| #include "rtl/process.h" |
| #include "rtl/bootstrap.hxx" |
| #include "rtl/random.h" |
| #include "rtl/string.hxx" |
| #include "rtl/ustrbuf.hxx" |
| #include "rtl/uri.hxx" |
| #if OSL_DEBUG_LEVEL > 0 |
| #include "rtl/strbuf.hxx" |
| #endif |
| #include "osl/diagnose.h" |
| #include "osl/file.hxx" |
| #include "osl/module.hxx" |
| #include "osl/security.hxx" |
| #include "osl/thread.hxx" |
| |
| #include "cppuhelper/shlib.hxx" |
| #include "cppuhelper/bootstrap.hxx" |
| #include "cppuhelper/component_context.hxx" |
| #include "cppuhelper/access_control.hxx" |
| #include "cppuhelper/findsofficepath.h" |
| |
| #include <cppuhelper/com/sun/star/container/XElementAccess.hpp> |
| |
| #include "com/sun/star/uno/XComponentContext.hpp" |
| #include "com/sun/star/uno/XCurrentContext.hpp" |
| |
| #include "com/sun/star/lang/XSingleServiceFactory.hpp" |
| #include "com/sun/star/lang/XSingleComponentFactory.hpp" |
| #include "com/sun/star/lang/XInitialization.hpp" |
| #include "com/sun/star/lang/XServiceInfo.hpp" |
| #include "com/sun/star/registry/XSimpleRegistry.hpp" |
| #include "com/sun/star/container/XSet.hpp" |
| #include "com/sun/star/beans/PropertyValue.hpp" |
| #include "com/sun/star/io/IOException.hpp" |
| #include "com/sun/star/bridge/UnoUrlResolver.hpp" |
| #include "com/sun/star/bridge/XUnoUrlResolver.hpp" |
| |
| #include "macro_expander.hxx" |
| |
| #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) |
| #define ARLEN(x) sizeof (x) / sizeof *(x) |
| |
| void primeWeakMap( void); // as defined in primeweak.cxx |
| |
| using namespace ::rtl; |
| using namespace ::osl; |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| |
| namespace cppu |
| { |
| |
| OUString const & get_this_libpath() |
| { |
| static OUString s_path; |
| if (0 == s_path.getLength()) |
| { |
| OUString path; |
| Module::getUrlFromAddress( reinterpret_cast<oslGenericFunction>(get_this_libpath), path ); |
| path = path.copy( 0, path.lastIndexOf( '/' ) ); |
| MutexGuard guard( Mutex::getGlobalMutex() ); |
| if (0 == s_path.getLength()) |
| s_path = path; |
| } |
| return s_path; |
| } |
| |
| Bootstrap const & get_unorc() SAL_THROW( () ) |
| { |
| static rtlBootstrapHandle s_bstrap = 0; |
| if (! s_bstrap) |
| { |
| OUString iniName( |
| get_this_libpath() + OUSTR("/" SAL_CONFIGFILE("uno")) ); |
| rtlBootstrapHandle bstrap = rtl_bootstrap_args_open( iniName.pData ); |
| |
| ClearableMutexGuard guard( Mutex::getGlobalMutex() ); |
| if (s_bstrap) |
| { |
| guard.clear(); |
| rtl_bootstrap_args_close( bstrap ); |
| } |
| else |
| { |
| s_bstrap = bstrap; |
| } |
| } |
| return *(Bootstrap const *)&s_bstrap; |
| } |
| |
| |
| void addFactories( |
| char const * const * ppNames /* lib, implname, ..., 0 */, |
| OUString const & bootstrapPath, |
| Reference< lang::XMultiComponentFactory > const & xMgr, |
| Reference< registry::XRegistryKey > const & xKey ) |
| SAL_THROW( (Exception) ) |
| { |
| Reference< container::XSet > xSet( xMgr, UNO_QUERY ); |
| OSL_ASSERT( xSet.is() ); |
| Reference< lang::XMultiServiceFactory > xSF( xMgr, UNO_QUERY ); |
| |
| while (*ppNames) |
| { |
| OUString lib( OUString::createFromAscii( *ppNames++ ) ); |
| OUString implName( OUString::createFromAscii( *ppNames++ ) ); |
| |
| Any aFac( makeAny( loadSharedLibComponentFactory( |
| lib, bootstrapPath, implName, xSF, xKey ) ) ); |
| xSet->insert( aFac ); |
| #if OSL_DEBUG_LEVEL > 1 |
| if (xSet->has( aFac )) |
| { |
| Reference< lang::XServiceInfo > xInfo; |
| if (aFac >>= xInfo) |
| { |
| ::fprintf( |
| stderr, "> implementation %s supports: ", ppNames[ -1 ] ); |
| Sequence< OUString > supported( |
| xInfo->getSupportedServiceNames() ); |
| for ( sal_Int32 nPos = supported.getLength(); nPos--; ) |
| { |
| OString str( OUStringToOString( |
| supported[ nPos ], RTL_TEXTENCODING_ASCII_US ) ); |
| ::fprintf( stderr, nPos ? "%s, " : "%s\n", str.getStr() ); |
| } |
| } |
| else |
| { |
| ::fprintf( |
| stderr, |
| "> implementation %s provides NO lang::XServiceInfo!!!\n", |
| ppNames[ -1 ] ); |
| } |
| } |
| #endif |
| #if OSL_DEBUG_LEVEL > 0 |
| if (! xSet->has( aFac )) |
| { |
| OStringBuffer buf( 64 ); |
| buf.append( "### failed inserting shared lib \"" ); |
| buf.append( ppNames[ -2 ] ); |
| buf.append( "\"!!!" ); |
| OString str( buf.makeStringAndClear() ); |
| OSL_ENSURE( 0, str.getStr() ); |
| } |
| #endif |
| } |
| } |
| |
| // private forward decl |
| Reference< lang::XMultiComponentFactory > bootstrapInitialSF( |
| OUString const & rBootstrapPath ) |
| SAL_THROW( (Exception) ); |
| |
| Reference< XComponentContext > bootstrapInitialContext( |
| Reference< lang::XMultiComponentFactory > const & xSF, |
| Reference< registry::XSimpleRegistry > const & types_xRegistry, |
| Reference< registry::XSimpleRegistry > const & services_xRegistry, |
| OUString const & rBootstrapPath, Bootstrap const & bootstrap ) |
| SAL_THROW( (Exception) ); |
| |
| Reference< XComponentContext > SAL_CALL createInitialCfgComponentContext( |
| ContextEntry_Init const * pEntries, sal_Int32 nEntries, |
| Reference< XComponentContext > const & xDelegate ) |
| SAL_THROW( () ); |
| |
| Reference< registry::XSimpleRegistry > SAL_CALL createRegistryWrapper( |
| const Reference< XComponentContext >& xContext ); |
| |
| namespace { |
| |
| template< class T > |
| inline beans::PropertyValue createPropertyValue( |
| OUString const & name, T const & value ) |
| SAL_THROW( () ) |
| { |
| return beans::PropertyValue( |
| name, -1, makeAny( value ), beans::PropertyState_DIRECT_VALUE ); |
| } |
| |
| OUString findBoostrapArgument( |
| const Bootstrap & bootstrap, |
| const OUString & arg_name, |
| sal_Bool * pFallenBack ) |
| SAL_THROW(()) |
| { |
| OUString result; |
| |
| OUString prefixed_arg_name = OUSTR("UNO_"); |
| prefixed_arg_name += arg_name.toAsciiUpperCase(); |
| |
| // environment not set -> try relative to executable |
| if(!bootstrap.getFrom(prefixed_arg_name, result)) |
| { |
| if(pFallenBack) |
| *pFallenBack = sal_True; |
| |
| OUString fileName; |
| bootstrap.getIniName(fileName); |
| |
| // cut the rc extension |
| OUStringBuffer result_buf( 64 ); |
| result_buf.append( |
| fileName.copy( |
| 0, fileName.getLength() - strlen(SAL_CONFIGFILE(""))) ); |
| result_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("_") ); |
| result_buf.append( arg_name.toAsciiLowerCase() ); |
| result_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".rdb") ); |
| result = result_buf.makeStringAndClear(); |
| |
| #if OSL_DEBUG_LEVEL > 1 |
| OString result_dbg = |
| OUStringToOString(result, RTL_TEXTENCODING_ASCII_US); |
| OString arg_name_dbg = |
| OUStringToOString(arg_name, RTL_TEXTENCODING_ASCII_US); |
| OSL_TRACE( |
| "cppuhelper::findBoostrapArgument - " |
| "setting %s relative to executable: %s\n", |
| arg_name_dbg.getStr(), |
| result_dbg.getStr() ); |
| #endif |
| } |
| else |
| { |
| if(pFallenBack) |
| *pFallenBack = sal_False; |
| |
| #if OSL_DEBUG_LEVEL > 1 |
| OString prefixed_arg_name_dbg = OUStringToOString( |
| prefixed_arg_name, RTL_TEXTENCODING_ASCII_US ); |
| OString result_dbg = OUStringToOString( |
| result, RTL_TEXTENCODING_ASCII_US ); |
| OSL_TRACE( |
| "cppuhelper::findBoostrapArgument - found %s in env: %s", |
| prefixed_arg_name_dbg.getStr(), |
| result_dbg.getStr() ); |
| #endif |
| } |
| |
| return result; |
| } |
| |
| Reference< registry::XSimpleRegistry > nestRegistries( |
| const OUString baseDir, |
| const Reference< lang::XSingleServiceFactory > & xSimRegFac, |
| const Reference< lang::XSingleServiceFactory > & xNesRegFac, |
| OUString csl_rdbs, |
| const OUString & write_rdb, |
| sal_Bool forceWrite_rdb, |
| sal_Bool bFallenBack ) |
| SAL_THROW((Exception)) |
| { |
| sal_Int32 index; |
| Reference< registry::XSimpleRegistry > lastRegistry; |
| |
| if(write_rdb.getLength()) // is there a write registry given? |
| { |
| lastRegistry.set(xSimRegFac->createInstance(), UNO_QUERY); |
| |
| try |
| { |
| lastRegistry->open(write_rdb, sal_False, forceWrite_rdb); |
| } |
| catch (registry::InvalidRegistryException & invalidRegistryException) |
| { |
| (void) invalidRegistryException; |
| #if OSL_DEBUG_LEVEL > 1 |
| OString rdb_name_tmp = OUStringToOString( |
| write_rdb, RTL_TEXTENCODING_ASCII_US); |
| OString message_dbg = OUStringToOString( |
| invalidRegistryException.Message, RTL_TEXTENCODING_ASCII_US); |
| OSL_TRACE( |
| "warning: couldn't open %s cause of %s", |
| rdb_name_tmp.getStr(), message_dbg.getStr() ); |
| #endif |
| } |
| |
| if(!lastRegistry->isValid()) |
| lastRegistry.clear(); |
| } |
| |
| do |
| { |
| index = csl_rdbs.indexOf((sal_Unicode)' '); |
| OUString rdb_name = (index == -1) ? csl_rdbs : csl_rdbs.copy(0, index); |
| csl_rdbs = (index == -1) ? OUString() : csl_rdbs.copy(index + 1); |
| |
| if (! rdb_name.getLength()) |
| continue; |
| |
| bool optional = ('?' == rdb_name[ 0 ]); |
| if (optional) |
| rdb_name = rdb_name.copy( 1 ); |
| |
| try |
| { |
| Reference<registry::XSimpleRegistry> simpleRegistry( |
| xSimRegFac->createInstance(), UNO_QUERY_THROW ); |
| |
| osl::FileBase::getAbsoluteFileURL(baseDir, rdb_name, rdb_name); |
| simpleRegistry->open(rdb_name, sal_True, sal_False); |
| |
| if(lastRegistry.is()) |
| { |
| Reference< registry::XSimpleRegistry > nestedRegistry( |
| xNesRegFac->createInstance(), UNO_QUERY ); |
| Reference< lang::XInitialization > nestedRegistry_xInit( |
| nestedRegistry, UNO_QUERY ); |
| |
| Sequence<Any> aArgs(2); |
| aArgs[0] <<= lastRegistry; |
| aArgs[1] <<= simpleRegistry; |
| |
| nestedRegistry_xInit->initialize(aArgs); |
| |
| lastRegistry = nestedRegistry; |
| } |
| else |
| lastRegistry = simpleRegistry; |
| } |
| catch(registry::InvalidRegistryException & invalidRegistryException) |
| { |
| if (! optional) |
| { |
| // if a registry was explicitly given, the exception shall fly |
| if( ! bFallenBack ) |
| throw; |
| } |
| |
| (void) invalidRegistryException; |
| #if OSL_DEBUG_LEVEL > 1 |
| OString rdb_name_tmp = OUStringToOString( |
| rdb_name, RTL_TEXTENCODING_ASCII_US ); |
| OString message_dbg = OUStringToOString( |
| invalidRegistryException.Message, RTL_TEXTENCODING_ASCII_US ); |
| OSL_TRACE( |
| "warning: couldn't open %s cause of %s", |
| rdb_name_tmp.getStr(), message_dbg.getStr() ); |
| #endif |
| } |
| } |
| while(index != -1 && csl_rdbs.getLength()); // are there more rdbs in list? |
| |
| return lastRegistry; |
| } |
| |
| Reference< XComponentContext > |
| SAL_CALL defaultBootstrap_InitialComponentContext( |
| Bootstrap const & bootstrap ) |
| SAL_THROW( (Exception) ) |
| { |
| primeWeakMap(); |
| |
| OUString bootstrapPath; |
| if (!bootstrap.getFrom( |
| rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URE_INTERNAL_LIB_DIR")), |
| bootstrapPath)) |
| { |
| bootstrapPath = get_this_libpath(); |
| } |
| |
| OUString iniDir; |
| osl_getProcessWorkingDir(&iniDir.pData); |
| |
| Reference<lang::XMultiComponentFactory> smgr_XMultiComponentFactory( |
| bootstrapInitialSF(bootstrapPath) ); |
| Reference<lang::XMultiServiceFactory> smgr_XMultiServiceFactory( |
| smgr_XMultiComponentFactory, UNO_QUERY ); |
| |
| Reference<registry::XRegistryKey> xEmptyKey; |
| Reference<lang::XSingleServiceFactory> xSimRegFac( |
| loadSharedLibComponentFactory( |
| OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrapPath, |
| OUSTR("com.sun.star.comp.stoc.SimpleRegistry"), |
| smgr_XMultiServiceFactory, |
| xEmptyKey), |
| UNO_QUERY); |
| |
| Reference<lang::XSingleServiceFactory> xNesRegFac( |
| loadSharedLibComponentFactory( |
| OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrapPath, |
| OUSTR("com.sun.star.comp.stoc.NestedRegistry"), |
| smgr_XMultiServiceFactory, |
| xEmptyKey), |
| UNO_QUERY); |
| |
| sal_Bool bFallenback_types; |
| OUString cls_uno_types = |
| findBoostrapArgument( bootstrap, OUSTR("TYPES"), &bFallenback_types ); |
| |
| Reference<registry::XSimpleRegistry> types_xRegistry = |
| nestRegistries( |
| iniDir, xSimRegFac, xNesRegFac, cls_uno_types, |
| OUString(), sal_False, bFallenback_types ); |
| |
| // ==== bootstrap from services registry ==== |
| |
| sal_Bool bFallenback_services; |
| OUString cls_uno_services = findBoostrapArgument( |
| bootstrap, OUSTR("SERVICES"), &bFallenback_services ); |
| |
| sal_Bool fallenBackWriteRegistry; |
| OUString write_rdb = findBoostrapArgument( |
| bootstrap, OUSTR("WRITERDB"), &fallenBackWriteRegistry ); |
| if (fallenBackWriteRegistry) |
| { |
| // no standard write rdb anymore |
| write_rdb = OUString(); |
| } |
| |
| Reference<registry::XSimpleRegistry> services_xRegistry = nestRegistries( |
| iniDir, xSimRegFac, xNesRegFac, cls_uno_services, write_rdb, |
| !fallenBackWriteRegistry, bFallenback_services ); |
| |
| Reference< XComponentContext > xContext( |
| bootstrapInitialContext( |
| smgr_XMultiComponentFactory, types_xRegistry, services_xRegistry, |
| bootstrapPath, bootstrap ) ); |
| |
| // initialize sf |
| Reference< lang::XInitialization > xInit( |
| smgr_XMultiComponentFactory, UNO_QUERY ); |
| OSL_ASSERT( xInit.is() ); |
| Sequence< Any > aSFInit( 1 ); |
| aSFInit[ 0 ] <<= services_xRegistry; |
| xInit->initialize( aSFInit ); |
| |
| return xContext; |
| } |
| |
| } |
| |
| Reference< XComponentContext > |
| SAL_CALL defaultBootstrap_InitialComponentContext( |
| OUString const & iniFile ) |
| SAL_THROW( (Exception) ) |
| { |
| Bootstrap bootstrap( iniFile ); |
| if (bootstrap.getHandle() == 0) |
| throw io::IOException(OUSTR("Cannot open for reading: ") + iniFile, 0); |
| return defaultBootstrap_InitialComponentContext( bootstrap ); |
| } |
| |
| Reference< XComponentContext > |
| SAL_CALL defaultBootstrap_InitialComponentContext() |
| SAL_THROW( (Exception) ) |
| { |
| return defaultBootstrap_InitialComponentContext( get_unorc() ); |
| } |
| |
| BootstrapException::BootstrapException() |
| { |
| } |
| |
| BootstrapException::BootstrapException( const ::rtl::OUString & rMessage ) |
| :m_aMessage( rMessage ) |
| { |
| } |
| |
| BootstrapException::BootstrapException( const BootstrapException & e ) |
| { |
| m_aMessage = e.m_aMessage; |
| } |
| |
| BootstrapException::~BootstrapException() |
| { |
| } |
| |
| BootstrapException & BootstrapException::operator=( const BootstrapException & e ) |
| { |
| m_aMessage = e.m_aMessage; |
| return *this; |
| } |
| |
| const ::rtl::OUString & BootstrapException::getMessage() const |
| { |
| return m_aMessage; |
| } |
| |
| Reference< XComponentContext > SAL_CALL bootstrap() |
| { |
| Reference< XComponentContext > xRemoteContext; |
| |
| try |
| { |
| char const * p1 = cppuhelper_detail_findSofficePath(); |
| if (p1 == NULL) { |
| throw BootstrapException( |
| OUSTR("no soffice installation found!")); |
| } |
| rtl::OUString p2; |
| if (!rtl_convertStringToUString( |
| &p2.pData, p1, strlen(p1), osl_getThreadTextEncoding(), |
| (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | |
| RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | |
| RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))) |
| { |
| throw BootstrapException( |
| OUSTR("bad characters in soffice installation path!")); |
| } |
| OUString path; |
| if (osl::FileBase::getFileURLFromSystemPath(p2, path) != |
| osl::FileBase::E_None) |
| { |
| throw BootstrapException( |
| OUSTR("cannot convert soffice installation path to URL!")); |
| } |
| if (path.getLength() > 0 && path[path.getLength() - 1] != '/') { |
| path += OUSTR("/"); |
| } |
| |
| OUString uri; |
| if (!Bootstrap::get(OUSTR("URE_BOOTSTRAP"), uri)) { |
| Bootstrap::set( |
| OUSTR("URE_BOOTSTRAP"), |
| Bootstrap::encode(path + OUSTR(SAL_CONFIGFILE("fundamental")))); |
| } |
| |
| // create default local component context |
| Reference< XComponentContext > xLocalContext( |
| defaultBootstrap_InitialComponentContext() ); |
| if ( !xLocalContext.is() ) |
| throw BootstrapException( OUSTR( "no local component context!" ) ); |
| |
| // create a random pipe name |
| rtlRandomPool hPool = rtl_random_createPool(); |
| if ( hPool == 0 ) |
| throw BootstrapException( OUSTR( "cannot create random pool!" ) ); |
| sal_uInt8 bytes[ 16 ]; |
| if ( rtl_random_getBytes( hPool, bytes, ARLEN( bytes ) ) |
| != rtl_Random_E_None ) |
| throw BootstrapException( OUSTR( "random pool error!" ) ); |
| rtl_random_destroyPool( hPool ); |
| ::rtl::OUStringBuffer buf; |
| buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno" ) ); |
| for ( sal_uInt32 i = 0; i < ARLEN( bytes ); ++i ) |
| buf.append( static_cast< sal_Int32 >( bytes[ i ] ) ); |
| OUString sPipeName( buf.makeStringAndClear() ); |
| |
| // accept string |
| OSL_ASSERT( buf.getLength() == 0 ); |
| buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "-accept=pipe,name=" ) ); |
| buf.append( sPipeName ); |
| buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ";urp;" ) ); |
| |
| // arguments |
| OUString args [] = { |
| OUSTR( "-nologo" ), |
| OUSTR( "-nodefault" ), |
| OUSTR( "-norestore" ), |
| OUSTR( "-nocrashreport" ), |
| OUSTR( "-nolockcheck" ), |
| buf.makeStringAndClear() |
| }; |
| rtl_uString * ar_args [] = { |
| args[ 0 ].pData, |
| args[ 1 ].pData, |
| args[ 2 ].pData, |
| args[ 3 ].pData, |
| args[ 4 ].pData, |
| args[ 5 ].pData |
| }; |
| ::osl::Security sec; |
| |
| // start office process |
| oslProcess hProcess = 0; |
| oslProcessError rc = osl_executeProcess( |
| (path + OUSTR("soffice")).pData, ar_args, ARLEN( ar_args ), |
| osl_Process_DETACHED, |
| sec.getHandle(), |
| 0, // => current working dir |
| 0, 0, // => no env vars |
| &hProcess ); |
| switch ( rc ) |
| { |
| case osl_Process_E_None: |
| osl_freeProcessHandle( hProcess ); |
| break; |
| case osl_Process_E_NotFound: |
| throw BootstrapException( OUSTR( "image not found!" ) ); |
| case osl_Process_E_TimedOut: |
| throw BootstrapException( OUSTR( "timout occured!" ) ); |
| case osl_Process_E_NoPermission: |
| throw BootstrapException( OUSTR( "permission denied!" ) ); |
| case osl_Process_E_Unknown: |
| throw BootstrapException( OUSTR( "unknown error!" ) ); |
| case osl_Process_E_InvalidError: |
| default: |
| throw BootstrapException( OUSTR( "unmapped error!" ) ); |
| } |
| |
| // create a URL resolver |
| Reference< bridge::XUnoUrlResolver > xUrlResolver( |
| bridge::UnoUrlResolver::create( xLocalContext ) ); |
| |
| // connection string |
| OSL_ASSERT( buf.getLength() == 0 ); |
| buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno:pipe,name=" ) ); |
| buf.append( sPipeName ); |
| buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( |
| ";urp;StarOffice.ComponentContext" ) ); |
| OUString sConnectString( buf.makeStringAndClear() ); |
| |
| // wait until office is started |
| for ( ; ; ) |
| { |
| try |
| { |
| // try to connect to office |
| xRemoteContext.set( |
| xUrlResolver->resolve( sConnectString ), UNO_QUERY_THROW ); |
| break; |
| } |
| catch ( connection::NoConnectException & ) |
| { |
| // wait 500 ms, then try to connect again |
| TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ }; |
| ::osl::Thread::wait( tv ); |
| } |
| } |
| } |
| catch ( Exception & e ) |
| { |
| throw BootstrapException( |
| OUSTR( "unexpected UNO exception caught: " ) + e.Message ); |
| } |
| |
| return xRemoteContext; |
| } |
| |
| OUString bootstrap_expandUri(OUString const & uri) { |
| static char const PREFIX[] = "vnd.sun.star.expand:"; |
| return uri.matchAsciiL(RTL_CONSTASCII_STRINGPARAM(PREFIX)) |
| ? cppuhelper::detail::expandMacros( |
| rtl::Uri::decode( |
| uri.copy(RTL_CONSTASCII_LENGTH(PREFIX)), |
| rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8)) |
| : uri; |
| } |
| |
| } // namespace cppu |