summaryrefslogtreecommitdiff
path: root/unotools
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2014-05-19 11:22:12 +0200
committerStephan Bergmann <sbergman@redhat.com>2014-05-19 11:22:12 +0200
commit6ad51a071c3de339a69b01865d7c4bf7cd6a57cf (patch)
tree455c1ba76c56dbb007ac50a3e3db2e8c01aed5d3 /unotools
parent6dc48ef517b60adb7cfe09a65773d4ff7d69489c (diff)
Abstract over Tokens algorithm
Change-Id: I16347d52dd7c102c7bf6a8fd2926e61e6cf75c0b
Diffstat (limited to 'unotools')
-rw-r--r--unotools/source/ucbhelper/tempfile.cxx173
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()