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

Generated by: LCOV version 1.10