aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjmarshallnz <jcmarsha@gmail.com>2013-09-26 21:12:02 -0700
committerjmarshallnz <jcmarsha@gmail.com>2013-09-26 21:12:02 -0700
commitff2d98b333414e8abc8fc3da63ce5a5b64474f14 (patch)
treedd68fb0d6b9c9777133ee2802f83b8b4e8cb9dbd
parenta141474c2cd38144001b1ba72e9ccb84e22e1f62 (diff)
parent02fd1ab143bfa35d77ace5ee557ac344c1cd6b25 (diff)
Merge pull request #3292 from bavison/faster_string_comparisons
Faster string comparison functions in StringUtils
-rw-r--r--xbmc/Application.cpp6
-rw-r--r--xbmc/CueDocument.cpp24
-rw-r--r--xbmc/addons/Addon.cpp2
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp2
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp2
-rw-r--r--xbmc/filesystem/test/TestRarFile.cpp20
-rw-r--r--xbmc/interfaces/generic/ScriptInvocationManager.cpp2
-rw-r--r--xbmc/music/windows/GUIWindowMusicBase.cpp2
-rw-r--r--xbmc/music/windows/GUIWindowMusicNav.cpp6
-rw-r--r--xbmc/network/WebServer.cpp2
-rw-r--r--xbmc/network/upnp/UPnPServer.cpp18
-rw-r--r--xbmc/settings/SettingDependency.cpp4
-rw-r--r--xbmc/settings/SettingsManager.cpp2
-rw-r--r--xbmc/settings/SkinSettings.cpp4
-rw-r--r--xbmc/utils/FileUtils.cpp22
-rw-r--r--xbmc/utils/LegacyPathTranslation.cpp2
-rw-r--r--xbmc/utils/StringUtils.cpp121
-rw-r--r--xbmc/utils/StringUtils.h14
-rw-r--r--xbmc/utils/StringValidation.cpp2
-rw-r--r--xbmc/utils/test/TestStringUtils.cpp24
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.cpp2
-rw-r--r--xbmc/video/windows/GUIWindowVideoNav.cpp6
-rw-r--r--xbmc/view/ViewDatabase.cpp4
23 files changed, 194 insertions, 99 deletions
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index fd6970200d..266b9d8488 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -1586,7 +1586,7 @@ void CApplication::OnSettingChanged(const CSetting *setting)
}
else if (settingId == "lookandfeel.skinzoom")
g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_WINDOW_RESIZE);
- else if (StringUtils::StartsWith(settingId, "audiooutput."))
+ else if (StringUtils::StartsWithNoCase(settingId, "audiooutput."))
{
if (settingId == "audiooutput.guisoundmode")
{
@@ -2224,13 +2224,13 @@ bool CApplication::OnKey(const CKey& key)
m_idleTimer.StartZero();
bool processKey = AlwaysProcess(action);
- if (StringUtils::StartsWith(action.GetName(),"CECToggleState") || StringUtils::StartsWith(action.GetName(),"CECStandby"))
+ if (StringUtils::StartsWithNoCase(action.GetName(),"CECToggleState") || StringUtils::StartsWithNoCase(action.GetName(),"CECStandby"))
{
bool ret = true;
CLog::Log(LOGDEBUG, "%s: action %s [%d], toggling state of playing device", __FUNCTION__, action.GetName().c_str(), action.GetID());
// do not wake up the screensaver right after switching off the playing device
- if (StringUtils::StartsWith(action.GetName(),"CECToggleState"))
+ if (StringUtils::StartsWithNoCase(action.GetName(),"CECToggleState"))
ret = CApplicationMessenger::Get().CECToggleState();
else
ret = CApplicationMessenger::Get().CECStandby();
diff --git a/xbmc/CueDocument.cpp b/xbmc/CueDocument.cpp
index 53b1f14844..e79cb02027 100644
--- a/xbmc/CueDocument.cpp
+++ b/xbmc/CueDocument.cpp
@@ -103,7 +103,7 @@ bool CCueDocument::Parse(const CStdString &strFile)
{
if (!ReadNextLine(strLine))
break;
- if (StringUtils::StartsWith(strLine,"INDEX 01"))
+ if (StringUtils::StartsWithNoCase(strLine,"INDEX 01"))
{
if (bCurrentFileChanged)
{
@@ -124,7 +124,7 @@ bool CCueDocument::Parse(const CStdString &strFile)
if (m_iTotalTracks >= 0)
m_Track[m_iTotalTracks].iStartTime = time; // start time of the next track
}
- else if (StringUtils::StartsWith(strLine,"TITLE"))
+ else if (StringUtils::StartsWithNoCase(strLine,"TITLE"))
{
if (m_iTotalTracks == -1) // No tracks yet
ExtractQuoteInfo(strLine, m_strAlbum);
@@ -140,14 +140,14 @@ bool CCueDocument::Parse(const CStdString &strFile)
}
}
}
- else if (StringUtils::StartsWith(strLine,"PERFORMER"))
+ else if (StringUtils::StartsWithNoCase(strLine,"PERFORMER"))
{
if (m_iTotalTracks == -1) // No tracks yet
ExtractQuoteInfo(strLine, m_strArtist);
else // New Artist for this track
ExtractQuoteInfo(strLine, m_Track[m_iTotalTracks].strArtist);
}
- else if (StringUtils::StartsWith(strLine,"TRACK"))
+ else if (StringUtils::StartsWithNoCase(strLine,"TRACK"))
{
int iTrackNumber = ExtractNumericInfo(strLine.Mid(5));
@@ -164,13 +164,13 @@ bool CCueDocument::Parse(const CStdString &strFile)
bCurrentFileChanged = false;
}
- else if (StringUtils::StartsWith(strLine,"REM DISCNUMBER"))
+ else if (StringUtils::StartsWithNoCase(strLine,"REM DISCNUMBER"))
{
int iDiscNumber = ExtractNumericInfo(strLine.Mid(14));
if (iDiscNumber > 0)
m_iDiscNumber = iDiscNumber;
}
- else if (StringUtils::StartsWith(strLine,"FILE"))
+ else if (StringUtils::StartsWithNoCase(strLine,"FILE"))
{
// already a file name? then the time computation will be changed
if(strCurrentFile.size() > 0)
@@ -182,13 +182,13 @@ bool CCueDocument::Parse(const CStdString &strFile)
if (strCurrentFile.length() > 0)
ResolvePath(strCurrentFile, strFile);
}
- else if (StringUtils::StartsWith(strLine,"REM DATE"))
+ else if (StringUtils::StartsWithNoCase(strLine,"REM DATE"))
{
int iYear = ExtractNumericInfo(strLine.Mid(8));
if (iYear > 0)
m_iYear = iYear;
}
- else if (StringUtils::StartsWith(strLine,"REM GENRE"))
+ else if (StringUtils::StartsWithNoCase(strLine,"REM GENRE"))
{
if (!ExtractQuoteInfo(strLine, m_strGenre))
{
@@ -201,13 +201,13 @@ bool CCueDocument::Parse(const CStdString &strFile)
}
}
}
- else if (StringUtils::StartsWith(strLine,"REM REPLAYGAIN_ALBUM_GAIN"))
+ else if (StringUtils::StartsWithNoCase(strLine,"REM REPLAYGAIN_ALBUM_GAIN"))
m_replayGainAlbumGain = (float)atof(strLine.Mid(26));
- else if (StringUtils::StartsWith(strLine,"REM REPLAYGAIN_ALBUM_PEAK"))
+ else if (StringUtils::StartsWithNoCase(strLine,"REM REPLAYGAIN_ALBUM_PEAK"))
m_replayGainAlbumPeak = (float)atof(strLine.Mid(26));
- else if (StringUtils::StartsWith(strLine,"REM REPLAYGAIN_TRACK_GAIN") && m_iTotalTracks >= 0)
+ else if (StringUtils::StartsWithNoCase(strLine,"REM REPLAYGAIN_TRACK_GAIN") && m_iTotalTracks >= 0)
m_Track[m_iTotalTracks].replayGainTrackGain = (float)atof(strLine.Mid(26));
- else if (StringUtils::StartsWith(strLine,"REM REPLAYGAIN_TRACK_PEAK") && m_iTotalTracks >= 0)
+ else if (StringUtils::StartsWithNoCase(strLine,"REM REPLAYGAIN_TRACK_PEAK") && m_iTotalTracks >= 0)
m_Track[m_iTotalTracks].replayGainTrackPeak = (float)atof(strLine.Mid(26));
}
diff --git a/xbmc/addons/Addon.cpp b/xbmc/addons/Addon.cpp
index 07a50cba39..4e5667135c 100644
--- a/xbmc/addons/Addon.cpp
+++ b/xbmc/addons/Addon.cpp
@@ -314,7 +314,7 @@ bool CAddon::MeetsVersion(const AddonVersion &version) const
// if the addon is one of xbmc's extension point definitions (addonid starts with "xbmc.")
// and the minversion is "0.0.0" i.e. no <backwards-compatibility> tag has been specified
// we need to assume that the current version is not backwards-compatible and therefore check against the actual version
- if (StringUtils::StartsWith(m_props.id, "xbmc.") &&
+ if (StringUtils::StartsWithNoCase(m_props.id, "xbmc.") &&
(strlen(m_props.minversion.c_str()) == 0 || StringUtils::EqualsNoCase(m_props.minversion.c_str(), "0.0.0")))
return m_props.version == version;
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
index 58d8ca6809..f4e7649aab 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
@@ -149,7 +149,7 @@ bool CAESinkDirectSound::Initialize(AEAudioFormat &format, std::string &device)
std::string deviceFriendlyName;
DirectSoundEnumerate(DSEnumCallback, &DSDeviceList);
- if(StringUtils::EndsWith(device, std::string("default")))
+ if(StringUtils::EndsWithNoCase(device, std::string("default")))
strDeviceGUID = GetDefaultDevice();
for (std::list<DSDevice>::iterator itt = DSDeviceList.begin(); itt != DSDeviceList.end(); ++itt)
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp
index f049bca9c0..1e87712f4f 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp
@@ -231,7 +231,7 @@ bool CAESinkWASAPI::Initialize(AEAudioFormat &format, std::string &device)
hr = pEnumDevices->GetCount(&uiCount);
EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint count failed.")
- if(StringUtils::EndsWith(device, std::string("default")))
+ if(StringUtils::EndsWithNoCase(device, std::string("default")))
bdefault = true;
if(!bdefault)
diff --git a/xbmc/filesystem/test/TestRarFile.cpp b/xbmc/filesystem/test/TestRarFile.cpp
index 9fcf914142..0536159dff 100644
--- a/xbmc/filesystem/test/TestRarFile.cpp
+++ b/xbmc/filesystem/test/TestRarFile.cpp
@@ -210,7 +210,7 @@ TEST(TestRarFile, StoredRAR)
* an uncompressed RAR archive. See TestRarFile.Read test case.
*/
strpathinrar = itemlist[1]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/reffile.txt", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/reffile.txt"));
EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFREG);
@@ -255,7 +255,7 @@ TEST(TestRarFile, StoredRAR)
/* /testsymlink -> testdir/reffile.txt */
strpathinrar = itemlist[2]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlink", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlink"));
EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
@@ -270,7 +270,7 @@ TEST(TestRarFile, StoredRAR)
/* /testsymlinksubdir -> testdir/testsubdir/reffile.txt */
strpathinrar = itemlist[3]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlinksubdir", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlinksubdir"));
EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
@@ -280,7 +280,7 @@ TEST(TestRarFile, StoredRAR)
/* /testdir/ */
strpathinrar = itemlist[0]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/"));
EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFDIR);
@@ -345,7 +345,7 @@ TEST(TestRarFile, StoredRAR)
/* FIXME: This directory appears a second time as a file */
strpathinrar = itemlist[3]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsubdir", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsubdir"));
/* /testdir/testsymlink -> testsubdir/reffile.txt */
strpathinrar = itemlist[4]->GetPath();
@@ -432,7 +432,7 @@ TEST(TestRarFile, NormalRAR)
/* /reffile.txt */
strpathinrar = itemlist[1]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/reffile.txt", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/reffile.txt"));
EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFREG);
@@ -477,7 +477,7 @@ TEST(TestRarFile, NormalRAR)
/* /testsymlink -> testdir/reffile.txt */
strpathinrar = itemlist[2]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlink", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlink"));
EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
@@ -492,7 +492,7 @@ TEST(TestRarFile, NormalRAR)
/* /testsymlinksubdir -> testdir/testsubdir/reffile.txt */
strpathinrar = itemlist[3]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlinksubdir", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testsymlinksubdir"));
EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFLNK);
@@ -502,7 +502,7 @@ TEST(TestRarFile, NormalRAR)
/* /testdir/ */
strpathinrar = itemlist[0]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/"));
EXPECT_EQ(0, XFILE::CFile::Stat(strpathinrar, &stat_buffer));
EXPECT_TRUE((stat_buffer.st_mode & S_IFMT) | S_IFDIR);
@@ -567,7 +567,7 @@ TEST(TestRarFile, NormalRAR)
/* FIXME: This directory appears a second time as a file */
strpathinrar = itemlist[3]->GetPath();
- ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsubdir", true));
+ ASSERT_TRUE(StringUtils::EndsWith(strpathinrar, "/testdir/testsubdir"));
/* /testdir/testsymlink -> testsubdir/reffile.txt */
strpathinrar = itemlist[4]->GetPath();
diff --git a/xbmc/interfaces/generic/ScriptInvocationManager.cpp b/xbmc/interfaces/generic/ScriptInvocationManager.cpp
index 3e47fa506d..b3c98f0dbb 100644
--- a/xbmc/interfaces/generic/ScriptInvocationManager.cpp
+++ b/xbmc/interfaces/generic/ScriptInvocationManager.cpp
@@ -122,7 +122,7 @@ void CScriptInvocationManager::RegisterLanguageInvocationHandler(ILanguageInvoca
string ext = extension;
StringUtils::ToLower(ext);
- if (!StringUtils::StartsWith(ext, "."))
+ if (!StringUtils::StartsWithNoCase(ext, "."))
ext = "." + ext;
CSingleLock lock(m_critSection);
diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp
index 875a3f21c4..72566f763e 100644
--- a/xbmc/music/windows/GUIWindowMusicBase.cpp
+++ b/xbmc/music/windows/GUIWindowMusicBase.cpp
@@ -1154,7 +1154,7 @@ bool CGUIWindowMusicBase::CheckFilterAdvanced(CFileItemList &items) const
bool CGUIWindowMusicBase::CanContainFilter(const CStdString &strDirectory) const
{
- return StringUtils::StartsWith(strDirectory, "musicdb://");
+ return StringUtils::StartsWithNoCase(strDirectory, "musicdb://");
}
void CGUIWindowMusicBase::OnInitWindow()
diff --git a/xbmc/music/windows/GUIWindowMusicNav.cpp b/xbmc/music/windows/GUIWindowMusicNav.cpp
index ef34b82587..90f83272e0 100644
--- a/xbmc/music/windows/GUIWindowMusicNav.cpp
+++ b/xbmc/music/windows/GUIWindowMusicNav.cpp
@@ -447,7 +447,7 @@ void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &butt
{
if (!item->m_bIsFolder) // music video
buttons.Add(CONTEXT_BUTTON_INFO, 20393);
- if (StringUtils::StartsWith(item->GetPath(), "videodb://musicvideos/artist/") && item->m_bIsFolder)
+ if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/artist/") && item->m_bIsFolder)
{
long idArtist = m_musicdatabase.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
if (idArtist > - 1)
@@ -565,7 +565,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
return CGUIWindowMusicBase::OnContextButton(itemNumber,button);
// music videos - artists
- if (StringUtils::StartsWith(item->GetPath(), "videodb://musicvideos/artists/"))
+ if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/artists/"))
{
long idArtist = m_musicdatabase.GetArtistByName(item->GetLabel());
if (idArtist == -1)
@@ -582,7 +582,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
}
// music videos - albums
- if (StringUtils::StartsWith(item->GetPath(), "videodb://musicvideos/albums/"))
+ if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/albums/"))
{
long idAlbum = m_musicdatabase.GetAlbumByName(item->GetLabel());
if (idAlbum == -1)
diff --git a/xbmc/network/WebServer.cpp b/xbmc/network/WebServer.cpp
index 68f9cbf83c..82625e19b5 100644
--- a/xbmc/network/WebServer.cpp
+++ b/xbmc/network/WebServer.cpp
@@ -965,7 +965,7 @@ int64_t CWebServer::ParseRangeHeader(const std::string &rangeHeaderValue, int64_
firstPosition = 0;
lastPosition = totalLength - 1;
- if (rangeHeaderValue.empty() || !StringUtils::StartsWith(rangeHeaderValue, "bytes="))
+ if (rangeHeaderValue.empty() || !StringUtils::StartsWithNoCase(rangeHeaderValue, "bytes="))
return totalLength;
int64_t rangesLength = 0;
diff --git a/xbmc/network/upnp/UPnPServer.cpp b/xbmc/network/upnp/UPnPServer.cpp
index dd92e6f3f8..f737495abc 100644
--- a/xbmc/network/upnp/UPnPServer.cpp
+++ b/xbmc/network/upnp/UPnPServer.cpp
@@ -547,7 +547,7 @@ CUPnPServer::OnBrowseMetadata(PLT_ActionReference& action,
// attempt to determine the parent of this item
CStdString parent;
- if (URIUtils::IsVideoDb((const char*)id) || URIUtils::IsMusicDb((const char*)id) || StringUtils::StartsWith((const char*)id, "library://video/")) {
+ if (URIUtils::IsVideoDb((const char*)id) || URIUtils::IsMusicDb((const char*)id) || StringUtils::StartsWithNoCase((const char*)id, "library://video/")) {
if (!URIUtils::GetParentPath((const char*)id, parent)) {
parent = "0";
}
@@ -560,11 +560,11 @@ CUPnPServer::OnBrowseMetadata(PLT_ActionReference& action,
// however this is quicker to implement and subsequently purge when a
// better solution presents itself
CStdString child_id((const char*)id);
- if (StringUtils::StartsWith(child_id, "special://musicplaylists/")) parent = "musicdb://";
- else if (StringUtils::StartsWith(child_id, "special://videoplaylists/")) parent = "library://video/";
- else if (StringUtils::StartsWith(child_id, "sources://video/")) parent = "library://video/";
- else if (StringUtils::StartsWith(child_id, "special://profile/playlists/music/")) parent = "special://musicplaylists/";
- else if (StringUtils::StartsWith(child_id, "special://profile/playlists/video/")) parent = "special://videoplaylists/";
+ if (StringUtils::StartsWithNoCase(child_id, "special://musicplaylists/")) parent = "musicdb://";
+ else if (StringUtils::StartsWithNoCase(child_id, "special://videoplaylists/")) parent = "library://video/";
+ else if (StringUtils::StartsWithNoCase(child_id, "sources://video/")) parent = "library://video/";
+ else if (StringUtils::StartsWithNoCase(child_id, "special://profile/playlists/music/")) parent = "special://musicplaylists/";
+ else if (StringUtils::StartsWithNoCase(child_id, "special://profile/playlists/video/")) parent = "special://videoplaylists/";
else parent = "sources://video/"; // this can only match video sources
}
@@ -729,13 +729,13 @@ CUPnPServer::BuildResponse(PLT_ActionReference& action,
NPT_Reference<CThumbLoader> thumb_loader;
if (URIUtils::IsVideoDb(items.GetPath()) ||
- StringUtils::StartsWith(items.GetPath(), "library://video/") ||
- StringUtils::StartsWith(items.GetPath(), "special://profile/playlists/video/")) {
+ StringUtils::StartsWithNoCase(items.GetPath(), "library://video/") ||
+ StringUtils::StartsWithNoCase(items.GetPath(), "special://profile/playlists/video/")) {
thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
}
else if (URIUtils::IsMusicDb(items.GetPath()) ||
- StringUtils::StartsWith(items.GetPath(), "special://profile/playlists/music/")) {
+ StringUtils::StartsWithNoCase(items.GetPath(), "special://profile/playlists/music/")) {
thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader());
}
diff --git a/xbmc/settings/SettingDependency.cpp b/xbmc/settings/SettingDependency.cpp
index a4959e41f2..32ac5d1ce9 100644
--- a/xbmc/settings/SettingDependency.cpp
+++ b/xbmc/settings/SettingDependency.cpp
@@ -131,12 +131,12 @@ bool CSettingDependencyCondition::setTarget(const std::string &target)
bool CSettingDependencyCondition::setOperator(const std::string &op)
{
size_t length = 0;
- if (StringUtils::EndsWith(op, "is"))
+ if (StringUtils::EndsWithNoCase(op, "is"))
{
m_operator = SettingDependencyOperatorEquals;
length = 2;
}
- else if (StringUtils::EndsWith(op, "contains"))
+ else if (StringUtils::EndsWithNoCase(op, "contains"))
{
m_operator = SettingDependencyOperatorContains;
length = 8;
diff --git a/xbmc/settings/SettingsManager.cpp b/xbmc/settings/SettingsManager.cpp
index ae676c7920..9c65ab53ca 100644
--- a/xbmc/settings/SettingsManager.cpp
+++ b/xbmc/settings/SettingsManager.cpp
@@ -476,7 +476,7 @@ bool CSettingsManager::GetBool(const std::string &id) const
if (setting == NULL || setting->GetType() != SettingTypeBool)
{
// Backward compatibility (skins use this setting)
- if (setting == NULL && StringUtils::EqualsNoCase(id.c_str(), "lookandfeel.enablemouse"))
+ if (setting == NULL && StringUtils::EqualsNoCase(id, "lookandfeel.enablemouse"))
return GetBool("input.enablemouse");
return false;
diff --git a/xbmc/settings/SkinSettings.cpp b/xbmc/settings/SkinSettings.cpp
index 31a885c720..13aba27e2f 100644
--- a/xbmc/settings/SkinSettings.cpp
+++ b/xbmc/settings/SkinSettings.cpp
@@ -175,13 +175,13 @@ void CSkinSettings::Reset()
// clear all the settings and strings from this skin.
for (map<int, CSkinBool>::iterator it = m_bools.begin(); it != m_bools.end(); ++it)
{
- if (StringUtils::StartsWith(it->second.name, currentSkin))
+ if (StringUtils::StartsWithNoCase(it->second.name, currentSkin))
it->second.value = false;
}
for (map<int, CSkinString>::iterator it = m_strings.begin(); it != m_strings.end(); ++it)
{
- if (StringUtils::StartsWith(it->second.name, currentSkin))
+ if (StringUtils::StartsWithNoCase(it->second.name, currentSkin))
it->second.value.clear();
}
diff --git a/xbmc/utils/FileUtils.cpp b/xbmc/utils/FileUtils.cpp
index 220f8ac8bf..18511ee1f8 100644
--- a/xbmc/utils/FileUtils.cpp
+++ b/xbmc/utils/FileUtils.cpp
@@ -116,27 +116,27 @@ bool CFileUtils::RemoteAccessAllowed(const CStdString &strPath)
while (URIUtils::IsInArchive(realPath))
realPath = CURL(realPath).GetHostName();
- if (StringUtils::StartsWith(realPath, "virtualpath://upnproot/"))
+ if (StringUtils::StartsWithNoCase(realPath, "virtualpath://upnproot/"))
return true;
- else if (StringUtils::StartsWith(realPath, "musicdb://"))
+ else if (StringUtils::StartsWithNoCase(realPath, "musicdb://"))
return true;
- else if (StringUtils::StartsWith(realPath, "videodb://"))
+ else if (StringUtils::StartsWithNoCase(realPath, "videodb://"))
return true;
- else if (StringUtils::StartsWith(realPath, "library://video"))
+ else if (StringUtils::StartsWithNoCase(realPath, "library://video"))
return true;
- else if (StringUtils::StartsWith(realPath, "sources://video"))
+ else if (StringUtils::StartsWithNoCase(realPath, "sources://video"))
return true;
- else if (StringUtils::StartsWith(realPath, "special://musicplaylists"))
+ else if (StringUtils::StartsWithNoCase(realPath, "special://musicplaylists"))
return true;
- else if (StringUtils::StartsWith(realPath, "special://profile/playlists"))
+ else if (StringUtils::StartsWithNoCase(realPath, "special://profile/playlists"))
return true;
- else if (StringUtils::StartsWith(realPath, "special://videoplaylists"))
+ else if (StringUtils::StartsWithNoCase(realPath, "special://videoplaylists"))
return true;
- else if (StringUtils::StartsWith(realPath, "addons://sources"))
+ else if (StringUtils::StartsWithNoCase(realPath, "addons://sources"))
return true;
- else if (StringUtils::StartsWith(realPath, "upnp://"))
+ else if (StringUtils::StartsWithNoCase(realPath, "upnp://"))
return true;
- else if (StringUtils::StartsWith(realPath, "plugin://"))
+ else if (StringUtils::StartsWithNoCase(realPath, "plugin://"))
return true;
bool isSource;
for (unsigned int index = 0; index < SourcesSize; index++)
diff --git a/xbmc/utils/LegacyPathTranslation.cpp b/xbmc/utils/LegacyPathTranslation.cpp
index 035eadf8b4..7658b36066 100644
--- a/xbmc/utils/LegacyPathTranslation.cpp
+++ b/xbmc/utils/LegacyPathTranslation.cpp
@@ -95,7 +95,7 @@ std::string CLegacyPathTranslation::TranslatePath(const std::string &legacyPath,
std::string newPath = legacyPath;
for (size_t index = 0; index < translationMapSize; index++)
{
- if (StringUtils::StartsWith(newPath, translationMap[index].legacyPath))
+ if (StringUtils::StartsWithNoCase(newPath, translationMap[index].legacyPath))
{
StringUtils::Replace(newPath, translationMap[index].legacyPath, translationMap[index].newPath);
break;
diff --git a/xbmc/utils/StringUtils.cpp b/xbmc/utils/StringUtils.cpp
index 6d82e48830..d316d715a0 100644
--- a/xbmc/utils/StringUtils.cpp
+++ b/xbmc/utils/StringUtils.cpp
@@ -114,12 +114,26 @@ void StringUtils::ToLower(string &str)
bool StringUtils::EqualsNoCase(const std::string &str1, const std::string &str2)
{
- string tmp1 = str1;
- string tmp2 = str2;
- ToLower(tmp1);
- ToLower(tmp2);
-
- return tmp1.compare(tmp2) == 0;
+ return EqualsNoCase(str1.c_str(), str2.c_str());
+}
+
+bool StringUtils::EqualsNoCase(const std::string &str1, const char *s2)
+{
+ return EqualsNoCase(str1.c_str(), s2);
+}
+
+bool StringUtils::EqualsNoCase(const char *s1, const char *s2)
+{
+ int c1, c2; // Yes, because the return type of tolower() is int.
+ // To make these chars would be to introduce an unnecesary extra bitmask/zero-extend (effectively caller-narowing) into the binary.
+ do
+ {
+ c1 = ::tolower(*s1++);
+ c2 = ::tolower(*s2++);
+ if (c1 != c2) // This includes the possibility that one of the characters is the null-terminator, which implies a string mismatch.
+ return false;
+ } while (c2 != '\0'); // At this point, we know c1 == c2, so there's no need to test them both.
+ return true;
}
string StringUtils::Left(const string &str, size_t count)
@@ -225,24 +239,95 @@ int StringUtils::Replace(std::string &str, const std::string &oldStr, const std:
return replacedChars;
}
-bool StringUtils::StartsWith(const std::string &str, const std::string &str2, bool useCase /* = false */)
+bool StringUtils::StartsWith(const std::string &str1, const std::string &str2)
{
- std::string left = StringUtils::Left(str, str2.size());
-
- if (useCase)
- return left.compare(str2) == 0;
+ return str1.compare(0, str2.size(), str2) == 0;
+}
- return StringUtils::EqualsNoCase(left, str2);
+bool StringUtils::StartsWith(const std::string &str1, const char *s2)
+{
+ return StartsWith(str1.c_str(), s2);
}
-bool StringUtils::EndsWith(const std::string &str, const std::string &str2, bool useCase /* = false */)
+bool StringUtils::StartsWith(const char *s1, const char *s2)
{
- std::string right = StringUtils::Right(str, str2.size());
-
- if (useCase)
- return right.compare(str2) == 0;
+ while (*s2 != '\0')
+ {
+ if (*s1 != *s2)
+ return false;
+ s1++;
+ s2++;
+ }
+ return true;
+}
- return StringUtils::EqualsNoCase(right, str2);
+bool StringUtils::StartsWithNoCase(const std::string &str1, const std::string &str2)
+{
+ return StartsWithNoCase(str1.c_str(), str2.c_str());
+}
+
+bool StringUtils::StartsWithNoCase(const std::string &str1, const char *s2)
+{
+ return StartsWithNoCase(str1.c_str(), s2);
+}
+
+bool StringUtils::StartsWithNoCase(const char *s1, const char *s2)
+{
+ while (*s2 != '\0')
+ {
+ if (::tolower(*s1) != ::tolower(*s2))
+ return false;
+ s1++;
+ s2++;
+ }
+ return true;
+}
+
+bool StringUtils::EndsWith(const std::string &str1, const std::string &str2)
+{
+ if (str1.size() < str2.size())
+ return false;
+ return str1.compare(str1.size() - str2.size(), str2.size(), str2) == 0;
+}
+
+bool StringUtils::EndsWith(const std::string &str1, const char *s2)
+{
+ size_t len2 = strlen(s2);
+ if (str1.size() < len2)
+ return false;
+ return str1.compare(str1.size() - len2, len2, s2) == 0;
+}
+
+bool StringUtils::EndsWithNoCase(const std::string &str1, const std::string &str2)
+{
+ if (str1.size() < str2.size())
+ return false;
+ const char *s1 = str1.c_str() + str1.size() - str2.size();
+ const char *s2 = str2.c_str();
+ while (*s2 != '\0')
+ {
+ if (::tolower(*s1) != ::tolower(*s2))
+ return false;
+ s1++;
+ s2++;
+ }
+ return true;
+}
+
+bool StringUtils::EndsWithNoCase(const std::string &str1, const char *s2)
+{
+ size_t len2 = strlen(s2);
+ if (str1.size() < len2)
+ return false;
+ const char *s1 = str1.c_str() + str1.size() - len2;
+ while (*s2 != '\0')
+ {
+ if (::tolower(*s1) != ::tolower(*s2))
+ return false;
+ s1++;
+ s2++;
+ }
+ return true;
}
void StringUtils::JoinString(const CStdStringArray &strings, const CStdString& delimiter, CStdString& result)
diff --git a/xbmc/utils/StringUtils.h b/xbmc/utils/StringUtils.h
index a75ba7549d..11f6f5e700 100644
--- a/xbmc/utils/StringUtils.h
+++ b/xbmc/utils/StringUtils.h
@@ -55,6 +55,8 @@ public:
static void ToUpper(std::string &str);
static void ToLower(std::string &str);
static bool EqualsNoCase(const std::string &str1, const std::string &str2);
+ static bool EqualsNoCase(const std::string &str1, const char *s2);
+ static bool EqualsNoCase(const char *s1, const char *s2);
static std::string Left(const std::string &str, size_t count);
static std::string Mid(const std::string &str, size_t first, size_t count = std::string::npos);
static std::string Right(const std::string &str, size_t count);
@@ -64,8 +66,16 @@ public:
static std::string& RemoveDuplicatedSpacesAndTabs(std::string& str);
static int Replace(std::string &str, char oldChar, char newChar);
static int Replace(std::string &str, const std::string &oldStr, const std::string &newStr);
- static bool StartsWith(const std::string &str, const std::string &str2, bool useCase = false);
- static bool EndsWith(const std::string &str, const std::string &str2, bool useCase = false);
+ static bool StartsWith(const std::string &str1, const std::string &str2);
+ static bool StartsWith(const std::string &str1, const char *s2);
+ static bool StartsWith(const char *s1, const char *s2);
+ static bool StartsWithNoCase(const std::string &str1, const std::string &str2);
+ static bool StartsWithNoCase(const std::string &str1, const char *s2);
+ static bool StartsWithNoCase(const char *s1, const char *s2);
+ static bool EndsWith(const std::string &str1, const std::string &str2);
+ static bool EndsWith(const std::string &str1, const char *s2);
+ static bool EndsWithNoCase(const std::string &str1, const std::string &str2);
+ static bool EndsWithNoCase(const std::string &str1, const char *s2);
static void JoinString(const CStdStringArray &strings, const CStdString& delimiter, CStdString& result);
static CStdString JoinString(const CStdStringArray &strings, const CStdString& delimiter);
diff --git a/xbmc/utils/StringValidation.cpp b/xbmc/utils/StringValidation.cpp
index 3a1df6decd..79ac19fe2a 100644
--- a/xbmc/utils/StringValidation.cpp
+++ b/xbmc/utils/StringValidation.cpp
@@ -37,7 +37,7 @@ bool StringValidation::IsTime(const std::string &input, void *data)
std::string strTime = input;
StringUtils::Trim(strTime);
- if (StringUtils::EndsWith(strTime, " min"))
+ if (StringUtils::EndsWithNoCase(strTime, " min"))
{
strTime = StringUtils::Left(strTime, strTime.size() - 4);
StringUtils::TrimRight(strTime);
diff --git a/xbmc/utils/test/TestStringUtils.cpp b/xbmc/utils/test/TestStringUtils.cpp
index 3bffc07f45..c7d732d542 100644
--- a/xbmc/utils/test/TestStringUtils.cpp
+++ b/xbmc/utils/test/TestStringUtils.cpp
@@ -175,28 +175,28 @@ TEST(TestStringUtils, StartsWith)
{
std::string refstr = "test";
- EXPECT_FALSE(StringUtils::StartsWith(refstr, "x"));
+ EXPECT_FALSE(StringUtils::StartsWithNoCase(refstr, "x"));
- EXPECT_TRUE(StringUtils::StartsWith(refstr, "te", true));
- EXPECT_TRUE(StringUtils::StartsWith(refstr, "test", true));
- EXPECT_FALSE(StringUtils::StartsWith(refstr, "Te", true));
+ EXPECT_TRUE(StringUtils::StartsWith(refstr, "te"));
+ EXPECT_TRUE(StringUtils::StartsWith(refstr, "test"));
+ EXPECT_FALSE(StringUtils::StartsWith(refstr, "Te"));
- EXPECT_TRUE(StringUtils::StartsWith(refstr, "Te", false));
- EXPECT_TRUE(StringUtils::StartsWith(refstr, "TesT", false));
+ EXPECT_TRUE(StringUtils::StartsWithNoCase(refstr, "Te"));
+ EXPECT_TRUE(StringUtils::StartsWithNoCase(refstr, "TesT"));
}
TEST(TestStringUtils, EndsWith)
{
std::string refstr = "test";
- EXPECT_FALSE(StringUtils::EndsWith(refstr, "x"));
+ EXPECT_FALSE(StringUtils::EndsWithNoCase(refstr, "x"));
- EXPECT_TRUE(StringUtils::EndsWith(refstr, "st", true));
- EXPECT_TRUE(StringUtils::EndsWith(refstr, "test", true));
- EXPECT_FALSE(StringUtils::EndsWith(refstr, "sT", true));
+ EXPECT_TRUE(StringUtils::EndsWith(refstr, "st"));
+ EXPECT_TRUE(StringUtils::EndsWith(refstr, "test"));
+ EXPECT_FALSE(StringUtils::EndsWith(refstr, "sT"));
- EXPECT_TRUE(StringUtils::EndsWith(refstr, "sT", false));
- EXPECT_TRUE(StringUtils::EndsWith(refstr, "TesT", false));
+ EXPECT_TRUE(StringUtils::EndsWithNoCase(refstr, "sT"));
+ EXPECT_TRUE(StringUtils::EndsWithNoCase(refstr, "TesT"));
}
TEST(TestStringUtils, JoinString)
diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp
index 57c66415bb..b53144778f 100644
--- a/xbmc/video/windows/GUIWindowVideoBase.cpp
+++ b/xbmc/video/windows/GUIWindowVideoBase.cpp
@@ -1791,7 +1791,7 @@ bool CGUIWindowVideoBase::CheckFilterAdvanced(CFileItemList &items) const
bool CGUIWindowVideoBase::CanContainFilter(const CStdString &strDirectory) const
{
- return StringUtils::StartsWith(strDirectory, "videodb://");
+ return StringUtils::StartsWithNoCase(strDirectory, "videodb://");
}
void CGUIWindowVideoBase::AddToDatabase(int iItem)
diff --git a/xbmc/video/windows/GUIWindowVideoNav.cpp b/xbmc/video/windows/GUIWindowVideoNav.cpp
index b888ea7f1c..1dfbb52165 100644
--- a/xbmc/video/windows/GUIWindowVideoNav.cpp
+++ b/xbmc/video/windows/GUIWindowVideoNav.cpp
@@ -674,7 +674,7 @@ void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
!pItem->GetPath().Left(9).Equals("newtag://"))
CGUIWindowVideoBase::OnDeleteItem(pItem);
}
- else if (StringUtils::StartsWith(pItem->GetPath(), "videodb://movies/sets/") &&
+ else if (StringUtils::StartsWithNoCase(pItem->GetPath(), "videodb://movies/sets/") &&
pItem->GetPath().size() > 22 && pItem->m_bIsFolder)
{
CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
@@ -967,7 +967,7 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt
if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
buttons.Add(CONTEXT_BUTTON_SET_SEASON_ART, 13511);
- if (StringUtils::StartsWith(item->GetPath(), "videodb://movies/sets/") && item->GetPath().size() > 22 && item->m_bIsFolder) // sets
+ if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://movies/sets/") && item->GetPath().size() > 22 && item->m_bIsFolder) // sets
{
buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_ART, 13511);
buttons.Add(CONTEXT_BUTTON_MOVIESET_ADD_REMOVE_ITEMS, 20465);
@@ -991,7 +991,7 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt
if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder)
{
- if (StringUtils::StartsWith(m_vecItems->GetPath(), "videodb://musicvideos")) // mvids
+ if (StringUtils::StartsWithNoCase(m_vecItems->GetPath(), "videodb://musicvideos")) // mvids
buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359);
else
buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403);
diff --git a/xbmc/view/ViewDatabase.cpp b/xbmc/view/ViewDatabase.cpp
index 25300f19a6..1425a4cb78 100644
--- a/xbmc/view/ViewDatabase.cpp
+++ b/xbmc/view/ViewDatabase.cpp
@@ -93,9 +93,9 @@ bool CViewDatabase::UpdateOldVersion(int version)
{
std::string originalPath = m_pDS->fv(1).get_asString();
std::string path = originalPath;
- if (StringUtils::StartsWith(path, "musicdb://"))
+ if (StringUtils::StartsWithNoCase(path, "musicdb://"))
path = CLegacyPathTranslation::TranslateMusicDbPath(path);
- else if (StringUtils::StartsWith(path, "videodb://"))
+ else if (StringUtils::StartsWithNoCase(path, "videodb://"))
path = CLegacyPathTranslation::TranslateVideoDbPath(path);
if (!StringUtils::EqualsNoCase(path, originalPath))