diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2014-05-19 11:22:12 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-05-19 11:22:12 +0200 |
commit | 6ad51a071c3de339a69b01865d7c4bf7cd6a57cf (patch) | |
tree | 455c1ba76c56dbb007ac50a3e3db2e8c01aed5d3 /unotools | |
parent | 6dc48ef517b60adb7cfe09a65773d4ff7d69489c (diff) |
Abstract over Tokens algorithm
Change-Id: I16347d52dd7c102c7bf6a8fd2926e61e6cf75c0b
Diffstat (limited to 'unotools')
-rw-r--r-- | unotools/source/ucbhelper/tempfile.cxx | 173 |
1 files changed, 73 insertions, 100 deletions
diff --git a/unotools/source/ucbhelper/tempfile.cxx b/unotools/source/ucbhelper/tempfile.cxx index 9fb5d25d5fb4..8d4152cf2100 100644 --- a/unotools/source/ucbhelper/tempfile.cxx +++ b/unotools/source/ucbhelper/tempfile.cxx @@ -19,6 +19,8 @@ #include <sal/config.h> +#include <cassert> + #include <com/sun/star/ucb/UniversalContentBroker.hpp> #include <comphelper/processfactory.hxx> #include <unotools/tempfile.hxx> @@ -159,106 +161,80 @@ OUString ConstructTempDir_Impl( const OUString* pParent ) return aName; } -OUString lcl_createName( - const OUString& rLeadingChars, unsigned long nSeed, sal_Int16 nRadix, - bool bFirst, const OUString* pExtension, const OUString* pParent, - bool bDirectory, bool bKeep, bool bLock) -{ - // 36 ** 6 == 2176782336 - unsigned long const nMaxRadix = 36; - unsigned long const nMax = (nMaxRadix*nMaxRadix*nMaxRadix*nMaxRadix*nMaxRadix*nMaxRadix); - nSeed %= nMax; - - // get correct directory - OUString aName = ConstructTempDir_Impl( pParent ); - - bool bUseNumber = bFirst; - // now use special naming scheme ( name takes leading chars and an index counting up from zero - aName += rLeadingChars; - for ( unsigned long i=nSeed;; ) - { - OUString aTmp( aName ); - if ( bUseNumber ) - aTmp += OUString::number(i, nRadix); - bUseNumber = true; - if ( pExtension ) - aTmp += *pExtension; - else - aTmp += ".tmp"; - if ( bDirectory ) - { - FileBase::RC err = Directory::create( aTmp ); - if ( err == FileBase::E_None ) - { - // !bKeep: only for creating a name, not a file or directory - if ( bKeep || Directory::remove( aTmp ) == FileBase::E_None ) - return aTmp; - else - return OUString(); - } - else if ( err != FileBase::E_EXIST ) - // if f.e. name contains invalid chars stop trying to create dirs - return OUString(); +class Tokens { +public: + virtual bool next(OUString *) = 0; + +protected: + virtual ~Tokens() {} // avoid warnings +}; + +class SequentialTokens: public Tokens { +public: + explicit SequentialTokens(bool showZero): m_value(0), m_show(showZero) {} + + bool next(OUString * token) SAL_OVERRIDE { + assert(token != 0); + if (m_value == SAL_MAX_UINT32) { + return false; } - else - { - DBG_ASSERT( bKeep, "Too expensive, use directory for creating name!" ); - File aFile( aTmp ); -#ifdef UNX - /* RW permission for the user only! */ - mode_t old_mode = umask(077); -#endif - FileBase::RC err = aFile.open(osl_File_OpenFlag_Create | (bLock ? 0 : osl_File_OpenFlag_NoLock)); -#ifdef UNX - umask(old_mode); -#endif - if ( err == FileBase::E_None || (bLock && err == FileBase::E_NOLCK) ) - { - aFile.close(); - return aTmp; - } - else if ( err != FileBase::E_EXIST ) - { - // if f.e. name contains invalid chars stop trying to create dirs - // but if there is a folder with such name proceed further + *token = m_show ? OUString::number(m_value) : OUString(); + ++m_value; + m_show = true; + return true; + } - DirectoryItem aTmpItem; - FileStatus aTmpStatus( osl_FileStatus_Mask_Type ); - if ( DirectoryItem::get( aTmp, aTmpItem ) != FileBase::E_None - || aTmpItem.getFileStatus( aTmpStatus ) != FileBase::E_None - || aTmpStatus.getFileType() != FileStatus::Directory ) - return OUString(); - } +private: + sal_uInt32 m_value; + bool m_show; +}; + +class UniqueTokens: public Tokens { +public: + UniqueTokens(): m_count(0) {} + + bool next(OUString * token) SAL_OVERRIDE { + assert(token != 0); + // Because of the shared globalValue, no single instance of UniqueTokens + // is guaranteed to exhaustively test all 36^6 possible values, but stop + // after that many attempts anyway: + sal_uInt32 radix = 36; + sal_uInt32 max = radix * radix * radix * radix * radix * radix; + // 36^6 == 2'176'782'336 < SAL_MAX_UINT32 == 4'294'967'295 + if (m_count == max) { + return false; } - i = (i + 1) % nMax; - if (i == nSeed) { - return OUString(); + sal_uInt32 v; + { + osl::MutexGuard g(osl::Mutex::getGlobalMutex()); + globalValue + = ((globalValue == SAL_MAX_UINT32 + ? Time::GetSystemTicks() : globalValue + 1) + % max); + v = globalValue; } + *token = OUString::number(v, radix); + ++m_count; + return true; } -} -OUString lcl_createName_BROKEN( - const OUString& rLeadingChars, sal_Int16 nRadix, - bool bFirst, const OUString* pExtension, const OUString* pParent, - bool bDirectory, bool bKeep, bool bLock) +private: + static sal_uInt32 globalValue; + + sal_uInt32 m_count; +}; + +sal_uInt32 UniqueTokens::globalValue = SAL_MAX_UINT32; + +OUString lcl_createName( + const OUString& rLeadingChars, Tokens & tokens, const OUString* pExtension, + const OUString* pParent, bool bDirectory, bool bKeep, bool bLock) { - // 36 ** 6 == 2176782336 - unsigned long const nMaxRadix = 36; - unsigned long const nMax = (nMaxRadix*nMaxRadix*nMaxRadix*nMaxRadix*nMaxRadix*nMaxRadix); - static unsigned long nSeed = Time::GetSystemTicks() % nMax; - - // get correct directory - OUString aName = ConstructTempDir_Impl( pParent ); - - bool bUseNumber = bFirst; - // now use special naming scheme ( name takes leading chars and an index counting up from zero - aName += rLeadingChars; - for ( unsigned long i=nSeed;; ) + OUString aName = ConstructTempDir_Impl( pParent ) + rLeadingChars;; + OUString token; + while (tokens.next(&token)) { - OUString aTmp( aName ); - if ( bUseNumber ) - aTmp += OUString::number(nSeed, nRadix); - bUseNumber = true; + OUString aTmp( aName + token ); if ( pExtension ) aTmp += *pExtension; else @@ -308,11 +284,8 @@ OUString lcl_createName_BROKEN( return OUString(); } } - nSeed = (nSeed + 1) % nMax; - if (i == nSeed) { - return OUString(); - } } + return OUString(); } OUString CreateTempName_Impl( const OUString* pParent, bool bKeep, bool bDir = true ) @@ -327,9 +300,8 @@ OUString CreateTempName_Impl( const OUString* pParent, bool bKeep, bool bDir = t } #endif #endif - return lcl_createName_BROKEN( - aEyeCatcher, 36, true, 0, pParent, bDir, bKeep, - false); + UniqueTokens t; + return lcl_createName(aEyeCatcher, t, 0, pParent, bDir, bKeep, false); } OUString TempFile::CreateTempName() @@ -356,7 +328,8 @@ TempFile::TempFile( const OUString& rLeadingChars, bool _bStartWithZero, const O , bIsDirectory( bDirectory ) , bKillingFileEnabled( false ) { - aName = lcl_createName(rLeadingChars, 0, 10, _bStartWithZero, pExtension, pParent, bDirectory, true, true); + SequentialTokens t(_bStartWithZero); + aName = lcl_createName(rLeadingChars, t, pExtension, pParent, bDirectory, true, true); } TempFile::~TempFile() |