[Libreoffice-commits] core.git: unotools/source

Stephan Bergmann sbergman at redhat.com
Mon May 19 02:22:46 PDT 2014


 unotools/source/ucbhelper/tempfile.cxx |  173 +++++++++++++--------------------
 1 file changed, 73 insertions(+), 100 deletions(-)

New commits:
commit 6ad51a071c3de339a69b01865d7c4bf7cd6a57cf
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon May 19 11:22:12 2014 +0200

    Abstract over Tokens algorithm
    
    Change-Id: I16347d52dd7c102c7bf6a8fd2926e61e6cf75c0b

diff --git a/unotools/source/ucbhelper/tempfile.cxx b/unotools/source/ucbhelper/tempfile.cxx
index 9fb5d25..8d4152c 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()


More information about the Libreoffice-commits mailing list