Abstract over Tokens algorithm
Change-Id: I16347d52dd7c102c7bf6a8fd2926e61e6cf75c0b
This commit is contained in:
parent
6dc48ef517
commit
6ad51a071c
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include <sal/config.h>
|
#include <sal/config.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include <com/sun/star/ucb/UniversalContentBroker.hpp>
|
#include <com/sun/star/ucb/UniversalContentBroker.hpp>
|
||||||
#include <comphelper/processfactory.hxx>
|
#include <comphelper/processfactory.hxx>
|
||||||
#include <unotools/tempfile.hxx>
|
#include <unotools/tempfile.hxx>
|
||||||
@ -159,28 +161,80 @@ OUString ConstructTempDir_Impl( const OUString* pParent )
|
|||||||
return aName;
|
return aName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
*token = m_show ? OUString::number(m_value) : OUString();
|
||||||
|
++m_value;
|
||||||
|
m_show = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static sal_uInt32 globalValue;
|
||||||
|
|
||||||
|
sal_uInt32 m_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
sal_uInt32 UniqueTokens::globalValue = SAL_MAX_UINT32;
|
||||||
|
|
||||||
OUString lcl_createName(
|
OUString lcl_createName(
|
||||||
const OUString& rLeadingChars, unsigned long nSeed, sal_Int16 nRadix,
|
const OUString& rLeadingChars, Tokens & tokens, const OUString* pExtension,
|
||||||
bool bFirst, const OUString* pExtension, const OUString* pParent,
|
const OUString* pParent, bool bDirectory, bool bKeep, bool bLock)
|
||||||
bool bDirectory, bool bKeep, bool bLock)
|
|
||||||
{
|
{
|
||||||
// 36 ** 6 == 2176782336
|
OUString aName = ConstructTempDir_Impl( pParent ) + rLeadingChars;;
|
||||||
unsigned long const nMaxRadix = 36;
|
OUString token;
|
||||||
unsigned long const nMax = (nMaxRadix*nMaxRadix*nMaxRadix*nMaxRadix*nMaxRadix*nMaxRadix);
|
while (tokens.next(&token))
|
||||||
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 );
|
OUString aTmp( aName + token );
|
||||||
if ( bUseNumber )
|
|
||||||
aTmp += OUString::number(i, nRadix);
|
|
||||||
bUseNumber = true;
|
|
||||||
if ( pExtension )
|
if ( pExtension )
|
||||||
aTmp += *pExtension;
|
aTmp += *pExtension;
|
||||||
else
|
else
|
||||||
@ -230,90 +284,9 @@ OUString lcl_createName(
|
|||||||
return OUString();
|
return OUString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = (i + 1) % nMax;
|
}
|
||||||
if (i == nSeed) {
|
|
||||||
return OUString();
|
return OUString();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OUString lcl_createName_BROKEN(
|
|
||||||
const OUString& rLeadingChars, 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);
|
|
||||||
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 aTmp( aName );
|
|
||||||
if ( bUseNumber )
|
|
||||||
aTmp += OUString::number(nSeed, 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();
|
|
||||||
}
|
|
||||||
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
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nSeed = (nSeed + 1) % nMax;
|
|
||||||
if (i == nSeed) {
|
|
||||||
return OUString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OUString CreateTempName_Impl( const OUString* pParent, bool bKeep, bool bDir = true )
|
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
|
||||||
#endif
|
#endif
|
||||||
return lcl_createName_BROKEN(
|
UniqueTokens t;
|
||||||
aEyeCatcher, 36, true, 0, pParent, bDir, bKeep,
|
return lcl_createName(aEyeCatcher, t, 0, pParent, bDir, bKeep, false);
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OUString TempFile::CreateTempName()
|
OUString TempFile::CreateTempName()
|
||||||
@ -356,7 +328,8 @@ TempFile::TempFile( const OUString& rLeadingChars, bool _bStartWithZero, const O
|
|||||||
, bIsDirectory( bDirectory )
|
, bIsDirectory( bDirectory )
|
||||||
, bKillingFileEnabled( false )
|
, 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()
|
TempFile::~TempFile()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user