LCOV - code coverage report
Current view: top level - scripting/source/stringresource - stringresource.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 37 1400 2.6 %
Date: 2014-11-03 Functions: 14 212 6.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include "stringresource.hxx"
      21             : #include <com/sun/star/io/TempFile.hpp>
      22             : #include <com/sun/star/io/TextInputStream.hpp>
      23             : #include <com/sun/star/io/TextOutputStream.hpp>
      24             : #include <com/sun/star/io/XActiveDataSink.hpp>
      25             : #include <com/sun/star/io/XActiveDataSource.hpp>
      26             : #include <com/sun/star/io/XStream.hpp>
      27             : #include <com/sun/star/io/XSeekable.hpp>
      28             : #include <com/sun/star/embed/ElementModes.hpp>
      29             : #include <com/sun/star/lang/XMultiComponentFactory.hpp>
      30             : #include <cppuhelper/implementationentry.hxx>
      31             : #include <cppuhelper/supportsservice.hxx>
      32             : #include <com/sun/star/beans/XPropertySet.hpp>
      33             : #include <com/sun/star/container/XNameAccess.hpp>
      34             : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
      35             : 
      36             : #include <rtl/tencinfo.h>
      37             : #include <rtl/ustrbuf.hxx>
      38             : #include <rtl/strbuf.hxx>
      39             : #include <tools/urlobj.hxx>
      40             : #include <i18nlangtag/languagetag.hxx>
      41             : 
      42             : using namespace ::com::sun::star;
      43             : using namespace ::com::sun::star::lang;
      44             : using namespace ::com::sun::star::uno;
      45             : using namespace ::com::sun::star::ucb;
      46             : using namespace ::com::sun::star::util;
      47             : using namespace ::com::sun::star::embed;
      48             : using namespace ::com::sun::star::container;
      49             : 
      50             : 
      51             : 
      52             : namespace stringresource
      53             : {
      54             : 
      55             : 
      56             : 
      57             : // mutex
      58             : 
      59             : 
      60           2 : ::osl::Mutex& getMutex()
      61             : {
      62             :     static ::osl::Mutex* s_pMutex = 0;
      63           2 :     if ( !s_pMutex )
      64             :     {
      65           2 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
      66           2 :         if ( !s_pMutex )
      67             :         {
      68           2 :             static ::osl::Mutex s_aMutex;
      69           2 :             s_pMutex = &s_aMutex;
      70           2 :         }
      71             :     }
      72           2 :     return *s_pMutex;
      73             : }
      74             : 
      75             : 
      76             : 
      77             : // StringResourceImpl
      78             : 
      79             : 
      80             : // component operations
      81           2 : static Sequence< OUString > getSupportedServiceNames_StringResourceImpl()
      82             : {
      83           2 :     Sequence< OUString > names(1);
      84           2 :     names[0] = "com.sun.star.resource.StringResource";
      85           2 :     return names;
      86             : }
      87             : 
      88           2 : static OUString getImplementationName_StringResourceImpl()
      89             : {
      90           2 :     return OUString( "com.sun.star.comp.scripting.StringResource" );
      91             : }
      92             : 
      93           2 : static Reference< XInterface > SAL_CALL create_StringResourceImpl(
      94             :     Reference< XComponentContext > const & xContext )
      95             : {
      96           2 :     return static_cast< ::cppu::OWeakObject * >( new StringResourcePersistenceImpl( xContext ) );
      97             : }
      98             : 
      99             : 
     100             : 
     101             : 
     102           2 : StringResourceImpl::StringResourceImpl( const Reference< XComponentContext >& rxContext )
     103             :     : m_xContext( rxContext )
     104             :     , m_pCurrentLocaleItem( NULL )
     105             :     , m_pDefaultLocaleItem( NULL )
     106             :     , m_bDefaultModified( false )
     107           2 :     , m_aListenerContainer( getMutex() )
     108             :     , m_bModified( false )
     109             :     , m_bReadOnly( false )
     110           4 :     , m_nNextUniqueNumericId( UNIQUE_NUMBER_NEEDS_INITIALISATION )
     111             : {
     112           2 : }
     113             : 
     114             : 
     115             : 
     116           4 : StringResourceImpl::~StringResourceImpl()
     117             : {
     118           2 :     for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
     119             :     {
     120           0 :         LocaleItem* pLocaleItem = *it;
     121           0 :         delete pLocaleItem;
     122             :     }
     123             : 
     124           2 :     for( LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin(); it != m_aDeletedLocaleItemVector.end(); ++it )
     125             :     {
     126           0 :         LocaleItem* pLocaleItem = *it;
     127           0 :         delete pLocaleItem;
     128             :     }
     129           2 : }
     130             : 
     131             : 
     132             : 
     133             : // XServiceInfo
     134             : 
     135           0 : OUString StringResourceImpl::getImplementationName(  ) throw (RuntimeException, std::exception)
     136             : {
     137           0 :     return getImplementationName_StringResourceImpl();
     138             : }
     139             : 
     140           0 : sal_Bool StringResourceImpl::supportsService( const OUString& rServiceName ) throw (RuntimeException, std::exception)
     141             : {
     142           0 :     return cppu::supportsService(this, rServiceName);
     143             : }
     144             : 
     145           0 : Sequence< OUString > StringResourceImpl::getSupportedServiceNames(  ) throw (RuntimeException, std::exception)
     146             : {
     147           0 :     return getSupportedServiceNames_StringResourceImpl();
     148             : }
     149             : 
     150             : 
     151             : 
     152             : // XModifyBroadcaster
     153             : 
     154           0 : void StringResourceImpl::addModifyListener( const Reference< XModifyListener >& aListener )
     155             :     throw (RuntimeException, std::exception)
     156             : {
     157           0 :     if( !aListener.is() )
     158           0 :         throw RuntimeException();
     159             : 
     160           0 :     ::osl::MutexGuard aGuard( getMutex() );
     161           0 :     m_aListenerContainer.addInterface( Reference<XInterface>( aListener, UNO_QUERY ) );
     162           0 : }
     163             : 
     164           0 : void StringResourceImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
     165             :     throw (RuntimeException, std::exception)
     166             : {
     167           0 :     if( !aListener.is() )
     168           0 :         throw RuntimeException();
     169             : 
     170           0 :     ::osl::MutexGuard aGuard( getMutex() );
     171           0 :     m_aListenerContainer.removeInterface( Reference<XInterface>( aListener, UNO_QUERY ) );
     172           0 : }
     173             : 
     174             : 
     175             : 
     176             : // XStringResourceResolver
     177             : 
     178           0 : OUString StringResourceImpl::implResolveString
     179             :     ( const OUString& ResourceID, LocaleItem* pLocaleItem )
     180             :         throw (::com::sun::star::resource::MissingResourceException)
     181             : {
     182           0 :     OUString aRetStr;
     183           0 :     bool bSuccess = false;
     184           0 :     if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
     185             :     {
     186           0 :         IdToStringMap::iterator it = pLocaleItem->m_aIdToStringMap.find( ResourceID );
     187           0 :         if( !( it == pLocaleItem->m_aIdToStringMap.end() ) )
     188             :         {
     189           0 :             aRetStr = (*it).second;
     190           0 :             bSuccess = true;
     191             :         }
     192             :     }
     193           0 :     if( !bSuccess )
     194             :     {
     195           0 :         OUString errorMsg("StringResourceImpl: No entry for ResourceID: ");
     196           0 :         errorMsg = errorMsg.concat( ResourceID );
     197           0 :         throw ::com::sun::star::resource::MissingResourceException( errorMsg );
     198             :     }
     199           0 :     return aRetStr;
     200             : }
     201             : 
     202           0 : OUString StringResourceImpl::resolveString( const OUString& ResourceID )
     203             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
     204             : {
     205           0 :     ::osl::MutexGuard aGuard( getMutex() );
     206           0 :     return implResolveString( ResourceID, m_pCurrentLocaleItem );
     207             : }
     208             : 
     209           0 : OUString StringResourceImpl::resolveStringForLocale( const OUString& ResourceID, const Locale& locale )
     210             :     throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
     211             : {
     212           0 :     ::osl::MutexGuard aGuard( getMutex() );
     213           0 :     LocaleItem* pLocaleItem = getItemForLocale( locale, false );
     214           0 :     return implResolveString( ResourceID, pLocaleItem );
     215             : }
     216             : 
     217           0 : bool StringResourceImpl::implHasEntryForId( const OUString& ResourceID, LocaleItem* pLocaleItem )
     218             : {
     219           0 :     bool bSuccess = false;
     220           0 :     if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
     221             :     {
     222           0 :         IdToStringMap::iterator it = pLocaleItem->m_aIdToStringMap.find( ResourceID );
     223           0 :         if( !( it == pLocaleItem->m_aIdToStringMap.end() ) )
     224           0 :             bSuccess = true;
     225             :     }
     226           0 :     return bSuccess;
     227             : }
     228             : 
     229           0 : sal_Bool StringResourceImpl::hasEntryForId( const OUString& ResourceID )
     230             :     throw (RuntimeException, std::exception)
     231             : {
     232           0 :     ::osl::MutexGuard aGuard( getMutex() );
     233           0 :     return implHasEntryForId( ResourceID, m_pCurrentLocaleItem );
     234             : }
     235             : 
     236           0 : sal_Bool StringResourceImpl::hasEntryForIdAndLocale( const OUString& ResourceID,
     237             :     const Locale& locale )
     238             :         throw (RuntimeException, std::exception)
     239             : {
     240           0 :     ::osl::MutexGuard aGuard( getMutex() );
     241           0 :     LocaleItem* pLocaleItem = getItemForLocale( locale, false );
     242           0 :     return implHasEntryForId( ResourceID, pLocaleItem );
     243             : }
     244             : 
     245           0 : Sequence< OUString > StringResourceImpl::implGetResourceIDs( LocaleItem* pLocaleItem )
     246             : {
     247           0 :     Sequence< OUString > aIDSeq( 0 );
     248           0 :     if( pLocaleItem && loadLocale( pLocaleItem ) )
     249             :     {
     250           0 :         const IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
     251           0 :         sal_Int32 nResourceIDCount = rHashMap.size();
     252           0 :         aIDSeq.realloc( nResourceIDCount );
     253           0 :         OUString* pStrings = aIDSeq.getArray();
     254             : 
     255           0 :         IdToStringMap::const_iterator it;
     256           0 :         int iTarget = 0;
     257           0 :         for( it = rHashMap.begin(); it != rHashMap.end(); ++it )
     258             :         {
     259           0 :             OUString aStr = (*it).first;
     260           0 :             pStrings[iTarget] = aStr;
     261           0 :             iTarget++;
     262           0 :         }
     263             :     }
     264           0 :     return aIDSeq;
     265             : }
     266             : 
     267           0 : Sequence< OUString > StringResourceImpl::getResourceIDsForLocale
     268             :     ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException, std::exception)
     269             : {
     270           0 :     ::osl::MutexGuard aGuard( getMutex() );
     271           0 :     LocaleItem* pLocaleItem = getItemForLocale( locale, false );
     272           0 :     return implGetResourceIDs( pLocaleItem );
     273             : }
     274             : 
     275           0 : Sequence< OUString > StringResourceImpl::getResourceIDs(  )
     276             :     throw (RuntimeException, std::exception)
     277             : {
     278           0 :     ::osl::MutexGuard aGuard( getMutex() );
     279           0 :     return implGetResourceIDs( m_pCurrentLocaleItem );
     280             : }
     281             : 
     282           0 : Locale StringResourceImpl::getCurrentLocale()
     283             :     throw (RuntimeException, std::exception)
     284             : {
     285           0 :     ::osl::MutexGuard aGuard( getMutex() );
     286             : 
     287           0 :     Locale aRetLocale;
     288           0 :     if( m_pCurrentLocaleItem != NULL )
     289           0 :         aRetLocale = m_pCurrentLocaleItem->m_locale;
     290           0 :     return aRetLocale;
     291             : }
     292             : 
     293           0 : Locale StringResourceImpl::getDefaultLocale(  )
     294             :     throw (RuntimeException, std::exception)
     295             : {
     296           0 :     ::osl::MutexGuard aGuard( getMutex() );
     297             : 
     298           0 :     Locale aRetLocale;
     299           0 :     if( m_pDefaultLocaleItem != NULL )
     300           0 :         aRetLocale = m_pDefaultLocaleItem->m_locale;
     301           0 :     return aRetLocale;
     302             : }
     303             : 
     304           0 : Sequence< Locale > StringResourceImpl::getLocales(  )
     305             :     throw (RuntimeException, std::exception)
     306             : {
     307           0 :     ::osl::MutexGuard aGuard( getMutex() );
     308             : 
     309           0 :     sal_Int32 nSize = m_aLocaleItemVector.size();
     310           0 :     Sequence< Locale > aLocalSeq( nSize );
     311           0 :     Locale* pLocales = aLocalSeq.getArray();
     312           0 :     int iTarget = 0;
     313           0 :     for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
     314             :     {
     315           0 :         LocaleItem* pLocaleItem = *it;
     316           0 :         pLocales[iTarget] = pLocaleItem->m_locale;
     317           0 :         iTarget++;
     318             :     }
     319           0 :     return aLocalSeq;
     320             : }
     321             : 
     322             : 
     323             : 
     324             : // XStringResourceManager
     325             : 
     326           0 : void StringResourceImpl::implCheckReadOnly( const sal_Char* pExceptionMsg )
     327             :     throw (NoSupportException)
     328             : {
     329           0 :     if( m_bReadOnly )
     330             :     {
     331           0 :         OUString errorMsg = OUString::createFromAscii( pExceptionMsg );
     332           0 :         throw NoSupportException( errorMsg );
     333             :     }
     334           0 : }
     335             : 
     336           0 : sal_Bool StringResourceImpl::isReadOnly()
     337             :     throw (RuntimeException, std::exception)
     338             : {
     339           0 :     return m_bReadOnly;
     340             : }
     341             : 
     342           0 : void StringResourceImpl::implSetCurrentLocale( const Locale& locale,
     343             :     bool FindClosestMatch, bool bUseDefaultIfNoMatch )
     344             :         throw (IllegalArgumentException, RuntimeException)
     345             : {
     346           0 :     ::osl::MutexGuard aGuard( getMutex() );
     347             : 
     348           0 :     LocaleItem* pLocaleItem = NULL;
     349           0 :     if( FindClosestMatch )
     350           0 :         pLocaleItem = getClosestMatchItemForLocale( locale );
     351             :     else
     352           0 :         pLocaleItem = getItemForLocale( locale, true );
     353             : 
     354           0 :     if( pLocaleItem == NULL && bUseDefaultIfNoMatch )
     355           0 :         pLocaleItem = m_pDefaultLocaleItem;
     356             : 
     357           0 :     if( pLocaleItem != NULL )
     358             :     {
     359           0 :         (void)loadLocale( pLocaleItem );
     360           0 :         m_pCurrentLocaleItem = pLocaleItem;
     361             : 
     362             :         // Only notify without modifying
     363           0 :         implNotifyListeners();
     364           0 :     }
     365           0 : }
     366             : 
     367           0 : void StringResourceImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
     368             :     throw (IllegalArgumentException, RuntimeException, std::exception)
     369             : {
     370           0 :     bool bUseDefaultIfNoMatch = false;
     371           0 :     implSetCurrentLocale( locale, FindClosestMatch, bUseDefaultIfNoMatch );
     372           0 : }
     373             : 
     374           0 : void StringResourceImpl::setDefaultLocale( const Locale& locale )
     375             :     throw (IllegalArgumentException, RuntimeException,NoSupportException, std::exception)
     376             : {
     377           0 :     ::osl::MutexGuard aGuard( getMutex() );
     378           0 :     implCheckReadOnly( "StringResourceImpl::setDefaultLocale(): Read only" );
     379             : 
     380           0 :     LocaleItem* pLocaleItem = getItemForLocale( locale, true );
     381           0 :     if( pLocaleItem && pLocaleItem != m_pDefaultLocaleItem )
     382             :     {
     383           0 :         if( m_pDefaultLocaleItem )
     384             :         {
     385           0 :             LocaleItem* pChangedDefaultLocaleItem = new LocaleItem( m_pDefaultLocaleItem->m_locale );
     386           0 :             m_aChangedDefaultLocaleVector.push_back( pChangedDefaultLocaleItem );
     387             :         }
     388             : 
     389           0 :         m_pDefaultLocaleItem = pLocaleItem;
     390           0 :         m_bDefaultModified = true;
     391           0 :         implModified();
     392           0 :     }
     393           0 : }
     394             : 
     395           0 : void StringResourceImpl::implSetString( const OUString& ResourceID,
     396             :     const OUString& Str, LocaleItem* pLocaleItem )
     397             : {
     398           0 :     if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
     399             :     {
     400           0 :         IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
     401             : 
     402           0 :         IdToStringMap::iterator it = rHashMap.find( ResourceID );
     403           0 :         bool bNew = ( it == rHashMap.end() );
     404           0 :         if( bNew )
     405             :         {
     406           0 :             IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap;
     407           0 :             rIndexMap[ ResourceID ] = pLocaleItem->m_nNextIndex++;
     408           0 :             implScanIdForNumber( ResourceID );
     409             :         }
     410           0 :         rHashMap[ ResourceID ] = Str;
     411           0 :         pLocaleItem->m_bModified = true;
     412           0 :         implModified();
     413             :     }
     414           0 : }
     415             : 
     416           0 : void StringResourceImpl::setString( const OUString& ResourceID, const OUString& Str )
     417             :     throw (NoSupportException, RuntimeException, std::exception)
     418             : {
     419           0 :     ::osl::MutexGuard aGuard( getMutex() );
     420           0 :     implCheckReadOnly( "StringResourceImpl::setString(): Read only" );
     421           0 :     implSetString( ResourceID, Str, m_pCurrentLocaleItem );
     422           0 : }
     423             : 
     424           0 : void StringResourceImpl::setStringForLocale
     425             :     ( const OUString& ResourceID, const OUString& Str, const Locale& locale )
     426             :         throw (NoSupportException, RuntimeException, std::exception)
     427             : {
     428           0 :     ::osl::MutexGuard aGuard( getMutex() );
     429           0 :     implCheckReadOnly( "StringResourceImpl::setStringForLocale(): Read only" );
     430           0 :     LocaleItem* pLocaleItem = getItemForLocale( locale, false );
     431           0 :     implSetString( ResourceID, Str, pLocaleItem );
     432           0 : }
     433             : 
     434           0 : void StringResourceImpl::implRemoveId( const OUString& ResourceID, LocaleItem* pLocaleItem )
     435             :     throw (::com::sun::star::resource::MissingResourceException)
     436             : {
     437           0 :     if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
     438             :     {
     439           0 :         IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
     440           0 :         IdToStringMap::iterator it = rHashMap.find( ResourceID );
     441           0 :         if( it == rHashMap.end() )
     442             :         {
     443           0 :             OUString errorMsg("StringResourceImpl: No entries for ResourceID: ");
     444           0 :             errorMsg = errorMsg.concat( ResourceID );
     445           0 :             throw ::com::sun::star::resource::MissingResourceException( errorMsg );
     446             :         }
     447           0 :         rHashMap.erase( it );
     448           0 :         pLocaleItem->m_bModified = true;
     449           0 :         implModified();
     450             :     }
     451           0 : }
     452             : 
     453           0 : void StringResourceImpl::removeId( const OUString& ResourceID )
     454             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
     455             : {
     456           0 :     ::osl::MutexGuard aGuard( getMutex() );
     457           0 :     implCheckReadOnly( "StringResourceImpl::removeId(): Read only" );
     458           0 :     implRemoveId( ResourceID, m_pCurrentLocaleItem );
     459           0 : }
     460             : 
     461           0 : void StringResourceImpl::removeIdForLocale( const OUString& ResourceID, const Locale& locale )
     462             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
     463             : {
     464           0 :     ::osl::MutexGuard aGuard( getMutex() );
     465           0 :     implCheckReadOnly( "StringResourceImpl::removeIdForLocale(): Read only" );
     466           0 :     LocaleItem* pLocaleItem = getItemForLocale( locale, false );
     467           0 :     implRemoveId( ResourceID, pLocaleItem );
     468           0 : }
     469             : 
     470           0 : void StringResourceImpl::newLocale( const Locale& locale )
     471             :     throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
     472             : {
     473           0 :     ::osl::MutexGuard aGuard( getMutex() );
     474           0 :     implCheckReadOnly( "StringResourceImpl::newLocale(): Read only" );
     475             : 
     476           0 :     if( getItemForLocale( locale, false ) != NULL )
     477             :     {
     478           0 :         OUString errorMsg("StringResourceImpl: locale already exists");
     479           0 :         throw ElementExistException( errorMsg );
     480             :     }
     481             : 
     482             :     // TODO?: Check if locale is valid? How?
     483             :     //if (!bValid)
     484             :     //{
     485             :     //    OUString errorMsg("StringResourceImpl: Invalid locale");
     486             :     //    throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
     487             :     //}
     488             : 
     489           0 :     LocaleItem* pLocaleItem = new LocaleItem( locale );
     490           0 :     m_aLocaleItemVector.push_back( pLocaleItem );
     491           0 :     pLocaleItem->m_bModified = true;
     492             : 
     493             :     // Copy strings from default locale
     494           0 :     LocaleItem* pCopyFromItem = m_pDefaultLocaleItem;
     495           0 :     if( pCopyFromItem == NULL )
     496           0 :         pCopyFromItem = m_pCurrentLocaleItem;
     497           0 :     if( pCopyFromItem != NULL && loadLocale( pCopyFromItem ) )
     498             :     {
     499           0 :         const IdToStringMap& rSourceMap = pCopyFromItem->m_aIdToStringMap;
     500           0 :         IdToStringMap& rTargetMap = pLocaleItem->m_aIdToStringMap;
     501           0 :         IdToStringMap::const_iterator it;
     502           0 :         for( it = rSourceMap.begin(); it != rSourceMap.end(); ++it )
     503             :         {
     504           0 :             OUString aId  = (*it).first;
     505           0 :             OUString aStr = (*it).second;
     506           0 :             rTargetMap[ aId ] = aStr;
     507           0 :         }
     508             : 
     509           0 :         const IdToIndexMap& rSourceIndexMap = pCopyFromItem->m_aIdToIndexMap;
     510           0 :         IdToIndexMap& rTargetIndexMap = pLocaleItem->m_aIdToIndexMap;
     511           0 :         IdToIndexMap::const_iterator it_index;
     512           0 :         for( it_index = rSourceIndexMap.begin(); it_index != rSourceIndexMap.end(); ++it_index )
     513             :         {
     514           0 :             OUString aId  = (*it_index).first;
     515           0 :             sal_Int32 nIndex = (*it_index).second;
     516           0 :             rTargetIndexMap[ aId ] = nIndex;
     517           0 :         }
     518           0 :         pLocaleItem->m_nNextIndex = pCopyFromItem->m_nNextIndex;
     519             :     }
     520             : 
     521           0 :     if( m_pCurrentLocaleItem == NULL )
     522           0 :         m_pCurrentLocaleItem = pLocaleItem;
     523             : 
     524           0 :     if( m_pDefaultLocaleItem == NULL )
     525             :     {
     526           0 :         m_pDefaultLocaleItem = pLocaleItem;
     527           0 :         m_bDefaultModified = true;
     528             :     }
     529             : 
     530           0 :     implModified();
     531           0 : }
     532             : 
     533           0 : void StringResourceImpl::removeLocale( const Locale& locale )
     534             :     throw (IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
     535             : {
     536           0 :     ::osl::MutexGuard aGuard( getMutex() );
     537           0 :     implCheckReadOnly( "StringResourceImpl::removeLocale(): Read only" );
     538             : 
     539           0 :     LocaleItem* pRemoveItem = getItemForLocale( locale, true );
     540           0 :     if( pRemoveItem )
     541             :     {
     542             :         // Last locale?
     543           0 :         sal_Int32 nLocaleCount = m_aLocaleItemVector.size();
     544           0 :         if( nLocaleCount > 1 )
     545             :         {
     546           0 :             LocaleItem* pFallbackItem = NULL;
     547           0 :             if( m_pCurrentLocaleItem == pRemoveItem ||
     548           0 :                 m_pDefaultLocaleItem  == pRemoveItem )
     549             :             {
     550           0 :                 for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
     551             :                 {
     552           0 :                     LocaleItem* pLocaleItem = *it;
     553           0 :                     if( pLocaleItem != pRemoveItem )
     554             :                     {
     555           0 :                         pFallbackItem = pLocaleItem;
     556           0 :                         break;
     557             :                     }
     558             :                 }
     559           0 :                 if( m_pCurrentLocaleItem == pRemoveItem )
     560             :                 {
     561           0 :                     bool FindClosestMatch = false;
     562           0 :                     setCurrentLocale( pFallbackItem->m_locale, FindClosestMatch );
     563             :                 }
     564           0 :                 if( m_pDefaultLocaleItem == pRemoveItem )
     565             :                 {
     566           0 :                     setDefaultLocale( pFallbackItem->m_locale );
     567             :                 }
     568             :             }
     569             :         }
     570           0 :         for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
     571             :         {
     572           0 :             LocaleItem* pLocaleItem = *it;
     573           0 :             if( pLocaleItem == pRemoveItem )
     574             :             {
     575             :                 // Remember locale item to delete file while storing
     576           0 :                 m_aDeletedLocaleItemVector.push_back( pLocaleItem );
     577             : 
     578             :                 // Last locale?
     579           0 :                 if( nLocaleCount == 1 )
     580             :                 {
     581           0 :                     m_nNextUniqueNumericId = 0;
     582           0 :                     if( m_pDefaultLocaleItem )
     583             :                     {
     584           0 :                         LocaleItem* pChangedDefaultLocaleItem = new LocaleItem( m_pDefaultLocaleItem->m_locale );
     585           0 :                         m_aChangedDefaultLocaleVector.push_back( pChangedDefaultLocaleItem );
     586             :                     }
     587           0 :                     m_pCurrentLocaleItem = NULL;
     588           0 :                     m_pDefaultLocaleItem = NULL;
     589             :                 }
     590             : 
     591           0 :                 m_aLocaleItemVector.erase( it );
     592             : 
     593           0 :                 implModified();
     594           0 :                 break;
     595             :             }
     596             :         }
     597           0 :     }
     598           0 : }
     599             : 
     600           0 : void StringResourceImpl::implScanIdForNumber( const OUString& ResourceID )
     601             : {
     602           0 :     const sal_Unicode* pSrc = ResourceID.getStr();
     603           0 :     sal_Int32 nLen = ResourceID.getLength();
     604             : 
     605           0 :     sal_Int32 nNumber = 0;
     606           0 :     for( sal_Int32 i = 0 ; i < nLen ; i++ )
     607             :     {
     608           0 :         sal_Unicode c = pSrc[i];
     609           0 :         if( c >= '0' && c <= '9' )
     610             :         {
     611           0 :             sal_uInt16 nDigitVal = c - '0';
     612           0 :             nNumber = 10*nNumber + nDigitVal;
     613             :         }
     614             :         else
     615             :             break;
     616             :     }
     617             : 
     618           0 :     if( m_nNextUniqueNumericId < nNumber + 1 )
     619           0 :         m_nNextUniqueNumericId = nNumber + 1;
     620           0 : }
     621             : 
     622           0 : sal_Int32 StringResourceImpl::getUniqueNumericId(  )
     623             :     throw (RuntimeException, NoSupportException, std::exception)
     624             : {
     625           0 :     if( m_nNextUniqueNumericId == UNIQUE_NUMBER_NEEDS_INITIALISATION )
     626             :     {
     627           0 :         implLoadAllLocales();
     628           0 :         m_nNextUniqueNumericId = 0;
     629             :     }
     630             : 
     631           0 :     if( m_nNextUniqueNumericId < UNIQUE_NUMBER_NEEDS_INITIALISATION )
     632             :     {
     633           0 :         OUString errorMsg("getUniqueNumericId: Extended sal_Int32 range");
     634           0 :         throw NoSupportException( errorMsg );
     635             :     }
     636           0 :     return m_nNextUniqueNumericId;
     637             : }
     638             : 
     639             : 
     640             : 
     641             : // Private helper methods
     642             : 
     643           0 : LocaleItem* StringResourceImpl::getItemForLocale
     644             :     ( const Locale& locale, bool bException )
     645             :         throw (::com::sun::star::lang::IllegalArgumentException)
     646             : {
     647           0 :     LocaleItem* pRetItem = NULL;
     648             : 
     649             :     // Search for locale
     650           0 :     for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
     651             :     {
     652           0 :         LocaleItem* pLocaleItem = *it;
     653           0 :         if( pLocaleItem )
     654             :         {
     655           0 :             Locale& cmp_locale = pLocaleItem->m_locale;
     656           0 :             if( cmp_locale.Language == locale.Language &&
     657           0 :                 cmp_locale.Country  == locale.Country &&
     658           0 :                 cmp_locale.Variant  == locale.Variant )
     659             :             {
     660           0 :                 pRetItem = pLocaleItem;
     661           0 :                 break;
     662             :             }
     663             :         }
     664             :     }
     665             : 
     666           0 :     if( pRetItem == NULL && bException )
     667             :     {
     668           0 :         OUString errorMsg("StringResourceImpl: Invalid locale");
     669           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
     670             :     }
     671           0 :     return pRetItem;
     672             : }
     673             : 
     674             : // Returns the LocaleItem for a given locale, if it exists, otherwise NULL.
     675             : // This method performs a closest match search, at least the language must match.
     676           0 : LocaleItem* StringResourceImpl::getClosestMatchItemForLocale( const Locale& locale )
     677             : {
     678           0 :     LocaleItem* pRetItem = NULL;
     679             : 
     680           0 :     ::std::vector< Locale > aLocales( m_aLocaleItemVector.size());
     681           0 :     size_t i = 0;
     682           0 :     for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it, ++i )
     683             :     {
     684           0 :         LocaleItem* pLocaleItem = *it;
     685           0 :         aLocales[i] = (pLocaleItem ? pLocaleItem->m_locale : Locale());
     686             :     }
     687           0 :     ::std::vector< Locale >::const_iterator iFound( LanguageTag::getMatchingFallback( aLocales, locale));
     688           0 :     if (iFound != aLocales.end())
     689           0 :         pRetItem = *(m_aLocaleItemVector.begin() + (iFound - aLocales.begin()));
     690             : 
     691           0 :     return pRetItem;
     692             : }
     693             : 
     694           0 : void StringResourceImpl::implModified( void )
     695             : {
     696           0 :     m_bModified = true;
     697           0 :     implNotifyListeners();
     698           0 : }
     699             : 
     700           0 : void StringResourceImpl::implNotifyListeners( void )
     701             : {
     702           0 :     EventObject aEvent;
     703           0 :     aEvent.Source = static_cast< XInterface* >( (OWeakObject*)this );
     704             : 
     705           0 :     ::cppu::OInterfaceIteratorHelper it( m_aListenerContainer );
     706           0 :     while( it.hasMoreElements() )
     707             :     {
     708           0 :         Reference< XInterface > xIface = it.next();
     709           0 :         Reference< XModifyListener > xListener( xIface, UNO_QUERY );
     710             :         try
     711             :         {
     712           0 :             xListener->modified( aEvent );
     713             :         }
     714           0 :         catch(RuntimeException&)
     715             :         {
     716           0 :             it.remove();
     717             :         }
     718           0 :     }
     719           0 : }
     720             : 
     721             : 
     722             : 
     723             : // Loading
     724             : 
     725           0 : bool StringResourceImpl::loadLocale( LocaleItem* pLocaleItem )
     726             : {
     727             :     // Base implementation has nothing to load
     728             :     (void)pLocaleItem;
     729           0 :     return true;
     730             : }
     731             : 
     732           0 : void StringResourceImpl::implLoadAllLocales( void )
     733             : {
     734             :     // Base implementation has nothing to load
     735           0 : }
     736             : 
     737             : 
     738           0 : Reference< XMultiComponentFactory > StringResourceImpl::getMultiComponentFactory( void )
     739             : {
     740           0 :     ::osl::MutexGuard aGuard( getMutex() );
     741             : 
     742           0 :     if( !m_xMCF.is() )
     743             :     {
     744           0 :         Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
     745           0 :         if( !xSMgr.is() )
     746             :         {
     747             :             throw RuntimeException(
     748           0 :                 "StringResourceImpl::getMultiComponentFactory: Couldn't instantiate MultiComponentFactory" );
     749             :         }
     750           0 :         m_xMCF = xSMgr;
     751             :     }
     752           0 :     return m_xMCF;
     753             : }
     754             : 
     755             : 
     756             : 
     757             : // StringResourcePersistenceImpl
     758             : 
     759             : 
     760           2 : StringResourcePersistenceImpl::StringResourcePersistenceImpl( const Reference< XComponentContext >& rxContext )
     761           2 :     : StringResourcePersistenceImpl_BASE( rxContext )
     762             : {
     763           2 : }
     764             : 
     765             : 
     766             : 
     767           4 : StringResourcePersistenceImpl::~StringResourcePersistenceImpl()
     768             : {
     769           4 : }
     770             : 
     771             : 
     772             : // XServiceInfo
     773             : 
     774             : 
     775           0 : OUString StringResourcePersistenceImpl::getImplementationName(  )
     776             :     throw (RuntimeException, std::exception)
     777             : {
     778           0 :     return OUString( "com.sun.star.comp.scripting.StringResourceWithLocation");
     779             : }
     780             : 
     781             : 
     782             : 
     783           0 : sal_Bool StringResourcePersistenceImpl::supportsService( const OUString& rServiceName )
     784             :     throw (RuntimeException, std::exception)
     785             : {
     786           0 :     return cppu::supportsService( this, rServiceName );
     787             : }
     788             : 
     789             : 
     790             : 
     791           0 : Sequence< OUString > StringResourcePersistenceImpl::getSupportedServiceNames(  )
     792             :     throw (RuntimeException, std::exception)
     793             : {
     794           0 :     return StringResourceImpl::getSupportedServiceNames();
     795             : }
     796             : 
     797             : 
     798             : // XInitialization base functionality for derived classes
     799             : 
     800             : 
     801           2 : static OUString aNameBaseDefaultStr("strings");
     802             : 
     803           0 : void StringResourcePersistenceImpl::implInitializeCommonParameters
     804             :     ( const Sequence< Any >& aArguments )
     805             :         throw (Exception, RuntimeException)
     806             : {
     807           0 :     bool bReadOnlyOk = (aArguments[1] >>= m_bReadOnly);
     808           0 :     if( !bReadOnlyOk )
     809             :     {
     810           0 :         OUString errorMsg("XInitialization::initialize: Expected ReadOnly flag");
     811           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 1 );
     812             :     }
     813             : 
     814           0 :     com::sun::star::lang::Locale aCurrentLocale;
     815           0 :     bool bLocaleOk = (aArguments[2] >>= aCurrentLocale);
     816           0 :     if( !bLocaleOk )
     817             :     {
     818           0 :         OUString errorMsg("XInitialization::initialize: Expected Locale");
     819           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 2 );
     820             :     }
     821             : 
     822           0 :     bool bNameBaseOk = (aArguments[3] >>= m_aNameBase);
     823           0 :     if( !bNameBaseOk )
     824             :     {
     825           0 :         OUString errorMsg("XInitialization::initialize: Expected NameBase string");
     826           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 3 );
     827             :     }
     828           0 :     if( m_aNameBase.isEmpty() )
     829           0 :         m_aNameBase = aNameBaseDefaultStr;
     830             : 
     831           0 :     bool bCommentOk = (aArguments[4] >>= m_aComment);
     832           0 :     if( !bCommentOk )
     833             :     {
     834           0 :         OUString errorMsg("XInitialization::initialize: Expected Comment string");
     835           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 4 );
     836             :     }
     837             : 
     838           0 :     implScanLocales();
     839             : 
     840           0 :     bool FindClosestMatch = true;
     841           0 :     bool bUseDefaultIfNoMatch = true;
     842           0 :     implSetCurrentLocale( aCurrentLocale, FindClosestMatch, bUseDefaultIfNoMatch );
     843           0 : }
     844             : 
     845             : 
     846             : // Forwarding calls to base class
     847             : 
     848             : // XModifyBroadcaster
     849           0 : void StringResourcePersistenceImpl::addModifyListener( const Reference< XModifyListener >& aListener )
     850             :     throw (RuntimeException, std::exception)
     851             : {
     852           0 :     StringResourceImpl::addModifyListener( aListener );
     853           0 : }
     854           0 : void StringResourcePersistenceImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
     855             :     throw (RuntimeException, std::exception)
     856             : {
     857           0 :     StringResourceImpl::removeModifyListener( aListener );
     858           0 : }
     859             : 
     860             : // XStringResourceResolver
     861           0 : OUString StringResourcePersistenceImpl::resolveString( const OUString& ResourceID )
     862             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
     863             : {
     864           0 :     return StringResourceImpl::resolveString( ResourceID ) ;
     865             : }
     866           0 : OUString StringResourcePersistenceImpl::resolveStringForLocale( const OUString& ResourceID, const Locale& locale )
     867             :     throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
     868             : {
     869           0 :     return StringResourceImpl::resolveStringForLocale( ResourceID, locale );
     870             : }
     871           0 : sal_Bool StringResourcePersistenceImpl::hasEntryForId( const OUString& ResourceID )
     872             :     throw (RuntimeException, std::exception)
     873             : {
     874           0 :     return StringResourceImpl::hasEntryForId( ResourceID ) ;
     875             : }
     876           0 : sal_Bool StringResourcePersistenceImpl::hasEntryForIdAndLocale( const OUString& ResourceID,
     877             :     const Locale& locale )
     878             :         throw (RuntimeException, std::exception)
     879             : {
     880           0 :     return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale );
     881             : }
     882           0 : Locale StringResourcePersistenceImpl::getCurrentLocale()
     883             :     throw (RuntimeException, std::exception)
     884             : {
     885           0 :     return StringResourceImpl::getCurrentLocale();
     886             : }
     887           0 : Locale StringResourcePersistenceImpl::getDefaultLocale(  )
     888             :     throw (RuntimeException, std::exception)
     889             : {
     890           0 :     return StringResourceImpl::getDefaultLocale();
     891             : }
     892           0 : Sequence< Locale > StringResourcePersistenceImpl::getLocales(  )
     893             :     throw (RuntimeException, std::exception)
     894             : {
     895           0 :     return StringResourceImpl::getLocales();
     896             : }
     897             : 
     898             : // XStringResourceManager
     899           0 : sal_Bool StringResourcePersistenceImpl::isReadOnly()
     900             :     throw (RuntimeException, std::exception)
     901             : {
     902           0 :     return StringResourceImpl::isReadOnly();
     903             : }
     904           0 : void StringResourcePersistenceImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
     905             :     throw (IllegalArgumentException, RuntimeException, std::exception)
     906             : {
     907           0 :     StringResourceImpl::setCurrentLocale( locale, FindClosestMatch );
     908           0 : }
     909           0 : void StringResourcePersistenceImpl::setDefaultLocale( const Locale& locale )
     910             :     throw (IllegalArgumentException, RuntimeException,NoSupportException, std::exception)
     911             : {
     912           0 :     StringResourceImpl::setDefaultLocale( locale );
     913           0 : }
     914           0 : Sequence< OUString > StringResourcePersistenceImpl::getResourceIDs(  )
     915             :     throw (RuntimeException, std::exception)
     916             : {
     917           0 :     return StringResourceImpl::getResourceIDs();
     918             : }
     919           0 : void StringResourcePersistenceImpl::setString( const OUString& ResourceID, const OUString& Str )
     920             :     throw (NoSupportException, RuntimeException, std::exception)
     921             : {
     922           0 :     StringResourceImpl::setString( ResourceID, Str );
     923           0 : }
     924           0 : void StringResourcePersistenceImpl::setStringForLocale
     925             :     ( const OUString& ResourceID, const OUString& Str, const Locale& locale )
     926             :         throw (NoSupportException, RuntimeException, std::exception)
     927             : {
     928           0 :     StringResourceImpl::setStringForLocale( ResourceID, Str, locale );
     929           0 : }
     930           0 : Sequence< OUString > StringResourcePersistenceImpl::getResourceIDsForLocale
     931             :     ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException, std::exception)
     932             : {
     933           0 :     return StringResourceImpl::getResourceIDsForLocale( locale );
     934             : }
     935           0 : void StringResourcePersistenceImpl::removeId( const OUString& ResourceID )
     936             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
     937             : {
     938           0 :     StringResourceImpl::removeId( ResourceID );
     939           0 : }
     940           0 : void StringResourcePersistenceImpl::removeIdForLocale( const OUString& ResourceID, const Locale& locale )
     941             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
     942             : {
     943           0 :     StringResourceImpl::removeIdForLocale( ResourceID, locale );
     944           0 : }
     945           0 : void StringResourcePersistenceImpl::newLocale( const Locale& locale )
     946             :     throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
     947             : {
     948           0 :     StringResourceImpl::newLocale( locale );
     949           0 : }
     950           0 : void StringResourcePersistenceImpl::removeLocale( const Locale& locale )
     951             :     throw (IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
     952             : {
     953           0 :     StringResourceImpl::removeLocale( locale );
     954           0 : }
     955           0 : sal_Int32 StringResourcePersistenceImpl::getUniqueNumericId(  )
     956             :     throw (RuntimeException, NoSupportException, std::exception)
     957             : {
     958           0 :     return StringResourceImpl::getUniqueNumericId();
     959             : }
     960             : 
     961             : 
     962             : // XStringResourcePersistence
     963             : 
     964           0 : void StringResourcePersistenceImpl::store()
     965             :     throw (NoSupportException, Exception, RuntimeException, std::exception)
     966             : {
     967           0 : }
     968             : 
     969           0 : sal_Bool StringResourcePersistenceImpl::isModified(  )
     970             :     throw (RuntimeException, std::exception)
     971             : {
     972           0 :     ::osl::MutexGuard aGuard( getMutex() );
     973             : 
     974           0 :     return m_bModified;
     975             : }
     976             : 
     977           0 : void StringResourcePersistenceImpl::setComment( const OUString& Comment )
     978             :     throw (::com::sun::star::uno::RuntimeException, std::exception)
     979             : {
     980           0 :     m_aComment = Comment;
     981           0 : }
     982             : 
     983           0 : void StringResourcePersistenceImpl::storeToStorage( const Reference< XStorage >& Storage,
     984             :     const OUString& NameBase, const OUString& Comment )
     985             :         throw (Exception, RuntimeException, std::exception)
     986             : {
     987           0 :     ::osl::MutexGuard aGuard( getMutex() );
     988             : 
     989           0 :     bool bUsedForStore = false;
     990           0 :     bool bStoreAll = true;
     991           0 :     implStoreAtStorage( NameBase, Comment, Storage, bUsedForStore, bStoreAll );
     992           0 : }
     993             : 
     994           0 : void StringResourcePersistenceImpl::implStoreAtStorage
     995             : (
     996             :     const OUString& aNameBase,
     997             :     const OUString& aComment,
     998             :     const Reference< ::com::sun::star::embed::XStorage >& Storage,
     999             :     bool bUsedForStore,
    1000             :     bool bStoreAll
    1001             : )
    1002             :     throw (Exception, RuntimeException)
    1003             : {
    1004             :     // Delete files for deleted locales
    1005           0 :     if( bUsedForStore )
    1006             :     {
    1007           0 :         while( m_aDeletedLocaleItemVector.size() > 0 )
    1008             :         {
    1009           0 :             LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin();
    1010           0 :             LocaleItem* pLocaleItem = *it;
    1011           0 :             if( pLocaleItem != NULL )
    1012             :             {
    1013           0 :                 OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase );
    1014           0 :                 aStreamName += ".properties";
    1015             : 
    1016             :                 try
    1017             :                 {
    1018           0 :                     Storage->removeElement( aStreamName );
    1019             :                 }
    1020           0 :                 catch( Exception& )
    1021             :                 {}
    1022             : 
    1023           0 :                 m_aDeletedLocaleItemVector.erase( it );
    1024           0 :                 delete pLocaleItem;
    1025             :             }
    1026             :         }
    1027             :     }
    1028             : 
    1029           0 :     for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
    1030             :     {
    1031           0 :         LocaleItem* pLocaleItem = *it;
    1032           0 :         if( pLocaleItem != NULL && (bStoreAll || pLocaleItem->m_bModified) &&
    1033           0 :             loadLocale( pLocaleItem ) )
    1034             :         {
    1035           0 :             OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, aNameBase );
    1036           0 :             aStreamName += ".properties";
    1037             : 
    1038             :             Reference< io::XStream > xElementStream =
    1039           0 :                     Storage->openStreamElement( aStreamName, ElementModes::READWRITE );
    1040             : 
    1041           0 :             OUString aPropName("MediaType");
    1042           0 :             OUString aMime("text/plain");
    1043             : 
    1044           0 :             uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
    1045             :             OSL_ENSURE( xProps.is(), "The StorageStream must implement XPropertySet interface!\n" );
    1046           0 :             if ( xProps.is() )
    1047             :             {
    1048           0 :                 xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
    1049             : 
    1050           0 :                 aPropName = "UseCommonStoragePasswordEncryption";
    1051           0 :                 xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
    1052             :             }
    1053             : 
    1054           0 :             Reference< io::XOutputStream > xOutputStream = xElementStream->getOutputStream();
    1055           0 :             if( xOutputStream.is() )
    1056           0 :                 implWritePropertiesFile( pLocaleItem, xOutputStream, aComment );
    1057           0 :             xOutputStream->closeOutput();
    1058             : 
    1059           0 :             if( bUsedForStore )
    1060           0 :                 pLocaleItem->m_bModified = false;
    1061             :         }
    1062             :     }
    1063             : 
    1064             :     // Delete files for changed defaults
    1065           0 :     if( bUsedForStore )
    1066             :     {
    1067           0 :         for( LocaleItemVectorIt it = m_aChangedDefaultLocaleVector.begin();
    1068           0 :              it != m_aChangedDefaultLocaleVector.end(); ++it )
    1069             :         {
    1070           0 :             LocaleItem* pLocaleItem = *it;
    1071           0 :             if( pLocaleItem != NULL )
    1072             :             {
    1073           0 :                 OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase );
    1074           0 :                 aStreamName += ".default";
    1075             : 
    1076             :                 try
    1077             :                 {
    1078           0 :                     Storage->removeElement( aStreamName );
    1079             :                 }
    1080           0 :                 catch( Exception& )
    1081             :                 {}
    1082             : 
    1083           0 :                 delete pLocaleItem;
    1084             :             }
    1085             :         }
    1086           0 :         m_aChangedDefaultLocaleVector.clear();
    1087             :     }
    1088             : 
    1089             :     // Default locale
    1090           0 :     if( m_pDefaultLocaleItem != NULL && (bStoreAll || m_bDefaultModified) )
    1091             :     {
    1092           0 :         OUString aStreamName = implGetFileNameForLocaleItem( m_pDefaultLocaleItem, aNameBase );
    1093           0 :         aStreamName += ".default";
    1094             : 
    1095             :         Reference< io::XStream > xElementStream =
    1096           0 :                 Storage->openStreamElement( aStreamName, ElementModes::READWRITE );
    1097             : 
    1098             :         // Only create stream without content
    1099           0 :         Reference< io::XOutputStream > xOutputStream = xElementStream->getOutputStream();
    1100           0 :         xOutputStream->closeOutput();
    1101             : 
    1102           0 :         if( bUsedForStore )
    1103           0 :             m_bDefaultModified = false;
    1104             :     }
    1105           0 : }
    1106             : 
    1107           0 : void StringResourcePersistenceImpl::storeToURL( const OUString& URL,
    1108             :     const OUString& NameBase, const OUString& Comment,
    1109             :     const Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
    1110             :         throw (Exception, RuntimeException, std::exception)
    1111             : {
    1112           0 :     ::osl::MutexGuard aGuard( getMutex() );
    1113             : 
    1114           0 :     bool bUsedForStore = false;
    1115           0 :     bool bStoreAll = true;
    1116             : 
    1117           0 :     Reference< ucb::XSimpleFileAccess3 > xFileAccess = ucb::SimpleFileAccess::create(m_xContext);
    1118           0 :     if( xFileAccess.is() && Handler.is() )
    1119           0 :         xFileAccess->setInteractionHandler( Handler );
    1120             : 
    1121           0 :     implStoreAtLocation( URL, NameBase, Comment, xFileAccess, bUsedForStore, bStoreAll );
    1122           0 : }
    1123             : 
    1124           0 : void StringResourcePersistenceImpl::implKillRemovedLocaleFiles
    1125             : (
    1126             :     const OUString& Location,
    1127             :     const OUString& aNameBase,
    1128             :     const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess3 >& xFileAccess
    1129             : )
    1130             :     throw (Exception, RuntimeException)
    1131             : {
    1132             :     // Delete files for deleted locales
    1133           0 :     while( m_aDeletedLocaleItemVector.size() > 0 )
    1134             :     {
    1135           0 :         LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin();
    1136           0 :         LocaleItem* pLocaleItem = *it;
    1137           0 :         if( pLocaleItem != NULL )
    1138             :         {
    1139             :             OUString aCompleteFileName =
    1140           0 :                 implGetPathForLocaleItem( pLocaleItem, aNameBase, Location );
    1141           0 :             if( xFileAccess->exists( aCompleteFileName ) )
    1142           0 :                 xFileAccess->kill( aCompleteFileName );
    1143             : 
    1144           0 :             m_aDeletedLocaleItemVector.erase( it );
    1145           0 :             delete pLocaleItem;
    1146             :         }
    1147             :     }
    1148           0 : }
    1149             : 
    1150           0 : void StringResourcePersistenceImpl::implKillChangedDefaultFiles
    1151             : (
    1152             :     const OUString& Location,
    1153             :     const OUString& aNameBase,
    1154             :     const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess3 >& xFileAccess
    1155             : )
    1156             :     throw (Exception, RuntimeException)
    1157             : {
    1158             :     // Delete files for changed defaults
    1159           0 :     for( LocaleItemVectorIt it = m_aChangedDefaultLocaleVector.begin();
    1160           0 :          it != m_aChangedDefaultLocaleVector.end(); ++it )
    1161             :     {
    1162           0 :         LocaleItem* pLocaleItem = *it;
    1163           0 :         if( pLocaleItem != NULL )
    1164             :         {
    1165             :             OUString aCompleteFileName =
    1166           0 :                 implGetPathForLocaleItem( pLocaleItem, aNameBase, Location, true );
    1167           0 :             if( xFileAccess->exists( aCompleteFileName ) )
    1168           0 :                 xFileAccess->kill( aCompleteFileName );
    1169             : 
    1170           0 :             delete pLocaleItem;
    1171             :         }
    1172             :     }
    1173           0 :     m_aChangedDefaultLocaleVector.clear();
    1174           0 : }
    1175             : 
    1176           0 : void StringResourcePersistenceImpl::implStoreAtLocation
    1177             : (
    1178             :     const OUString& Location,
    1179             :     const OUString& aNameBase,
    1180             :     const OUString& aComment,
    1181             :     const Reference< ucb::XSimpleFileAccess3 >& xFileAccess,
    1182             :     bool bUsedForStore,
    1183             :     bool bStoreAll,
    1184             :     bool bKillAll
    1185             : )
    1186             :     throw (Exception, RuntimeException)
    1187             : {
    1188             :     // Delete files for deleted locales
    1189           0 :     if( bUsedForStore || bKillAll )
    1190           0 :         implKillRemovedLocaleFiles( Location, aNameBase, xFileAccess );
    1191             : 
    1192           0 :     for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
    1193             :     {
    1194           0 :         LocaleItem* pLocaleItem = *it;
    1195           0 :         if( pLocaleItem != NULL && (bStoreAll || bKillAll || pLocaleItem->m_bModified) &&
    1196           0 :             loadLocale( pLocaleItem ) )
    1197             :         {
    1198             :             OUString aCompleteFileName =
    1199           0 :                 implGetPathForLocaleItem( pLocaleItem, aNameBase, Location );
    1200           0 :             if( xFileAccess->exists( aCompleteFileName ) )
    1201           0 :                 xFileAccess->kill( aCompleteFileName );
    1202             : 
    1203           0 :             if( !bKillAll )
    1204             :             {
    1205             :                 // Create Output stream
    1206           0 :                 Reference< io::XOutputStream > xOutputStream = xFileAccess->openFileWrite( aCompleteFileName );
    1207           0 :                 if( xOutputStream.is() )
    1208             :                 {
    1209           0 :                     implWritePropertiesFile( pLocaleItem, xOutputStream, aComment );
    1210           0 :                     xOutputStream->closeOutput();
    1211             :                 }
    1212           0 :                 if( bUsedForStore )
    1213           0 :                     pLocaleItem->m_bModified = false;
    1214           0 :             }
    1215             :         }
    1216             :     }
    1217             : 
    1218             :     // Delete files for changed defaults
    1219           0 :     if( bUsedForStore || bKillAll )
    1220           0 :         implKillChangedDefaultFiles( Location, aNameBase, xFileAccess );
    1221             : 
    1222             :     // Default locale
    1223           0 :     if( m_pDefaultLocaleItem != NULL && (bStoreAll || bKillAll || m_bDefaultModified) )
    1224             :     {
    1225             :         OUString aCompleteFileName =
    1226           0 :             implGetPathForLocaleItem( m_pDefaultLocaleItem, aNameBase, Location, true );
    1227           0 :         if( xFileAccess->exists( aCompleteFileName ) )
    1228           0 :             xFileAccess->kill( aCompleteFileName );
    1229             : 
    1230           0 :         if( !bKillAll )
    1231             :         {
    1232             :             // Create Output stream
    1233           0 :             Reference< io::XOutputStream > xOutputStream = xFileAccess->openFileWrite( aCompleteFileName );
    1234           0 :             if( xOutputStream.is() )
    1235           0 :                 xOutputStream->closeOutput();
    1236             : 
    1237           0 :             if( bUsedForStore )
    1238           0 :                 m_bDefaultModified = false;
    1239           0 :         }
    1240             :     }
    1241           0 : }
    1242             : 
    1243             : 
    1244             : 
    1245             : // BinaryOutput, helper class for exportBinary
    1246             : 
    1247           0 : class BinaryOutput
    1248             : {
    1249             :     Reference< XMultiComponentFactory >     m_xMCF;
    1250             :     Reference< XComponentContext >          m_xContext;
    1251             :     Reference< XInterface >                 m_xTempFile;
    1252             :     Reference< io::XOutputStream >          m_xOutputStream;
    1253             : 
    1254             : public:
    1255             :     BinaryOutput( Reference< XMultiComponentFactory > xMCF,
    1256             :         Reference< XComponentContext > xContext );
    1257             : 
    1258           0 :     Reference< io::XOutputStream > getOutputStream() const
    1259           0 :         { return m_xOutputStream; }
    1260             : 
    1261             :     Sequence< ::sal_Int8 > closeAndGetData();
    1262             : 
    1263             :     // Template to be used with sal_Int16 and sal_Unicode
    1264             :     template< class T >
    1265             :     void write16BitInt( T n );
    1266           0 :     void writeInt16( sal_Int16 n )
    1267           0 :         { write16BitInt( n ); }
    1268           0 :     void writeUnicodeChar( sal_Unicode n )
    1269           0 :         { write16BitInt( n ); }
    1270             :     void writeInt32( sal_Int32 n );
    1271             :     void writeString( const OUString& aStr );
    1272             : };
    1273             : 
    1274           0 : BinaryOutput::BinaryOutput( Reference< XMultiComponentFactory > xMCF,
    1275             :     Reference< XComponentContext > xContext )
    1276             :         : m_xMCF( xMCF )
    1277           0 :         , m_xContext( xContext )
    1278             : {
    1279           0 :     m_xTempFile = io::TempFile::create( m_xContext );
    1280           0 :     m_xOutputStream = Reference< io::XOutputStream >( m_xTempFile, UNO_QUERY_THROW );
    1281           0 : }
    1282             : 
    1283             : template< class T >
    1284           0 : void BinaryOutput::write16BitInt( T n )
    1285             : {
    1286           0 :     if( !m_xOutputStream.is() )
    1287           0 :         return;
    1288             : 
    1289           0 :     Sequence< sal_Int8 > aSeq( 2 );
    1290           0 :     sal_Int8* p = aSeq.getArray();
    1291             : 
    1292           0 :     sal_Int8 nLow  = sal_Int8( n & 0xff );
    1293           0 :     sal_Int8 nHigh = sal_Int8( n >> 8 );
    1294             : 
    1295           0 :     p[0] = nLow;
    1296           0 :     p[1] = nHigh;
    1297           0 :     m_xOutputStream->writeBytes( aSeq );
    1298             : }
    1299             : 
    1300           0 : void BinaryOutput::writeInt32( sal_Int32 n )
    1301             : {
    1302           0 :     if( !m_xOutputStream.is() )
    1303           0 :         return;
    1304             : 
    1305           0 :     Sequence< sal_Int8 > aSeq( 4 );
    1306           0 :     sal_Int8* p = aSeq.getArray();
    1307             : 
    1308           0 :     for( sal_Int16 i = 0 ; i < 4 ; i++ )
    1309             :     {
    1310           0 :         p[i] = sal_Int8( n & 0xff );
    1311           0 :         n >>= 8;
    1312             :     }
    1313           0 :     m_xOutputStream->writeBytes( aSeq );
    1314             : }
    1315             : 
    1316           0 : void BinaryOutput::writeString( const OUString& aStr )
    1317             : {
    1318           0 :     sal_Int32 nLen = aStr.getLength();
    1319           0 :     const sal_Unicode* pStr = aStr.getStr();
    1320             : 
    1321           0 :     for( sal_Int32 i = 0 ; i < nLen ; i++ )
    1322           0 :         writeUnicodeChar( pStr[i] );
    1323             : 
    1324           0 :     writeUnicodeChar( 0 );
    1325           0 : }
    1326             : 
    1327           0 : Sequence< ::sal_Int8 > BinaryOutput::closeAndGetData()
    1328             : {
    1329           0 :     Sequence< ::sal_Int8 > aRetSeq;
    1330           0 :     if( !m_xOutputStream.is() )
    1331           0 :         return aRetSeq;
    1332             : 
    1333           0 :     m_xOutputStream->closeOutput();
    1334             : 
    1335           0 :     Reference< io::XSeekable> xSeekable( m_xTempFile, UNO_QUERY );
    1336           0 :     if( !xSeekable.is() )
    1337           0 :         return aRetSeq;
    1338             : 
    1339           0 :     sal_Int32 nSize = (sal_Int32)xSeekable->getPosition();
    1340             : 
    1341           0 :     Reference< io::XInputStream> xInputStream( m_xTempFile, UNO_QUERY );
    1342           0 :     if( !xInputStream.is() )
    1343           0 :         return aRetSeq;
    1344             : 
    1345           0 :     xSeekable->seek( 0 );
    1346           0 :     sal_Int32 nRead = xInputStream->readBytes( aRetSeq, nSize );
    1347             :     (void)nRead;
    1348             :     OSL_ENSURE( nRead == nSize, "BinaryOutput::closeAndGetData: nRead != nSize" );
    1349             : 
    1350           0 :     return aRetSeq;
    1351             : }
    1352             : 
    1353             : 
    1354             : // Binary format:
    1355             : 
    1356             : // Header
    1357             : // Byte         Content
    1358             : // 0 + 1        sal_Int16:  Version, currently 0, low byte first
    1359             : // 2 + 3        sal_Int16:  Locale count = n, low byte first
    1360             : // 4 + 5        sal_Int16:  Default Locale position in Locale list, == n if none
    1361             : // 6 - 7        sal_Int32:  Start index locale block 0, lowest byte first
    1362             : // (n-1) *      sal_Int32:  Start index locale block 1 to n, lowest byte first
    1363             : // 6 + 4*n      sal_Int32:  "Start index" non existing locale block n+1,
    1364             : //                          marks the first invalid index, kind of EOF
    1365             : 
    1366             : // Locale block
    1367             : // All strings are stored as 2-Byte-0 terminated sequence
    1368             : // of 16 bit Unicode characters, each with low byte first
    1369             : // Empty strings only contain the 2-Byte-0
    1370             : 
    1371             : // Members of com.sun.star.lang.Locale
    1372             : // with l1 = Locale.Language.getLength()
    1373             : // with l2 = Locale.Country.getLength()
    1374             : // with l3 = Locale.Variant.getLength()
    1375             : // pos0 = 0                     Locale.Language
    1376             : // pos1 = 2 * (l1 + 1)          Locale.Country
    1377             : // pos2 = pos1 + 2 * (l2 + 1)   Locale.Variant
    1378             : // pos3 = pos2 + 2 * (l3 + 1)
    1379             : // pos3                         Properties file written by implWritePropertiesFile
    1380             : 
    1381           0 : Sequence< sal_Int8 > StringResourcePersistenceImpl::exportBinary(  )
    1382             :     throw (RuntimeException, std::exception)
    1383             : {
    1384           0 :     Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
    1385           0 :     BinaryOutput aOut( xMCF, m_xContext );
    1386             : 
    1387           0 :     sal_Int32 nLocaleCount = m_aLocaleItemVector.size();
    1388           0 :     Sequence< sal_Int8 >* pLocaleDataSeq = new Sequence< sal_Int8 >[ nLocaleCount ];
    1389             : 
    1390           0 :     sal_Int32 iLocale = 0;
    1391           0 :     sal_Int32 iDefault = 0;
    1392           0 :     for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin();
    1393           0 :          it != m_aLocaleItemVector.end(); ++it,++iLocale )
    1394             :     {
    1395           0 :         LocaleItem* pLocaleItem = *it;
    1396           0 :         if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
    1397             :         {
    1398           0 :             if( m_pDefaultLocaleItem == pLocaleItem )
    1399           0 :                 iDefault = iLocale;
    1400             : 
    1401           0 :             BinaryOutput aLocaleOut( m_xMCF, m_xContext );
    1402           0 :             implWriteLocaleBinary( pLocaleItem, aLocaleOut );
    1403             : 
    1404           0 :             pLocaleDataSeq[iLocale] = aLocaleOut.closeAndGetData();
    1405             :         }
    1406             :     }
    1407             : 
    1408             :     // Write header
    1409           0 :     sal_Int16 nVersion = 0;
    1410           0 :     sal_Int16 nLocaleCount16 = (sal_Int16)nLocaleCount;
    1411           0 :     sal_Int16 iDefault16 = (sal_Int16)iDefault;
    1412           0 :     aOut.writeInt16( nVersion );
    1413           0 :     aOut.writeInt16( nLocaleCount16 );
    1414           0 :     aOut.writeInt16( iDefault16 );
    1415             : 
    1416             :     // Write data positions
    1417           0 :     sal_Int32 nDataPos = 6 + 4 * (nLocaleCount + 1);
    1418           0 :     for( iLocale = 0; iLocale < nLocaleCount; iLocale++ )
    1419             :     {
    1420           0 :         aOut.writeInt32( nDataPos );
    1421             : 
    1422           0 :         Sequence< sal_Int8 >& rSeq = pLocaleDataSeq[iLocale];
    1423           0 :         sal_Int32 nSeqLen = rSeq.getLength();
    1424           0 :         nDataPos += nSeqLen;
    1425             :     }
    1426             :     // Write final position
    1427           0 :     aOut.writeInt32( nDataPos );
    1428             : 
    1429             :     // Write data
    1430           0 :     Reference< io::XOutputStream > xOutputStream = aOut.getOutputStream();
    1431           0 :     if( xOutputStream.is() )
    1432             :     {
    1433           0 :         for( iLocale = 0; iLocale < nLocaleCount; iLocale++ )
    1434             :         {
    1435           0 :             Sequence< sal_Int8 >& rSeq = pLocaleDataSeq[iLocale];
    1436           0 :             xOutputStream->writeBytes( rSeq );
    1437             :         }
    1438             :     }
    1439             : 
    1440           0 :     delete[] pLocaleDataSeq;
    1441             : 
    1442           0 :     Sequence< sal_Int8 > aRetSeq = aOut.closeAndGetData();
    1443           0 :     return aRetSeq;
    1444             : }
    1445             : 
    1446           0 : void StringResourcePersistenceImpl::implWriteLocaleBinary
    1447             :     ( LocaleItem* pLocaleItem, BinaryOutput& rOut )
    1448             : {
    1449           0 :     Reference< io::XOutputStream > xOutputStream = rOut.getOutputStream();
    1450           0 :     if( !xOutputStream.is() )
    1451           0 :         return;
    1452             : 
    1453           0 :     Locale& rLocale = pLocaleItem->m_locale;
    1454           0 :     rOut.writeString( rLocale.Language );
    1455           0 :     rOut.writeString( rLocale.Country );
    1456           0 :     rOut.writeString( rLocale.Variant );
    1457           0 :     implWritePropertiesFile( pLocaleItem, xOutputStream, m_aComment );
    1458             : }
    1459             : 
    1460             : 
    1461             : // BinaryOutput, helper class for exportBinary
    1462             : 
    1463           0 : class BinaryInput
    1464             : {
    1465             :     Sequence< sal_Int8 >                    m_aData;
    1466             :     Reference< XMultiComponentFactory >     m_xMCF;
    1467             :     Reference< XComponentContext >          m_xContext;
    1468             : 
    1469             :     const sal_Int8*                         m_pData;
    1470             :     sal_Int32                               m_nCurPos;
    1471             :     sal_Int32                               m_nSize;
    1472             : 
    1473             : public:
    1474             :     BinaryInput( const Sequence< ::sal_Int8 >& aData, Reference< XMultiComponentFactory > xMCF,
    1475             :         Reference< XComponentContext > xContext );
    1476             : 
    1477             :     Reference< io::XInputStream > getInputStreamForSection( sal_Int32 nSize );
    1478             : 
    1479             :     void seek( sal_Int32 nPos );
    1480           0 :     sal_Int32 getPosition( void ) const
    1481           0 :         { return m_nCurPos; }
    1482             : 
    1483             :     sal_Int16 readInt16( void );
    1484             :     sal_Int32 readInt32( void );
    1485             :     sal_Unicode readUnicodeChar( void );
    1486             :     OUString readString( void );
    1487             : };
    1488             : 
    1489           0 : BinaryInput::BinaryInput( const Sequence< ::sal_Int8 >& aData, Reference< XMultiComponentFactory > xMCF,
    1490             :     Reference< XComponentContext > xContext )
    1491             :         : m_aData( aData )
    1492             :         , m_xMCF( xMCF )
    1493           0 :         , m_xContext( xContext )
    1494             : {
    1495           0 :     m_pData = m_aData.getConstArray();
    1496           0 :     m_nCurPos = 0;
    1497           0 :     m_nSize = m_aData.getLength();
    1498           0 : }
    1499             : 
    1500           0 : Reference< io::XInputStream > BinaryInput::getInputStreamForSection( sal_Int32 nSize )
    1501             : {
    1502           0 :     Reference< io::XInputStream > xIn;
    1503           0 :     if( m_nCurPos + nSize <= m_nSize )
    1504             :     {
    1505           0 :         Reference< io::XOutputStream > xTempOut( io::TempFile::create(m_xContext), UNO_QUERY_THROW );
    1506           0 :         Sequence< sal_Int8 > aSection( m_pData + m_nCurPos, nSize );
    1507           0 :         xTempOut->writeBytes( aSection );
    1508             : 
    1509           0 :         Reference< io::XSeekable> xSeekable( xTempOut, UNO_QUERY );
    1510           0 :         if( xSeekable.is() )
    1511           0 :             xSeekable->seek( 0 );
    1512             : 
    1513           0 :         xIn = Reference< io::XInputStream>( xTempOut, UNO_QUERY );
    1514             :     }
    1515             :     else
    1516             :         OSL_FAIL( "BinaryInput::getInputStreamForSection(): Read past end" );
    1517             : 
    1518           0 :     return xIn;
    1519             : }
    1520             : 
    1521           0 : void BinaryInput::seek( sal_Int32 nPos )
    1522             : {
    1523           0 :     if( nPos <= m_nSize )
    1524           0 :         m_nCurPos = nPos;
    1525             :     else
    1526             :         OSL_FAIL( "BinaryInput::seek(): Position past end" );
    1527           0 : }
    1528             : 
    1529             : 
    1530           0 : sal_Int16 BinaryInput::readInt16( void )
    1531             : {
    1532           0 :     sal_Int16 nRet = 0;
    1533           0 :     if( m_nCurPos + 2 <= m_nSize )
    1534             :     {
    1535           0 :         nRet = nRet + sal_Int16( sal_uInt8( m_pData[m_nCurPos++] ) );
    1536           0 :         nRet += 256 * sal_Int16( sal_uInt8( m_pData[m_nCurPos++] ) );
    1537             :     }
    1538             :     else
    1539             :         OSL_FAIL( "BinaryInput::readInt16(): Read past end" );
    1540             : 
    1541           0 :     return nRet;
    1542             : }
    1543             : 
    1544           0 : sal_Int32 BinaryInput::readInt32( void )
    1545             : {
    1546           0 :     sal_Int32 nRet = 0;
    1547           0 :     if( m_nCurPos + 4 <= m_nSize )
    1548             :     {
    1549           0 :         sal_Int32 nFactor = 1;
    1550           0 :         for( sal_Int16 i = 0; i < 4; i++ )
    1551             :         {
    1552           0 :             nRet += sal_uInt8( m_pData[m_nCurPos++] ) * nFactor;
    1553           0 :             nFactor *= 256;
    1554             :         }
    1555             :     }
    1556             :     else
    1557             :         OSL_FAIL( "BinaryInput::readInt32(): Read past end" );
    1558             : 
    1559           0 :     return nRet;
    1560             : }
    1561             : 
    1562           0 : sal_Unicode BinaryInput::readUnicodeChar( void )
    1563             : {
    1564           0 :     sal_uInt16 nRet = 0;
    1565           0 :     if( m_nCurPos + 2 <= m_nSize )
    1566             :     {
    1567           0 :         nRet = nRet + sal_uInt8( m_pData[m_nCurPos++] );
    1568           0 :         nRet += 256 * sal_uInt8( m_pData[m_nCurPos++] );
    1569             :     }
    1570             :     else
    1571             :         OSL_FAIL( "BinaryInput::readUnicodeChar(): Read past end" );
    1572             : 
    1573           0 :     sal_Unicode cRet = nRet;
    1574           0 :     return cRet;
    1575             : }
    1576             : 
    1577           0 : OUString BinaryInput::readString( void )
    1578             : {
    1579           0 :     OUStringBuffer aBuf;
    1580             :     sal_Unicode c;
    1581           0 :     do
    1582             :     {
    1583           0 :         c = readUnicodeChar();
    1584           0 :         if( c != 0 )
    1585           0 :             aBuf.append( c );
    1586             :     }
    1587             :     while( c != 0 );
    1588             : 
    1589           0 :     OUString aRetStr = aBuf.makeStringAndClear();
    1590           0 :     return aRetStr;
    1591             : }
    1592             : 
    1593           0 : void StringResourcePersistenceImpl::importBinary( const Sequence< ::sal_Int8 >& Data )
    1594             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    1595             : {
    1596             :     // Init: Remove all locales
    1597           0 :     sal_Int32 nOldLocaleCount = 0;
    1598           0 :     do
    1599             :     {
    1600           0 :         Sequence< Locale > aLocaleSeq = getLocales();
    1601           0 :         nOldLocaleCount = aLocaleSeq.getLength();
    1602           0 :         if( nOldLocaleCount > 0 )
    1603             :         {
    1604           0 :             Locale aLocale = aLocaleSeq[0];
    1605           0 :             removeLocale( aLocale );
    1606           0 :         }
    1607             :     }
    1608             :     while( nOldLocaleCount > 0 );
    1609             : 
    1610             :     // Import data
    1611           0 :     Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
    1612           0 :     BinaryInput aIn( Data, xMCF, m_xContext );
    1613             : 
    1614           0 :     sal_Int32 nVersion = aIn.readInt16();
    1615             :     (void)nVersion;
    1616           0 :     sal_Int32 nLocaleCount = aIn.readInt16();
    1617           0 :     sal_Int32 iDefault = aIn.readInt16();
    1618             :     (void)iDefault;
    1619             : 
    1620           0 :     sal_Int32* pPositions = new sal_Int32[nLocaleCount + 1];
    1621           0 :     for( sal_Int32 i = 0; i < nLocaleCount + 1; i++ )
    1622           0 :         pPositions[i] = aIn.readInt32();
    1623             : 
    1624             :     // Import locales
    1625           0 :     LocaleItem* pUseAsDefaultItem = NULL;
    1626           0 :     for( sal_Int32 i = 0; i < nLocaleCount; i++ )
    1627             :     {
    1628           0 :         sal_Int32 nPos = pPositions[i];
    1629           0 :         aIn.seek( nPos );
    1630             : 
    1631           0 :         Locale aLocale;
    1632           0 :         aLocale.Language = aIn.readString();
    1633           0 :         aLocale.Country = aIn.readString();
    1634           0 :         aLocale.Variant = aIn.readString();
    1635             : 
    1636           0 :         sal_Int32 nAfterStringPos = aIn.getPosition();
    1637           0 :         sal_Int32 nSize = pPositions[i+1] - nAfterStringPos;
    1638           0 :         Reference< io::XInputStream > xInput = aIn.getInputStreamForSection( nSize );
    1639           0 :         if( xInput.is() )
    1640             :         {
    1641           0 :             LocaleItem* pLocaleItem = new LocaleItem( aLocale );
    1642           0 :             if( iDefault == i )
    1643           0 :                 pUseAsDefaultItem = pLocaleItem;
    1644           0 :             m_aLocaleItemVector.push_back( pLocaleItem );
    1645           0 :             implReadPropertiesFile( pLocaleItem, xInput );
    1646             :         }
    1647           0 :     }
    1648             : 
    1649           0 :     if( pUseAsDefaultItem != NULL )
    1650           0 :         setDefaultLocale( pUseAsDefaultItem->m_locale );
    1651             : 
    1652           0 :     delete[] pPositions;
    1653           0 : }
    1654             : 
    1655             : 
    1656             : 
    1657             : // Private helper methods
    1658             : 
    1659           0 : bool checkNamingSceme( const OUString& aName, const OUString& aNameBase,
    1660             :                        Locale& aLocale )
    1661             : {
    1662           0 :     bool bSuccess = false;
    1663             : 
    1664           0 :     sal_Int32 nNameLen = aName.getLength();
    1665           0 :     sal_Int32 nNameBaseLen = aNameBase.getLength();
    1666             : 
    1667             :     // Name has to start with NameBase followed
    1668             :     // by a '_' and at least one more character
    1669           0 :     if( aName.startsWith( aNameBase ) && nNameBaseLen < nNameLen-1 &&
    1670           0 :         aName[nNameBaseLen] == '_' )
    1671             :     {
    1672           0 :         bSuccess = true;
    1673             : 
    1674             :         /* FIXME-BCP47: this uses '_' underscore character as separator and
    1675             :          * also appends Variant, which can't be blindly changed as it would
    1676             :          * violate the naming scheme in use. */
    1677             : 
    1678           0 :         sal_Int32 iStart = nNameBaseLen + 1;
    1679           0 :         sal_Int32 iNext_ = aName.indexOf( '_', iStart );
    1680           0 :         if( iNext_ != -1 && iNext_ < nNameLen-1 )
    1681             :         {
    1682           0 :             aLocale.Language = aName.copy( iStart, iNext_ - iStart );
    1683             : 
    1684           0 :             iStart = iNext_ + 1;
    1685           0 :             iNext_ = aName.indexOf( '_', iStart );
    1686           0 :             if( iNext_ != -1 && iNext_ < nNameLen-1 )
    1687             :             {
    1688           0 :                 aLocale.Country = aName.copy( iStart, iNext_ - iStart );
    1689           0 :                 aLocale.Variant = aName.copy( iNext_ + 1 );
    1690             :             }
    1691             :             else
    1692           0 :                 aLocale.Country = aName.copy( iStart );
    1693             :         }
    1694             :         else
    1695           0 :             aLocale.Language = aName.copy( iStart );
    1696             :     }
    1697           0 :     return bSuccess;
    1698             : }
    1699             : 
    1700           0 : void StringResourcePersistenceImpl::implLoadAllLocales( void )
    1701             : {
    1702           0 :     for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
    1703             :     {
    1704           0 :         LocaleItem* pLocaleItem = *it;
    1705           0 :         if( pLocaleItem != NULL )
    1706           0 :             loadLocale( pLocaleItem );
    1707             :     }
    1708           0 : }
    1709             : 
    1710             : // Scan locale properties files helper
    1711           0 : void StringResourcePersistenceImpl::implScanLocaleNames( const Sequence< OUString >& aContentSeq )
    1712             : {
    1713           0 :     Locale aDefaultLocale;
    1714           0 :     bool bDefaultFound = false;
    1715             : 
    1716           0 :     sal_Int32 nCount = aContentSeq.getLength();
    1717           0 :     const OUString* pFiles = aContentSeq.getConstArray();
    1718           0 :     for( int i = 0 ; i < nCount ; i++ )
    1719             :     {
    1720           0 :         OUString aCompleteName = pFiles[i];
    1721           0 :         OUString aPureName;
    1722           0 :         OUString aExtension;
    1723           0 :         sal_Int32 iDot = aCompleteName.lastIndexOf( '.' );
    1724           0 :         sal_Int32 iSlash = aCompleteName.lastIndexOf( '/' );
    1725           0 :         if( iDot != -1 && iDot > iSlash)
    1726             :         {
    1727           0 :             sal_Int32 iCopyFrom = (iSlash != -1) ? iSlash + 1 : 0;
    1728           0 :             aPureName = aCompleteName.copy( iCopyFrom, iDot-iCopyFrom );
    1729           0 :             aExtension = aCompleteName.copy( iDot + 1 );
    1730             :         }
    1731             : 
    1732           0 :         if ( aExtension == "properties" )
    1733             :         {
    1734             :             //OUString aName = aInetObj.getBase();
    1735           0 :             Locale aLocale;
    1736             : 
    1737           0 :             if( checkNamingSceme( aPureName, m_aNameBase, aLocale ) )
    1738             :             {
    1739           0 :                 LocaleItem* pLocaleItem = new LocaleItem( aLocale, false );
    1740           0 :                 m_aLocaleItemVector.push_back( pLocaleItem );
    1741             : 
    1742           0 :                 if( m_pCurrentLocaleItem == NULL )
    1743           0 :                     m_pCurrentLocaleItem = pLocaleItem;
    1744             : 
    1745           0 :                 if( m_pDefaultLocaleItem == NULL )
    1746             :                 {
    1747           0 :                     m_pDefaultLocaleItem = pLocaleItem;
    1748           0 :                     m_bDefaultModified = true;
    1749             :                 }
    1750           0 :             }
    1751             :         }
    1752           0 :         else if( !bDefaultFound && aExtension == "default" )
    1753             :         {
    1754             :             //OUString aName = aInetObj.getBase();
    1755           0 :             Locale aLocale;
    1756             : 
    1757           0 :             if( checkNamingSceme( aPureName, m_aNameBase, aDefaultLocale ) )
    1758           0 :                 bDefaultFound = true;
    1759             :         }
    1760           0 :     }
    1761           0 :     if( bDefaultFound )
    1762             :     {
    1763           0 :         LocaleItem* pLocaleItem = getItemForLocale( aDefaultLocale, false );
    1764           0 :         if( pLocaleItem )
    1765             :         {
    1766           0 :             m_pDefaultLocaleItem = pLocaleItem;
    1767           0 :             m_bDefaultModified = false;
    1768             :         }
    1769           0 :     }
    1770           0 : }
    1771             : 
    1772             : // Scan locale properties files
    1773           0 : void StringResourcePersistenceImpl::implScanLocales( void )
    1774             : {
    1775             :     // Dummy implementation, method not called for this
    1776             :     // base class, but pure virtual not possible-
    1777           0 : }
    1778             : 
    1779           0 : bool StringResourcePersistenceImpl::loadLocale( LocaleItem* pLocaleItem )
    1780             : {
    1781           0 :     bool bSuccess = false;
    1782             : 
    1783             :     OSL_ENSURE( pLocaleItem, "StringResourcePersistenceImpl::loadLocale(): pLocaleItem == NULL" );
    1784           0 :     if( pLocaleItem )
    1785             :     {
    1786           0 :         if( pLocaleItem->m_bLoaded )
    1787             :         {
    1788           0 :             bSuccess = true;
    1789             :         }
    1790             :         else
    1791             :         {
    1792           0 :             bSuccess = implLoadLocale( pLocaleItem );
    1793           0 :             pLocaleItem->m_bLoaded = true;      // = bSuccess??? -> leads to more tries
    1794             :         }
    1795             :     }
    1796           0 :     return bSuccess;
    1797             : }
    1798             : 
    1799           0 : bool StringResourcePersistenceImpl::implLoadLocale( LocaleItem* )
    1800             : {
    1801             :     // Dummy implementation, method not called for this
    1802             :     // base class, but pure virtual not possible-
    1803           0 :     return false;
    1804             : }
    1805             : 
    1806           0 : OUString implGetNameScemeForLocaleItem( const LocaleItem* pLocaleItem )
    1807             : {
    1808             :     /* FIXME-BCP47: this uses '_' underscore character as separator and
    1809             :      * also appends Variant, which can't be blindly changed as it would
    1810             :      * violate the naming scheme in use. */
    1811             : 
    1812           0 :     static OUString aUnder("_");
    1813             : 
    1814             :     OSL_ENSURE( pLocaleItem,
    1815             :         "StringResourcePersistenceImpl::implGetNameScemeForLocaleItem(): pLocaleItem == NULL" );
    1816           0 :     Locale aLocale = pLocaleItem->m_locale;
    1817             : 
    1818           0 :     OUString aRetStr = aUnder;
    1819           0 :     aRetStr += aLocale.Language;
    1820             : 
    1821           0 :     OUString aCountry  = aLocale.Country;
    1822           0 :     if( !aCountry.isEmpty() )
    1823             :     {
    1824           0 :         aRetStr += aUnder;
    1825           0 :         aRetStr += aCountry;
    1826             :     }
    1827             : 
    1828           0 :     OUString aVariant  = aLocale.Variant;
    1829           0 :     if( !aVariant.isEmpty() )
    1830             :     {
    1831           0 :         aRetStr += aUnder;
    1832           0 :         aRetStr += aVariant;
    1833             :     }
    1834           0 :     return aRetStr;
    1835             : }
    1836             : 
    1837           0 : OUString StringResourcePersistenceImpl::implGetFileNameForLocaleItem
    1838             :     ( LocaleItem* pLocaleItem, const OUString& aNameBase )
    1839             : {
    1840           0 :     OUString aFileName = aNameBase;
    1841           0 :     if( aFileName.isEmpty() )
    1842           0 :         aFileName = aNameBaseDefaultStr;
    1843             : 
    1844           0 :     aFileName += implGetNameScemeForLocaleItem( pLocaleItem );
    1845           0 :     return aFileName;
    1846             : }
    1847             : 
    1848           0 : OUString StringResourcePersistenceImpl::implGetPathForLocaleItem
    1849             :     ( LocaleItem* pLocaleItem, const OUString& aNameBase,
    1850             :       const OUString& aLocation, bool bDefaultFile )
    1851             : {
    1852           0 :     OUString aFileName = implGetFileNameForLocaleItem( pLocaleItem, aNameBase );
    1853           0 :     INetURLObject aInetObj( aLocation );
    1854           0 :     aInetObj.insertName( aFileName, true, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
    1855           0 :     if( bDefaultFile )
    1856           0 :         aInetObj.setExtension( OUString( "default" ) );
    1857             :     else
    1858           0 :         aInetObj.setExtension( OUString( "properties" ) );
    1859           0 :     OUString aCompleteFileName = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
    1860           0 :     return aCompleteFileName;
    1861             : }
    1862             : 
    1863             : // White space according to Java property files specification in
    1864             : // http://java.sun.com/j2se/1.4.2/docs/api/java/util/Properties.html#load(java.io.InputStream)
    1865           0 : inline bool isWhiteSpace( sal_Unicode c )
    1866             : {
    1867           0 :     bool bWhite = ( c == 0x0020 ||      // space
    1868           0 :                     c == 0x0009 ||      // tab
    1869           0 :                     c == 0x000a ||      // line feed, not always handled by TextInputStream
    1870           0 :                     c == 0x000d ||      // carriage return, not always handled by TextInputStream
    1871           0 :                     c == 0x000C );      // form feed
    1872           0 :     return bWhite;
    1873             : }
    1874             : 
    1875           0 : inline void skipWhites( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri )
    1876             : {
    1877           0 :     while( ri < nLen )
    1878             :     {
    1879           0 :         if( !isWhiteSpace( pBuf[ri] ) )
    1880           0 :             break;
    1881           0 :         ri++;
    1882             :     }
    1883           0 : }
    1884             : 
    1885           0 : inline bool isHexDigit( sal_Unicode c, sal_uInt16& nDigitVal )
    1886             : {
    1887           0 :     bool bRet = true;
    1888           0 :     if( c >= '0' && c <= '9' )
    1889           0 :         nDigitVal = c - '0';
    1890           0 :     else if( c >= 'a' && c <= 'f' )
    1891           0 :         nDigitVal = c - 'a' + 10;
    1892           0 :     else if( c >= 'A' && c <= 'F' )
    1893           0 :         nDigitVal = c - 'A' + 10;
    1894             :     else
    1895           0 :         bRet = false;
    1896           0 :     return bRet;
    1897             : }
    1898             : 
    1899           0 : sal_Unicode getEscapeChar( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri )
    1900             : {
    1901           0 :     sal_Int32 i = ri;
    1902             : 
    1903           0 :     sal_Unicode cRet = 0;
    1904           0 :     sal_Unicode c = pBuf[i];
    1905           0 :     switch( c )
    1906             :     {
    1907             :         case 't':
    1908           0 :             cRet = 0x0009;
    1909           0 :             break;
    1910             :         case 'n':
    1911           0 :             cRet = 0x000a;
    1912           0 :             break;
    1913             :         case 'f':
    1914           0 :             cRet = 0x000c;
    1915           0 :             break;
    1916             :         case 'r':
    1917           0 :             cRet = 0x000d;
    1918           0 :             break;
    1919             :         case '\\':
    1920           0 :             cRet = '\\';
    1921           0 :             break;
    1922             :         case 'u':
    1923             :         {
    1924             :             // Skip multiple u
    1925           0 :             i++;
    1926           0 :             while( i < nLen && pBuf[i] == 'u' )
    1927           0 :                 i++;
    1928             : 
    1929             :             // Process hex digits
    1930           0 :             sal_Int32 nDigitCount = 0;
    1931             :             sal_uInt16 nDigitVal;
    1932           0 :             while( i < nLen && isHexDigit( pBuf[i], nDigitVal ) )
    1933             :             {
    1934           0 :                 cRet = 16 * cRet + nDigitVal;
    1935             : 
    1936           0 :                 nDigitCount++;
    1937           0 :                 if( nDigitCount == 4 )
    1938             :                 {
    1939             :                     // Write back position
    1940           0 :                     ri = i;
    1941           0 :                     break;
    1942             :                 }
    1943           0 :                 i++;
    1944             :             }
    1945           0 :             break;
    1946             :         }
    1947             :         default:
    1948           0 :             cRet = c;
    1949             :     }
    1950             : 
    1951           0 :     return cRet;
    1952             : }
    1953             : 
    1954           0 : void CheckContinueInNextLine( Reference< io::XTextInputStream2 > xTextInputStream,
    1955             :     OUString& aLine, bool& bEscapePending, const sal_Unicode*& pBuf,
    1956             :     sal_Int32& nLen, sal_Int32& i )
    1957             : {
    1958           0 :     if( i == nLen && bEscapePending )
    1959             :     {
    1960           0 :         bEscapePending = false;
    1961             : 
    1962           0 :         if( !xTextInputStream->isEOF() )
    1963             :         {
    1964           0 :             aLine = xTextInputStream->readLine();
    1965           0 :             nLen = aLine.getLength();
    1966           0 :             pBuf = aLine.getStr();
    1967           0 :             i = 0;
    1968             : 
    1969           0 :             skipWhites( pBuf, nLen, i );
    1970             :         }
    1971             :     }
    1972           0 : }
    1973             : 
    1974           0 : bool StringResourcePersistenceImpl::implReadPropertiesFile
    1975             :     ( LocaleItem* pLocaleItem, const Reference< io::XInputStream >& xInputStream )
    1976             : {
    1977           0 :     if( !xInputStream.is() || pLocaleItem == NULL )
    1978           0 :         return false;
    1979             : 
    1980           0 :     bool bSuccess = false;
    1981           0 :     Reference< io::XTextInputStream2 > xTextInputStream = io::TextInputStream::create( m_xContext );
    1982             : 
    1983           0 :     bSuccess = true;
    1984             : 
    1985           0 :     xTextInputStream->setInputStream( xInputStream );
    1986             : 
    1987             :     OUString aEncodingStr = OUString::createFromAscii
    1988           0 :         ( rtl_getMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
    1989           0 :     xTextInputStream->setEncoding( aEncodingStr );
    1990             : 
    1991           0 :     OUString aLine;
    1992           0 :     while( !xTextInputStream->isEOF() )
    1993             :     {
    1994           0 :         aLine = xTextInputStream->readLine();
    1995             : 
    1996           0 :         sal_Int32 nLen = aLine.getLength();
    1997           0 :         if( 0 == nLen )
    1998           0 :             continue;
    1999           0 :         const sal_Unicode* pBuf = aLine.getStr();
    2000           0 :         OUStringBuffer aBuf;
    2001           0 :         sal_Unicode c = 0;
    2002           0 :         sal_Int32 i = 0;
    2003             : 
    2004           0 :         skipWhites( pBuf, nLen, i );
    2005           0 :         if( i == nLen )
    2006           0 :             continue;   // line contains only white spaces
    2007             : 
    2008             :         // Comment?
    2009           0 :         c = pBuf[i];
    2010           0 :         if( c == '#' || c == '!' )
    2011           0 :             continue;
    2012             : 
    2013             :         // Scan key
    2014           0 :         OUString aResourceID;
    2015           0 :         bool bEscapePending = false;
    2016           0 :         bool bStrComplete = false;
    2017           0 :         while( i < nLen && !bStrComplete )
    2018             :         {
    2019           0 :             c = pBuf[i];
    2020           0 :             if( bEscapePending )
    2021             :             {
    2022           0 :                 aBuf.append( getEscapeChar( pBuf, nLen, i ) );
    2023           0 :                 bEscapePending = false;
    2024             :             }
    2025             :             else
    2026             :             {
    2027           0 :                 if( c == '\\' )
    2028             :                 {
    2029           0 :                     bEscapePending = true;
    2030             :                 }
    2031             :                 else
    2032             :                 {
    2033           0 :                     if( c == ':' || c == '=' || isWhiteSpace( c ) )
    2034           0 :                         bStrComplete = true;
    2035             :                     else
    2036           0 :                         aBuf.append( c );
    2037             :                 }
    2038             :             }
    2039           0 :             i++;
    2040             : 
    2041           0 :             CheckContinueInNextLine( xTextInputStream, aLine, bEscapePending, pBuf, nLen, i );
    2042           0 :             if( i == nLen )
    2043           0 :                 bStrComplete = true;
    2044             : 
    2045           0 :             if( bStrComplete )
    2046           0 :                 aResourceID = aBuf.makeStringAndClear();
    2047             :         }
    2048             : 
    2049             :         // Ignore lines with empty keys
    2050           0 :         if( aResourceID.isEmpty() )
    2051           0 :             continue;
    2052             : 
    2053             :         // Scan value
    2054           0 :         skipWhites( pBuf, nLen, i );
    2055             : 
    2056           0 :         OUString aValueStr;
    2057           0 :         bEscapePending = false;
    2058           0 :         bStrComplete = false;
    2059           0 :         while( i < nLen && !bStrComplete )
    2060             :         {
    2061           0 :             c = pBuf[i];
    2062           0 :             if( c == 0x000a || c == 0x000d )    // line feed/carriage return, not always handled by TextInputStream
    2063             :             {
    2064           0 :                 i++;
    2065             :             }
    2066             :             else
    2067             :             {
    2068           0 :                 if( bEscapePending )
    2069             :                 {
    2070           0 :                     aBuf.append( getEscapeChar( pBuf, nLen, i ) );
    2071           0 :                     bEscapePending = false;
    2072             :                 }
    2073           0 :                 else if( c == '\\' )
    2074           0 :                     bEscapePending = true;
    2075             :                 else
    2076           0 :                     aBuf.append( c );
    2077           0 :                 i++;
    2078             : 
    2079           0 :                 CheckContinueInNextLine( xTextInputStream, aLine, bEscapePending, pBuf, nLen, i );
    2080             :             }
    2081           0 :             if( i == nLen )
    2082           0 :                 bStrComplete = true;
    2083             : 
    2084           0 :             if( bStrComplete )
    2085           0 :                 aValueStr = aBuf.makeStringAndClear();
    2086             :         }
    2087             : 
    2088             :         // Push into table
    2089           0 :         pLocaleItem->m_aIdToStringMap[ aResourceID ] = aValueStr;
    2090           0 :         implScanIdForNumber( aResourceID );
    2091           0 :         IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap;
    2092           0 :         rIndexMap[ aResourceID ] = pLocaleItem->m_nNextIndex++;
    2093           0 :     }
    2094             : 
    2095           0 :     return bSuccess;
    2096             : }
    2097             : 
    2098             : 
    2099           0 : inline sal_Unicode getHexCharForDigit( sal_uInt16 nDigitVal )
    2100             : {
    2101           0 :     sal_Unicode cRet = ( nDigitVal < 10 ) ? ('0' + nDigitVal) : ('a' + (nDigitVal-10));
    2102           0 :     return cRet;
    2103             : }
    2104             : 
    2105           0 : void implWriteCharToBuffer( OUStringBuffer& aBuf, sal_Unicode cu, bool bKey )
    2106             : {
    2107           0 :     if( cu == '\\' )
    2108             :     {
    2109           0 :         aBuf.append( '\\' );
    2110           0 :         aBuf.append( '\\' );
    2111             :     }
    2112           0 :     else if( cu == 0x000a )
    2113             :     {
    2114           0 :         aBuf.append( '\\' );
    2115           0 :         aBuf.append( 'n' );
    2116             :     }
    2117           0 :     else if( cu == 0x000d )
    2118             :     {
    2119           0 :         aBuf.append( '\\' );
    2120           0 :         aBuf.append( 'r' );
    2121             :     }
    2122           0 :     else if( bKey && cu == '=' )
    2123             :     {
    2124           0 :         aBuf.append( '\\' );
    2125           0 :         aBuf.append( '=' );
    2126             :     }
    2127           0 :     else if( bKey && cu == ':' )
    2128             :     {
    2129           0 :         aBuf.append( '\\' );
    2130           0 :         aBuf.append( ':' );
    2131             :     }
    2132             :     // ISO/IEC 8859-1 range according to:
    2133             :     // http://en.wikipedia.org/wiki/ISO/IEC_8859-1
    2134           0 :     else if( (cu >= 0x20 && cu <= 0x7e) )
    2135             :     //TODO: Check why (cu >= 0xa0 && cu <= 0xFF)
    2136             :     //is encoded in sample properties files
    2137             :     //else if( (cu >= 0x20 && cu <= 0x7e) ||
    2138             :     //       (cu >= 0xa0 && cu <= 0xFF) )
    2139             :     {
    2140           0 :         aBuf.append( cu );
    2141             :     }
    2142             :     else
    2143             :     {
    2144             :         // Unicode encoding
    2145           0 :         aBuf.append( '\\' );
    2146           0 :         aBuf.append( 'u' );
    2147             : 
    2148           0 :         sal_uInt16 nVal = cu;
    2149           0 :         for( sal_uInt16 i = 0 ; i < 4 ; i++ )
    2150             :         {
    2151           0 :             sal_uInt16 nDigit = nVal / 0x1000;
    2152           0 :             nVal -= nDigit * 0x1000;
    2153           0 :             nVal *= 0x10;
    2154           0 :             aBuf.append( getHexCharForDigit( nDigit ) );
    2155             :         }
    2156             :     }
    2157           0 : }
    2158             : 
    2159           0 : void implWriteStringWithEncoding( const OUString& aStr,
    2160             :     Reference< io::XTextOutputStream2 > xTextOutputStream, bool bKey )
    2161             : {
    2162             :     static sal_Unicode cLineFeed = 0xa;
    2163             : 
    2164             :     (void)aStr;
    2165             :     (void)xTextOutputStream;
    2166             : 
    2167           0 :     OUStringBuffer aBuf;
    2168           0 :     sal_Int32 nLen = aStr.getLength();
    2169           0 :     const sal_Unicode* pSrc = aStr.getStr();
    2170           0 :     for( sal_Int32 i = 0 ; i < nLen ; i++ )
    2171             :     {
    2172           0 :         sal_Unicode cu = pSrc[i];
    2173           0 :         implWriteCharToBuffer( aBuf, cu, bKey );
    2174             :         // TODO?: split long lines
    2175             :     }
    2176           0 :     if( !bKey )
    2177           0 :         aBuf.append( cLineFeed );
    2178             : 
    2179           0 :     OUString aWriteStr = aBuf.makeStringAndClear();
    2180           0 :     xTextOutputStream->writeString( aWriteStr );
    2181           0 : }
    2182             : 
    2183           0 : bool StringResourcePersistenceImpl::implWritePropertiesFile( LocaleItem* pLocaleItem,
    2184             :     const Reference< io::XOutputStream >& xOutputStream, const OUString& aComment )
    2185             : {
    2186           0 :     static OUString aAssignmentStr("=");
    2187           0 :     static OUString aLineFeedStr("\n");
    2188             : 
    2189           0 :     if( !xOutputStream.is() || pLocaleItem == NULL )
    2190           0 :         return false;
    2191             : 
    2192           0 :     bool bSuccess = false;
    2193           0 :     Reference< io::XTextOutputStream2 > xTextOutputStream = io::TextOutputStream::create(m_xContext);
    2194             : 
    2195           0 :     xTextOutputStream->setOutputStream( xOutputStream );
    2196             : 
    2197             :     OUString aEncodingStr = OUString::createFromAscii
    2198           0 :         ( rtl_getMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
    2199           0 :     xTextOutputStream->setEncoding( aEncodingStr );
    2200             : 
    2201           0 :     xTextOutputStream->writeString( aComment );
    2202           0 :     xTextOutputStream->writeString( aLineFeedStr );
    2203             : 
    2204           0 :     const IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
    2205           0 :     if( rHashMap.size() > 0 )
    2206             :     {
    2207             :         // Sort ids according to read order
    2208           0 :         const IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap;
    2209           0 :         IdToIndexMap::const_iterator it_index;
    2210             : 
    2211             :         // Find max/min index
    2212           0 :         sal_Int32 nMinIndex = -1;
    2213           0 :         sal_Int32 nMaxIndex = -1;
    2214           0 :         for( it_index = rIndexMap.begin(); it_index != rIndexMap.end(); ++it_index )
    2215             :         {
    2216           0 :             sal_Int32 nIndex = (*it_index).second;
    2217           0 :             if( nMinIndex > nIndex || nMinIndex == -1 )
    2218           0 :                 nMinIndex = nIndex;
    2219           0 :             if( nMaxIndex < nIndex )
    2220           0 :                 nMaxIndex = nIndex;
    2221             :         }
    2222           0 :         sal_Int32 nTabSize = nMaxIndex - nMinIndex + 1;
    2223             : 
    2224             :         // Create sorted array of pointers to the id strings
    2225           0 :         const OUString** pIdPtrs = new const OUString*[nTabSize];
    2226           0 :         for(sal_Int32 i = 0 ; i < nTabSize ; i++ )
    2227           0 :             pIdPtrs[i] = NULL;
    2228           0 :         for( it_index = rIndexMap.begin(); it_index != rIndexMap.end(); ++it_index )
    2229             :         {
    2230           0 :             sal_Int32 nIndex = (*it_index).second;
    2231           0 :             pIdPtrs[nIndex - nMinIndex] = &((*it_index).first);
    2232             :         }
    2233             : 
    2234             :         // Write lines in correct order
    2235           0 :         for(sal_Int32 i = 0 ; i < nTabSize ; i++ )
    2236             :         {
    2237           0 :             const OUString* pStr = pIdPtrs[i];
    2238           0 :             if( pStr != NULL )
    2239             :             {
    2240           0 :                 OUString aResourceID = *pStr;
    2241           0 :                 IdToStringMap::const_iterator it = rHashMap.find( aResourceID );
    2242           0 :                 if( !( it == rHashMap.end() ) )
    2243             :                 {
    2244           0 :                     implWriteStringWithEncoding( aResourceID, xTextOutputStream, true );
    2245           0 :                     xTextOutputStream->writeString( aAssignmentStr );
    2246           0 :                     OUString aValStr = (*it).second;
    2247           0 :                     implWriteStringWithEncoding( aValStr, xTextOutputStream, false );
    2248           0 :                 }
    2249             :             }
    2250             :         }
    2251             : 
    2252           0 :         delete[] pIdPtrs;
    2253             :     }
    2254             : 
    2255           0 :     bSuccess = true;
    2256             : 
    2257           0 :     return bSuccess;
    2258             : }
    2259             : 
    2260             : 
    2261             : 
    2262             : // StringResourceWithStorageImpl
    2263             : 
    2264             : 
    2265             : // component operations
    2266           0 : static Sequence< OUString > getSupportedServiceNames_StringResourceWithStorageImpl()
    2267             : {
    2268           0 :     Sequence< OUString > names(1);
    2269           0 :     names[0] = "com.sun.star.resource.StringResourceWithStorage";
    2270           0 :     return names;
    2271             : }
    2272             : 
    2273           2 : static OUString getImplementationName_StringResourceWithStorageImpl()
    2274             : {
    2275           2 :     return OUString( "com.sun.star.comp.scripting.StringResourceWithStorage" );
    2276             : }
    2277             : 
    2278           0 : static Reference< XInterface > SAL_CALL create_StringResourceWithStorageImpl(
    2279             :     Reference< XComponentContext > const & xContext )
    2280             : {
    2281           0 :     return static_cast< ::cppu::OWeakObject * >( new StringResourceWithStorageImpl( xContext ) );
    2282             : }
    2283             : 
    2284             : 
    2285             : 
    2286           0 : StringResourceWithStorageImpl::StringResourceWithStorageImpl( const Reference< XComponentContext >& rxContext )
    2287             :     : StringResourceWithStorageImpl_BASE( rxContext )
    2288           0 :     , m_bStorageChanged( false )
    2289             : {
    2290           0 : }
    2291             : 
    2292             : 
    2293             : 
    2294           0 : StringResourceWithStorageImpl::~StringResourceWithStorageImpl()
    2295             : {
    2296           0 : }
    2297             : 
    2298             : 
    2299             : // XServiceInfo
    2300             : 
    2301             : 
    2302           0 : OUString StringResourceWithStorageImpl::getImplementationName(  ) throw (RuntimeException, std::exception)
    2303             : {
    2304           0 :     return getImplementationName_StringResourceWithStorageImpl();
    2305             : }
    2306             : 
    2307           0 : sal_Bool StringResourceWithStorageImpl::supportsService( const OUString& rServiceName ) throw (RuntimeException, std::exception)
    2308             : {
    2309           0 :     return cppu::supportsService(this, rServiceName);
    2310             : }
    2311             : 
    2312           0 : Sequence< OUString > StringResourceWithStorageImpl::getSupportedServiceNames(  ) throw (RuntimeException, std::exception)
    2313             : {
    2314           0 :     return getSupportedServiceNames_StringResourceWithStorageImpl();
    2315             : }
    2316             : 
    2317             : 
    2318             : // XInitialization
    2319             : 
    2320             : 
    2321           0 : void StringResourceWithStorageImpl::initialize( const Sequence< Any >& aArguments )
    2322             :     throw (Exception, RuntimeException, std::exception)
    2323             : {
    2324           0 :     ::osl::MutexGuard aGuard( getMutex() );
    2325             : 
    2326           0 :     if ( aArguments.getLength() != 5 )
    2327             :     {
    2328             :         throw RuntimeException(
    2329           0 :             "StringResourceWithStorageImpl::initialize: invalid number of arguments!" );
    2330             :     }
    2331             : 
    2332           0 :     bool bOk = (aArguments[0] >>= m_xStorage);
    2333           0 :     if( bOk && !m_xStorage.is() )
    2334           0 :         bOk = false;
    2335             : 
    2336           0 :     if( !bOk )
    2337             :     {
    2338           0 :         OUString errorMsg("StringResourceWithStorageImpl::initialize: invalid storage");
    2339           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
    2340             :     }
    2341             : 
    2342           0 :     implInitializeCommonParameters( aArguments );
    2343           0 : }
    2344             : 
    2345             : 
    2346             : // Forwarding calls to base class
    2347             : 
    2348             : // XModifyBroadcaster
    2349           0 : void StringResourceWithStorageImpl::addModifyListener( const Reference< XModifyListener >& aListener )
    2350             :     throw (RuntimeException, std::exception)
    2351             : {
    2352           0 :     StringResourceImpl::addModifyListener( aListener );
    2353           0 : }
    2354           0 : void StringResourceWithStorageImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
    2355             :     throw (RuntimeException, std::exception)
    2356             : {
    2357           0 :     StringResourceImpl::removeModifyListener( aListener );
    2358           0 : }
    2359             : 
    2360             : // XStringResourceResolver
    2361           0 : OUString StringResourceWithStorageImpl::resolveString( const OUString& ResourceID )
    2362             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
    2363             : {
    2364           0 :     return StringResourceImpl::resolveString( ResourceID ) ;
    2365             : }
    2366           0 : OUString StringResourceWithStorageImpl::resolveStringForLocale( const OUString& ResourceID, const Locale& locale )
    2367             :     throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
    2368             : {
    2369           0 :     return StringResourceImpl::resolveStringForLocale( ResourceID, locale );
    2370             : }
    2371           0 : sal_Bool StringResourceWithStorageImpl::hasEntryForId( const OUString& ResourceID )
    2372             :     throw (RuntimeException, std::exception)
    2373             : {
    2374           0 :     return StringResourceImpl::hasEntryForId( ResourceID ) ;
    2375             : }
    2376           0 : sal_Bool StringResourceWithStorageImpl::hasEntryForIdAndLocale( const OUString& ResourceID,
    2377             :     const Locale& locale )
    2378             :         throw (RuntimeException, std::exception)
    2379             : {
    2380           0 :     return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale );
    2381             : }
    2382           0 : Sequence< OUString > StringResourceWithStorageImpl::getResourceIDs(  )
    2383             :     throw (RuntimeException, std::exception)
    2384             : {
    2385           0 :     return StringResourceImpl::getResourceIDs();
    2386             : }
    2387           0 : Sequence< OUString > StringResourceWithStorageImpl::getResourceIDsForLocale
    2388             :     ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException, std::exception)
    2389             : {
    2390           0 :     return StringResourceImpl::getResourceIDsForLocale( locale );
    2391             : }
    2392           0 : Locale StringResourceWithStorageImpl::getCurrentLocale()
    2393             :     throw (RuntimeException, std::exception)
    2394             : {
    2395           0 :     return StringResourceImpl::getCurrentLocale();
    2396             : }
    2397           0 : Locale StringResourceWithStorageImpl::getDefaultLocale(  )
    2398             :     throw (RuntimeException, std::exception)
    2399             : {
    2400           0 :     return StringResourceImpl::getDefaultLocale();
    2401             : }
    2402           0 : Sequence< Locale > StringResourceWithStorageImpl::getLocales(  )
    2403             :     throw (RuntimeException, std::exception)
    2404             : {
    2405           0 :     return StringResourceImpl::getLocales();
    2406             : }
    2407             : 
    2408             : // XStringResourceManager
    2409           0 : sal_Bool StringResourceWithStorageImpl::isReadOnly()
    2410             :     throw (RuntimeException, std::exception)
    2411             : {
    2412           0 :     return StringResourceImpl::isReadOnly();
    2413             : }
    2414           0 : void StringResourceWithStorageImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
    2415             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    2416             : {
    2417           0 :     StringResourceImpl::setCurrentLocale( locale, FindClosestMatch );
    2418           0 : }
    2419           0 : void StringResourceWithStorageImpl::setDefaultLocale( const Locale& locale )
    2420             :     throw (IllegalArgumentException, RuntimeException,NoSupportException, std::exception)
    2421             : {
    2422           0 :     StringResourceImpl::setDefaultLocale( locale );
    2423           0 : }
    2424           0 : void StringResourceWithStorageImpl::setString( const OUString& ResourceID, const OUString& Str )
    2425             :     throw (NoSupportException, RuntimeException, std::exception)
    2426             : {
    2427           0 :     StringResourceImpl::setString( ResourceID, Str );
    2428           0 : }
    2429           0 : void StringResourceWithStorageImpl::setStringForLocale
    2430             :     ( const OUString& ResourceID, const OUString& Str, const Locale& locale )
    2431             :         throw (NoSupportException, RuntimeException, std::exception)
    2432             : {
    2433           0 :     StringResourceImpl::setStringForLocale( ResourceID, Str, locale );
    2434           0 : }
    2435           0 : void StringResourceWithStorageImpl::removeId( const OUString& ResourceID )
    2436             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
    2437             : {
    2438           0 :     StringResourceImpl::removeId( ResourceID );
    2439           0 : }
    2440           0 : void StringResourceWithStorageImpl::removeIdForLocale( const OUString& ResourceID, const Locale& locale )
    2441             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
    2442             : {
    2443           0 :     StringResourceImpl::removeIdForLocale( ResourceID, locale );
    2444           0 : }
    2445           0 : void StringResourceWithStorageImpl::newLocale( const Locale& locale )
    2446             :     throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
    2447             : {
    2448           0 :     StringResourceImpl::newLocale( locale );
    2449           0 : }
    2450           0 : void StringResourceWithStorageImpl::removeLocale( const Locale& locale )
    2451             :     throw (IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
    2452             : {
    2453           0 :     StringResourceImpl::removeLocale( locale );
    2454           0 : }
    2455           0 : sal_Int32 StringResourceWithStorageImpl::getUniqueNumericId(  )
    2456             :     throw (RuntimeException, NoSupportException, std::exception)
    2457             : {
    2458           0 :     return StringResourceImpl::getUniqueNumericId();
    2459             : }
    2460             : 
    2461             : // XStringResourcePersistence
    2462           0 : void StringResourceWithStorageImpl::store()
    2463             :     throw (NoSupportException, Exception, RuntimeException, std::exception)
    2464             : {
    2465           0 :     ::osl::MutexGuard aGuard( getMutex() );
    2466           0 :     implCheckReadOnly( "StringResourceWithStorageImpl::store(): Read only" );
    2467             : 
    2468           0 :     bool bUsedForStore = true;
    2469           0 :     bool bStoreAll = m_bStorageChanged;
    2470           0 :     m_bStorageChanged = false;
    2471           0 :     if( !m_bModified && !bStoreAll )
    2472           0 :         return;
    2473             : 
    2474           0 :     implStoreAtStorage( m_aNameBase, m_aComment, m_xStorage, bUsedForStore, bStoreAll );
    2475           0 :     m_bModified = false;
    2476             : }
    2477             : 
    2478           0 : sal_Bool StringResourceWithStorageImpl::isModified(  )
    2479             :     throw (RuntimeException, std::exception)
    2480             : {
    2481           0 :     return StringResourcePersistenceImpl::isModified();
    2482             : }
    2483           0 : void StringResourceWithStorageImpl::setComment( const OUString& Comment )
    2484             :     throw (::com::sun::star::uno::RuntimeException, std::exception)
    2485             : {
    2486           0 :     StringResourcePersistenceImpl::setComment( Comment );
    2487           0 : }
    2488           0 : void StringResourceWithStorageImpl::storeToStorage( const Reference< XStorage >& Storage,
    2489             :     const OUString& NameBase, const OUString& Comment )
    2490             :         throw (Exception, RuntimeException, std::exception)
    2491             : {
    2492           0 :     StringResourcePersistenceImpl::storeToStorage( Storage, NameBase, Comment );
    2493           0 : }
    2494           0 : void StringResourceWithStorageImpl::storeToURL( const OUString& URL,
    2495             :     const OUString& NameBase, const OUString& Comment,
    2496             :     const Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
    2497             :         throw (Exception, RuntimeException, std::exception)
    2498             : {
    2499           0 :     StringResourcePersistenceImpl::storeToURL( URL, NameBase, Comment, Handler );
    2500           0 : }
    2501           0 : Sequence< ::sal_Int8 > StringResourceWithStorageImpl::exportBinary(  )
    2502             :     throw (RuntimeException, std::exception)
    2503             : {
    2504           0 :     return StringResourcePersistenceImpl::exportBinary();
    2505             : }
    2506           0 : void StringResourceWithStorageImpl::importBinary( const Sequence< ::sal_Int8 >& Data )
    2507             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    2508             : {
    2509           0 :     StringResourcePersistenceImpl::importBinary( Data );
    2510           0 : }
    2511             : 
    2512             : 
    2513             : // XStringResourceWithStorage
    2514             : 
    2515           0 : void StringResourceWithStorageImpl::storeAsStorage( const Reference< XStorage >& Storage )
    2516             :     throw (Exception, RuntimeException, std::exception)
    2517             : {
    2518           0 :     setStorage( Storage );
    2519           0 :     store();
    2520           0 : }
    2521             : 
    2522           0 : void StringResourceWithStorageImpl::setStorage( const Reference< XStorage >& Storage )
    2523             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    2524             : {
    2525           0 :     ::osl::MutexGuard aGuard( getMutex() );
    2526             : 
    2527           0 :     if( !Storage.is() )
    2528             :     {
    2529           0 :         OUString errorMsg( "StringResourceWithStorageImpl::setStorage: invalid storage" );
    2530           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
    2531             :     }
    2532             : 
    2533           0 :     implLoadAllLocales();
    2534             : 
    2535           0 :     m_xStorage = Storage;
    2536           0 :     m_bStorageChanged = true;
    2537           0 : }
    2538             : 
    2539             : 
    2540             : 
    2541             : // Private helper methods
    2542             : 
    2543             : 
    2544             : // Scan locale properties files
    2545           0 : void StringResourceWithStorageImpl::implScanLocales( void )
    2546             : {
    2547           0 :     Reference< container::XNameAccess > xNameAccess( m_xStorage, UNO_QUERY );
    2548           0 :     if( xNameAccess.is() )
    2549             :     {
    2550           0 :         Sequence< OUString > aContentSeq = xNameAccess->getElementNames();
    2551           0 :         implScanLocaleNames( aContentSeq );
    2552             :     }
    2553             : 
    2554           0 :     implLoadAllLocales();
    2555           0 : }
    2556             : 
    2557             : // Loading
    2558           0 : bool StringResourceWithStorageImpl::implLoadLocale( LocaleItem* pLocaleItem )
    2559             : {
    2560           0 :     bool bSuccess = false;
    2561             :     try
    2562             :     {
    2563           0 :         OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase );
    2564           0 :         aStreamName += ".properties";
    2565             : 
    2566             :         Reference< io::XStream > xElementStream =
    2567           0 :             m_xStorage->openStreamElement( aStreamName, ElementModes::READ );
    2568             : 
    2569           0 :         if( xElementStream.is() )
    2570             :         {
    2571           0 :             Reference< io::XInputStream > xInputStream = xElementStream->getInputStream();
    2572           0 :             if( xInputStream.is() )
    2573             :             {
    2574           0 :                 bSuccess = StringResourcePersistenceImpl::implReadPropertiesFile( pLocaleItem, xInputStream );
    2575           0 :                 xInputStream->closeInput();
    2576           0 :             }
    2577           0 :         }
    2578             :     }
    2579           0 :     catch( uno::Exception& )
    2580             :     {}
    2581             : 
    2582           0 :     return bSuccess;
    2583             : }
    2584             : 
    2585             : 
    2586             : 
    2587             : // StringResourceWithLocationImpl
    2588             : 
    2589             : 
    2590             : // component operations
    2591           0 : static Sequence< OUString > getSupportedServiceNames_StringResourceWithLocationImpl()
    2592             : {
    2593           0 :     Sequence< OUString > names(1);
    2594           0 :     names[0] = "com.sun.star.resource.StringResourceWithLocation";
    2595           0 :     return names;
    2596             : }
    2597             : 
    2598           2 : static OUString getImplementationName_StringResourceWithLocationImpl()
    2599             : {
    2600           2 :     return OUString( "com.sun.star.comp.scripting.StringResourceWithLocation" );
    2601             : }
    2602             : 
    2603           0 : static Reference< XInterface > SAL_CALL create_StringResourceWithLocationImpl(
    2604             :     Reference< XComponentContext > const & xContext )
    2605             : {
    2606           0 :     return static_cast< ::cppu::OWeakObject * >( new StringResourceWithLocationImpl( xContext ) );
    2607             : }
    2608             : 
    2609             : 
    2610             : 
    2611           0 : StringResourceWithLocationImpl::StringResourceWithLocationImpl( const Reference< XComponentContext >& rxContext )
    2612             :     : StringResourceWithLocationImpl_BASE( rxContext )
    2613           0 :     , m_bLocationChanged( false )
    2614             : {
    2615           0 : }
    2616             : 
    2617             : 
    2618             : 
    2619           0 : StringResourceWithLocationImpl::~StringResourceWithLocationImpl()
    2620             : {
    2621           0 : }
    2622             : 
    2623             : 
    2624             : // XServiceInfo
    2625             : 
    2626             : 
    2627           0 : OUString StringResourceWithLocationImpl::getImplementationName(  ) throw (RuntimeException, std::exception)
    2628             : {
    2629           0 :     return getImplementationName_StringResourceWithLocationImpl();
    2630             : }
    2631             : 
    2632           0 : sal_Bool StringResourceWithLocationImpl::supportsService( const OUString& rServiceName ) throw (RuntimeException, std::exception)
    2633             : {
    2634           0 :     return cppu::supportsService(this, rServiceName);
    2635             : }
    2636             : 
    2637           0 : Sequence< OUString > StringResourceWithLocationImpl::getSupportedServiceNames(  ) throw (RuntimeException, std::exception)
    2638             : {
    2639           0 :     return getSupportedServiceNames_StringResourceWithLocationImpl();
    2640             : }
    2641             : 
    2642             : 
    2643             : // XInitialization
    2644             : 
    2645             : 
    2646           0 : void StringResourceWithLocationImpl::initialize( const Sequence< Any >& aArguments )
    2647             :     throw (Exception, RuntimeException, std::exception)
    2648             : {
    2649           0 :     ::osl::MutexGuard aGuard( getMutex() );
    2650             : 
    2651           0 :     if ( aArguments.getLength() != 6 )
    2652             :     {
    2653             :         throw RuntimeException(
    2654           0 :             "XInitialization::initialize: invalid number of arguments!" );
    2655             :     }
    2656             : 
    2657           0 :     bool bOk = (aArguments[0] >>= m_aLocation);
    2658           0 :     sal_Int32 nLen = m_aLocation.getLength();
    2659           0 :     if( bOk && nLen == 0 )
    2660             :     {
    2661           0 :         bOk = false;
    2662             :     }
    2663             :     else
    2664             :     {
    2665           0 :         if( m_aLocation[nLen - 1] != '/' )
    2666           0 :             m_aLocation += "/";
    2667             :     }
    2668             : 
    2669           0 :     if( !bOk )
    2670             :     {
    2671           0 :         OUString errorMsg("XInitialization::initialize: invalid URL");
    2672           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
    2673             :     }
    2674             : 
    2675             : 
    2676           0 :     bOk = (aArguments[5] >>= m_xInteractionHandler);
    2677           0 :     if( !bOk )
    2678             :     {
    2679           0 :         OUString errorMsg("StringResourceWithStorageImpl::initialize: invalid type");
    2680           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 5 );
    2681             :     }
    2682             : 
    2683           0 :     implInitializeCommonParameters( aArguments );
    2684           0 : }
    2685             : 
    2686             : 
    2687             : // Forwarding calls to base class
    2688             : 
    2689             : // XModifyBroadcaster
    2690           0 : void StringResourceWithLocationImpl::addModifyListener( const Reference< XModifyListener >& aListener )
    2691             :     throw (RuntimeException, std::exception)
    2692             : {
    2693           0 :     StringResourceImpl::addModifyListener( aListener );
    2694           0 : }
    2695           0 : void StringResourceWithLocationImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
    2696             :     throw (RuntimeException, std::exception)
    2697             : {
    2698           0 :     StringResourceImpl::removeModifyListener( aListener );
    2699           0 : }
    2700             : 
    2701             : // XStringResourceResolver
    2702           0 : OUString StringResourceWithLocationImpl::resolveString( const OUString& ResourceID )
    2703             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
    2704             : {
    2705           0 :     return StringResourceImpl::resolveString( ResourceID ) ;
    2706             : }
    2707           0 : OUString StringResourceWithLocationImpl::resolveStringForLocale( const OUString& ResourceID, const Locale& locale )
    2708             :     throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
    2709             : {
    2710           0 :     return StringResourceImpl::resolveStringForLocale( ResourceID, locale );
    2711             : }
    2712           0 : sal_Bool StringResourceWithLocationImpl::hasEntryForId( const OUString& ResourceID )
    2713             :     throw (RuntimeException, std::exception)
    2714             : {
    2715           0 :     return StringResourceImpl::hasEntryForId( ResourceID ) ;
    2716             : }
    2717           0 : sal_Bool StringResourceWithLocationImpl::hasEntryForIdAndLocale( const OUString& ResourceID,
    2718             :     const Locale& locale )
    2719             :         throw (RuntimeException, std::exception)
    2720             : {
    2721           0 :     return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale );
    2722             : }
    2723           0 : Sequence< OUString > StringResourceWithLocationImpl::getResourceIDs(  )
    2724             :     throw (RuntimeException, std::exception)
    2725             : {
    2726           0 :     return StringResourceImpl::getResourceIDs();
    2727             : }
    2728           0 : Sequence< OUString > StringResourceWithLocationImpl::getResourceIDsForLocale
    2729             :     ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException, std::exception)
    2730             : {
    2731           0 :     return StringResourceImpl::getResourceIDsForLocale( locale );
    2732             : }
    2733           0 : Locale StringResourceWithLocationImpl::getCurrentLocale()
    2734             :     throw (RuntimeException, std::exception)
    2735             : {
    2736           0 :     return StringResourceImpl::getCurrentLocale();
    2737             : }
    2738           0 : Locale StringResourceWithLocationImpl::getDefaultLocale(  )
    2739             :     throw (RuntimeException, std::exception)
    2740             : {
    2741           0 :     return StringResourceImpl::getDefaultLocale();
    2742             : }
    2743           0 : Sequence< Locale > StringResourceWithLocationImpl::getLocales(  )
    2744             :     throw (RuntimeException, std::exception)
    2745             : {
    2746           0 :     return StringResourceImpl::getLocales();
    2747             : }
    2748             : 
    2749             : // XStringResourceManager
    2750           0 : sal_Bool StringResourceWithLocationImpl::isReadOnly()
    2751             :     throw (RuntimeException, std::exception)
    2752             : {
    2753           0 :     return StringResourceImpl::isReadOnly();
    2754             : }
    2755           0 : void StringResourceWithLocationImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
    2756             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    2757             : {
    2758           0 :     StringResourceImpl::setCurrentLocale( locale, FindClosestMatch );
    2759           0 : }
    2760           0 : void StringResourceWithLocationImpl::setDefaultLocale( const Locale& locale )
    2761             :     throw (IllegalArgumentException, RuntimeException,NoSupportException, std::exception)
    2762             : {
    2763           0 :     StringResourceImpl::setDefaultLocale( locale );
    2764           0 : }
    2765           0 : void StringResourceWithLocationImpl::setString( const OUString& ResourceID, const OUString& Str )
    2766             :     throw (NoSupportException, RuntimeException, std::exception)
    2767             : {
    2768           0 :     StringResourceImpl::setString( ResourceID, Str );
    2769           0 : }
    2770           0 : void StringResourceWithLocationImpl::setStringForLocale
    2771             :     ( const OUString& ResourceID, const OUString& Str, const Locale& locale )
    2772             :         throw (NoSupportException, RuntimeException, std::exception)
    2773             : {
    2774           0 :     StringResourceImpl::setStringForLocale( ResourceID, Str, locale );
    2775           0 : }
    2776           0 : void StringResourceWithLocationImpl::removeId( const OUString& ResourceID )
    2777             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
    2778             : {
    2779           0 :     StringResourceImpl::removeId( ResourceID );
    2780           0 : }
    2781           0 : void StringResourceWithLocationImpl::removeIdForLocale( const OUString& ResourceID, const Locale& locale )
    2782             :     throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
    2783             : {
    2784           0 :     StringResourceImpl::removeIdForLocale( ResourceID, locale );
    2785           0 : }
    2786           0 : void StringResourceWithLocationImpl::newLocale( const Locale& locale )
    2787             :     throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
    2788             : {
    2789           0 :     StringResourceImpl::newLocale( locale );
    2790           0 : }
    2791           0 : void StringResourceWithLocationImpl::removeLocale( const Locale& locale )
    2792             :     throw (IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
    2793             : {
    2794           0 :     StringResourceImpl::removeLocale( locale );
    2795           0 : }
    2796           0 : sal_Int32 StringResourceWithLocationImpl::getUniqueNumericId(  )
    2797             :     throw (RuntimeException, NoSupportException, std::exception)
    2798             : {
    2799           0 :     return StringResourceImpl::getUniqueNumericId();
    2800             : }
    2801             : 
    2802             : // XStringResourcePersistence
    2803           0 : void StringResourceWithLocationImpl::store()
    2804             :     throw (NoSupportException, Exception, RuntimeException, std::exception)
    2805             : {
    2806           0 :     ::osl::MutexGuard aGuard( getMutex() );
    2807           0 :     implCheckReadOnly( "StringResourceWithLocationImpl::store(): Read only" );
    2808             : 
    2809           0 :     bool bUsedForStore = true;
    2810           0 :     bool bStoreAll = m_bLocationChanged;
    2811           0 :     m_bLocationChanged = false;
    2812           0 :     if( !m_bModified && !bStoreAll )
    2813           0 :         return;
    2814             : 
    2815           0 :     Reference< ucb::XSimpleFileAccess3 > xFileAccess = getFileAccess();
    2816             :     implStoreAtLocation( m_aLocation, m_aNameBase, m_aComment,
    2817           0 :         xFileAccess, bUsedForStore, bStoreAll );
    2818           0 :     m_bModified = false;
    2819             : }
    2820             : 
    2821           0 : sal_Bool StringResourceWithLocationImpl::isModified(  )
    2822             :     throw (RuntimeException, std::exception)
    2823             : {
    2824           0 :     return StringResourcePersistenceImpl::isModified();
    2825             : }
    2826           0 : void StringResourceWithLocationImpl::setComment( const OUString& Comment )
    2827             :     throw (::com::sun::star::uno::RuntimeException, std::exception)
    2828             : {
    2829           0 :     StringResourcePersistenceImpl::setComment( Comment );
    2830           0 : }
    2831           0 : void StringResourceWithLocationImpl::storeToStorage( const Reference< XStorage >& Storage,
    2832             :     const OUString& NameBase, const OUString& Comment )
    2833             :         throw (Exception, RuntimeException, std::exception)
    2834             : {
    2835           0 :     StringResourcePersistenceImpl::storeToStorage( Storage, NameBase, Comment );
    2836           0 : }
    2837           0 : void StringResourceWithLocationImpl::storeToURL( const OUString& URL,
    2838             :     const OUString& NameBase, const OUString& Comment,
    2839             :     const Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
    2840             :         throw (Exception, RuntimeException, std::exception)
    2841             : {
    2842           0 :     StringResourcePersistenceImpl::storeToURL( URL, NameBase, Comment, Handler );
    2843           0 : }
    2844           0 : Sequence< ::sal_Int8 > StringResourceWithLocationImpl::exportBinary(  )
    2845             :     throw (RuntimeException, std::exception)
    2846             : {
    2847           0 :     return StringResourcePersistenceImpl::exportBinary();
    2848             : }
    2849           0 : void StringResourceWithLocationImpl::importBinary( const Sequence< ::sal_Int8 >& Data )
    2850             :     throw (IllegalArgumentException, RuntimeException, std::exception)
    2851             : {
    2852           0 :     StringResourcePersistenceImpl::importBinary( Data );
    2853           0 : }
    2854             : 
    2855             : 
    2856             : // XStringResourceWithLocation
    2857             : 
    2858             : // XStringResourceWithLocation
    2859           0 : void StringResourceWithLocationImpl::storeAsURL( const OUString& URL )
    2860             :     throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
    2861             : {
    2862           0 :     setURL( URL );
    2863           0 :     store();
    2864           0 : }
    2865             : 
    2866           0 : void StringResourceWithLocationImpl::setURL( const OUString& URL )
    2867             :     throw (css::lang::IllegalArgumentException,
    2868             :            css::lang::NoSupportException,
    2869             :            css::uno::RuntimeException, std::exception)
    2870             : {
    2871           0 :     ::osl::MutexGuard aGuard( getMutex() );
    2872           0 :     implCheckReadOnly( "StringResourceWithLocationImpl::setURL(): Read only" );
    2873             : 
    2874           0 :     sal_Int32 nLen = URL.getLength();
    2875           0 :     if( nLen == 0 )
    2876             :     {
    2877           0 :         OUString errorMsg( "StringResourceWithLocationImpl::setURL: invalid URL" );
    2878           0 :         throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
    2879             :     }
    2880             : 
    2881           0 :     implLoadAllLocales();
    2882             : 
    2883             :     // Delete files at old location
    2884           0 :     bool bUsedForStore = false;
    2885           0 :     bool bStoreAll = false;
    2886           0 :     bool bKillAll = true;
    2887             :     implStoreAtLocation( m_aLocation, m_aNameBase, m_aComment,
    2888           0 :         getFileAccess(), bUsedForStore, bStoreAll, bKillAll );
    2889             : 
    2890           0 :     m_aLocation = URL;
    2891           0 :     m_bLocationChanged = true;
    2892           0 : }
    2893             : 
    2894             : 
    2895             : 
    2896             : // Private helper methods
    2897             : 
    2898             : 
    2899             : // Scan locale properties files
    2900           0 : void StringResourceWithLocationImpl::implScanLocales( void )
    2901             : {
    2902           0 :     const Reference< ucb::XSimpleFileAccess3 > xFileAccess = getFileAccess();
    2903           0 :     if( xFileAccess.is() && xFileAccess->isFolder( m_aLocation ) )
    2904             :     {
    2905           0 :         Sequence< OUString > aContentSeq = xFileAccess->getFolderContents( m_aLocation, false );
    2906           0 :         implScanLocaleNames( aContentSeq );
    2907           0 :     }
    2908           0 : }
    2909             : 
    2910             : // Loading
    2911           0 : bool StringResourceWithLocationImpl::implLoadLocale( LocaleItem* pLocaleItem )
    2912             : {
    2913           0 :     bool bSuccess = false;
    2914             : 
    2915           0 :     const Reference< ucb::XSimpleFileAccess3 > xFileAccess = getFileAccess();
    2916           0 :     if( xFileAccess.is() )
    2917             :     {
    2918             :         OUString aCompleteFileName =
    2919           0 :             implGetPathForLocaleItem( pLocaleItem, m_aNameBase, m_aLocation );
    2920             : 
    2921           0 :         Reference< io::XInputStream > xInputStream;
    2922             :         try
    2923             :         {
    2924           0 :             xInputStream = xFileAccess->openFileRead( aCompleteFileName );
    2925             :         }
    2926           0 :         catch( Exception& )
    2927             :         {}
    2928           0 :         if( xInputStream.is() )
    2929             :         {
    2930           0 :             bSuccess = StringResourcePersistenceImpl::implReadPropertiesFile( pLocaleItem, xInputStream );
    2931           0 :             xInputStream->closeInput();
    2932           0 :         }
    2933             :     }
    2934             : 
    2935           0 :     return bSuccess;
    2936             : }
    2937             : 
    2938           0 : const Reference< ucb::XSimpleFileAccess3 > StringResourceWithLocationImpl::getFileAccess( void )
    2939             : {
    2940           0 :     ::osl::MutexGuard aGuard( getMutex() );
    2941             : 
    2942           0 :     if( !m_xSFI.is() )
    2943             :     {
    2944           0 :         m_xSFI = ucb::SimpleFileAccess::create(m_xContext);
    2945             : 
    2946           0 :         if( m_xSFI.is() && m_xInteractionHandler.is() )
    2947           0 :             m_xSFI->setInteractionHandler( m_xInteractionHandler );
    2948             :     }
    2949           0 :     return m_xSFI;
    2950             : }
    2951             : 
    2952             : 
    2953             : 
    2954             : // component export operations
    2955             : 
    2956             : 
    2957             : static const struct ::cppu::ImplementationEntry s_component_entries [] =
    2958             : {
    2959             :     {
    2960             :         create_StringResourceImpl, getImplementationName_StringResourceImpl,
    2961             :         getSupportedServiceNames_StringResourceImpl,
    2962             :         ::cppu::createSingleComponentFactory,
    2963             :         0, 0
    2964             :     },
    2965             :     {
    2966             :         create_StringResourceWithLocationImpl, getImplementationName_StringResourceWithLocationImpl,
    2967             :         getSupportedServiceNames_StringResourceWithLocationImpl,
    2968             :         ::cppu::createSingleComponentFactory,
    2969             :         0, 0
    2970             :     },
    2971             :     {
    2972             :         create_StringResourceWithStorageImpl, getImplementationName_StringResourceWithStorageImpl,
    2973             :         getSupportedServiceNames_StringResourceWithStorageImpl,
    2974             :         ::cppu::createSingleComponentFactory,
    2975             :         0, 0
    2976             :     },
    2977             :     { 0, 0, 0, 0, 0, 0 }
    2978             : };
    2979             : 
    2980             : 
    2981             : 
    2982             : }   // namespace dlgprov
    2983             : 
    2984             : 
    2985             : 
    2986             : 
    2987             : // component exports
    2988             : 
    2989             : 
    2990             : extern "C"
    2991             : {
    2992           2 :     SAL_DLLPUBLIC_EXPORT void * SAL_CALL stringresource_component_getFactory(
    2993             :         const sal_Char * pImplName, void * pServiceManager,
    2994             :         void * pRegistryKey )
    2995             :     {
    2996             :         return ::cppu::component_getFactoryHelper(
    2997           2 :             pImplName, pServiceManager, pRegistryKey, ::stringresource::s_component_entries );
    2998             :     }
    2999           6 : }
    3000             : 
    3001             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10