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

Generated by: LCOV version 1.10