This commit is contained in:
Glenn Maynard
2005-09-03 18:40:21 +00:00
parent 4d2f2308bd
commit f9005f72b9
2 changed files with 149 additions and 143 deletions
+122 -116
View File
@@ -5,14 +5,14 @@
#include "RageLog.h" #include "RageLog.h"
/* Search for "beginning*containing*ending". */ /* Search for "beginning*containing*ending". */
void FileSet::GetFilesMatching(const CString &beginning, const CString &containing, const CString &ending, vector<CString> &out, bool bOnlyDirs) const void FileSet::GetFilesMatching( const CString &sBeginning, const CString &sContaining, const CString &sEnding, vector<CString> &asOut, bool bOnlyDirs ) const
{ {
/* "files" is a case-insensitive mapping, by filename. Use lower_bound to figure /* "files" is a case-insensitive mapping, by filename. Use lower_bound to figure
* out where to start. */ * out where to start. */
CString containing_lower = containing; CString sContainingLower = sContaining;
containing_lower.ToLower(); sContainingLower.ToLower();
set<File>::const_iterator i = files.lower_bound( File(beginning) ); set<File>::const_iterator i = files.lower_bound( File(sBeginning) );
for( ; i != files.end(); ++i ) for( ; i != files.end(); ++i )
{ {
const File &f = *i; const File &f = *i;
@@ -20,72 +20,72 @@ void FileSet::GetFilesMatching(const CString &beginning, const CString &containi
if( bOnlyDirs && !f.dir ) if( bOnlyDirs && !f.dir )
continue; continue;
/* Check beginning. Once we hit a filename that no longer matches beginning, /* Check sBeginning. Once we hit a filename that no longer matches sBeginning,
* we're past all possible matches in the sort, so stop. */ * we're past all possible matches in the sort, so stop. */
if( beginning.size() > f.name.size() ) if( sBeginning.size() > f.name.size() )
break; /* can't start with it */ break; /* can't start with it */
if( strnicmp(i->name, beginning, beginning.size()) ) if( strnicmp(i->name, sBeginning, sBeginning.size()) )
break; /* doesn't start with it */ break; /* doesn't start with it */
/* Position the end starts on: */ /* Position the end starts on: */
int end_pos = int(f.name.size())-int(ending.size()); int end_pos = int(f.name.size())-int(sEnding.size());
/* Check end. */ /* Check end. */
if( end_pos < 0 ) if( end_pos < 0 )
continue; /* can't end with it */ continue; /* can't end with it */
if( stricmp(f.name.c_str()+end_pos, ending) ) if( stricmp(f.name.c_str()+end_pos, sEnding) )
continue; /* doesn't end with it */ continue; /* doesn't end with it */
/* Check containing. Do this last, since it's the slowest (substring /* Check sContaining. Do this last, since it's the slowest (substring
* search instead of string match). */ * search instead of string match). */
if( containing.size() ) if( sContaining.size() )
{ {
CString name = f.name; CString name = f.name;
name.ToLower(); name.ToLower();
size_t pos = name.find( containing_lower, beginning.size() ); size_t pos = name.find( sContainingLower, sBeginning.size() );
if( pos == name.npos ) if( pos == name.npos )
continue; /* doesn't contain it */ continue; /* doesn't contain it */
if( pos + containing.size() > unsigned(end_pos) ) if( pos + sContaining.size() > unsigned(end_pos) )
continue; /* found it but it overlaps with the end */ continue; /* found it but it overlaps with the end */
} }
out.push_back( f.name ); asOut.push_back( f.name );
} }
} }
void FileSet::GetFilesEqualTo(const CString &str, vector<CString> &out, bool bOnlyDirs) const void FileSet::GetFilesEqualTo( const CString &sStr, vector<CString> &asOut, bool bOnlyDirs ) const
{ {
set<File>::const_iterator i = files.find( File(str) ); set<File>::const_iterator i = files.find( File(sStr) );
if( i == files.end() ) if( i == files.end() )
return; return;
if( bOnlyDirs && !i->dir ) if( bOnlyDirs && !i->dir )
return; return;
out.push_back( i->name ); asOut.push_back( i->name );
} }
RageFileManager::FileType FileSet::GetFileType(const CString &path ) const RageFileManager::FileType FileSet::GetFileType( const CString &sPath ) const
{ {
set<File>::const_iterator i = files.find( File(path) ); set<File>::const_iterator i = files.find( File(sPath) );
if( i == files.end() ) if( i == files.end() )
return RageFileManager::TYPE_NONE; return RageFileManager::TYPE_NONE;
return i->dir? RageFileManager::TYPE_DIR:RageFileManager::TYPE_FILE; return i->dir? RageFileManager::TYPE_DIR:RageFileManager::TYPE_FILE;
} }
int FileSet::GetFileSize(const CString &path) const int FileSet::GetFileSize( const CString &sPath ) const
{ {
set<File>::const_iterator i = files.find( File(path) ); set<File>::const_iterator i = files.find( File(sPath) );
if( i == files.end() ) if( i == files.end() )
return -1; return -1;
return i->size; return i->size;
} }
int FileSet::GetFileHash(const CString &path) const int FileSet::GetFileHash( const CString &sPath ) const
{ {
set<File>::const_iterator i = files.find( File(path) ); set<File>::const_iterator i = files.find( File(sPath) );
if( i == files.end() ) if( i == files.end() )
return -1; return -1;
return i->hash + i->size; return i->hash + i->size;
@@ -95,22 +95,22 @@ int FileSet::GetFileHash(const CString &path) const
* Given "foo/bar/baz/" or "foo/bar/baz", return "foo/bar/" and "baz". * Given "foo/bar/baz/" or "foo/bar/baz", return "foo/bar/" and "baz".
* "foo" -> "", "foo" * "foo" -> "", "foo"
*/ */
static void SplitPath( CString Path, CString &Dir, CString &Name ) static void SplitPath( CString sPath, CString &sDir, CString &sName )
{ {
CollapsePath( Path ); CollapsePath( sPath );
if( Path.Right(1) == "/" ) if( sPath.Right(1) == "/" )
Path.erase( Path.size()-1 ); sPath.erase( sPath.size()-1 );
size_t sep = Path.find_last_of( '/' ); size_t iSep = sPath.find_last_of( '/' );
if( sep == CString::npos ) if( iSep == CString::npos )
{ {
Dir = ""; sDir = "";
Name = Path; sName = sPath;
} }
else else
{ {
Dir = Path.substr( 0, sep+1 ); sDir = sPath.substr( 0, iSep+1 );
Name = Path.substr( sep+1 ); sName = sPath.substr( iSep+1 );
} }
} }
@@ -119,14 +119,14 @@ RageFileManager::FileType FilenameDB::GetFileType( const CString &sPath )
{ {
ASSERT( !m_Mutex.IsLockedByThisThread() ); ASSERT( !m_Mutex.IsLockedByThisThread() );
CString Dir, Name; CString sDir, sName;
SplitPath( sPath, Dir, Name ); SplitPath( sPath, sDir, sName );
if( Name == "/" ) if( sName == "/" )
return RageFileManager::TYPE_DIR; return RageFileManager::TYPE_DIR;
const FileSet *fs = GetFileSet( Dir ); const FileSet *fs = GetFileSet( sDir );
RageFileManager::FileType ret = fs->GetFileType( Name ); RageFileManager::FileType ret = fs->GetFileType( sName );
m_Mutex.Unlock(); /* locked by GetFileSet */ m_Mutex.Unlock(); /* locked by GetFileSet */
return ret; return ret;
} }
@@ -136,11 +136,11 @@ int FilenameDB::GetFileSize( const CString &sPath )
{ {
ASSERT( !m_Mutex.IsLockedByThisThread() ); ASSERT( !m_Mutex.IsLockedByThisThread() );
CString Dir, Name; CString sDir, sName;
SplitPath(sPath, Dir, Name); SplitPath( sPath, sDir, sName );
const FileSet *fs = GetFileSet( Dir ); const FileSet *fs = GetFileSet( sDir );
int ret = fs->GetFileSize(Name); int ret = fs->GetFileSize( sName );
m_Mutex.Unlock(); /* locked by GetFileSet */ m_Mutex.Unlock(); /* locked by GetFileSet */
return ret; return ret;
} }
@@ -149,23 +149,23 @@ int FilenameDB::GetFileHash( const CString &sPath )
{ {
ASSERT( !m_Mutex.IsLockedByThisThread() ); ASSERT( !m_Mutex.IsLockedByThisThread() );
CString Dir, Name; CString sDir, sName;
SplitPath(sPath, Dir, Name); SplitPath( sPath, sDir, sName );
const FileSet *fs = GetFileSet( Dir ); const FileSet *fs = GetFileSet( sDir );
int ret = fs->GetFileHash(Name); int ret = fs->GetFileHash( sName );
m_Mutex.Unlock(); /* locked by GetFileSet */ m_Mutex.Unlock(); /* locked by GetFileSet */
return ret; return ret;
} }
/* path should be fully collapsed, so we can operate in-place: no . or .. */ /* path should be fully collapsed, so we can operate in-place: no . or .. */
bool FilenameDB::ResolvePath(CString &path) bool FilenameDB::ResolvePath( CString &sPath )
{ {
if( path == "/" || path == "" ) if( sPath == "/" || sPath == "" )
return true; return true;
/* Split path into components. */ /* Split path into components. */
int begin = 0, size = -1; int iBegin = 0, iSize = -1;
/* Resolve each component. */ /* Resolve each component. */
CString ret = ""; CString ret = "";
@@ -174,8 +174,8 @@ bool FilenameDB::ResolvePath(CString &path)
static const CString slash("/"); static const CString slash("/");
while( 1 ) while( 1 )
{ {
split( path, slash, begin, size, true ); split( sPath, slash, iBegin, iSize, true );
if( begin == (int) path.size() ) if( iBegin == (int) sPath.size() )
break; break;
if( fs == NULL ) if( fs == NULL )
@@ -183,9 +183,9 @@ bool FilenameDB::ResolvePath(CString &path)
else else
m_Mutex.Lock(); /* for access to fs */ m_Mutex.Lock(); /* for access to fs */
CString p = path.substr( begin, size ); CString p = sPath.substr( iBegin, iSize );
ASSERT_M( p.size() != 1 || p[0] != '.', path ); // no . ASSERT_M( p.size() != 1 || p[0] != '.', sPath ); // no .
ASSERT_M( p.size() != 2 || p[0] != '.' || p[1] != '.', path ); // no .. ASSERT_M( p.size() != 2 || p[0] != '.' || p[1] != '.', sPath ); // no ..
set<File>::const_iterator it = fs->files.find( File(p) ); set<File>::const_iterator it = fs->files.find( File(p) );
/* If there were no matches, the path isn't found. */ /* If there were no matches, the path isn't found. */
@@ -202,53 +202,57 @@ bool FilenameDB::ResolvePath(CString &path)
m_Mutex.Unlock(); /* locked by GetFileSet */ m_Mutex.Unlock(); /* locked by GetFileSet */
} }
if( path.size() && path[path.size()-1] == '/' ) if( sPath.size() && sPath[sPath.size()-1] == '/' )
path = ret + "/"; sPath = ret + "/";
else else
path = ret; sPath = ret;
return true; return true;
} }
void FilenameDB::GetFilesMatching(const CString &dir, const CString &beginning, const CString &containing, const CString &ending, vector<CString> &out, bool bOnlyDirs) void FilenameDB::GetFilesMatching( const CString &sDir, const CString &sBeginning, const CString &sContaining, const CString &sEnding, vector<CString> &asOut, bool bOnlyDirs )
{ {
ASSERT( !m_Mutex.IsLockedByThisThread() ); ASSERT( !m_Mutex.IsLockedByThisThread() );
const FileSet *fs = GetFileSet( dir ); const FileSet *fs = GetFileSet( sDir );
fs->GetFilesMatching(beginning, containing, ending, out, bOnlyDirs); fs->GetFilesMatching( sBeginning, sContaining, sEnding, asOut, bOnlyDirs );
m_Mutex.Unlock(); /* locked by GetFileSet */ m_Mutex.Unlock(); /* locked by GetFileSet */
} }
void FilenameDB::GetFilesEqualTo(const CString &dir, const CString &fn, vector<CString> &out, bool bOnlyDirs) void FilenameDB::GetFilesEqualTo( const CString &sDir, const CString &sFile, vector<CString> &asOut, bool bOnlyDirs )
{ {
ASSERT( !m_Mutex.IsLockedByThisThread() ); ASSERT( !m_Mutex.IsLockedByThisThread() );
const FileSet *fs = GetFileSet( dir ); const FileSet *fs = GetFileSet( sDir );
fs->GetFilesEqualTo(fn, out, bOnlyDirs); fs->GetFilesEqualTo( sFile, asOut, bOnlyDirs );
m_Mutex.Unlock(); /* locked by GetFileSet */ m_Mutex.Unlock(); /* locked by GetFileSet */
} }
void FilenameDB::GetFilesSimpleMatch(const CString &dir, const CString &fn, vector<CString> &out, bool bOnlyDirs) void FilenameDB::GetFilesSimpleMatch( const CString &sDir, const CString &sMask, vector<CString> &asOut, bool bOnlyDirs )
{ {
/* Does this contain a wildcard? */ /* Does this contain a wildcard? */
size_t first_pos = fn.find_first_of('*'); size_t first_pos = sMask.find_first_of('*');
if(first_pos == fn.npos) if( first_pos == sMask.npos )
{ {
/* No; just do a regular search. */ /* No; just do a regular search. */
GetFilesEqualTo(dir, fn, out, bOnlyDirs); GetFilesEqualTo( sDir, sMask, asOut, bOnlyDirs );
} else { }
size_t second_pos = fn.find_first_of('*', first_pos+1); else
if(second_pos == fn.npos) {
size_t second_pos = sMask.find_first_of('*', first_pos+1);
if( second_pos == sMask.npos )
{ {
/* Only one *: "A*B". */ /* Only one *: "A*B". */
/* XXX: "_blank.png*.png" shouldn't match the file "_blank.png". */ /* XXX: "_blank.png*.png" shouldn't match the file "_blank.png". */
GetFilesMatching(dir, fn.substr(0, first_pos), "", fn.substr(first_pos+1), out, bOnlyDirs); GetFilesMatching( sDir, sMask.substr(0, first_pos), "", sMask.substr(first_pos+1), asOut, bOnlyDirs );
} else { }
else
{
/* Two *s: "A*B*C". */ /* Two *s: "A*B*C". */
GetFilesMatching(dir, GetFilesMatching( sDir,
fn.substr(0, first_pos), sMask.substr(0, first_pos),
fn.substr(first_pos+1, second_pos-first_pos-1), sMask.substr(first_pos+1, second_pos-first_pos-1),
fn.substr(second_pos+1), out, bOnlyDirs); sMask.substr(second_pos+1), asOut, bOnlyDirs );
} }
} }
} }
@@ -260,29 +264,29 @@ void FilenameDB::GetFilesSimpleMatch(const CString &dir, const CString &fn, vect
* be locked when this is called. It will be locked on return; the caller must * be locked when this is called. It will be locked on return; the caller must
* unlock it. * unlock it.
*/ */
FileSet *FilenameDB::GetFileSet( CString dir, bool create ) FileSet *FilenameDB::GetFileSet( CString sDir, bool bCreate )
{ {
/* Creating can take a long time; don't hold the lock if we might do that. */ /* Creating can take a long time; don't hold the lock if we might do that. */
if( create && m_Mutex.IsLockedByThisThread() && LOG ) if( bCreate && m_Mutex.IsLockedByThisThread() && LOG )
LOG->Warn( "FilenameDB::GetFileSet: m_Mutex was locked" ); LOG->Warn( "FilenameDB::GetFileSet: m_Mutex was locked" );
/* Normalize the path. */ /* Normalize the path. */
dir.Replace("\\", "/"); /* foo\bar -> foo/bar */ sDir.Replace("\\", "/"); /* foo\bar -> foo/bar */
dir.Replace("//", "/"); /* foo//bar -> foo/bar */ sDir.Replace("//", "/"); /* foo//bar -> foo/bar */
if( dir == "" ) if( sDir == "" )
dir = "/"; sDir = "/";
CString lower = dir; CString sLower = sDir;
lower.MakeLower(); sLower.MakeLower();
m_Mutex.Lock(); m_Mutex.Lock();
while(1) while(1)
{ {
/* Look for the directory. */ /* Look for the directory. */
map<CString, FileSet *>::iterator i = dirs.find( lower ); map<CString, FileSet *>::iterator i = dirs.find( sLower );
if( !create ) if( !bCreate )
{ {
if( i == dirs.end() ) if( i == dirs.end() )
return NULL; return NULL;
@@ -320,24 +324,24 @@ FileSet *FilenameDB::GetFileSet( CString dir, bool create )
/* Create the FileSet and insert it. Set it to !m_bFilled, so if other threads /* Create the FileSet and insert it. Set it to !m_bFilled, so if other threads
* happen to try to use this directory before we finish filling it, they'll wait. */ * happen to try to use this directory before we finish filling it, they'll wait. */
FileSet *ret = new FileSet; FileSet *pRet = new FileSet;
ret->m_bFilled = false; pRet->m_bFilled = false;
dirs[lower] = ret; dirs[sLower] = pRet;
/* Unlock while we populate the directory. This way, reads to other directories /* Unlock while we populate the directory. This way, reads to other directories
* won't block if this takes a while. */ * won't block if this takes a while. */
m_Mutex.Unlock(); m_Mutex.Unlock();
ASSERT( !m_Mutex.IsLockedByThisThread() ); ASSERT( !m_Mutex.IsLockedByThisThread() );
PopulateFileSet( *ret, dir ); PopulateFileSet( *pRet, sDir );
/* If this isn't the root directory, we want to set the dirp pointer of our parent /* If this isn't the root directory, we want to set the dirp pointer of our parent
* to the newly-created directory. Find the pointer we need to set. Be careful of * to the newly-created directory. Find the pointer we need to set. Be careful of
* order of operations, here: since we just unlocked, any this->dirs searches we did * order of operations, here: since we just unlocked, any this->dirs searches we did
* previously are no longer valid. */ * previously are no longer valid. */
FileSet **parent_dirp = NULL; FileSet **pParentDirp = NULL;
if( dir != "/" ) if( sDir != "/" )
{ {
CString sParent = Dirname( dir ); CString sParent = Dirname( sDir );
if( sParent == "./" ) if( sParent == "./" )
sParent = ""; sParent = "";
@@ -345,31 +349,31 @@ FileSet *FilenameDB::GetFileSet( CString dir, bool create )
FileSet *pParent = GetFileSet( sParent ); FileSet *pParent = GetFileSet( sParent );
if( pParent != NULL ) if( pParent != NULL )
{ {
set<File>::iterator it = pParent->files.find( File(Basename(dir)) ); set<File>::iterator it = pParent->files.find( File(Basename(sDir)) );
if( it != pParent->files.end() ) if( it != pParent->files.end() )
parent_dirp = const_cast<FileSet **>(&it->dirp); pParentDirp = const_cast<FileSet **>(&it->dirp);
} }
} }
else else
m_Mutex.Lock(); m_Mutex.Lock();
if( parent_dirp != NULL ) if( pParentDirp != NULL )
*parent_dirp = ret; *pParentDirp = pRet;
ret->age.Touch(); pRet->age.Touch();
ret->m_bFilled = true; pRet->m_bFilled = true;
/* Signal the event, to wake up any other threads that might be waiting for this /* Signal the event, to wake up any other threads that might be waiting for this
* directory. Leave the mutex locked; those threads will wake up when the current * directory. Leave the mutex locked; those threads will wake up when the current
* operation completes. */ * operation completes. */
m_Mutex.Broadcast(); m_Mutex.Broadcast();
return ret; return pRet;
} }
/* Add the file or directory "sPath". sPath is a directory if it ends with /* Add the file or directory "sPath". sPath is a directory if it ends with
* a slash. */ * a slash. */
void FilenameDB::AddFile( const CString &sPath_, int size, int hash, void *priv ) void FilenameDB::AddFile( const CString &sPath_, int iSize, int iHash, void *pPriv )
{ {
CString sPath(sPath_); CString sPath(sPath_);
@@ -379,11 +383,11 @@ void FilenameDB::AddFile( const CString &sPath_, int size, int hash, void *priv
if( sPath[0] != '/' ) if( sPath[0] != '/' )
sPath = "/" + sPath; sPath = "/" + sPath;
vector<CString> parts; vector<CString> asParts;
split( sPath, "/", parts, false ); split( sPath, "/", asParts, false );
CStringArray::const_iterator begin = parts.begin(); CStringArray::const_iterator begin = asParts.begin();
CStringArray::const_iterator end = parts.end(); CStringArray::const_iterator end = asParts.end();
bool IsDir = true; bool IsDir = true;
if( sPath[sPath.size()-1] != '/' ) if( sPath[sPath.size()-1] != '/' )
@@ -411,9 +415,9 @@ void FilenameDB::AddFile( const CString &sPath_, int size, int hash, void *priv
f.dir = IsDir; f.dir = IsDir;
if( !IsDir ) if( !IsDir )
{ {
f.size = size; f.size = iSize;
f.hash = hash; f.hash = iHash;
f.priv = priv; f.priv = pPriv;
} }
fs->files.insert( f ); fs->files.insert( f );
} }
@@ -541,7 +545,7 @@ const void *FilenameDB::GetFilePriv( const CString &path )
void FilenameDB::GetDirListing( CString sPath, CStringArray &AddTo, bool bOnlyDirs, bool bReturnPathToo ) void FilenameDB::GetDirListing( CString sPath, CStringArray &asAddTo, bool bOnlyDirs, bool bReturnPathToo )
{ {
// LOG->Trace( "GetDirListing( %s )", sPath.c_str() ); // LOG->Trace( "GetDirListing( %s )", sPath.c_str() );
@@ -554,7 +558,9 @@ void FilenameDB::GetDirListing( CString sPath, CStringArray &AddTo, bool bOnlyDi
{ {
fn = sPath; fn = sPath;
sPath = ""; sPath = "";
} else { }
else
{
fn = sPath.substr(pos+1); fn = sPath.substr(pos+1);
sPath = sPath.substr(0, pos+1); sPath = sPath.substr(0, pos+1);
} }
@@ -563,16 +569,16 @@ void FilenameDB::GetDirListing( CString sPath, CStringArray &AddTo, bool bOnlyDi
if( fn.size() == 0 ) if( fn.size() == 0 )
fn = "*"; fn = "*";
unsigned start = AddTo.size(); unsigned iStart = asAddTo.size();
GetFilesSimpleMatch(sPath, fn, AddTo, bOnlyDirs); GetFilesSimpleMatch( sPath, fn, asAddTo, bOnlyDirs );
if(bReturnPathToo && start < AddTo.size()) if( bReturnPathToo && iStart < asAddTo.size() )
{ {
ResolvePath( sPath ); ResolvePath( sPath );
while(start < AddTo.size()) while( iStart < asAddTo.size() )
{ {
AddTo[start] = sPath + AddTo[start]; asAddTo[iStart] = sPath + asAddTo[iStart];
start++; iStart++;
} }
} }
} }
+18 -18
View File
@@ -70,13 +70,13 @@ struct FileSet
FileSet() { m_bFilled = true; } FileSet() { m_bFilled = true; }
void GetFilesMatching( void GetFilesMatching(
const CString &beginning, const CString &containing, const CString &ending, const CString &sBeginning, const CString &sContaining, const CString &sEnding,
vector<CString> &out, bool bOnlyDirs) const; vector<CString> &asOut, bool bOnlyDirs ) const;
void GetFilesEqualTo( const CString &pat, vector<CString> &out, bool bOnlyDirs ) const; void GetFilesEqualTo( const CString &pat, vector<CString> &out, bool bOnlyDirs ) const;
RageFileManager::FileType GetFileType( const CString &path ) const; RageFileManager::FileType GetFileType( const CString &sPath ) const;
int GetFileSize(const CString &path) const; int GetFileSize( const CString &sPath ) const;
int GetFileHash(const CString &path) const; int GetFileHash( const CString &sPath ) const;
}; };
class FilenameDB class FilenameDB
@@ -84,17 +84,17 @@ class FilenameDB
protected: protected:
RageEvent m_Mutex; RageEvent m_Mutex;
FileSet *GetFileSet( CString dir, bool create=true ); FileSet *GetFileSet( CString sDir, bool create=true );
/* Directories we have cached: */ /* Directories we have cached: */
map<CString, FileSet *> dirs; map<CString, FileSet *> dirs;
int ExpireSeconds; int ExpireSeconds;
void GetFilesEqualTo(const CString &dir, const CString &fn, vector<CString> &out, bool bOnlyDirs); void GetFilesEqualTo( const CString &sDir, const CString &sName, vector<CString> &asOut, bool bOnlyDirs );
void GetFilesMatching(const CString &dir, void GetFilesMatching( const CString &sDir,
const CString &beginning, const CString &containing, const CString &ending, const CString &sBeginning, const CString &sContaining, const CString &sEnding,
vector<CString> &out, bool bOnlyDirs); vector<CString> &asOut, bool bOnlyDirs );
void DelFileSet( map<CString, FileSet *>::iterator dir ); void DelFileSet( map<CString, FileSet *>::iterator dir );
/* The given path wasn't cached. Cache it. */ /* The given path wasn't cached. Cache it. */
@@ -105,24 +105,24 @@ public:
m_Mutex("FilenameDB"), ExpireSeconds( -1 ) { } m_Mutex("FilenameDB"), ExpireSeconds( -1 ) { }
virtual FilenameDB::~FilenameDB() { FlushDirCache(); } virtual FilenameDB::~FilenameDB() { FlushDirCache(); }
void AddFile( const CString &sPath, int size, int hash, void *priv=NULL ); void AddFile( const CString &sPath, int iSize, int iHash, void *pPriv=NULL );
void DelFile( const CString &sPath ); void DelFile( const CString &sPath );
const File *GetFile( const CString &path ); const File *GetFile( const CString &sPath );
const void *GetFilePriv( const CString &path ); const void *GetFilePriv( const CString &sPath );
/* This handles at most two * wildcards. If we need anything more complicated, /* This handles at most two * wildcards. If we need anything more complicated,
* we'll need to use fnmatch or regex. */ * we'll need to use fnmatch or regex. */
void GetFilesSimpleMatch(const CString &dir, const CString &fn, vector<CString> &out, bool bOnlyDirs); void GetFilesSimpleMatch( const CString &sDir, const CString &sFile, vector<CString> &asOut, bool bOnlyDirs );
/* Search for "path" case-insensitively and replace it with the correct /* Search for "path" case-insensitively and replace it with the correct
* case. If only a portion of the path exists, resolve as much as possible. * case. If only a portion of the path exists, resolve as much as possible.
* Return true if the entire path was matched. */ * Return true if the entire path was matched. */
bool ResolvePath( CString &path ); bool ResolvePath( CString &sPath );
RageFileManager::FileType GetFileType( const CString &path ); RageFileManager::FileType GetFileType( const CString &sPath );
int GetFileSize(const CString &path); int GetFileSize( const CString &sPath );
int GetFileHash( const CString &sFilePath ); int GetFileHash( const CString &sFilePath );
void GetDirListing( CString sPath, CStringArray &AddTo, bool bOnlyDirs, bool bReturnPathToo ); void GetDirListing( CString sPath, CStringArray &asAddTo, bool bOnlyDirs, bool bReturnPathToo );
void FlushDirCache(); void FlushDirCache();