diff options
author | jmarshallnz <jcmarsha@gmail.com> | 2013-09-26 21:12:02 -0700 |
---|---|---|
committer | jmarshallnz <jcmarsha@gmail.com> | 2013-09-26 21:12:02 -0700 |
commit | ff2d98b333414e8abc8fc3da63ce5a5b64474f14 (patch) | |
tree | dd68fb0d6b9c9777133ee2802f83b8b4e8cb9dbd | |
parent | a141474c2cd38144001b1ba72e9ccb84e22e1f62 (diff) | |
parent | 02fd1ab143bfa35d77ace5ee557ac344c1cd6b25 (diff) |
Merge pull request #3292 from bavison/faster_string_comparisons
Faster string comparison functions in StringUtils
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)) |