diff options
author | Merov Linden <merov@lindenlab.com> | 2011-01-13 11:15:47 -0800 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2011-01-13 11:15:47 -0800 |
commit | 804495ad41cbd0eb511c02d5306fc3b8f9be0b89 (patch) | |
tree | a4b1f3995878302a9f62dc25e7cdbb2d53f8c3a3 /indra/llvfs | |
parent | 55322713fc071a3e171fd4cfbea989945dc8d084 (diff) |
STORM-477 : backout changeset 6f5cb303d3e2
Diffstat (limited to 'indra/llvfs')
-rw-r--r-- | indra/llvfs/lldir.cpp | 6 | ||||
-rw-r--r-- | indra/llvfs/lldir.h | 25 | ||||
-rw-r--r-- | indra/llvfs/lldir_linux.cpp | 62 | ||||
-rw-r--r-- | indra/llvfs/lldir_linux.h | 1 | ||||
-rw-r--r-- | indra/llvfs/lldir_mac.cpp | 61 | ||||
-rw-r--r-- | indra/llvfs/lldir_mac.h | 1 | ||||
-rw-r--r-- | indra/llvfs/lldir_solaris.cpp | 62 | ||||
-rw-r--r-- | indra/llvfs/lldir_solaris.h | 1 | ||||
-rw-r--r-- | indra/llvfs/lldir_win32.cpp | 61 | ||||
-rw-r--r-- | indra/llvfs/lldir_win32.h | 3 |
10 files changed, 278 insertions, 5 deletions
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index ab7d15dfef..64556bcb4c 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -40,8 +40,6 @@ #include "lltimer.h" // ms_sleep() #include "lluuid.h" -#include "lldiriterator.h" - #if LL_WINDOWS #include "lldir_win32.h" LLDir_Win32 gDirUtil; @@ -85,9 +83,7 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) std::string filename; std::string fullpath; S32 result; - - LLDirIterator iter(dirname, mask); - while (iter.next(filename)) + while (getNextFileInDir(dirname, mask, filename)) { fullpath = dirname; fullpath += getDirDelimiter(); diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index 5ee8bdb542..42996fd051 100644 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -75,6 +75,31 @@ class LLDir // pure virtual functions virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0; + /// Walk the files in a directory, with file pattern matching + virtual BOOL getNextFileInDir(const std::string& dirname, ///< directory path - must end in trailing slash! + const std::string& mask, ///< file pattern string (use "*" for all) + std::string& fname ///< output: found file name + ) = 0; + /**< + * @returns true if a file was found, false if the entire directory has been scanned. + * + * @note that this function is NOT thread safe + * + * This function may not be used to scan part of a directory, then start a new search of a different + * directory, and then restart the first search where it left off; the entire search must run to + * completion or be abandoned - there is no restart. + * + * @bug: See http://jira.secondlife.com/browse/VWR-23697 + * and/or the tests in test/lldir_test.cpp + * This is known to fail with patterns that have both: + * a wildcard left of a . and more than one sequential ? right of a . + * the pattern foo.??x appears to work + * but *.??x or foo?.??x do not + * + * @todo this really should be rewritten as an iterator object, and the + * filtering should be done in a platform-independent way. + */ + virtual std::string getCurPath() = 0; virtual BOOL fileExists(const std::string &filename) const = 0; diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp index 4ba2f519b0..73f2336f94 100644 --- a/indra/llvfs/lldir_linux.cpp +++ b/indra/llvfs/lldir_linux.cpp @@ -242,6 +242,68 @@ U32 LLDir_Linux::countFilesInDir(const std::string &dirname, const std::string & return (file_count); } +// get the next file in the directory +BOOL LLDir_Linux::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) +{ + glob_t g; + BOOL result = FALSE; + fname = ""; + + if(!(dirname == mCurrentDir)) + { + // different dir specified, close old search + mCurrentDirIndex = -1; + mCurrentDirCount = -1; + mCurrentDir = dirname; + } + + std::string tmp_str; + tmp_str = dirname; + tmp_str += mask; + + if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0) + { + if(g.gl_pathc > 0) + { + if((int)g.gl_pathc != mCurrentDirCount) + { + // Number of matches has changed since the last search, meaning a file has been added or deleted. + // Reset the index. + mCurrentDirIndex = -1; + mCurrentDirCount = g.gl_pathc; + } + + mCurrentDirIndex++; + + if(mCurrentDirIndex < (int)g.gl_pathc) + { +// llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl; + + // The API wants just the filename, not the full path. + //fname = g.gl_pathv[mCurrentDirIndex]; + + char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/'); + + if(s == NULL) + s = g.gl_pathv[mCurrentDirIndex]; + else if(s[0] == '/') + s++; + + fname = s; + + result = TRUE; + } + } + + globfree(&g); + } + + return(result); +} + + + + std::string LLDir_Linux::getCurPath() { char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */ diff --git a/indra/llvfs/lldir_linux.h b/indra/llvfs/lldir_linux.h index ff4c48759a..451e81ae93 100644 --- a/indra/llvfs/lldir_linux.h +++ b/indra/llvfs/lldir_linux.h @@ -43,6 +43,7 @@ public: public: virtual std::string getCurPath(); virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask); + virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname); /*virtual*/ BOOL fileExists(const std::string &filename) const; /*virtual*/ std::string getLLPluginLauncher(); diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp index 2d039527c0..445285aa43 100644 --- a/indra/llvfs/lldir_mac.cpp +++ b/indra/llvfs/lldir_mac.cpp @@ -258,6 +258,67 @@ U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &ma return (file_count); } +// get the next file in the directory +BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) +{ + glob_t g; + BOOL result = FALSE; + fname = ""; + + if(!(dirname == mCurrentDir)) + { + // different dir specified, close old search + mCurrentDirIndex = -1; + mCurrentDirCount = -1; + mCurrentDir = dirname; + } + + std::string tmp_str; + tmp_str = dirname; + tmp_str += mask; + + if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0) + { + if(g.gl_pathc > 0) + { + if(g.gl_pathc != mCurrentDirCount) + { + // Number of matches has changed since the last search, meaning a file has been added or deleted. + // Reset the index. + mCurrentDirIndex = -1; + mCurrentDirCount = g.gl_pathc; + } + + mCurrentDirIndex++; + + if(mCurrentDirIndex < g.gl_pathc) + { +// llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl; + + // The API wants just the filename, not the full path. + //fname = g.gl_pathv[mCurrentDirIndex]; + + char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/'); + + if(s == NULL) + s = g.gl_pathv[mCurrentDirIndex]; + else if(s[0] == '/') + s++; + + fname = s; + + result = TRUE; + } + } + + globfree(&g); + } + + return(result); +} + + + S32 LLDir_Mac::deleteFilesInDir(const std::string &dirname, const std::string &mask) { glob_t g; diff --git a/indra/llvfs/lldir_mac.h b/indra/llvfs/lldir_mac.h index e60d5e41c2..4eac3c3ae6 100644 --- a/indra/llvfs/lldir_mac.h +++ b/indra/llvfs/lldir_mac.h @@ -43,6 +43,7 @@ public: virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask); virtual std::string getCurPath(); virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask); + virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname); virtual BOOL fileExists(const std::string &filename) const; /*virtual*/ std::string getLLPluginLauncher(); diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp index 21f8c3acdb..515fd66b6e 100644 --- a/indra/llvfs/lldir_solaris.cpp +++ b/indra/llvfs/lldir_solaris.cpp @@ -260,6 +260,68 @@ U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string return (file_count); } +// get the next file in the directory +BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) +{ + glob_t g; + BOOL result = FALSE; + fname = ""; + + if(!(dirname == mCurrentDir)) + { + // different dir specified, close old search + mCurrentDirIndex = -1; + mCurrentDirCount = -1; + mCurrentDir = dirname; + } + + std::string tmp_str; + tmp_str = dirname; + tmp_str += mask; + + if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0) + { + if(g.gl_pathc > 0) + { + if((int)g.gl_pathc != mCurrentDirCount) + { + // Number of matches has changed since the last search, meaning a file has been added or deleted. + // Reset the index. + mCurrentDirIndex = -1; + mCurrentDirCount = g.gl_pathc; + } + + mCurrentDirIndex++; + + if(mCurrentDirIndex < (int)g.gl_pathc) + { +// llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl; + + // The API wants just the filename, not the full path. + //fname = g.gl_pathv[mCurrentDirIndex]; + + char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/'); + + if(s == NULL) + s = g.gl_pathv[mCurrentDirIndex]; + else if(s[0] == '/') + s++; + + fname = s; + + result = TRUE; + } + } + + globfree(&g); + } + + return(result); +} + + + + std::string LLDir_Solaris::getCurPath() { char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */ diff --git a/indra/llvfs/lldir_solaris.h b/indra/llvfs/lldir_solaris.h index f7e1a6301d..4a1794f539 100644 --- a/indra/llvfs/lldir_solaris.h +++ b/indra/llvfs/lldir_solaris.h @@ -43,6 +43,7 @@ public: public: virtual std::string getCurPath(); virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask); + virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname); /*virtual*/ BOOL fileExists(const std::string &filename) const; private: diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index 2f96fbbbc1..33718e520d 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -236,6 +236,67 @@ U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string & return (file_count); } + +// get the next file in the directory +BOOL LLDir_Win32::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) +{ + BOOL fileFound = FALSE; + fname = ""; + + WIN32_FIND_DATAW FileData; + llutf16string pathname = utf8str_to_utf16str(dirname) + utf8str_to_utf16str(mask); + + if (pathname != mCurrentDir) + { + // different dir specified, close old search + if (mCurrentDir[0]) + { + FindClose(mDirSearch_h); + } + mCurrentDir = pathname; + + // and open new one + // Check error opening Directory structure + if ((mDirSearch_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE) + { + fileFound = TRUE; + } + } + + // Loop to skip over the current (.) and parent (..) directory entries + // (apparently returned in Win7 but not XP) + do + { + if ( fileFound + && ( (lstrcmp(FileData.cFileName, (LPCTSTR)TEXT(".")) == 0) + ||(lstrcmp(FileData.cFileName, (LPCTSTR)TEXT("..")) == 0) + ) + ) + { + fileFound = FALSE; + } + } while ( mDirSearch_h != INVALID_HANDLE_VALUE + && !fileFound + && (fileFound = FindNextFile(mDirSearch_h, &FileData) + ) + ); + + if (!fileFound && GetLastError() == ERROR_NO_MORE_FILES) + { + // No more files, so reset to beginning of directory + FindClose(mDirSearch_h); + mCurrentDir[0] = '\000'; + } + + if (fileFound) + { + // convert from TCHAR to char + fname = utf16str_to_utf8str(FileData.cFileName); + } + + return fileFound; +} + std::string LLDir_Win32::getCurPath() { WCHAR w_str[MAX_PATH]; diff --git a/indra/llvfs/lldir_win32.h b/indra/llvfs/lldir_win32.h index 19c610eb8b..4c932c932c 100644 --- a/indra/llvfs/lldir_win32.h +++ b/indra/llvfs/lldir_win32.h @@ -40,12 +40,15 @@ public: /*virtual*/ std::string getCurPath(); /*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask); + /*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname); /*virtual*/ BOOL fileExists(const std::string &filename) const; /*virtual*/ std::string getLLPluginLauncher(); /*virtual*/ std::string getLLPluginFilename(std::string base_name); private: + BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname); + void* mDirSearch_h; llutf16string mCurrentDir; }; |