Merge pull request #4630 from Red-F/gotham-resume-pvr-lastplayedposition
[vuplus_xbmc] / xbmc / Util.cpp
index f283377..f614f17 100644 (file)
@@ -230,7 +230,7 @@ CStdString CUtil::GetTitleFromPath(const CStdString& strFileNameAndPath, bool bI
   }
   
   // URLDecode since the original path may be an URL
-  CURL::Decode(strFilename);
+  strFilename = CURL::Decode(strFilename);
   return strFilename;
 }
 
@@ -243,8 +243,8 @@ void CUtil::CleanString(const CStdString& strFileName, CStdString& strTitle, CSt
 
   const CStdStringArray &regexps = g_advancedSettings.m_videoCleanStringRegExps;
 
-  CRegExp reTags(true, true);
-  CRegExp reYear(false, true);
+  CRegExp reTags(true, CRegExp::autoUtf8);
+  CRegExp reYear(false, CRegExp::autoUtf8);
 
   if (!reYear.RegComp(g_advancedSettings.m_videoCleanDateTimeRegExp))
   {
@@ -270,7 +270,7 @@ void CUtil::CleanString(const CStdString& strFileName, CStdString& strTitle, CSt
     }
     int j=0;
     if ((j=reTags.RegFind(strTitleAndYear.c_str())) > 0)
-      strTitleAndYear = strTitleAndYear.Mid(0, j);
+      strTitleAndYear = strTitleAndYear.substr(0, j);
   }
 
   // final cleanup - special characters used instead of spaces:
@@ -281,18 +281,18 @@ void CUtil::CleanString(const CStdString& strFileName, CStdString& strTitle, CSt
   if (bCleanChars)
   {
     bool initialDots = true;
-    bool alreadyContainsSpace = (strTitleAndYear.Find(' ') >= 0);
+    bool alreadyContainsSpace = (strTitleAndYear.find(' ') != std::string::npos);
 
-    for (int i = 0; i < (int)strTitleAndYear.size(); i++)
+    for (size_t i = 0; i < strTitleAndYear.size(); i++)
     {
-      char c = strTitleAndYear.GetAt(i);
+      char c = strTitleAndYear[i];
 
       if (c != '.')
         initialDots = false;
 
       if ((c == '_') || ((!alreadyContainsSpace) && !initialDots && (c == '.')))
       {
-        strTitleAndYear.SetAt(i, ' ');
+        strTitleAndYear[i] = ' ';
       }
     }
   }
@@ -329,22 +329,22 @@ void CUtil::GetQualifiedFilename(const CStdString &strBasePath, CStdString &strF
   strFilename = URIUtils::AddFileToFolder(strBasePath, strFilename);
 
   // get rid of any /./ or \.\ that happen to be there
-  strFilename.Replace("\\.\\", "\\");
-  strFilename.Replace("/./", "/");
+  StringUtils::Replace(strFilename, "\\.\\", "\\");
+  StringUtils::Replace(strFilename, "/./", "/");
 
   // now find any "\\..\\" and remove them via GetParentPath
-  int pos;
-  while ((pos = strFilename.Find("/../")) > 0)
+  size_t pos;
+  while ((pos = strFilename.find("/../")) != std::string::npos)
   {
-    CStdString basePath = strFilename.Left(pos+1);
-    strFilename = strFilename.Mid(pos+4);
+    CStdString basePath = strFilename.substr(0, pos + 1);
+    strFilename.erase(0, pos + 4);
     basePath = URIUtils::GetParentPath(basePath);
     strFilename = URIUtils::AddFileToFolder(basePath, strFilename);
   }
-  while ((pos = strFilename.Find("\\..\\")) > 0)
+  while ((pos = strFilename.find("\\..\\")) != std::string::npos)
   {
-    CStdString basePath = strFilename.Left(pos+1);
-    strFilename = strFilename.Mid(pos+4);
+    CStdString basePath = strFilename.substr(0, pos + 1);
+    strFilename.erase(0, pos + 4);
     basePath = URIUtils::GetParentPath(basePath);
     strFilename = URIUtils::AddFileToFolder(basePath, strFilename);
   }
@@ -450,7 +450,7 @@ void CUtil::GetHomePath(CStdString& strPath, const CStdString& strTarget)
 #endif
     size_t last_sep = strHomePath.find_last_of(PATH_SEPARATOR_CHAR);
     if (last_sep != string::npos)
-      strPath = strHomePath.Left(last_sep);
+      strPath = strHomePath.substr(0, last_sep);
     else
       strPath = strHomePath;
   }
@@ -519,7 +519,7 @@ bool CUtil::ExcludeFileOrFolder(const CStdString& strFileOrFolder, const CStdStr
   if (strFileOrFolder.empty())
     return false;
 
-  CRegExp regExExcludes(true, true);  // case insensitive regex
+  CRegExp regExExcludes(true, CRegExp::autoUtf8);  // case insensitive regex
 
   for (unsigned int i = 0; i < regexps.size(); i++)
   {
@@ -552,7 +552,7 @@ int CUtil::GetDVDIfoTitle(const CStdString& strFile)
   CStdString strFilename = URIUtils::GetFileName(strFile);
   if (strFilename.Equals("video_ts.ifo")) return 0;
   //VTS_[TITLE]_0.IFO
-  return atoi(strFilename.Mid(4, 2).c_str());
+  return atoi(strFilename.substr(4, 2).c_str());
 }
 
 CStdString CUtil::GetFileMD5(const CStdString& strPath)
@@ -581,17 +581,12 @@ CStdString CUtil::GetFileMD5(const CStdString& strPath)
 bool CUtil::GetDirectoryName(const CStdString& strFileName, CStdString& strDescription)
 {
   CStdString strFName = URIUtils::GetFileName(strFileName);
-  strDescription = strFileName.Left(strFileName.size() - strFName.size());
+  strDescription = URIUtils::GetDirectory(strFileName);
   URIUtils::RemoveSlashAtEnd(strDescription);
 
-  int iPos = strDescription.ReverseFind("\\");
-  if (iPos < 0)
-    iPos = strDescription.ReverseFind("/");
-  if (iPos >= 0)
-  {
-    CStdString strTmp = strDescription.Right(strDescription.size()-iPos-1);
-    strDescription = strTmp;//strDescription.Right(strDescription.size() - iPos - 1);
-  }
+  size_t iPos = strDescription.find_last_of("/\\");
+  if (iPos != std::string::npos)
+    strDescription = strDescription.substr(iPos + 1);
   else if (strDescription.size() <= 0)
     strDescription = strFName;
   return true;
@@ -665,7 +660,8 @@ void CUtil::ClearSubtitles()
   {
     if (!items[i]->m_bIsFolder)
     {
-      if ( items[i]->GetPath().Find("subtitle") >= 0 || items[i]->GetPath().Find("vobsub_queue") >= 0 )
+      if (items[i]->GetPath().find("subtitle") != std::string::npos ||
+          items[i]->GetPath().find("vobsub_queue") != std::string::npos)
       {
         CLog::Log(LOGDEBUG, "%s - Deleting temporary subtitle %s", __FUNCTION__, items[i]->GetPath().c_str());
         CFile::Delete(items[i]->GetPath());
@@ -705,7 +701,7 @@ int64_t CUtil::ToInt64(uint32_t high, uint32_t low)
 
 CStdString CUtil::GetNextFilename(const CStdString &fn_template, int max)
 {
-  if (!fn_template.Find("%03d"))
+  if (fn_template.find("%03d") == std::string::npos)
     return "";
 
   CStdString searchPath = URIUtils::GetDirectory(fn_template);
@@ -728,7 +724,7 @@ CStdString CUtil::GetNextFilename(const CStdString &fn_template, int max)
 
 CStdString CUtil::GetNextPathname(const CStdString &path_template, int max)
 {
-  if (!path_template.Find("%04d"))
+  if (path_template.find("%04d") == std::string::npos)
     return "";
   
   for (int i = 0; i <= max; i++)
@@ -898,20 +894,20 @@ CStdString CUtil::MakeLegalFileName(const CStdString &strFile, int LegalType)
 {
   CStdString result = strFile;
 
-  result.Replace('/', '_');
-  result.Replace('\\', '_');
-  result.Replace('?', '_');
+  StringUtils::Replace(result, '/', '_');
+  StringUtils::Replace(result, '\\', '_');
+  StringUtils::Replace(result, '?', '_');
 
   if (LegalType == LEGAL_WIN32_COMPAT)
   {
     // just filter out some illegal characters on windows
-    result.Replace(':', '_');
-    result.Replace('*', '_');
-    result.Replace('?', '_');
-    result.Replace('\"', '_');
-    result.Replace('<', '_');
-    result.Replace('>', '_');
-    result.Replace('|', '_');
+    StringUtils::Replace(result, ':', '_');
+    StringUtils::Replace(result, '*', '_');
+    StringUtils::Replace(result, '?', '_');
+    StringUtils::Replace(result, '\"', '_');
+    StringUtils::Replace(result, '<', '_');
+    StringUtils::Replace(result, '>', '_');
+    StringUtils::Replace(result, '|', '_');
     StringUtils::TrimRight(result, ". ");
   }
   return result;
@@ -948,7 +944,7 @@ CStdString CUtil::ValidatePath(const CStdString &path, bool bFixDoubleSlashes /*
   // filenames. NOTE: Don't use IsInZip or IsInRar here since it will infinitely
   // recurse and crash XBMC
   if (URIUtils::IsURL(path) && 
-     (path.Find('%') >= 0 ||
+      (path.find('%') != std::string::npos ||
       StringUtils::StartsWithNoCase(path, "apk:") ||
       StringUtils::StartsWithNoCase(path, "zip:") ||
       StringUtils::StartsWithNoCase(path, "rar:") ||
@@ -961,36 +957,36 @@ CStdString CUtil::ValidatePath(const CStdString &path, bool bFixDoubleSlashes /*
 #ifdef TARGET_WINDOWS
   if (URIUtils::IsDOSPath(path))
   {
-    result.Replace('/', '\\');
+    StringUtils::Replace(result, '/', '\\');
     /* The double slash correction should only be used when *absolutely*
        necessary! This applies to certain DLLs or use from Python DLLs/scripts
        that incorrectly generate double (back) slashes.
     */
-    if (bFixDoubleSlashes)
+    if (bFixDoubleSlashes && !result.empty())
     {
       // Fixup for double back slashes (but ignore the \\ of unc-paths)
-      for (int x = 1; x < result.GetLength() - 1; x++)
+      for (size_t x = 1; x < result.size() - 1; x++)
       {
         if (result[x] == '\\' && result[x+1] == '\\')
-          result.Delete(x);
+          result.erase(x);
       }
     }
   }
-  else if (path.Find("://") >= 0 || path.Find(":\\\\") >= 0)
+  else if (path.find("://") != std::string::npos || path.find(":\\\\") != std::string::npos)
 #endif
   {
-    result.Replace('\\', '/');
+    StringUtils::Replace(result, '\\', '/');
     /* The double slash correction should only be used when *absolutely*
        necessary! This applies to certain DLLs or use from Python DLLs/scripts
        that incorrectly generate double (back) slashes.
     */
-    if (bFixDoubleSlashes)
+    if (bFixDoubleSlashes && !result.empty())
     {
       // Fixup for double forward slashes(/) but don't touch the :// of URLs
-      for (int x = 2; x < result.GetLength() - 1; x++)
+      for (size_t x = 2; x < result.size() - 1; x++)
       {
         if ( result[x] == '/' && result[x + 1] == '/' && !(result[x - 1] == ':' || (result[x - 1] == '/' && result[x - 2] == ':')) )
-          result.Delete(x);
+          result.erase(x);
       }
     }
   }
@@ -1034,12 +1030,12 @@ void CUtil::SplitExecFunction(const CStdString &execString, CStdString &function
 {
   CStdString paramString;
 
-  int iPos = execString.Find("(");
-  int iPos2 = execString.ReverseFind(")");
-  if (iPos > 0 && iPos2 > 0)
+  size_t iPos = execString.find("(");
+  size_t iPos2 = execString.rfind(")");
+  if (iPos != std::string::npos && iPos2 != std::string::npos)
   {
-    paramString = execString.Mid(iPos + 1, iPos2 - iPos - 1);
-    function = execString.Left(iPos);
+    paramString = execString.substr(iPos + 1, iPos2 - iPos - 1);
+    function = execString.substr(0, iPos);
   }
   else
     function = execString;
@@ -1047,7 +1043,7 @@ void CUtil::SplitExecFunction(const CStdString &execString, CStdString &function
   // remove any whitespace, and the standard prefix (if it exists)
   StringUtils::Trim(function);
   if( StringUtils::StartsWithNoCase(function, "xbmc.") )
-    function.Delete(0, 5);
+    function.erase(0, 5);
 
   SplitParams(paramString, parameters);
 }
@@ -1089,18 +1085,18 @@ void CUtil::SplitParams(const CStdString &paramString, std::vector<CStdString> &
       if (!inFunction && ch == ',')
       { // not in a function, so a comma signfies the end of this parameter
         if (whiteSpacePos)
-          parameter = parameter.Left(whiteSpacePos);
+          parameter = parameter.substr(0, whiteSpacePos);
         // trim off start and end quotes
-        if (parameter.GetLength() > 1 && parameter[0] == '"' && parameter[parameter.GetLength() - 1] == '"')
-          parameter = parameter.Mid(1,parameter.GetLength() - 2);
-        else if (parameter.GetLength() > 3 && parameter[parameter.GetLength() - 1] == '"')
+        if (parameter.length() > 1 && parameter[0] == '"' && parameter[parameter.length() - 1] == '"')
+          parameter = parameter.substr(1, parameter.length() - 2);
+        else if (parameter.length() > 3 && parameter[parameter.length() - 1] == '"')
         {
           // check name="value" style param.
-          int quotaPos = parameter.Find('"');
-          if (quotaPos > 1 && quotaPos < parameter.GetLength() - 1 && parameter[quotaPos - 1] == '=')
+          size_t quotaPos = parameter.find('"');
+          if (quotaPos > 1 && quotaPos < parameter.length() - 1 && parameter[quotaPos - 1] == '=')
           {
-            parameter.Delete(parameter.GetLength() - 1);
-            parameter.Delete(quotaPos);
+            parameter.erase(parameter.length() - 1);
+            parameter.erase(quotaPos);
           }
         }
         parameters.push_back(parameter);
@@ -1129,18 +1125,18 @@ void CUtil::SplitParams(const CStdString &paramString, std::vector<CStdString> &
   if (inFunction || inQuotes)
     CLog::Log(LOGWARNING, "%s(%s) - end of string while searching for ) or \"", __FUNCTION__, paramString.c_str());
   if (whiteSpacePos)
-    parameter = parameter.Left(whiteSpacePos);
+    parameter.erase(whiteSpacePos);
   // trim off start and end quotes
-  if (parameter.GetLength() > 1 && parameter[0] == '"' && parameter[parameter.GetLength() - 1] == '"')
-    parameter = parameter.Mid(1,parameter.GetLength() - 2);
-  else if (parameter.GetLength() > 3 && parameter[parameter.GetLength() - 1] == '"')
+  if (parameter.size() > 1 && parameter[0] == '"' && parameter[parameter.size() - 1] == '"')
+    parameter = parameter.substr(1,parameter.size() - 2);
+  else if (parameter.size() > 3 && parameter[parameter.size() - 1] == '"')
   {
     // check name="value" style param.
-    int quotaPos = parameter.Find('"');
-    if (quotaPos > 1 && quotaPos < parameter.GetLength() - 1 && parameter[quotaPos - 1] == '=')
+    size_t quotaPos = parameter.find('"');
+    if (quotaPos > 1 && quotaPos < parameter.length() - 1 && parameter[quotaPos - 1] == '=')
     {
-      parameter.Delete(parameter.GetLength() - 1);
-      parameter.Delete(quotaPos);
+      parameter.erase(parameter.length() - 1);
+      parameter.erase(quotaPos);
     }
   }
   if (!parameter.empty() || parameters.size())
@@ -1158,9 +1154,12 @@ int CUtil::GetMatchingSource(const CStdString& strPath1, VECSOURCES& VECSOURCES,
   // Check for special protocols
   CURL checkURL(strPath);
 
+  if (StringUtils::StartsWith(strPath, "special://skin/"))
+    return 1;
+
   // stack://
   if (checkURL.GetProtocol() == "stack")
-    strPath.Delete(0, 8); // remove the stack protocol
+    strPath.erase(0, 8); // remove the stack protocol
 
   if (checkURL.GetProtocol() == "shout")
     strPath = checkURL.GetHostName();
@@ -1173,7 +1172,7 @@ int CUtil::GetMatchingSource(const CStdString& strPath1, VECSOURCES& VECSOURCES,
 
   bIsSourceName = false;
   int iIndex = -1;
-  int iLength = -1;
+
   // we first test the NAME of a source
   for (int i = 0; i < (int)VECSOURCES.size(); ++i)
   {
@@ -1189,9 +1188,9 @@ int CUtil::GetMatchingSource(const CStdString& strPath1, VECSOURCES& VECSOURCES,
       // not a path, so we need to modify the source name
       // since we add the drive status and disc name to the source
       // "Name (Drive Status/Disc Name)"
-      int iPos = strName.ReverseFind('(');
-      if (iPos > 1)
-        strName = strName.Mid(0, iPos - 1);
+      size_t iPos = strName.rfind('(');
+      if (iPos != std::string::npos && iPos > 1)
+        strName = strName.substr(0, iPos - 1);
     }
     if (strPath.Equals(strName))
     {
@@ -1210,8 +1209,9 @@ int CUtil::GetMatchingSource(const CStdString& strPath1, VECSOURCES& VECSOURCES,
   ForceForwardSlashes(strDest);
   if (!URIUtils::HasSlashAtEnd(strDest))
     strDest += "/";
-  int iLenPath = strDest.size();
 
+  size_t iLength = 0;
+  size_t iLenPath = strDest.size();
   for (int i = 0; i < (int)VECSOURCES.size(); ++i)
   {
     CMediaSource share = VECSOURCES.at(i);
@@ -1245,7 +1245,7 @@ int CUtil::GetMatchingSource(const CStdString& strPath1, VECSOURCES& VECSOURCES,
       ForceForwardSlashes(strShare);
       if (!URIUtils::HasSlashAtEnd(strShare))
         strShare += "/";
-      int iLenShare = strShare.size();
+      size_t iLenShare = strShare.size();
 
       if ((iLenPath >= iLenShare) && StringUtils::StartsWithNoCase(strDest, strShare) && (iLenShare > iLength))
       {
@@ -1291,28 +1291,28 @@ CStdString CUtil::TranslateSpecialSource(const CStdString &strSpecial)
   if (!strSpecial.empty() && strSpecial[0] == '$')
   {
     if (StringUtils::StartsWithNoCase(strSpecial, "$home"))
-      return URIUtils::AddFileToFolder("special://home/", strSpecial.Mid(5));
+      return URIUtils::AddFileToFolder("special://home/", strSpecial.substr(5));
     else if (StringUtils::StartsWithNoCase(strSpecial, "$subtitles"))
-      return URIUtils::AddFileToFolder("special://subtitles/", strSpecial.Mid(10));
+      return URIUtils::AddFileToFolder("special://subtitles/", strSpecial.substr(10));
     else if (StringUtils::StartsWithNoCase(strSpecial, "$userdata"))
-      return URIUtils::AddFileToFolder("special://userdata/", strSpecial.Mid(9));
+      return URIUtils::AddFileToFolder("special://userdata/", strSpecial.substr(9));
     else if (StringUtils::StartsWithNoCase(strSpecial, "$database"))
-      return URIUtils::AddFileToFolder("special://database/", strSpecial.Mid(9));
+      return URIUtils::AddFileToFolder("special://database/", strSpecial.substr(9));
     else if (StringUtils::StartsWithNoCase(strSpecial, "$thumbnails"))
-      return URIUtils::AddFileToFolder("special://thumbnails/", strSpecial.Mid(11));
+      return URIUtils::AddFileToFolder("special://thumbnails/", strSpecial.substr(11));
     else if (StringUtils::StartsWithNoCase(strSpecial, "$recordings"))
-      return URIUtils::AddFileToFolder("special://recordings/", strSpecial.Mid(11));
+      return URIUtils::AddFileToFolder("special://recordings/", strSpecial.substr(11));
     else if (StringUtils::StartsWithNoCase(strSpecial, "$screenshots"))
-      return URIUtils::AddFileToFolder("special://screenshots/", strSpecial.Mid(12));
+      return URIUtils::AddFileToFolder("special://screenshots/", strSpecial.substr(12));
     else if (StringUtils::StartsWithNoCase(strSpecial, "$musicplaylists"))
-      return URIUtils::AddFileToFolder("special://musicplaylists/", strSpecial.Mid(15));
+      return URIUtils::AddFileToFolder("special://musicplaylists/", strSpecial.substr(15));
     else if (StringUtils::StartsWithNoCase(strSpecial, "$videoplaylists"))
-      return URIUtils::AddFileToFolder("special://videoplaylists/", strSpecial.Mid(15));
+      return URIUtils::AddFileToFolder("special://videoplaylists/", strSpecial.substr(15));
     else if (StringUtils::StartsWithNoCase(strSpecial, "$cdrips"))
-      return URIUtils::AddFileToFolder("special://cdrips/", strSpecial.Mid(7));
+      return URIUtils::AddFileToFolder("special://cdrips/", strSpecial.substr(7));
     // this one will be removed post 2.0
     else if (StringUtils::StartsWithNoCase(strSpecial, "$playlists"))
-      return URIUtils::AddFileToFolder(CSettings::Get().GetString("system.playlistspath"), strSpecial.Mid(10));
+      return URIUtils::AddFileToFolder(CSettings::Get().GetString("system.playlistspath"), strSpecial.substr(10));
   }
   return strSpecial;
 }
@@ -1357,7 +1357,7 @@ void CUtil::DeleteDirectoryCache(const CStdString &prefix)
     if (items[i]->m_bIsFolder)
       continue;
     CStdString fileName = URIUtils::GetFileName(items[i]->GetPath());
-    if (fileName.Left(prefix.GetLength()) == prefix)
+    if (StringUtils::StartsWith(fileName, prefix))
       XFILE::CFile::Delete(items[i]->GetPath());
   }
 }
@@ -1395,11 +1395,11 @@ void CUtil::GetRecursiveDirsListing(const CStdString& strPath, CFileItemList& it
 
 void CUtil::ForceForwardSlashes(CStdString& strPath)
 {
-  int iPos = strPath.ReverseFind('\\');
-  while (iPos > 0)
+  size_t iPos = strPath.rfind('\\');
+  while (iPos != string::npos)
   {
     strPath.at(iPos) = '/';
-    iPos = strPath.ReverseFind('\\');
+    iPos = strPath.rfind('\\');
   }
 }
 
@@ -1426,22 +1426,22 @@ double CUtil::AlbumRelevance(const CStdString& strAlbumTemp1, const CStdString&
   return fRelevance;
 }
 
-bool CUtil::MakeShortenPath(CStdString StrInput, CStdString& StrOutput, int iTextMaxLength)
+bool CUtil::MakeShortenPath(CStdString StrInput, CStdString& StrOutput, size_t iTextMaxLength)
 {
-  int iStrInputSize = StrInput.size();
-  if((iStrInputSize <= 0) || (iTextMaxLength >= iStrInputSize))
+  size_t iStrInputSize = StrInput.size();
+  if(iStrInputSize <= 0 || iTextMaxLength >= iStrInputSize)
     return false;
 
   char cDelim = '\0';
   size_t nGreaterDelim, nPos;
 
   nPos = StrInput.find_last_of( '\\' );
-  if ( nPos != CStdString::npos )
+  if (nPos != std::string::npos)
     cDelim = '\\';
   else
   {
     nPos = StrInput.find_last_of( '/' );
-    if ( nPos != CStdString::npos )
+    if (nPos != std::string::npos)
       cDelim = '/';
   }
   if ( cDelim == '\0' )
@@ -1450,13 +1450,13 @@ bool CUtil::MakeShortenPath(CStdString StrInput, CStdString& StrOutput, int iTex
   if (nPos == StrInput.size() - 1)
   {
     StrInput.erase(StrInput.size() - 1);
-    nPos = StrInput.find_last_of( cDelim );
+    nPos = StrInput.find_last_of(cDelim);
   }
   while( iTextMaxLength < iStrInputSize )
   {
     nPos = StrInput.find_last_of( cDelim, nPos );
     nGreaterDelim = nPos;
-    if ( nPos != CStdString::npos )
+    if ( nPos != std::string::npos )
       nPos = StrInput.find_last_of( cDelim, nPos - 1 );
     if ( nPos == CStdString::npos ) break;
     if ( nGreaterDelim > nPos ) StrInput.replace( nPos + 1, nGreaterDelim - nPos - 1, ".." );
@@ -1465,7 +1465,7 @@ bool CUtil::MakeShortenPath(CStdString StrInput, CStdString& StrOutput, int iTex
   // replace any additional /../../ with just /../ if necessary
   CStdString replaceDots = StringUtils::Format("..%c..", cDelim);
   while (StrInput.size() > (unsigned int)iTextMaxLength)
-    if (!StrInput.Replace(replaceDots, ".."))
+    if (!StringUtils::Replace(StrInput, replaceDots, ".."))
       break;
   // finally, truncate our string to force inside our max text length,
   // replacing the last 2 characters with ".."
@@ -1474,7 +1474,7 @@ bool CUtil::MakeShortenPath(CStdString StrInput, CStdString& StrOutput, int iTex
   // "smb://../Playboy Swimsuit Cal.."
   if (iTextMaxLength > 2 && StrInput.size() > (unsigned int)iTextMaxLength)
   {
-    StrInput = StrInput.Left(iTextMaxLength - 2);
+    StrInput.erase(iTextMaxLength - 2);
     StrInput += "..";
   }
   StrOutput = StrInput;
@@ -1540,11 +1540,11 @@ void CUtil::GetSkinThemes(vector<CStdString>& vecTheme)
     if (!pItem->m_bIsFolder)
     {
       CStdString strExtension = URIUtils::GetExtension(pItem->GetPath());
-      if ((strExtension == ".xpr" && pItem->GetLabel().CompareNoCase("Textures.xpr")) ||
-          (strExtension == ".xbt" && pItem->GetLabel().CompareNoCase("Textures.xbt")))
+      if ((strExtension == ".xpr" && !StringUtils::EqualsNoCase(pItem->GetLabel(), "Textures.xpr")) ||
+          (strExtension == ".xbt" && !StringUtils::EqualsNoCase(pItem->GetLabel(), "Textures.xbt")))
       {
         CStdString strLabel = pItem->GetLabel();
-        vecTheme.push_back(strLabel.Mid(0, strLabel.size() - 4));
+        vecTheme.push_back(strLabel.substr(0, strLabel.size() - 4));
       }
     }
   }
@@ -1899,7 +1899,7 @@ void CUtil::ScanForExternalSubtitles(const CStdString& strMovie, std::vector<CSt
     CMediaSettings::Get().SetAdditionalSubtitleDirectoryChecked(1);
   }
   
-  if (strMovie.Left(6) == "rar://") // <--- if this is found in main path then ignore it!
+  if (StringUtils::StartsWith(strMovie, "rar://")) // <--- if this is found in main path then ignore it!
   {
     CURL url(strMovie);
     CStdString strArchive = url.GetHostName();
@@ -2101,7 +2101,7 @@ int CUtil::ScanArchiveForSubtitles( const CStdString& strArchivePath, const CStd
    int iPos=0;
     while (sub_exts[iPos])
     {
-     if (strExt.CompareNoCase(sub_exts[iPos]) == 0)
+     if (StringUtils::EqualsNoCase(strExt, sub_exts[iPos]))
      {
       CStdString strSourceUrl;
       if (URIUtils::HasExtension(strArchivePath, ".rar"))
@@ -2130,8 +2130,8 @@ void CUtil::GetExternalStreamDetailsFromFilename(const CStdString& strVideo, con
   URIUtils::RemoveExtension(toParse);
 
   // we check left part - if it's same as video base name - strip it
-  if (toParse.Left(videoBaseName.length()).Equals(videoBaseName))
-    toParse = toParse.Mid(videoBaseName.length());
+  if (StringUtils::StartsWithNoCase(toParse, videoBaseName))
+    toParse = toParse.substr(videoBaseName.length());
 
   // trim any non-alphanumeric char in the begining
   std::string::iterator result = std::find_if(toParse.begin(), toParse.end(), ::isalnum);
@@ -2157,26 +2157,26 @@ void CUtil::GetExternalStreamDetailsFromFilename(const CStdString& strVideo, con
           continue;
         }
       }
-      if (info.flag == 0x1111)
+
+      // try to recognize a flag
+      std::string flag_tmp(*it);
+      StringUtils::ToLower(flag_tmp);
+      if (!flag_tmp.compare("none"))
       {
-        std::string  flag_tmp(*it);
-        StringUtils::ToLower(flag_tmp);
-        if (!flag_tmp.compare("none"))
-        {
-          info.flag = CDemuxStream::FLAG_NONE;
-          continue;
-        }
-        else if (!flag_tmp.compare("default"))
-        {
-          info.flag = CDemuxStream::FLAG_DEFAULT;
-          continue;
-        }
-        else if (!flag_tmp.compare("forced"))
-        {
-          info.flag = CDemuxStream::FLAG_FORCED;
-          continue;
-        }
+        info.flag |= CDemuxStream::FLAG_NONE;
+        continue;
       }
+      else if (!flag_tmp.compare("default"))
+      {
+        info.flag |= CDemuxStream::FLAG_DEFAULT;
+        continue;
+      }
+      else if (!flag_tmp.compare("forced"))
+      {
+        info.flag |= CDemuxStream::FLAG_FORCED;
+        continue;
+      }
+
       name += " " + (*it);
     }
   }
@@ -2184,7 +2184,7 @@ void CUtil::GetExternalStreamDetailsFromFilename(const CStdString& strVideo, con
   name += g_localizeStrings.Get(21602); // External
   StringUtils::Trim(name);
   info.name = StringUtils::RemoveDuplicatedSpacesAndTabs(name);
-  if (info.flag == 0x1111)
+  if (info.flag == 0)
     info.flag = CDemuxStream::FLAG_NONE;
 
   CLog::Log(LOGDEBUG, "%s - Language = '%s' / Name = '%s' / Flag = '%u' from %s", __FUNCTION__, info.language.c_str(), info.name.c_str(), info.flag, strStream.c_str());
@@ -2205,10 +2205,11 @@ bool CUtil::FindVobSubPair( const std::vector<CStdString>& vecSubtitles, const C
       CStdString strSubDirectory;
       URIUtils::Split(vecSubtitles[j], strSubDirectory, strSubFile);
       if (URIUtils::IsInArchive(vecSubtitles[j]))
-        CURL::Decode(strSubDirectory);
+        strSubDirectory = CURL::Decode(strSubDirectory);
       if (URIUtils::HasExtension(strSubFile, ".sub") &&
           (URIUtils::ReplaceExtension(strIdxFile,"").Equals(URIUtils::ReplaceExtension(strSubFile,"")) ||
-           strSubDirectory.Mid(6, strSubDirectory.length()-11).Equals(URIUtils::ReplaceExtension(strIdxPath,""))))
+           (strSubDirectory.size() >= 11 &&
+            StringUtils::EqualsNoCase(strSubDirectory.substr(6, strSubDirectory.length()-11), URIUtils::ReplaceExtension(strIdxPath,"")))))
       {
         strSubPath = vecSubtitles[j];
         return true;
@@ -2228,7 +2229,7 @@ bool CUtil::IsVobSub( const std::vector<CStdString>& vecSubtitles, const CStdStr
     CStdString strSubDirectory;
     URIUtils::Split(strSubPath, strSubDirectory, strSubFile);
     if (URIUtils::IsInArchive(strSubPath))
-      CURL::Decode(strSubDirectory);
+      strSubDirectory = CURL::Decode(strSubDirectory);
     for (unsigned int j=0; j < vecSubtitles.size(); j++)
     {
       CStdString strIdxFile;
@@ -2236,7 +2237,8 @@ bool CUtil::IsVobSub( const std::vector<CStdString>& vecSubtitles, const CStdStr
       URIUtils::Split(vecSubtitles[j], strIdxDirectory, strIdxFile);
       if (URIUtils::HasExtension(strIdxFile, ".idx") &&
           (URIUtils::ReplaceExtension(strIdxFile,"").Equals(URIUtils::ReplaceExtension(strSubFile,"")) ||
-           strSubDirectory.Mid(6, strSubDirectory.length()-11).Equals(URIUtils::ReplaceExtension(vecSubtitles[j],""))))
+           (strSubDirectory.size() >= 11 &&
+            StringUtils::EqualsNoCase(strSubDirectory.substr(6, strSubDirectory.length()-11), URIUtils::ReplaceExtension(vecSubtitles[j],"")))))
         return true;
     }
   }