llrender and lldir merge. Removed duplicate assets from skins. cleaned up skin textures.xml files to only include changes from default.

This commit is contained in:
Shyotl
2016-04-11 02:51:08 -05:00
parent d40256fb31
commit be5d2f20bc
1280 changed files with 2354 additions and 10692 deletions

View File

@@ -71,8 +71,15 @@ LLDir_Linux gDirUtil;
LLDir *gDirUtilp = (LLDir *)&gDirUtil;
/// Values for findSkinnedFilenames(subdir) parameter
const char
*LLDir::XUI = "xui",
*LLDir::TEXTURES = "textures",
*LLDir::SKINBASE = "";
static const char* const empty = "";
std::string LLDir::sDumpDir = "";
LLDir::LLDir()
: mAppName(""),
mExecutablePathAndName(""),
@@ -85,7 +92,9 @@ LLDir::LLDir()
mOSCacheDir(""),
mCAFile(""),
mTempDir(""),
mDirDelimiter("/") // fallback to forward slash if not overridden
mDirDelimiter("/"), // fallback to forward slash if not overridden
mLanguage("en"),
mUserName("undefined")
{
}
@@ -97,7 +106,11 @@ std::vector<std::string> LLDir::getFilesInDir(const std::string &dirname)
{
//Returns a vector of fullpath filenames.
#if LL_WINDOWS
boost::filesystem::path p (utf8str_to_utf16str(dirname).c_str());
#else
boost::filesystem::path p (dirname);
#endif
std::vector<std::string> v;
if (exists(p))
@@ -188,19 +201,33 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
U32 LLDir::deleteDirAndContents(const std::string& dir_name)
{
//Removes the directory and its contents. Returns number of files removed.
// Singu Note: boost::filesystem throws exceptions
S32 res = 0;
U32 num_deleted = 0;
try
try
{
res = boost::filesystem::remove_all(dir_name);
#if LL_WINDOWS
boost::filesystem::path dir_path(utf8str_to_utf16str(dir_name).c_str());
#else
boost::filesystem::path dir_path(dir_name);
#endif
if (boost::filesystem::exists (dir_path))
{
if (!boost::filesystem::is_empty (dir_path))
{ // Directory has content
num_deleted = boost::filesystem::remove_all (dir_path);
}
else
{ // Directory is empty
boost::filesystem::remove (dir_path);
}
}
}
catch(const boost::filesystem::filesystem_error& e)
{
LL_WARNS() << "boost::filesystem::remove_all(\"" + dir_name + "\") failed: '" + e.code().message() + "'" << LL_ENDL;
}
return res;
catch (boost::filesystem::filesystem_error &er)
{
LL_WARNS() << "Failed to delete " << dir_name << " with error " << er.code().message() << LL_ENDL;
}
return num_deleted;
}
const std::string LLDir::findFile(const std::string &filename,
@@ -346,6 +373,12 @@ const std::string LLDir::getCacheDir(bool get_default) const
}
}
#if (defined(_WIN64) || defined(__amd64__) || defined(__x86_64__))
#define OS_CACHE_DIR "SingularityViewer64"
#else
#define OS_CACHE_DIR "Obsidian"
#endif
// Return the default cache directory
std::string LLDir::buildSLOSCacheDir() const
{
@@ -363,11 +396,7 @@ std::string LLDir::buildSLOSCacheDir() const
}
else
{
#if defined(_WIN64)
res = add(getOSCacheDir(), "SingularityViewer64");
#else
res = add(getOSCacheDir(), "SingularityViewer");
#endif
res = add(getOSCacheDir(), OS_CACHE_DIR);
}
return res;
}
@@ -390,20 +419,26 @@ const std::string &LLDir::getDirDelimiter() const
return mDirDelimiter;
}
const std::string& LLDir::getDefaultSkinDir() const
{
return mDefaultSkinDir;
}
const std::string &LLDir::getSkinDir() const
{
return mSkinDir;
}
const std::string& LLDir::getUserDefaultSkinDir() const
{
return mUserDefaultSkinDir;
}
const std::string &LLDir::getUserSkinDir() const
{
return mUserSkinDir;
}
const std::string& LLDir::getDefaultSkinDir() const
{
return mDefaultSkinDir;
}
const std::string LLDir::getSkinBaseDir() const
{
@@ -415,6 +450,11 @@ const std::string &LLDir::getLLPluginDir() const
return mLLPluginDir;
}
const std::string &LLDir::getUserName() const
{
return mUserName;
}
static std::string ELLPathToString(ELLPath location)
{
typedef std::map<ELLPath, const char*> ELLPathMap;
@@ -602,7 +642,7 @@ std::string LLDir::getBaseFileName(const std::string& filepath, bool strip_exten
std::string LLDir::getDirName(const std::string& filepath) const
{
std::size_t offset = filepath.find_last_of(getDirDelimiter());
S32 len = (offset == std::string::npos) ? 0 : offset;
size_t len = (offset == std::string::npos) ? 0 : offset;
std::string dirname = filepath.substr(0, len);
return dirname;
}
@@ -618,31 +658,207 @@ std::string LLDir::getExtension(const std::string& filepath) const
return exten;
}
std::string LLDir::findSkinnedFilename(const std::string &filename) const
std::string LLDir::findSkinnedFilenameBaseLang(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint) const
{
return findSkinnedFilename("", "", filename);
// This implementation is basically just as described in the declaration comments.
std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint));
if (found.empty())
{
return "";
}
return found.front();
}
std::string LLDir::findSkinnedFilename(const std::string &subdir, const std::string &filename) const
std::string LLDir::findSkinnedFilename(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint) const
{
return findSkinnedFilename("", subdir, filename);
// This implementation is basically just as described in the declaration comments.
std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint));
if (found.empty())
{
return "";
}
return found.back();
}
std::string LLDir::findSkinnedFilename(const std::string &subdir1, const std::string &subdir2, const std::string &filename) const
// This method exists because the two code paths for
// findSkinnedFilenames(ALL_SKINS) and findSkinnedFilenames(CURRENT_SKIN) must
// generate the list of candidate pathnames in identical ways. The only
// difference is in the body of the inner loop.
template <typename FUNCTION>
void LLDir::walkSearchSkinDirs(const std::string& subdir,
const std::vector<std::string>& subsubdirs,
const std::string& filename,
const FUNCTION& function) const
{
// generate subdirectory path fragment, e.g. "/foo/bar", "/foo", ""
std::string subdirs = ((subdir1.empty() ? "" : mDirDelimiter) + subdir1)
+ ((subdir2.empty() ? "" : mDirDelimiter) + subdir2);
BOOST_FOREACH(std::string skindir, mSearchSkinDirs)
{
std::string subdir_path(add(skindir, subdir));
BOOST_FOREACH(std::string subsubdir, subsubdirs)
{
std::string full_path(add(add(subdir_path, subsubdir), filename));
if (fileExists(full_path))
{
function(subsubdir, full_path);
}
}
}
}
std::vector<std::string> search_paths;
search_paths.push_back(getUserSkinDir() + subdirs); // first look in user skin override
search_paths.push_back(getSkinDir() + subdirs); // then in current skin
search_paths.push_back(getDefaultSkinDir() + subdirs); // then default skin
search_paths.push_back(getCacheDir() + subdirs); // and last in preload directory
// ridiculous little helper function that should go away when we can use lambda
inline void push_back(std::vector<std::string>& vector, const std::string& value)
{
vector.push_back(value);
}
std::string found_file = findFile(filename, search_paths);
return found_file;
typedef std::map<std::string, std::string> StringMap;
// ridiculous little helper function that should go away when we can use lambda
inline void store_in_map(StringMap& map, const std::string& key, const std::string& value)
{
map[key] = value;
}
std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,
const std::string& filename,
ESkinConstraint constraint) const
{
// Recognize subdirs that have no localization.
static const std::set<std::string> sUnlocalized = list_of
("") // top-level directory not localized
("textures") // textures not localized
;
LL_DEBUGS("LLDir") << "subdir '" << subdir << "', filename '" << filename
<< "', constraint "
<< ((constraint == CURRENT_SKIN)? "CURRENT_SKIN" : "ALL_SKINS")
<< LL_ENDL;
// Cache the default language directory for each subdir we've encountered.
// A cache entry whose value is the empty string means "not localized,
// don't bother checking again."
static StringMap sLocalized;
// Check whether we've already discovered if this subdir is localized.
StringMap::const_iterator found = sLocalized.find(subdir);
if (found == sLocalized.end())
{
// We have not yet determined that. Is it one of the subdirs "known"
// to be unlocalized?
if (sUnlocalized.find(subdir) != sUnlocalized.end())
{
// This subdir is known to be unlocalized. Remember that.
found = sLocalized.insert(StringMap::value_type(subdir, "")).first;
}
else
{
// We do not recognize this subdir. Investigate.
std::string subdir_path(add(getDefaultSkinDir(), subdir));
if (fileExists(add(subdir_path, "en")))
{
// defaultSkinDir/subdir contains subdir "en". That's our
// default language; this subdir is localized.
found = sLocalized.insert(StringMap::value_type(subdir, "en")).first;
}
else if (fileExists(add(subdir_path, "en-us")))
{
// defaultSkinDir/subdir contains subdir "en-us" but not "en".
// Set as default language; this subdir is localized.
found = sLocalized.insert(StringMap::value_type(subdir, "en-us")).first;
}
else
{
// defaultSkinDir/subdir contains neither "en" nor "en-us".
// Assume it's not localized. Remember that assumption.
found = sLocalized.insert(StringMap::value_type(subdir, "")).first;
}
}
}
// Every code path above should have resulted in 'found' becoming a valid
// iterator to an entry in sLocalized.
llassert(found != sLocalized.end());
// Now -- is this subdir localized, or not? The answer determines what
// subdirectories we check (under subdir) for the requested filename.
std::vector<std::string> subsubdirs;
if (found->second.empty())
{
// subdir is not localized. filename should be located directly within it.
subsubdirs.push_back("");
}
else
{
// subdir is localized, and found->second is the default language
// directory within it. Check both the default language and the
// current language -- if it differs from the default, of course.
subsubdirs.push_back(found->second);
if (mLanguage != found->second)
{
subsubdirs.push_back(mLanguage);
}
}
// Build results vector.
std::vector<std::string> results;
// The process we use depends on 'constraint'.
if (constraint != CURRENT_SKIN) // meaning ALL_SKINS
{
// ALL_SKINS is simpler: just return every pathname generated by
// walkSearchSkinDirs(). Tricky bit: walkSearchSkinDirs() passes its
// FUNCTION the subsubdir as well as the full pathname. We just want
// the full pathname.
walkSearchSkinDirs(subdir, subsubdirs, filename,
boost::bind(push_back, boost::ref(results), _2));
}
else // CURRENT_SKIN
{
// CURRENT_SKIN turns out to be a bit of a misnomer because we might
// still return files from two different skins. In any case, this
// value of 'constraint' means we will return at most two paths: one
// for the default language, one for the current language (supposing
// those differ).
// It is important to allow a user to override only the localization
// for a particular file, for all viewer installs, without also
// overriding the default-language file.
// It is important to allow a user to override only the default-
// language file, for all viewer installs, without also overriding the
// applicable localization of that file.
// Therefore, treat the default language and the current language as
// two separate cases. For each, capture the most-specialized file
// that exists.
// Use a map keyed by subsubdir (i.e. language code). This allows us
// to handle the case of a single subsubdirs entry with the same logic
// that handles two. For every real file path generated by
// walkSearchSkinDirs(), update the map entry for its subsubdir.
StringMap path_for;
walkSearchSkinDirs(subdir, subsubdirs, filename,
boost::bind(store_in_map, boost::ref(path_for), _1, _2));
// Now that we have a path for each of the default language and the
// current language, copy them -- in proper order -- into results.
// Don't drive this by walking the map itself: it matters that we
// generate results in the same order as subsubdirs.
BOOST_FOREACH(std::string subsubdir, subsubdirs)
{
StringMap::const_iterator found(path_for.find(subsubdir));
if (found != path_for.end())
{
results.push_back(found->second);
}
}
}
LL_DEBUGS("LLDir") << empty;
const char* comma = "";
BOOST_FOREACH(std::string path, results)
{
LL_CONT << comma << "'" << path << "'";
comma = ", ";
}
LL_CONT << LL_ENDL;
return results;
}
std::string LLDir::getTempFilename() const
@@ -657,7 +873,7 @@ std::string LLDir::getTempFilename() const
}
// static
std::string LLDir::getScrubbedFileName(const std::string uncleanFileName)
std::string LLDir::getScrubbedFileName(const std::string& uncleanFileName)
{
std::string name(uncleanFileName);
std::string illegalChars(getForbiddenFileChars());
@@ -668,8 +884,8 @@ std::string LLDir::getScrubbedFileName(const std::string uncleanFileName)
// replace any illegal file chars with and underscore '_'
for( unsigned int i = 0; i < illegalChars.length(); i++ )
{
int j = -1;
while((j = name.find(illegalChars[i])) > -1)
size_t j = std::string::npos;
while ((j = name.find(illegalChars[i])) != std::string::npos)
{
name[j] = '_';
}
@@ -683,6 +899,19 @@ std::string LLDir::getForbiddenFileChars()
return "\\/:*?\"<>|";
}
// static
std::string LLDir::getGridSpecificDir( const std::string& in, const std::string& grid )
{
std::string ret;
if (!grid.empty())
{
std::string gridlower(grid);
LLStringUtil::toLower(gridlower);
ret = in + "@" + gridlower;
}
return ret;
}
void LLDir::setLindenUserDir(const std::string &grid, const std::string &first, const std::string &last)
{
// if both first and last aren't set, assume we're grabbing the cached dir
@@ -692,15 +921,7 @@ void LLDir::setLindenUserDir(const std::string &grid, const std::string &first,
// utterly consistent with our firstname/lastname case.
std::string userlower(first+"_"+last);
LLStringUtil::toLower(userlower);
mLindenUserDir = add(getOSUserAppDir(), userlower);
if (!grid.empty())
{
std::string gridlower(grid);
LLStringUtil::toLower(gridlower);
mLindenUserDir += "@";
mLindenUserDir += gridlower;
}
mLindenUserDir = getGridSpecificDir(grid, add(getOSUserAppDir(), userlower));
}
else
{
@@ -737,7 +958,7 @@ void LLDir::makePortable()
initAppDirs(mAppName); // This is kinda lazy, but it's probably the quickest, most uniform way.
}
void LLDir::setChatLogsDir(const std::string &path)
void LLDir::setChatLogsDir( const std::string& path)
{
if (!path.empty() )
{
@@ -749,6 +970,11 @@ void LLDir::setChatLogsDir(const std::string &path)
}
}
void LLDir::updatePerAccountChatLogsDir(const std::string &grid)
{
mPerAccountChatLogsDir = getGridSpecificDir(grid, add(getChatLogsDir(), mUserName));
}
void LLDir::setPerAccountChatLogsDir(const std::string &grid, const std::string &first, const std::string &last)
{
// if both first and last aren't set, assume we're grabbing the cached dir
@@ -758,14 +984,9 @@ void LLDir::setPerAccountChatLogsDir(const std::string &grid, const std::string
// utterly consistent with our firstname/lastname case.
std::string userlower(first+"_"+last);
LLStringUtil::toLower(userlower);
mPerAccountChatLogsDir = add(getChatLogsDir(), userlower);
if (!grid.empty())
{
std::string gridlower(grid);
LLStringUtil::toLower(gridlower);
mPerAccountChatLogsDir += "@";
mPerAccountChatLogsDir += gridlower;
}
mUserName = userlower;
updatePerAccountChatLogsDir(grid);
}
else
{
@@ -773,21 +994,59 @@ void LLDir::setPerAccountChatLogsDir(const std::string &grid, const std::string
}
}
void LLDir::setSkinFolder(const std::string &skin_folder)
void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language)
{
mSkinDir = getSkinBaseDir();
append(mSkinDir, skin_folder);
LL_DEBUGS("LLDir") << "Setting skin '" << skin_folder << "', language '" << language << "'"
<< LL_ENDL;
mSkinName = skin_folder;
mLanguage = language;
// user modifications to current skin
// e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle
mUserSkinDir = getOSUserAppDir();
append(mUserSkinDir, "skins_sg1");
append(mUserSkinDir, skin_folder);
// This method is called multiple times during viewer initialization. Each
// time it's called, reset mSearchSkinDirs.
mSearchSkinDirs.clear();
// base skin which is used as fallback for all skinned files
// e.g. c:\program files\secondlife\skins\default
mDefaultSkinDir = getSkinBaseDir();
append(mDefaultSkinDir, "default");
// This is always the most general of the search skin directories.
addSearchSkinDir(mDefaultSkinDir);
mSkinDir = getSkinBaseDir();
append(mSkinDir, skin_folder);
// Next level of generality is a skin installed with the viewer.
addSearchSkinDir(mSkinDir);
// user modifications to skins, current and default
// e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle
mUserSkinDir = getOSUserAppDir();
append(mUserSkinDir, "skins_sg1");
mUserDefaultSkinDir = mUserSkinDir;
append(mUserDefaultSkinDir, "default");
append(mUserSkinDir, skin_folder);
// Next level of generality is user modifications to default skin...
addSearchSkinDir(mUserDefaultSkinDir);
// then user-defined skins.
addSearchSkinDir(mUserSkinDir);
}
void LLDir::addSearchSkinDir(const std::string& skindir)
{
if (std::find(mSearchSkinDirs.begin(), mSearchSkinDirs.end(), skindir) == mSearchSkinDirs.end())
{
LL_DEBUGS("LLDir") << "search skin: '" << skindir << "'" << LL_ENDL;
mSearchSkinDirs.push_back(skindir);
}
}
std::string LLDir::getSkinFolder() const
{
return mSkinName;
}
std::string LLDir::getLanguage() const
{
return mLanguage;
}
bool LLDir::setCacheDir(const std::string &path)

View File

@@ -78,7 +78,7 @@ class LLDir
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0;
virtual std::string getCurPath() = 0;
virtual BOOL fileExists(const std::string &filename) const = 0;
virtual bool fileExists(const std::string &filename) const = 0;
const std::string findFile(const std::string& filename, const std::vector<std::string> filenames) const;
const std::string findFile(const std::string& filename, const std::string& searchPath1 = "", const std::string& searchPath2 = "", const std::string& searchPath3 = "") const;
@@ -103,11 +103,13 @@ class LLDir
const std::string &getOSCacheDir() const; // location of OS-specific cache folder (may be empty string)
const std::string &getCAFile() const; // File containing TLS certificate authorities
const std::string &getDirDelimiter() const; // directory separator for platform (ie. '\' or '/' or ':')
const std::string &getSkinDir() const; // User-specified skin folder.
const std::string &getUserSkinDir() const; // User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin
const std::string &getDefaultSkinDir() const; // folder for default skin. e.g. c:\program files\second life\skins\default
const std::string &getSkinDir() const; // User-specified skin folder.
const std::string &getUserDefaultSkinDir() const; // dir with user modifications to default skin
const std::string &getUserSkinDir() const; // User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin
const std::string getSkinBaseDir() const; // folder that contains all installed skins (not user modifications). e.g. c:\program files\second life\skins
const std::string &getLLPluginDir() const; // Directory containing plugins and plugin shell
const std::string &getUserName() const;
// Expanded filename
std::string getExpandedFilename(ELLPath location, const std::string &filename) const;
@@ -120,25 +122,80 @@ class LLDir
std::string getExtension(const std::string& filepath) const; // Excludes '.', e.g getExtension("foo.wav") == "wav"
// these methods search the various skin paths for the specified file in the following order:
// getUserSkinDir(), getSkinDir(), getDefaultSkinDir()
std::string findSkinnedFilename(const std::string &filename) const;
std::string findSkinnedFilename(const std::string &subdir, const std::string &filename) const;
std::string findSkinnedFilename(const std::string &subdir1, const std::string &subdir2, const std::string &filename) const;
// getUserSkinDir(), getUserDefaultSkinDir(), getSkinDir(), getDefaultSkinDir()
/// param value for findSkinnedFilenames(), explained below
enum ESkinConstraint { CURRENT_SKIN, ALL_SKINS };
/**
* Given a filename within skin, return an ordered sequence of paths to
* search. Nonexistent files will be filtered out -- which means that the
* vector might be empty.
*
* @param subdir Identify top-level skin subdirectory by passing one of
* LLDir::XUI (file lives under "xui" subtree), LLDir::TEXTURES (file
* lives under "textures" subtree), LLDir::SKINBASE (file lives at top
* level of skin subdirectory).
* @param filename Desired filename within subdir within skin, e.g.
* "panel_login.xml". DO NOT prepend (e.g.) "xui" or the desired language.
* @param constraint Callers perform two different kinds of processing.
* When fetching a XUI file, for instance, the existence of @a filename in
* the specified skin completely supercedes any @a filename in the default
* skin. For that case, leave the default @a constraint=CURRENT_SKIN. The
* returned vector will contain only
* ".../<i>current_skin</i>/xui/en/<i>filename</i>",
* ".../<i>current_skin</i>/xui/<i>current_language</i>/<i>filename</i>".
* But for (e.g.) "strings.xml", we want a given skin to be able to
* override only specific entries from the default skin. Any string not
* defined in the specified skin will be sought in the default skin. For
* that case, pass @a constraint=ALL_SKINS. The returned vector will
* contain at least ".../default/xui/en/strings.xml",
* ".../default/xui/<i>current_language</i>/strings.xml",
* ".../<i>current_skin</i>/xui/en/strings.xml",
* ".../<i>current_skin</i>/xui/<i>current_language</i>/strings.xml".
*/
std::vector<std::string> findSkinnedFilenames(const std::string& subdir,
const std::string& filename,
ESkinConstraint constraint=CURRENT_SKIN) const;
/// Values for findSkinnedFilenames(subdir) parameter
static const char *XUI, *TEXTURES, *SKINBASE;
/**
* Return the base-language pathname from findSkinnedFilenames(), or
* the empty string if no such file exists. Parameters are identical to
* findSkinnedFilenames(). This is shorthand for capturing the vector
* returned by findSkinnedFilenames(), checking for empty() and then
* returning front().
*/
std::string findSkinnedFilenameBaseLang(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint=CURRENT_SKIN) const;
/**
* Return the "most localized" pathname from findSkinnedFilenames(), or
* the empty string if no such file exists. Parameters are identical to
* findSkinnedFilenames(). This is shorthand for capturing the vector
* returned by findSkinnedFilenames(), checking for empty() and then
* returning back().
*/
std::string findSkinnedFilename(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint=CURRENT_SKIN) const;
// random filename in common temporary directory
std::string getTempFilename() const;
// For producing safe download file names from potentially unsafe ones
static std::string getScrubbedFileName(const std::string uncleanFileName);
static std::string getScrubbedFileName(const std::string& uncleanFileName);
static std::string getForbiddenFileChars();
static std::string getGridSpecificDir( const std::string& in, const std::string& grid );
void setDumpDir( const std::string& path );
void makePortable();
virtual void setChatLogsDir(const std::string &path); // Set the chat logs dir to this user's dir
virtual void setPerAccountChatLogsDir(const std::string &grid, const std::string &first, const std::string &last); // Set the per user chat log directory.
virtual void setPerAccountChatLogsDir(const std::string &grid, const std::string &first, const std::string& last); // Set the per user chat log directory.
virtual void setLindenUserDir(const std::string& grid, const std::string& first, const std::string& last); // Set the linden user dir to this user's dir
virtual void setSkinFolder(const std::string &skin_folder);
virtual void setSkinFolder(const std::string &skin_folder, const std::string& language);
virtual std::string getSkinFolder() const;
virtual std::string getLanguage() const;
virtual bool setCacheDir(const std::string &path);
virtual void updatePerAccountChatLogsDir(const std::string &grid);
virtual void dumpCurrentDirectories();
@@ -156,6 +213,16 @@ protected:
// Does an add() or append() call need a directory delimiter?
typedef std::pair<bool, unsigned short> SepOff;
SepOff needSep(const std::string& path, const std::string& name) const;
// build mSearchSkinDirs without adding duplicates
void addSearchSkinDir(const std::string& skindir);
// Internal to findSkinnedFilenames()
template <typename FUNCTION>
void walkSearchSkinDirs(const std::string& subdir,
const std::vector<std::string>& subsubdirs,
const std::string& filename,
const FUNCTION& function) const;
std::string mAppName; // install directory under progams/ ie "SecondLife"
std::string mExecutablePathAndName; // full path + Filename of .exe
std::string mExecutableFilename; // Filename of .exe
@@ -173,12 +240,21 @@ protected:
std::string mDefaultCacheDir; // default cache diretory
std::string mOSCacheDir; // operating system cache dir
std::string mDirDelimiter;
std::string mSkinName; // caller-specified skin name
std::string mSkinBaseDir; // Base for skins paths.
std::string mSkinDir; // Location for current skin info.
std::string mDefaultSkinDir; // Location for default skin info.
std::string mSkinDir; // Location for current skin info.
std::string mUserDefaultSkinDir; // Location for default skin info.
std::string mUserSkinDir; // Location for user-modified skin info.
// Skin directories to search, most general to most specific. This order
// works well for composing fine-grained files, in which an individual item
// in a specific file overrides the corresponding item in more general
// files. Of course, for a file-level search, iterate backwards.
std::vector<std::string> mSearchSkinDirs;
std::string mLanguage; // Current viewer language
std::string mLLPluginDir; // Location for plugins and plugin shell
static std::string sDumpDir; // Per-run crash report subdir of log directory.
std::string mUserName; // Current user name
};
void dir_exists_or_crash(const std::string &dir_name);

View File

@@ -257,7 +257,7 @@ std::string LLDir_Linux::getCurPath()
}
BOOL LLDir_Linux::fileExists(const std::string &filename) const
bool LLDir_Linux::fileExists(const std::string &filename) const
{
struct stat stat_data;
// Check the age of the file

View File

@@ -53,7 +53,7 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
/*virtual*/ BOOL fileExists(const std::string &filename) const;
/*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);

View File

@@ -267,7 +267,7 @@ std::string LLDir_Mac::getCurPath()
BOOL LLDir_Mac::fileExists(const std::string &filename) const
bool LLDir_Mac::fileExists(const std::string &filename) const
{
struct stat stat_data;
// Check the age of the file

View File

@@ -52,7 +52,7 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
virtual BOOL fileExists(const std::string &filename) const;
virtual bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);

View File

@@ -278,7 +278,7 @@ std::string LLDir_Solaris::getCurPath()
}
BOOL LLDir_Solaris::fileExists(const std::string &filename) const
bool LLDir_Solaris::fileExists(const std::string &filename) const
{
struct stat stat_data;
// Check the age of the file

View File

@@ -53,7 +53,7 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
/*virtual*/ BOOL fileExists(const std::string &filename) const;
/*virtual*/ bool fileExists(const std::string &filename) const;
private:
DIR *mDirp;

View File

@@ -48,60 +48,28 @@ LLDir_Win32::LLDir_Win32()
WCHAR w_str[MAX_PATH];
HRESULT (WINAPI* pSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath) = NULL;
HMODULE shell = LoadLibrary(L"shell32");
if(shell) //SHGetSpecialFolderPath is deprecated from Vista an onwards. Try to use SHGetKnownFolderPath if it's available
{
pSHGetKnownFolderPath = (HRESULT (WINAPI *)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *))GetProcAddress(shell, "SHGetKnownFolderPath");
}
WCHAR* pPath = NULL;
if(SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str, pPath);
// Application Data is where user settings go
if(pSHGetKnownFolderPath)
{
WCHAR* pPath = NULL;
if((*pSHGetKnownFolderPath)(FOLDERID_RoamingAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str,pPath);
else
SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
if(pPath)
CoTaskMemFree(pPath);
}
else //XP doesn't support SHGetKnownFolderPath
{
SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
}
CoTaskMemFree(pPath);
pPath = NULL;
mOSUserDir = utf16str_to_utf8str(llutf16string(w_str));
// We want cache files to go on the local disk, even if the
// user is on a network with a "roaming profile".
//
// On XP this is:
// C:\Docments and Settings\James\Local Settings\Application Data
// On Vista this is:
// C:\Users\James\AppData\Local
// On Vista and above this is:
// C:\Users\<USERNAME>\AppData\Local
//
// We used to store the cache in AppData\Roaming, and the installer
// cleans up that version on upgrade. JC
if(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str, pPath);
if(pSHGetKnownFolderPath)
{
WCHAR* pPath = NULL;
if((*pSHGetKnownFolderPath)(FOLDERID_LocalAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str,pPath);
else
SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
if(pPath)
CoTaskMemFree(pPath);
}
else //XP doesn't support SHGetKnownFolderPath
{
SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
}
if(shell)
FreeLibrary(shell);
CoTaskMemFree(pPath);
pPath = NULL;
mOSCacheDir = utf16str_to_utf8str(llutf16string(w_str));
@@ -288,7 +256,7 @@ std::string LLDir_Win32::getCurPath()
}
BOOL LLDir_Win32::fileExists(const std::string &filename) const
bool LLDir_Win32::fileExists(const std::string &filename) const
{
llstat stat_data;
// Check the age of the file

View File

@@ -50,7 +50,7 @@ public:
/*virtual*/ std::string getCurPath();
/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask);
/*virtual*/ BOOL fileExists(const std::string &filename) const;
/*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);

View File

@@ -49,7 +49,11 @@ private:
LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
: mIsValid(false)
{
#if LL_WINDOWS
fs::path dir_path(utf8str_to_utf16str(dirname).c_str());
#else
fs::path dir_path(dirname);
#endif
bool is_dir = false;
@@ -58,11 +62,7 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
{
is_dir = fs::is_directory(dir_path);
}
#if BOOST_FILESYSTEM_VERSION >= 3
catch (fs::filesystem_error& e)
#else
catch (fs::basic_filesystem_error<fs::path>& e)
#endif
catch (const fs::filesystem_error& e)
{
LL_WARNS() << e.what() << LL_ENDL;
return;
@@ -79,13 +79,9 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
{
mIter = fs::directory_iterator(dir_path);
}
#if BOOST_FILESYSTEM_VERSION >= 3
catch (fs::filesystem_error& e)
#else
catch (fs::basic_filesystem_error<fs::path>& e)
#endif
catch (const fs::filesystem_error& e)
{
LL_ERRS() << e.what() << LL_ENDL;
LL_WARNS() << e.what() << LL_ENDL;
return;
}
@@ -101,7 +97,7 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
}
catch (boost::regex_error& e)
{
LL_ERRS() << "\"" << exp << "\" is not a valid regular expression: "
LL_WARNS() << "\"" << exp << "\" is not a valid regular expression: "
<< e.what() << LL_ENDL;
return;
}
@@ -125,20 +121,26 @@ bool LLDirIterator::Impl::next(std::string &fname)
fs::directory_iterator end_itr; // default construction yields past-the-end
bool found = false;
while (mIter != end_itr && !found)
{
boost::smatch match;
#if BOOST_FILESYSTEM_VERSION >= 3
std::string name = mIter->path().filename().string();
#else
std::string name = mIter->path().filename();
#endif
if ((found = boost::regex_match(name, match, mFilterExp)))
{
fname = name;
}
++mIter;
// Check if path is a directory.
try
{
while (mIter != end_itr && !found)
{
boost::smatch match;
std::string name = mIter->path().filename().string();
found = boost::regex_match(name, match, mFilterExp);
if (found)
{
fname = name;
}
++mIter;
}
}
catch (const fs::filesystem_error& e)
{
LL_WARNS() << e.what() << LL_ENDL;
}
return found;