Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Win32: fix path slashes #3374

Open
wants to merge 27 commits into from

6 participants

@Karlson2k
Collaborator

Allow to correctly process libbluray-generated filenames with several back- and forwardslashes.

Also contain some removal of CStdString.

This PR was done thanks to original @koying idea (original PR #3267).

@Karlson2k
Collaborator

jenkins build this please

xbmc/filesystem/HDFile.cpp
((12 lines not shown))
{
// file://drive[:]/path
// file:///drive:/path
- CStdString host( url.GetHostName() );
+ std::string host(url.GetHostName());
if(host.size() > 0)
@jmarshallnz Owner

No big deal, but mayaswell fix it to !host.empty()

@Karlson2k Collaborator

Missed it. Will fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/filesystem/windows/WINFileSMB.h
@@ -58,7 +58,7 @@ class CWINFileSMB : public IFile
virtual int IoControl(EIoControl request, void* param);
protected:
- CStdString GetLocal(const CURL &url); /* crate a properly format path from an url */
+ std::string GetLocal(const CURL &url); /* crate a properly format path from an url */
@jmarshallnz Owner

mayaswell fix the typo "create" - same above.

@Karlson2k Collaborator

OK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/filesystem/windows/WINSMBDirectory.h
@@ -31,7 +31,9 @@ class CWINSMBDirectory : public IDirectory
public:
CWINSMBDirectory(void);
virtual ~CWINSMBDirectory(void);
- virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items);
+ virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items)
+ { return GetDirectory((std::string)strPath, items); }
+ virtual bool GetDirectory(const std::string& strPath, CFileItemList &items);
@jmarshallnz Owner

IMO remove this - it will just make things less clear once all of IDirectory subclasses have CStdString removed.

@Karlson2k Collaborator

OK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/utils/URIUtils.cpp
((23 lines not shown))
- if (strFile.Left(8).CompareNoCase("iso9660:") == 0)
- return true;
+ if (str.length() >= 2 && str.compare(1, 1, ":", 1) == 0)
@jmarshallnz Owner

str.length check not required, and surely you want str[1] == ':' ?

@Karlson2k Collaborator

Actually, required. Got exception thrown when str is empty.
MS string implementation checks offset > size.
EDIT: it's C++ standard,

@jmarshallnz Owner

You already return false if str.length() < 2 above.

@Karlson2k Collaborator

Right. And after that I can erase first 4 chars.

@jmarshallnz Owner

Ah, yup - missed that. You want str[1] == ':' though I think?

@Karlson2k Collaborator

Thanks, this is exactly what I want. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmarshallnz jmarshallnz commented on the diff
xbmc/utils/URIUtils.cpp
((30 lines not shown))
- if (strFile.Left(5).CompareNoCase("cdda:") == 0)
+ if (str.compare(0, 4, "dvd:", 4) == 0 || str.compare(0, 4, "udf:", 4) == 0 ||
+ str.compare(0, 8, "iso9660:", 8) == 0 || str.compare(0, 5, "cdda:", 5) == 0)
@jmarshallnz Owner

These can all be StringUtils::StartsWith("dvd:") etc.

@Karlson2k Collaborator

Same as #3374 (comment) :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmarshallnz jmarshallnz commented on the diff
xbmc/utils/URIUtils.cpp
((16 lines not shown))
return true;
#if defined(TARGET_WINDOWS)
- if (StringUtils::StartsWithNoCase(strFile, "dvd://"))
+ if (strFileLow.compare(0, 5, "dvd://", 5) == 0 || strFileLow.compare(0, 5, "dvd:\\\\", 5) == 0)
@jmarshallnz Owner

StringUtils::StartsWith

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmarshallnz jmarshallnz commented on the diff
xbmc/utils/URIUtils.cpp
((21 lines not shown))
return true;
- if(strFile.Mid(1) != ":\\"
- && strFile.Mid(1) != ":")
+ if (strFileLow.compare(0, 4, "\\\\?\\", 4) == 0)
+ strFileLow.erase(0, 4);
+
+ if (strFileLow.length() < 2 || strFileLow.length() > 3)
+ return false;
+
+ if (strFileLow.compare(1, std::string::npos, ":\\", 2) != 0
+ && strFileLow.compare(1, std::string::npos, ":/", 2) != 0
+ && strFileLow.compare(1, std::string::npos, ":", 1) != 0)
@jmarshallnz Owner

Just use StringUtils::EndsWith()

@Karlson2k Collaborator

Can't. It should be at offset 1.

@jmarshallnz Owner

You check the length already, no? Or are you eliminating the ":\" path here?

@Karlson2k Collaborator

If strFile isn't "x:", "x:\" or "x:/" than this is not DVD :)

@jmarshallnz Owner

Let's leave it at this then - it's readable enough.

@t-nelson
t-nelson added a note

Just the last test should be enough, no?

@jmarshallnz Owner

_: is not a valid path. Nor is a:x.

@Karlson2k Collaborator

Right. Last test will match if the whole string is equal to "x:", without any suffixes.
Cases like "#:" or "(:/" will be handled by win32 GetDriveType.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmarshallnz jmarshallnz commented on the diff
xbmc/utils/URIUtils.cpp
((38 lines not shown))
return true;
#else
+ if (strFileLow.length() < 6 || strFileLow.length() > 10)
+ return false;
+
@jmarshallnz Owner

I really don't think this is worth doing.

@Karlson2k Collaborator

Discovered this while debugging. This functions called often, usually with long names. Size check will be much quicker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmarshallnz jmarshallnz commented on the diff
xbmc/utils/URIUtils.cpp
@@ -953,7 +966,7 @@ void URIUtils::RemoveSlashAtEnd(CStdString& strFolder)
}
while (HasSlashAtEnd(strFolder))
- strFolder.Delete(strFolder.size() - 1);
+ strFolder.erase(strFolder.size()-1, 1);
@jmarshallnz Owner

strFolder.pop_back() ?

@Karlson2k Collaborator

It's C++11, available only with MSVC (GCC in C++11 mode can't compile XBMC)

@jmarshallnz Owner

OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/win32/WIN32Util.cpp
((6 lines not shown))
{
- CStdString strRetPath(strPath);
- if(StringUtils::StartsWith(strRetPath, "\\\\"))
- {
- strRetPath = "smb:" + strPath;
- strRetPath.Replace("\\","/");
- }
- return strRetPath;
+ if (strPath.length() > 2 && strPath.compare(0, 2, "\\\\", 2) == 0 && strPath.compare(2, 2, "?\\", 2) != 0)
+ return "smb://" + strPath.substr(2);
+ return strPath;
@jmarshallnz Owner

The returned path is likely to contain mixed slashes. Why?

@Karlson2k Collaborator

It's in commit comment.
We don't care about it here. It's handled in File/Directory class anyway. No need to do it twice.

@jmarshallnz Owner

You KNOW you're return a path with invalid stuff here, and it's almost certain that someone will go and use this function somewhere else, assuming that it does the right thing.

@Karlson2k Collaborator

It's question of definitions. This path will be valid inside XBMC.
Just like path "c:/windows\system32\\Recovery/\" is valid on win32 (without \\?\ prefix).

@jmarshallnz Owner

The path is only valid inside XBMC if all code that deals with them knows to expect \ in a smb:// path. The trick here is that \ is already a valid character in smb:// paths, so it's ambiguous.

It just so happens that you're probably safe doing so, due to CUtil::ValidatePath() being done in CURL::Parse().

IMO it's good code to just transform things into the correct form whenever you know the form you want. In this case you want to take a DOS path and return a smb:// one. Thus, you know you want to convert the slashes. Mayaswell get it right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmarshallnz jmarshallnz commented on the diff
xbmc/win32/WIN32Util.cpp
((21 lines not shown))
{
- CStdString strRetPath(strPath);
- if(StringUtils::StartsWithNoCase(strRetPath, "smb://"))
- {
- strRetPath.Replace("smb://","\\\\");
- strRetPath.Replace("/","\\");
- }
- return strRetPath;
+ if(StringUtils::StartsWithNoCase(strPath, "smb://"))
+ return "\\\\" + strPath.substr(6);
+ return strPath;
@jmarshallnz Owner

The return path is likely to contain mixed slashes. Why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/win32/WIN32Util.cpp
@@ -517,6 +509,71 @@ bool CWIN32Util::RemoveExtraLongPathPrefix(std::wstring& path)
return false;
}
+std::string CWIN32Util::SmartFixWin32PathSlashes(const std::string& path)
+{
+ size_t startReplaceFrom;
+ if (path.compare(0, 4, "\\\\?\\", 4) == 0)
@jmarshallnz Owner

StringUtils::StartsWith

@Karlson2k Collaborator

Right. It's equal. But this way is faster.
Almost same readability. :)

@jmarshallnz Owner

It is faster, I agree (mostly because you've manually computed the strlen). It's easier to screw up though (I'm I supposed to count all those slashes to figure out that the length is 4 :p)

@Karlson2k Collaborator

This is why I think that form with explicit size is clearer. :)
And each function call cost a lot. With this short strings is much better to have minimal number of calls (as each call will produce relatively huge overhead).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/win32/WIN32Util.cpp
((37 lines not shown))
+
+ // skip any following slashes
+ do e++; while ((str[e] == '\\' || str[e] == '/')); // str is null-terminated, no need to check for buffer overrun
+ s = e; // start of next directory name
+ if (e == len)
+ break;
+ }
+ } while(++e < len);
+
+ if (s != e)
+ result.append(str + s, len - s); // last chars is not slash, append last subdirectory name
+
+ return result;
+}
+
+std::wstring CWIN32Util::ConverLocalPathToWin32Form(const std::string& pathUtf8)
@jmarshallnz Owner

Typo. Convert is spelt with a t.

@Karlson2k Collaborator

Ooops. Thanks!

@wsoltys Collaborator
wsoltys added a note

I would have expect this method to do local and unc paths rather than doing unc manually in the SMB classes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/win32/WIN32Util.cpp
@@ -517,6 +509,71 @@ bool CWIN32Util::RemoveExtraLongPathPrefix(std::wstring& path)
return false;
}
+std::string CWIN32Util::SmartFixWin32PathSlashes(const std::string& path)
+{
+ size_t startReplaceFrom;
+ if (path.compare(0, 4, "\\\\?\\", 4) == 0)
+ startReplaceFrom = 4;
+ else
+ startReplaceFrom = 0;
+
+ return SimpleFixWin32PathSlashes(path, startReplaceFrom);
+}
+
+std::string CWIN32Util::SimpleFixWin32PathSlashes(const std::string& path, size_t startPos /*= 0*/)
@jmarshallnz Owner

Do you ever need to call the "simple" version directly? Why not always call the "smart" version (thus eliminating the need for 2 separate functions?)

@Karlson2k Collaborator

"Simple" version is called from WinSMBFile/Directory

@Karlson2k Collaborator

They can be changed to overloads, but I'm not sure that overload is better.

@jmarshallnz Owner

The Smart version is only called once, so I'd either cover that in the simple version anyway (it doesn't hurt to do the check + skip) or eliminate the smart version in the one spot it's called.

@wsoltys Collaborator
wsoltys added a note

Just for my understanding: What is this method doing exactly?
Isn't it just this (without the startPos) or do I miss something?
if(URIUtils::IsDOSPath(path))
path.replace("/","\");
else
path.replace("\,"/");

@jmarshallnz Owner

Yes, but it also removes duplicate slashes (my version below might be a bit more obvious?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xbmc/win32/WIN32Util.cpp
((27 lines not shown))
+ {
+ if (str[e] == '\\' || str[e] == '/')
+ { // found first slash after non-slash chars
+ if (str[e] == '\\' )
+ result.append(str + s, e - s + 1); // append directory name with slash
+ else
+ {
+ result.append(str + s, e - s); // append directory name
+ result.push_back('\\'); // append slash
+ }
+
+ // skip any following slashes
+ do e++; while ((str[e] == '\\' || str[e] == '/')); // str is null-terminated, no need to check for buffer overrun
+ s = e; // start of next directory name
+ if (e == len)
+ break;
@jmarshallnz Owner

All to stop the ++e, right? Seems to me like a different looping construct might yield more readable code? Either something using find_first_of/find_first_not_of, or just a per-character routine:

size_t pos = 0, len = str.size();
while (str[pos])
{
  if (str[pos] == '/' || str[pos] == '\\')
  {
    result += '\\';
    // skip extra slashes (safe due to null-termination)
    while (str[pos] == '/' || str[pos] == '\\')
      pos++;
  }
  else
    result += str[pos++];
}
@Karlson2k Collaborator

Right, this 'if' can be removed. It was needed in previous version of code.

@jmarshallnz Owner

I think the check is needed in your current code, as you're avoiding the pre-increment in the while condition, which will screw up the s != e check later.

IMO my version is just as good and easier to read.

@Karlson2k Collaborator

@jmarshallnz
I'll implement this in your way, but with small change: while .c_str() is guaranteed to be null-terminated, operator[] at pos == length has undefined behavior. So I'll convert string to C-string at first. And processing C-array is much faster that using std::string::operator[].

@jmarshallnz Owner

Agreed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@wsoltys
Collaborator

While this is really nice work I would like to see that you keep things simple. The last amount of speed isn't that important over readability. Just keep that in mind please.

@Karlson2k
Collaborator

After some code analysis I think that best way is to do:

  1. In CUtil::ValidatePath() process all possible path types, including smb:// and "\\server\share\" form on Win32. Correct slashes at this point.
  2. in CURL::Parse() process "\\server\share" paths on Win32 just like "smb://" paths
  3. In all xFile/xDirectory classes do not apply additional correction (slashes), as path in always processed by CURL
  4. Remove SmbToUnc and UncToSmb function and use standard CFile interface to open, move, rename files.
@wsoltys
Collaborator

Remove SmbToUnc and UncToSmb function and use standard CFile interface to open, move, rename files.

Please reconsider this. At least for winexception I used the plain windows api intentional. At this point I don't want to depend on any XBMC api.

@Karlson2k
Collaborator

@wsoltys OK, no problem.
For winexpection we can use ValidatePath -> SmbToUnc. Both are only string processing function.

@jmarshallnz
Owner

I strongly recommend not relying on CUtil::ValidatePath. Ideally we'd completely remove it from CURL, as ideally CURL(string).Get() == string. (I suspect this is wishful thinking, but at least it's something we should aspire to).

i.e. in functions where you know you're the form the URL must be in, convert it directly. In other functions, don't - we don't want paths mysteriously changing due to passing through CURL at a point we weren't expecting.

@ghost

imo the constructor should be made explicit to avoid such surprises.

@jmarshallnz
Owner

I don't think that functions that take CURL are necessarily the problem (though no reason not to make it explicit as you say), rather it's some path processing that goes via CURL and is then reconstructed.

Things like URIUtils::AddFileToFolder() can process the string via CURL, and the "folder" bit may well change due to this behaviour, even though it shouldn't need to.

@Karlson2k
Collaborator

There is no problem to make CURL to simple process string as is, without any correction. In that case CURL will fill host/protocol/username etc. only when incoming string is stricly fit one of URL templates, in other cases store string as filepath. Then we get CURL(string).Get() ==string.
But we need to rewrite all file/directory classes as most of them process paths through CURL to correct it. Is it what we want?

@wsoltys
Collaborator

Rome wasn't fixed in one day either ;)
Why not just create a convert method which handles unc and local path (slash stripping, conversion, etc) which is then called in the file/directory classes as we do already?
Then the bug is fixed and we have enough time to discuss further fixes (if any needed).

@Karlson2k
Collaborator

jenkins build this please

@Karlson2k
Collaborator

@jmarshallnz Now path is minimally modified by CURL or by ValidatePath. Slashes are fixed inside File/Directory classes.
@wsoltys ConverPathToWin32Form now works with all types of Win32 path. HDFile and Win32SMBFile works similar. UncToSmb was removed, SmbToUnc still in place.

@wsoltys
Collaborator

UNC paths are supported directly

Mind explaining that a little? Goal was that internally only smb:// paths should be used. Is this path translated later or do we again mixing unc and smb paths inside XBMC?

Collaborator

Path is translated to smb:// in CURL::Parse.
So CURL("\server\share\folder\file").Get() == "smb://server/share/folder/file"
See e9ec286

@wsoltys
Collaborator

mmh, wouldn't it better then to rename this function?

Collaborator

Than we have to rename it in many places.
undef is enough and used in safe way (ifdef - undef -endif)

@wsoltys
Collaborator

Wouldn't it be better to fix IsLocal() directly?

Collaborator

IsLocal is OK for itself name, just wrongly used here.

@wsoltys
Collaborator

You really show great effort in fixing stuff which I appreciate therefore don't get me wrong on the following ;)
What was the pr about at first place? A bugfix. What is it now? A mixture of cosmetic changes, CStdString removal, optimisations and somewhere hidden the bugfix.
I would assume the bugfix would have been already accepted if it would be the only change. But now this pr gets bigger and bigger for every iteration.
I would suggest that you again put some thoughts on the bugfix only and split that from the rest. The first approach doesn't have to be 100% correct, 80% is enough :P

@Karlson2k
Collaborator

@wsoltys I don't want to use CStdString in new code, that force me to rewrite other functions.
I can try to split this PR to several PRs, just share your thoughts - what's good and what's wrong in this PR.

@elupus elupus commented on the diff
xbmc/URL.cpp
((78 lines not shown))
- if(strProtocol2.Equals("http")
- || strProtocol2.Equals("https")
- || strProtocol2.Equals("plugin")
- || strProtocol2.Equals("addons")
- || strProtocol2.Equals("hdhomerun")
- || strProtocol2.Equals("rtsp")
- || strProtocol2.Equals("apk")
- || strProtocol2.Equals("zip"))
+ else if (strProtocol2 == "http"
+ || strProtocol2 == "https"
+ || strProtocol2 == "plugin"
+ || strProtocol2 == "addons"
+ || strProtocol2 == "hdhomerun"
+ || strProtocol2 == "rtsp"
+ || strProtocol2 == "apk"
+ || strProtocol2 == "zip")
@elupus Collaborator
elupus added a note

Try to keep the strProtocol... checks in line with the first one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@elupus
Collaborator

It's rather unreviewable due to the removal of cstdtring thou :(

@Karlson2k
Collaborator

@elupus Bug fix only: #3408

@wsoltys wsoltys was assigned
@wsoltys
Collaborator

@Karlson2k can we close this in favor of #3408 or do you want to update it?

@Karlson2k
Collaborator

I'd like to update it, it has more fixes

@wsoltys
Collaborator
@Karlson2k
Collaborator

@wsoltys Will do it after UTF-8 fixes.

@MartijnKaijser

nudge if still needed

@Karlson2k
Collaborator

Need to review it.
OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 3, 2013
  1. @Karlson2k

    [win32] WIN32Util: update UncToSmb and SmbToUnc

    Karlson2k authored
    No need to replace all slashes, they will be replaced in File/Directory class anyway
  2. @Karlson2k
  3. @Karlson2k
  4. @Karlson2k
Commits on Oct 5, 2013
  1. @Karlson2k
  2. @Karlson2k
  3. @Karlson2k
Commits on Oct 8, 2013
  1. @Karlson2k
  2. @Karlson2k
  3. @Karlson2k
  4. @Karlson2k
  5. @Karlson2k
  6. @Karlson2k
  7. @Karlson2k
  8. @Karlson2k
  9. @Karlson2k

    [win32] CURL::GetDirectorySeparator: fix

    Karlson2k authored
    IsLocal() returns true for network files on localhost
  10. @Karlson2k
  11. @Karlson2k

    CURL::Parse: optimization

    Karlson2k authored
  12. @Karlson2k
Commits on Oct 9, 2013
  1. @Karlson2k
  2. @Karlson2k
  3. @Karlson2k
  4. @Karlson2k
  5. @Karlson2k
  6. @Karlson2k
  7. @Karlson2k
  8. @Karlson2k

    WIN32Util: remove UncToSmb functions

    Karlson2k authored
    UNC paths are supported directly
This page is out of date. Refresh to see the latest.
View
329 xbmc/URL.cpp
@@ -43,7 +43,7 @@ CStdString URLEncodeInline(const CStdString& strData)
return buffer;
}
-CURL::CURL(const CStdString& strURL1)
+CURL::CURL(const std::string& strURL1)
{
Parse(strURL1);
}
@@ -74,50 +74,70 @@ void CURL::Reset()
m_iPort = 0;
}
-void CURL::Parse(const CStdString& strURL1)
+void CURL::Parse(const std::string& strURL1)
{
Reset();
// start by validating the path
- CStdString strURL = CUtil::ValidatePath(strURL1);
+ std::string strURL(CUtil::ValidatePath(strURL1));
// strURL can be one of the following:
// format 1: protocol://[username:password]@hostname[:port]/directoryandfile
// format 2: protocol://file
- // format 3: drive:directoryandfile
+ // format 3: drive:directoryandfile (or (win32 only) \\?\drive:directoryandfile)
+ // format 4 (win32 only): \\Server\Share\directoryandfile (or \\?\UNC\Server\Share\directoryandfile)
//
// first need 2 check if this is a protocol or just a normal drive & path
- if (!strURL.size()) return ;
- if (strURL.Equals("?", true)) return;
+ if (strURL.empty())
+ return;
+ if (strURL == "?")
+ return;
+
+#ifdef TARGET_WINDOWS
+ if (StringUtils::StartsWith(strURL, "\\\\"))
+ {
+ size_t serverNamePos;
+ if (strURL.length() > 8 && strURL.compare(2, 6, "?\\UNC\\", 6) == 0) // win32 long UNC path
+ serverNamePos = 8;
+ else if (strURL.length() > 3 && strURL.compare(2, 2, "?\\", 2) == 0) // win32 long local path
+ {
+ SetFileName(strURL);
+ return;
+ }
+ else
+ serverNamePos = 2; // win32 "\\server\share\file" path
+
+ strURL = "smb://" + CUtil::FixSlashes(strURL.substr(serverNamePos), false, true); // handling of "smb://" require forward slashes
+ }
+#endif // TARGET_WINDOWS
// form is format 1 or 2
// format 1: protocol://[domain;][username:password]@hostname[:port]/directoryandfile
// format 2: protocol://file
// decode protocol
- int iPos = strURL.Find("://");
- if (iPos < 0)
+ size_t iPos = strURL.find("://");
+ if (iPos == std::string::npos)
{
// This is an ugly hack that needs some work.
// example: filename /foo/bar.zip/alice.rar/bob.avi
// This should turn into zip://rar:///foo/bar.zip/alice.rar/bob.avi
iPos = 0;
- bool is_apk = (strURL.Find(".apk/", iPos) > 0);
while (1)
{
- if (is_apk)
- iPos = strURL.Find(".apk/", iPos);
- else
- iPos = strURL.Find(".zip/", iPos);
+ iPos = strURL.find(".apk/", iPos);
+ const bool is_apk = (iPos != std::string::npos);
- int extLen = 3;
- if (iPos < 0)
+ if (!is_apk)
+ iPos = strURL.find(".zip/", iPos);
+
+ if (iPos == std::string::npos)
{
/* set filename and update extension*/
SetFileName(strURL);
- return ;
+ return;
}
- iPos += extLen + 1;
- CStdString archiveName = strURL.Left(iPos);
+ iPos += 4; // length of ".apk" or ".zip"
+ std::string archiveName(strURL, 0, iPos);
struct __stat64 s;
if (XFILE::CFile::Stat(archiveName, &s) == 0)
{
@@ -130,12 +150,12 @@ void CURL::Parse(const CStdString& strURL1)
Encode(archiveName);
if (is_apk)
{
- CURL c((CStdString)"apk" + "://" + archiveName + '/' + strURL.Right(strURL.size() - iPos - 1));
+ CURL c((std::string)"apk" + "://" + archiveName + '/' + strURL.substr(iPos + 1));
*this = c;
}
else
{
- CURL c((CStdString)"zip" + "://" + archiveName + '/' + strURL.Right(strURL.size() - iPos - 1));
+ CURL c((std::string)"zip" + "://" + archiveName + '/' + strURL.substr(iPos + 1));
*this = c;
}
return;
@@ -145,67 +165,73 @@ void CURL::Parse(const CStdString& strURL1)
}
else
{
- SetProtocol(strURL.Left(iPos));
- iPos += 3;
+ SetProtocol(strURL.substr(0, iPos));
+ iPos += 3; // length of "://"
}
- // virtual protocols
- // why not handle all format 2 (protocol://file) style urls here?
- // ones that come to mind are iso9660, cdda, musicdb, etc.
- // they are all local protocols and have no server part, port number, special options, etc.
- // this removes the need for special handling below.
- if (
- m_strProtocol.Equals("stack") ||
- m_strProtocol.Equals("virtualpath") ||
- m_strProtocol.Equals("multipath") ||
- m_strProtocol.Equals("filereader") ||
- m_strProtocol.Equals("special")
- )
+ // virtual protocols / local protocols
+ // they have no server part, port number, special options, etc.
+ // FIXME: add more protocols here?
+ if ( m_strProtocol == "stack" ||
+ m_strProtocol == "virtualpath" ||
+ m_strProtocol == "multipath" ||
+ m_strProtocol == "filereader" ||
+ m_strProtocol == "special" ||
+ m_strProtocol == "iso9660" ||
+ m_strProtocol == "musicdb" ||
+ m_strProtocol == "videodb" ||
+ m_strProtocol == "sources" ||
+ m_strProtocol == "pvr" ||
+ m_strProtocol == "cdda" ||
+ m_strProtocol.compare(0, 3, "mem", 3) == 0)
{
- SetFileName(strURL.Mid(iPos));
+ SetFileName(strURL.substr(iPos));
return;
}
- // check for username/password - should occur before first /
- if (iPos == -1) iPos = 0;
+ const size_t strLen = strURL1.length();
+
+ if (iPos >= strLen)
+ return;
+
+ if (iPos == std::string::npos)
+ iPos = 0;
// for protocols supporting options, chop that part off here
- // maybe we should invert this list instead?
- int iEnd = strURL.length();
+ size_t iEnd = strLen;
const char* sep = NULL;
//TODO fix all Addon paths
- CStdString strProtocol2 = GetTranslatedProtocol();
- if(m_strProtocol.Equals("rss") ||
- m_strProtocol.Equals("rar") ||
- m_strProtocol.Equals("addons") ||
- m_strProtocol.Equals("image") ||
- m_strProtocol.Equals("videodb") ||
- m_strProtocol.Equals("musicdb") ||
- m_strProtocol.Equals("androidapp"))
+ std::string strProtocol2(GetTranslatedProtocol());
+ if (m_strProtocol == "rss" ||
+ m_strProtocol == "rar" ||
+ m_strProtocol == "addons" ||
+ m_strProtocol == "image" ||
+ m_strProtocol == "videodb" ||
+ m_strProtocol == "musicdb" ||
+ m_strProtocol == "androidapp")
sep = "?";
- else
- if(strProtocol2.Equals("http")
- || strProtocol2.Equals("https")
- || strProtocol2.Equals("plugin")
- || strProtocol2.Equals("addons")
- || strProtocol2.Equals("hdhomerun")
- || strProtocol2.Equals("rtsp")
- || strProtocol2.Equals("apk")
- || strProtocol2.Equals("zip"))
+ else if (strProtocol2 == "http"
+ || strProtocol2 == "https"
+ || strProtocol2 == "plugin"
+ || strProtocol2 == "addons"
+ || strProtocol2 == "hdhomerun"
+ || strProtocol2 == "rtsp"
+ || strProtocol2 == "apk"
+ || strProtocol2 == "zip")
@elupus Collaborator
elupus added a note

Try to keep the strProtocol... checks in line with the first one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
sep = "?;#|";
- else if(strProtocol2.Equals("ftp")
- || strProtocol2.Equals("ftps"))
+ else if (strProtocol2 == "ftp"
+ || strProtocol2 == "ftps")
sep = "?;|";
- if(sep)
+ if (sep)
{
- int iOptions = strURL.find_first_of(sep, iPos);
- if (iOptions >= 0 )
+ const size_t iOptions = strURL.find_first_of(sep, iPos);
+ if (iOptions != std::string::npos)
{
// we keep the initial char as it can be any of the above
- int iProto = strURL.find_first_of("|",iOptions);
- if (iProto >= 0)
+ const size_t iProto = strURL.find('|', iOptions);
+ if (iProto != std::string::npos)
{
SetProtocolOptions(strURL.substr(iProto+1));
SetOptions(strURL.substr(iOptions,iProto-iOptions));
@@ -216,129 +242,94 @@ void CURL::Parse(const CStdString& strURL1)
}
}
- int iSlash = strURL.Find("/", iPos);
- if(iSlash >= iEnd)
- iSlash = -1; // was an invalid slash as it was contained in options
+ size_t iSlash = strURL.find('/', iPos);
+ if (iSlash != std::string::npos && iSlash >= iEnd)
+ iSlash = std::string::npos; // was an invalid slash as it was contained in options
- if( !m_strProtocol.Equals("iso9660") )
+ // check for username/password - should occur before first '/'
+ const size_t iAlphaSign = strURL.find('@', iPos);
+ if (iAlphaSign != std::string::npos && iAlphaSign < iEnd && iAlphaSign < iSlash)
{
- int iAlphaSign = strURL.Find("@", iPos);
- if (iAlphaSign >= 0 && iAlphaSign < iEnd && (iAlphaSign < iSlash || iSlash < 0))
- {
- // username/password found
- CStdString strUserNamePassword = strURL.Mid(iPos, iAlphaSign - iPos);
+ // username/password found
+ std::string strUserNamePassword(strURL, iPos, iAlphaSign - iPos);
- // first extract domain, if protocol is smb
- if (m_strProtocol.Equals("smb"))
- {
- int iSemiColon = strUserNamePassword.Find(";");
+ // first extract domain, if protocol is smb
+ if (m_strProtocol.Equals("smb"))
+ {
+ const size_t iSemiColon = strUserNamePassword.find(';');
- if (iSemiColon >= 0)
- {
- m_strDomain = strUserNamePassword.Left(iSemiColon);
- strUserNamePassword.Delete(0, iSemiColon + 1);
- }
+ if (iSemiColon != std::string::npos && iSemiColon < strUserNamePassword.find(':'))
+ { // domain;username
+ m_strDomain = strUserNamePassword.substr(0, iSemiColon);
+ strUserNamePassword.erase(0, iSemiColon + 1);
}
+ }
- // username:password
- int iColon = strUserNamePassword.Find(":");
- if (iColon >= 0)
- {
- m_strUserName = strUserNamePassword.Left(iColon);
- iColon++;
- m_strPassword = strUserNamePassword.Right(strUserNamePassword.size() - iColon);
- }
- // username
- else
- {
- m_strUserName = strUserNamePassword;
- }
+ const size_t iColon = strUserNamePassword.find(':');
+ if (iColon != std::string::npos)
+ { // username:password
+ m_strUserName = strUserNamePassword.substr(0, iColon);
+ m_strPassword = strUserNamePassword.substr(iColon + 1);
+ }
+ else // username
+ m_strUserName = strUserNamePassword;
- iPos = iAlphaSign + 1;
- iSlash = strURL.Find("/", iAlphaSign);
+ iPos = iAlphaSign + 1;
+ iSlash = strURL.find('/', iAlphaSign);
- if(iSlash >= iEnd)
- iSlash = -1;
- }
+ if (iSlash >= iEnd)
+ iSlash = std::string::npos;
}
+ if (iPos >= strLen)
+ return;
+
// detect hostname:port/
- if (iSlash < 0)
+ if (iSlash == std::string::npos)
{
- CStdString strHostNameAndPort = strURL.Mid(iPos, iEnd - iPos);
- int iColon = strHostNameAndPort.Find(":");
- if (iColon >= 0)
+ std::string strHostNameAndPort(strURL, iPos, iEnd - iPos);
+ const size_t iColon = strHostNameAndPort.find(':');
+ if (iColon != std::string::npos)
{
- m_strHostName = strHostNameAndPort.Left(iColon);
- iColon++;
- CStdString strPort = strHostNameAndPort.Right(strHostNameAndPort.size() - iColon);
+ m_strHostName = strHostNameAndPort.substr(0, iColon);
+ std::string strPort(strHostNameAndPort, iColon + 1);
m_iPort = atoi(strPort.c_str());
}
else
- {
m_strHostName = strHostNameAndPort;
- }
}
else
{
- CStdString strHostNameAndPort = strURL.Mid(iPos, iSlash - iPos);
- int iColon = strHostNameAndPort.Find(":");
- if (iColon >= 0)
+ std::string strHostNameAndPort(strURL, iPos, iSlash - iPos);
+ const size_t iColon = strHostNameAndPort.find(':');
+ if (iColon != std::string::npos)
{
- m_strHostName = strHostNameAndPort.Left(iColon);
- iColon++;
- CStdString strPort = strHostNameAndPort.Right(strHostNameAndPort.size() - iColon);
+ m_strHostName = strHostNameAndPort.substr(iColon);
+ std::string strPort(strHostNameAndPort, 0, iColon + 1);
m_iPort = atoi(strPort.c_str());
}
else
- {
m_strHostName = strHostNameAndPort;
- }
+
iPos = iSlash + 1;
if (iEnd > iPos)
{
- m_strFileName = strURL.Mid(iPos, iEnd - iPos);
+ m_strFileName = strURL.substr(iPos, iEnd - iPos);
- iSlash = m_strFileName.Find("/");
- if(iSlash < 0)
+ iSlash = m_strFileName.find('/');
+ if (iSlash == std::string::npos)
m_strShareName = m_strFileName;
else
- m_strShareName = m_strFileName.Left(iSlash);
+ m_strShareName = m_strFileName.substr(0, iSlash);
}
}
- // iso9960 doesnt have an hostname;-)
- if (m_strProtocol.CompareNoCase("iso9660") == 0
- || m_strProtocol.CompareNoCase("musicdb") == 0
- || m_strProtocol.CompareNoCase("videodb") == 0
- || m_strProtocol.CompareNoCase("sources") == 0
- || m_strProtocol.CompareNoCase("pvr") == 0
- || m_strProtocol.Left(3).CompareNoCase("mem") == 0)
- {
- if (m_strHostName != "" && m_strFileName != "")
- {
- CStdString strFileName = m_strFileName;
- m_strFileName.Format("%s/%s", m_strHostName.c_str(), strFileName.c_str());
- m_strHostName = "";
- }
- else
- {
- if (!m_strHostName.IsEmpty() && strURL[iEnd-1]=='/')
- m_strFileName = m_strHostName + "/";
- else
- m_strFileName = m_strHostName;
- m_strHostName = "";
- }
- }
-
- m_strFileName.Replace("\\", "/");
-
/* update extension */
SetFileName(m_strFileName);
/* decode urlencoding on this stuff */
- if(URIUtils::ProtocolHasEncodedHostname(m_strProtocol))
+ if (URIUtils::ProtocolHasEncodedHostname(m_strProtocol))
{
Decode(m_strHostName);
// Validate it as it is likely to contain a filename
@@ -349,18 +340,20 @@ void CURL::Parse(const CStdString& strURL1)
Decode(m_strPassword);
}
-void CURL::SetFileName(const CStdString& strFileName)
+void CURL::SetFileName(const std::string& strFileName)
{
m_strFileName = strFileName;
- int slash = m_strFileName.find_last_of(GetDirectorySeparator());
- int period = m_strFileName.find_last_of('.');
- if(period != -1 && (slash == -1 || period > slash))
+ size_t slash = m_strFileName.find_last_of(GetDirectorySeparator());
+ size_t period = m_strFileName.find_last_of('.');
+ if (period != std::string::npos && (slash == std::string::npos || period > slash))
+ {
m_strFileType = m_strFileName.substr(period+1);
+ StringUtils::Trim(m_strFileType);
+ StringUtils::ToLower(m_strFileType);
+ }
else
- m_strFileType = "";
-
- m_strFileType.Normalize();
+ m_strFileType.clear();
}
void CURL::SetHostName(const CStdString& strHostName)
@@ -502,8 +495,8 @@ const CStdString CURL::GetFileNameWithoutPath() const
char CURL::GetDirectorySeparator() const
{
-#ifndef TARGET_POSIX
- if ( IsLocal() )
+#ifdef TARGET_WINDOWS
+ if (m_strProtocol.empty() || m_strProtocol == "file")
return '\\';
else
#endif
@@ -726,28 +719,22 @@ void CURL::Decode(CStdString& strURLData)
strURLData = strResult;
}
-void CURL::Encode(CStdString& strURLData)
+void CURL::Encode(std::string& strURLData)
{
- CStdString strResult;
+ std::string strResult;
/* wonder what a good value is here is, depends on how often it occurs */
- strResult.reserve( strURLData.length() * 2 );
+ strResult.reserve(strURLData.length() * 2);
- for (int i = 0; i < (int)strURLData.size(); ++i)
+ for (size_t i = 0; i < strURLData.length(); ++i)
{
- int kar = (unsigned char)strURLData[i];
- //if (kar == ' ') strResult += '+'; // obsolete
+ const int kar = (unsigned char)strURLData[i];
if (isalnum(kar) || strchr("-_.!()" , kar) ) // Don't URL encode these according to RFC1738
- {
- strResult += kar;
- }
+ strResult.push_back((unsigned char)kar);
else
- {
- CStdString strTmp;
- strTmp.Format("%%%02.2x", kar);
- strResult += strTmp;
- }
+ strResult += StringUtils::Format("%%%02.2x", kar);
}
+
strURLData = strResult;
}
@@ -760,7 +747,7 @@ std::string CURL::Decode(const std::string& strURLData)
std::string CURL::Encode(const std::string& strURLData)
{
- CStdString url = strURLData;
+ std::string url = strURLData;
Encode(url);
return url;
}
View
11 xbmc/URL.h
@@ -24,18 +24,21 @@
#ifdef TARGET_WINDOWS
#undef SetPort // WIN32INCLUDES this is defined as SetPortA in WinSpool.h which is being included _somewhere_
+#ifdef GetUserName
+#undef GetUserName
+#endif // GetUserName
#endif
class CURL
{
public:
- CURL(const CStdString& strURL);
+ CURL(const std::string& strURL);
CURL();
virtual ~CURL(void);
void Reset();
- void Parse(const CStdString& strURL);
- void SetFileName(const CStdString& strFileName);
+ void Parse(const std::string& strURL);
+ void SetFileName(const std::string& strFileName);
void SetHostName(const CStdString& strHostName);
void SetUserName(const CStdString& strUserName);
void SetPassword(const CStdString& strPassword);
@@ -70,7 +73,7 @@ class CURL
static bool IsFileOnly(const CStdString &url); ///< return true if there are no directories in the url.
static bool IsFullPath(const CStdString &url); ///< return true if the url includes the full path
static void Decode(CStdString& strURLData);
- static void Encode(CStdString& strURLData);
+ static void Encode(std::string& strURLData);
static std::string Decode(const std::string& strURLData);
static std::string Encode(const std::string& strURLData);
static CStdString TranslateProtocol(const CStdString& prot);
View
79 xbmc/Util.cpp
@@ -897,6 +897,38 @@ bool CUtil::CreateDirectoryEx(const CStdString& strPath)
return true;
}
+std::string CUtil::FixSlashes(const std::string& path, const bool removeDuplicated /*= false*/, const bool useForwardSlashes /*= true*/, const size_t startFrom /*= 0*/)
+{
+ const size_t len = path.length();
+ if (startFrom >= len)
+ return path;
+
+ std::string result(path, 0, startFrom);
+ result.reserve(len);
+
+ const char targetSlash = useForwardSlashes ? '/' : '\\';
+ const char* const str = path.c_str();
+ size_t pos = startFrom;
+ do
+ {
+ if (str[pos] == '\\' || str[pos] == '/')
+ {
+ result.push_back(targetSlash); // append one slash
+ pos++;
+ if (removeDuplicated)
+ { // skip any following slashes
+ while (str[pos] == '\\' || str[pos] == '/') // str is null-terminated, no need to check for buffer overrun
+ pos++;
+ }
+ }
+ else
+ result.push_back(str[pos++]); // append current char and advance pos to next char
+
+ } while(pos < len);
+
+ return result;
+}
+
CStdString CUtil::MakeLegalFileName(const CStdString &strFile, int LegalType)
{
CStdString result = strFile;
@@ -944,15 +976,15 @@ CStdString CUtil::MakeLegalPath(const CStdString &strPathAndFile, int LegalType)
return dir;
}
-CStdString CUtil::ValidatePath(const CStdString &path, bool bFixDoubleSlashes /* = false */)
+std::string CUtil::ValidatePath(const std::string& path, bool bFixDoubleSlashes /* = false */)
{
- CStdString result = path;
+ std::string result(path);
// Don't do any stuff on URLs containing %-characters or protocols that embed
// 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:") ||
@@ -963,41 +995,14 @@ CStdString CUtil::ValidatePath(const CStdString &path, bool bFixDoubleSlashes /*
// check the path for incorrect slashes
#ifdef TARGET_WINDOWS
- if (URIUtils::IsDOSPath(path))
- {
- result.Replace('/', '\\');
- /* 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)
- {
- // Fixup for double back slashes (but ignore the \\ of unc-paths)
- for (int x = 1; x < result.GetLength() - 1; x++)
- {
- if (result[x] == '\\' && result[x+1] == '\\')
- result.Delete(x);
- }
- }
- }
- else if (path.Find("://") >= 0 || path.Find(":\\\\") >= 0)
+ if (result.length() >= 2 && result[1] == ':' && (result.length() == 2 || result[2] == '\\' || result[2] == '/')) // path in form "x:\"...
+ result = FixSlashes(result, bFixDoubleSlashes, false);
+ else if (result.compare(0, 2, "\\\\", 2) == 0) // 'result' starts with "\\": it's ether "\\server\share\ or "\\?\"
+ result = FixSlashes(result, bFixDoubleSlashes, false, 2);
+ else if (path.find("://") != std::string::npos || path.find(":\\\\") != std::string::npos)
#endif
- {
- result.Replace('\\', '/');
- /* 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)
- {
- // Fixup for double forward slashes(/) but don't touch the :// of URLs
- for (int x = 2; x < result.GetLength() - 1; x++)
- {
- if ( result[x] == '/' && result[x + 1] == '/' && !(result[x - 1] == ':' || (result[x - 1] == '/' && result[x - 2] == ':')) )
- result.Delete(x);
- }
- }
- }
+ result = FixSlashes(result, bFixDoubleSlashes);
+
return result;
}
View
10 xbmc/Util.h
@@ -27,10 +27,15 @@
#include "MediaSource.h"
+#ifdef TARGET_WINDOWS
+#ifdef CreateDirectoryEx
+#undef CreateDirectoryEx
+#endif // CreateDirectoryEx
+#endif // TARGET_WINDOWS
+
// A list of filesystem types for LegalPath/FileName
#define LEGAL_NONE 0
#define LEGAL_WIN32_COMPAT 1
-#define LEGAL_FATX 2
namespace XFILE
{
@@ -110,6 +115,7 @@ class CUtil
#endif
static bool CreateDirectoryEx(const CStdString& strPath);
+ static std::string FixSlashes(const std::string& path, const bool removeDuplicated = false, const bool useForwardSlashes = true, const size_t startFrom = 0);
#ifdef TARGET_WINDOWS
static CStdString MakeLegalFileName(const CStdString &strFile, int LegalType=LEGAL_WIN32_COMPAT);
static CStdString MakeLegalPath(const CStdString &strPath, int LegalType=LEGAL_WIN32_COMPAT);
@@ -117,7 +123,7 @@ class CUtil
static CStdString MakeLegalFileName(const CStdString &strFile, int LegalType=LEGAL_NONE);
static CStdString MakeLegalPath(const CStdString &strPath, int LegalType=LEGAL_NONE);
#endif
- static CStdString ValidatePath(const CStdString &path, bool bFixDoubleSlashes = false); ///< return a validated path, with correct directory separators.
+ static std::string ValidatePath(const std::string& path, bool bFixDoubleSlashes = false); ///< return a validated path, with correct directory separators.
static bool IsUsingTTFSubtitles();
View
2  xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
@@ -950,7 +950,7 @@ extern "C"
CURL url(CSpecialProtocol::TranslatePath(file));
if (url.IsLocal())
{ // Make sure the slashes are correct & translate the path
- return opendir(CUtil::ValidatePath(url.Get().c_str()));
+ return opendir(CUtil::ValidatePath(url.Get()).c_str());
}
// locate next free directory
View
44 xbmc/filesystem/HDDirectory.cpp
@@ -27,8 +27,9 @@
#include "utils/AliasShortcutUtils.h"
#include "utils/URIUtils.h"
-#ifndef TARGET_POSIX
+#ifdef TARGET_WINDOWS
#include "utils/CharsetConverter.h"
+#include "win32/WIN32Util.h"
#endif
#ifndef INVALID_FILE_ATTRIBUTES
@@ -57,6 +58,7 @@ CHDDirectory::~CHDDirectory(void)
bool CHDDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items)
{
LOCAL_WIN32_FIND_DATA wfd;
+ memset(&wfd, 0, sizeof(wfd));
CStdString strPath=strPath1;
@@ -66,11 +68,7 @@ bool CHDDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items
CStdString strRoot = strPath;
CURL url(strPath);
- memset(&wfd, 0, sizeof(wfd));
URIUtils::AddSlashAtEnd(strRoot);
-#ifdef TARGET_WINDOWS
- strRoot.Replace("/", "\\");
-#endif
if (URIUtils::IsDVD(strRoot) && m_isoReader.IsScanned())
{
// Reset iso reader and remount or
@@ -79,12 +77,10 @@ bool CHDDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items
}
#ifdef TARGET_WINDOWS
- CStdStringW strSearchMask;
- g_charsetConverter.utf8ToW(strRoot, strSearchMask, false);
- strSearchMask.Insert(0, L"\\\\?\\");
- strSearchMask += "*.*";
+ std::wstring strSearchMask(CWIN32Util::ConvertPathToWin32Form(strRoot));
+ strSearchMask += L"*.*";
#else
- CStdString strSearchMask = strRoot;
+ CStdString strSearchMask(strRoot);
#endif
FILETIME localTime;
@@ -102,7 +98,7 @@ bool CHDDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items
{
CStdString strLabel;
#ifdef TARGET_WINDOWS
- g_charsetConverter.wToUTF8(wfd.cFileName,strLabel);
+ g_charsetConverter.wToUTF8(wfd.cFileName,strLabel, true);
#else
strLabel = wfd.cFileName;
#endif
@@ -146,17 +142,15 @@ bool CHDDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items
bool CHDDirectory::Create(const char* strPath)
{
+ if (!strPath || !*strPath)
+ return false;
CStdString strPath1 = strPath;
URIUtils::AddSlashAtEnd(strPath1);
#ifdef TARGET_WINDOWS
if (strPath1.size() == 3 && strPath1[1] == ':')
return Exists(strPath); // A drive - we can't "create" a drive
- CStdStringW strWPath1;
- strPath1.Replace("/", "\\");
- g_charsetConverter.utf8ToW(strPath1, strWPath1, false);
- strWPath1.Insert(0, L"\\\\?\\");
- if(::CreateDirectoryW(strWPath1, NULL))
+ if(::CreateDirectoryW(CWIN32Util::ConvertPathToWin32Form(strPath1).c_str(), NULL))
#else
if(::CreateDirectory(strPath1.c_str(), NULL))
#endif
@@ -169,12 +163,10 @@ bool CHDDirectory::Create(const char* strPath)
bool CHDDirectory::Remove(const char* strPath)
{
+ if (!strPath || !*strPath)
+ return false;
#ifdef TARGET_WINDOWS
- CStdStringW strWPath;
- g_charsetConverter.utf8ToW(strPath, strWPath, false);
- strWPath.Replace(L"/", L"\\");
- strWPath.Insert(0, L"\\\\?\\");
- return (::RemoveDirectoryW(strWPath) || GetLastError() == ERROR_PATH_NOT_FOUND) ? true : false;
+ return (::RemoveDirectoryW(CWIN32Util::ConvertPathToWin32Form(strPath).c_str()) || GetLastError() == ERROR_PATH_NOT_FOUND) ? true : false;
#else
return ::RemoveDirectory(strPath) ? true : false;
#endif
@@ -184,16 +176,10 @@ bool CHDDirectory::Exists(const char* strPath)
{
if (!strPath || !*strPath)
return false;
- CStdString strReplaced=strPath;
#ifdef TARGET_WINDOWS
- CStdStringW strWReplaced;
- strReplaced.Replace("/","\\");
- URIUtils::AddSlashAtEnd(strReplaced);
- g_charsetConverter.utf8ToW(strReplaced, strWReplaced, false);
- strWReplaced.Insert(0, L"\\\\?\\");
- DWORD attributes = GetFileAttributesW(strWReplaced);
+ DWORD attributes = GetFileAttributesW(CWIN32Util::ConvertPathToWin32Form(strPath).c_str());
#else
- DWORD attributes = GetFileAttributes(strReplaced.c_str());
+ DWORD attributes = GetFileAttributes(strPath);
#endif
if(attributes == INVALID_FILE_ATTRIBUTES)
return false;
View
74 xbmc/filesystem/HDFile.cpp
@@ -37,6 +37,7 @@
#include <io.h>
#include "utils/CharsetConverter.h"
#include "utils/URIUtils.h"
+#include "win32/WIN32Util.h"
#endif
#include "utils/log.h"
@@ -60,30 +61,25 @@ CHDFile::~CHDFile()
if (m_hFile != INVALID_HANDLE_VALUE) Close();
}
//*********************************************************************************************
-CStdString CHDFile::GetLocal(const CURL &url)
+std::string CHDFile::GetLocal(const CURL &url)
{
- CStdString path( url.GetFileName() );
+ std::string path(url.GetFileName());
- if( url.GetProtocol().Equals("file", false) )
+ if(url.GetProtocol() == "file")
{
// file://drive[:]/path
// file:///drive:/path
- CStdString host( url.GetHostName() );
+ std::string host(url.GetHostName());
- if(host.size() > 0)
+ if(!host.empty())
{
- if(host.Right(1) == ":")
+ if(host[host.length()-1] == ':')
path = host + "/" + path;
else
path = host + ":/" + path;
}
}
-#ifdef TARGET_WINDOWS
- path.Insert(0, "\\\\?\\");
- path.Replace('/', '\\');
-#endif
-
if (IsAliasShortcut(path))
TranslateAliasShortcut(path);
@@ -93,12 +89,10 @@ CStdString CHDFile::GetLocal(const CURL &url)
//*********************************************************************************************
bool CHDFile::Open(const CURL& url)
{
- CStdString strFile = GetLocal(url);
+ std::string strFile(GetLocal(url));
#ifdef TARGET_WINDOWS
- CStdStringW strWFile;
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
- m_hFile.attach(CreateFileW(strWFile.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
+ m_hFile.attach(CreateFileW(CWIN32Util::ConvertPathToWin32Form(strFile).c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
#else
m_hFile.attach(CreateFile(strFile.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
#endif
@@ -113,18 +107,16 @@ bool CHDFile::Open(const CURL& url)
bool CHDFile::Exists(const CURL& url)
{
- struct __stat64 buffer;
- CStdString strFile = GetLocal(url);
+ std::string strFile(GetLocal(url));
#ifdef TARGET_WINDOWS
- CStdStringW strWFile;
URIUtils::RemoveSlashAtEnd(strFile);
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
- DWORD attributes = GetFileAttributesW(strWFile);
+ DWORD attributes = GetFileAttributesW(CWIN32Util::ConvertPathToWin32Form(strFile).c_str());
if(attributes == INVALID_FILE_ATTRIBUTES)
return false;
return true;
#else
+ struct __stat64 buffer;
return (_stat64(strFile.c_str(), &buffer)==0);
#endif
}
@@ -157,20 +149,19 @@ int CHDFile::Stat(struct __stat64* buffer)
int CHDFile::Stat(const CURL& url, struct __stat64* buffer)
{
- CStdString strFile = GetLocal(url);
+ std::string strFile(GetLocal(url));
#ifdef TARGET_WINDOWS
- CStdStringW strWFile;
+ std::wstring strWFile(CWIN32Util::ConvertPathToWin32Form(strFile));
/* _wstat64 can't handle long paths therefore we remove the \\?\ */
- strFile.Replace("\\\\?\\", "");
+ CWIN32Util::RemoveExtraLongPathPrefix(strWFile);
// win32 can only stat root drives with a slash at the end
- if(strFile.length() == 2 && strFile[1] ==':')
- URIUtils::AddSlashAtEnd(strFile);
+ if(strWFile.length() == 2 && strWFile[1] == L':')
+ strWFile.push_back(L'\\');
/* _wstat64 calls FindFirstFileEx. According to MSDN, the path should not end in a trailing backslash.
Remove it before calling _wstat64 */
- if (strFile.length() > 3 && URIUtils::HasSlashAtEnd(strFile))
- URIUtils::RemoveSlashAtEnd(strFile);
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
+ else if (strWFile.length() > 3 && URIUtils::HasSlashAtEnd(strFile))
+ strWFile.pop_back();
return _wstat64(strWFile.c_str(), buffer);
#else
return _stat64(strFile.c_str(), buffer);
@@ -180,10 +171,8 @@ int CHDFile::Stat(const CURL& url, struct __stat64* buffer)
bool CHDFile::SetHidden(const CURL &url, bool hidden)
{
#ifdef TARGET_WINDOWS
- CStdStringW path;
- g_charsetConverter.utf8ToW(GetLocal(url), path, false);
DWORD attributes = hidden ? FILE_ATTRIBUTE_HIDDEN : FILE_ATTRIBUTE_NORMAL;
- if (SetFileAttributesW(path.c_str(), attributes))
+ if (SetFileAttributesW(CWIN32Util::ConvertPathToWin32Form(GetLocal(url)).c_str(), attributes))
return true;
#endif
return false;
@@ -192,13 +181,10 @@ bool CHDFile::SetHidden(const CURL &url, bool hidden)
//*********************************************************************************************
bool CHDFile::OpenForWrite(const CURL& url, bool bOverWrite)
{
- // make sure it's a legal FATX filename (we are writing to the harddisk)
- CStdString strPath = GetLocal(url);
+ std::string strPath(GetLocal(url));
#ifdef TARGET_WINDOWS
- CStdStringW strWPath;
- g_charsetConverter.utf8ToW(strPath, strWPath, false);
- m_hFile.attach(CreateFileW(strWPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
+ m_hFile.attach(CreateFileW(CWIN32Util::ConvertPathToWin32Form(strPath).c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
#else
m_hFile.attach(CreateFile(strPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
#endif
@@ -318,12 +304,10 @@ int64_t CHDFile::GetPosition()
bool CHDFile::Delete(const CURL& url)
{
- CStdString strFile=GetLocal(url);
+ std::string strFile(GetLocal(url));
#ifdef TARGET_WINDOWS
- CStdStringW strWFile;
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
- return ::DeleteFileW(strWFile.c_str()) ? true : false;
+ return ::DeleteFileW(CWIN32Util::ConvertPathToWin32Form(strFile).c_str()) ? true : false;
#else
return ::DeleteFile(strFile.c_str()) ? true : false;
#endif
@@ -331,15 +315,11 @@ bool CHDFile::Delete(const CURL& url)
bool CHDFile::Rename(const CURL& url, const CURL& urlnew)
{
- CStdString strFile=GetLocal(url);
- CStdString strNewFile=GetLocal(urlnew);
+ std::string strFile(GetLocal(url));
+ std::string strNewFile(GetLocal(urlnew));
#ifdef TARGET_WINDOWS
- CStdStringW strWFile;
- CStdStringW strWNewFile;
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
- g_charsetConverter.utf8ToW(strNewFile, strWNewFile, false);
- return ::MoveFileW(strWFile.c_str(), strWNewFile.c_str()) ? true : false;
+ return ::MoveFileW(CWIN32Util::ConvertPathToWin32Form(strFile).c_str(), CWIN32Util::ConvertPathToWin32Form(strNewFile).c_str()) ? true : false;
#else
return ::MoveFile(strFile.c_str(), strNewFile.c_str()) ? true : false;
#endif
View
2  xbmc/filesystem/HDFile.h
@@ -60,7 +60,7 @@ class CHDFile : public IFile
virtual int IoControl(EIoControl request, void* param);
protected:
- CStdString GetLocal(const CURL &url); /* crate a properly format path from an url */
+ std::string GetLocal(const CURL &url); /* crate a properly format path from an url */
AUTOPTR::CAutoPtrHandle m_hFile;
int64_t m_i64FilePos;
int64_t m_i64FileLen;
View
6 xbmc/filesystem/SMBDirectory.cpp
@@ -150,8 +150,8 @@ bool CSMBDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
#endif
if ((m_flags & DIR_FLAG_NO_FILE_INFO)==0 && g_advancedSettings.m_sambastatfiles)
{
- // make sure we use the authenticated path wich contains any default username
- CStdString strFullName = strAuth + smb.URLEncode(strFile);
+ // make sure we use the authenticated path which contains any default username
+ std::string strFullName((std::string&)strAuth + smb.URLEncode(strFile));
lock.Enter();
@@ -165,7 +165,7 @@ bool CSMBDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
char value[20];
// We poll for extended attributes which symbolizes bits but split up into a string. Where 0x02 is hidden and 0x12 is hidden directory.
// According to the libsmbclient.h it's supposed to return 0 if ok, or the length of the string. It seems always to return the length wich is 4
- if (smbc_getxattr(strFullName, "system.dos_attr.mode", value, sizeof(value)) > 0)
+ if (smbc_getxattr(strFullName.c_str(), "system.dos_attr.mode", value, sizeof(value)) > 0)
{
long longvalue = strtol(value, NULL, 16);
if (longvalue & SMBC_DOS_MODE_HIDDEN)
View
8 xbmc/filesystem/SmbFile.cpp
@@ -240,11 +240,11 @@ void CSMB::PurgeEx(const CURL& url)
m_strLastHost = url.GetHostName();
}
-CStdString CSMB::URLEncode(const CURL &url)
+std::string CSMB::URLEncode(const CURL &url)
{
/* due to smb wanting encoded urls we have to build it manually */
- CStdString flat = "smb://";
+ std::string flat = "smb://";
if(url.GetDomain().length() > 0)
{
@@ -278,9 +278,9 @@ CStdString CSMB::URLEncode(const CURL &url)
return flat;
}
-CStdString CSMB::URLEncode(const CStdString &value)
+std::string CSMB::URLEncode(const std::string &value)
{
- CStdString encoded(value);
+ std::string encoded(value);
CURL::Encode(encoded);
return encoded;
}
View
4 xbmc/filesystem/SmbFile.h
@@ -67,8 +67,8 @@ class CSMB : public CCriticalSection
void AddActiveConnection();
void AddIdleConnection();
#endif
- CStdString URLEncode(const CStdString &value);
- CStdString URLEncode(const CURL &url);
+ std::string URLEncode(const std::string &value);
+ std::string URLEncode(const CURL &url);
DWORD ConvertUnixToNT(int error);
private:
View
7 xbmc/filesystem/SpecialProtocol.cpp
@@ -83,14 +83,13 @@ bool CSpecialProtocol::ComparePath(const CStdString &path1, const CStdString &pa
return TranslatePath(path1) == TranslatePath(path2);
}
-CStdString CSpecialProtocol::TranslatePath(const CStdString &path)
+CStdString CSpecialProtocol::TranslatePath(const std::string& path)
{
CURL url(path);
// check for special-protocol, if not, return
- if (!url.GetProtocol().Equals("special"))
- {
+ if (url.GetProtocol() != "special")
return path;
- }
+
return TranslatePath(url);
}
View
2  xbmc/filesystem/SpecialProtocol.h
@@ -64,7 +64,7 @@ class CSpecialProtocol
static bool ComparePath(const CStdString &path1, const CStdString &path2);
static void LogPaths();
- static CStdString TranslatePath(const CStdString &path);
+ static CStdString TranslatePath(const std::string& path);
static CStdString TranslatePath(const CURL &url);
static CStdString TranslatePathConvertCase(const CStdString& path);
View
84 xbmc/filesystem/windows/WINFileSMB.cpp
@@ -30,6 +30,8 @@
#include "utils/CharsetConverter.h"
#include "utils/URIUtils.h"
#include "WINSMBDirectory.h"
+#include "Util.h"
+#include "win32/WIN32Util.h"
using namespace XFILE;
@@ -48,21 +50,11 @@ CWINFileSMB::~CWINFileSMB()
if (m_hFile != INVALID_HANDLE_VALUE) Close();
}
//*********************************************************************************************
-CStdString CWINFileSMB::GetLocal(const CURL &url)
+std::string CWINFileSMB::GetLocal(const CURL &url)
{
- CStdString path( url.GetFileName() );
-
- if( url.GetProtocol().Equals("smb", false) )
- {
- CStdString host( url.GetHostName() );
-
- if(host.size() > 0)
- {
- path = "\\\\?\\UNC\\" + host + "\\" + path;
- }
- }
-
- path.Replace('/', '\\');
+ std::string path(url.GetFileName());
+ if (url.GetProtocol().Equals("smb", false) && !url.GetHostName().empty())
+ path = "\\\\?\\UNC\\" + (std::string&)url.GetHostName() + "\\" + path;
return path;
}
@@ -70,11 +62,9 @@ CStdString CWINFileSMB::GetLocal(const CURL &url)
//*********************************************************************************************
bool CWINFileSMB::Open(const CURL& url)
{
- CStdString strFile = GetLocal(url);
+ std::wstring wfilename(CWIN32Util::ConvertPathToWin32Form(GetLocal(url)));
- CStdStringW strWFile;
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
- m_hFile.attach(CreateFileW(strWFile.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
+ m_hFile.attach(CreateFileW(wfilename.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
if (!m_hFile.isValid())
{
@@ -83,10 +73,10 @@ bool CWINFileSMB::Open(const CURL& url)
XFILE::CWINSMBDirectory smb;
smb.ConnectToShare(url);
- m_hFile.attach(CreateFileW(strWFile.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
+ m_hFile.attach(CreateFileW(wfilename.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
if (!m_hFile.isValid())
{
- CLog::Log(LOGERROR,"CWINFileSMB: Unable to open file %s Error: %d", strFile.c_str(), GetLastError());
+ CLog::Log(LOGERROR, __FUNCTION__ ": Unable to open file %s Error: %d", url.Get().c_str(), GetLastError());
return false;
}
}
@@ -99,10 +89,8 @@ bool CWINFileSMB::Open(const CURL& url)
bool CWINFileSMB::Exists(const CURL& url)
{
- CStdString strFile = GetLocal(url);
- URIUtils::RemoveSlashAtEnd(strFile);
- CStdStringW strWFile;
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
+ std::wstring strWFile(CWIN32Util::ConvertPathToWin32Form(GetLocal(url)));
+
DWORD attributes = GetFileAttributesW(strWFile.c_str());
if(attributes != INVALID_FILE_ATTRIBUTES)
return true;
@@ -129,14 +117,14 @@ int CWINFileSMB::Stat(struct __stat64* buffer)
HANDLE hFileDup;
if (0 == DuplicateHandle(GetCurrentProcess(), (HANDLE)m_hFile, GetCurrentProcess(), &hFileDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
{
- CLog::Log(LOGERROR, __FUNCTION__" - DuplicateHandle()");
+ CLog::Log(LOGERROR, __FUNCTION__ ": - DuplicateHandle()");
return -1;
}
fd = _open_osfhandle((intptr_t)((HANDLE)hFileDup), 0);
if (fd == -1)
{
- CLog::Log(LOGERROR, "CWINFileSMB Stat: fd == -1");
+ CLog::Log(LOGERROR, __FUNCTION__ ": Stat: fd == -1");
return -1;
}
@@ -147,15 +135,17 @@ int CWINFileSMB::Stat(struct __stat64* buffer)
int CWINFileSMB::Stat(const CURL& url, struct __stat64* buffer)
{
- CStdString strFile = GetLocal(url);
+ std::wstring strWFile(CWIN32Util::ConvertPathToWin32Form(GetLocal(url)));
+
/* _wstat64 can't handle long paths therefore we remove the \\?\UNC\ */
- strFile.Replace("\\\\?\\UNC\\", "\\\\");
+ if (strWFile.compare(0, 8, L"\\\\?\\UNC\\", 8) == 0)
+ strWFile.erase(2, 6);
+
/* _wstat64 calls FindFirstFileEx. According to MSDN, the path should not end in a trailing backslash.
Remove it before calling _wstat64 */
- if (strFile.length() > 3 && URIUtils::HasSlashAtEnd(strFile))
- URIUtils::RemoveSlashAtEnd(strFile);
- CStdStringW strWFile;
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
+ if (strWFile[strWFile.length()-1] == L'\\')
+ strWFile.pop_back();
+
if(_wstat64(strWFile.c_str(), buffer) == 0)
return 0;
@@ -173,10 +163,8 @@ int CWINFileSMB::Stat(const CURL& url, struct __stat64* buffer)
//*********************************************************************************************
bool CWINFileSMB::OpenForWrite(const CURL& url, bool bOverWrite)
{
- CStdString strPath = GetLocal(url);
+ std::wstring strWPath(CWIN32Util::ConvertPathToWin32Form(GetLocal(url)));
- CStdStringW strWPath;
- g_charsetConverter.utf8ToW(strPath, strWPath, false);
m_hFile.attach(CreateFileW(strWPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
if (!m_hFile.isValid())
@@ -189,7 +177,7 @@ bool CWINFileSMB::OpenForWrite(const CURL& url, bool bOverWrite)
m_hFile.attach(CreateFileW(strWPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
if (!m_hFile.isValid())
{
- CLog::Log(LOGERROR,"CWINFileSMB: Unable to open file for writing '%s' Error '%d%",strPath.c_str(), GetLastError());
+ CLog::Log(LOGERROR,__FUNCTION__ ": Unable to open file for writing '%s' Error '%d%", url.Get().c_str(), GetLastError());
return false;
}
}
@@ -289,31 +277,17 @@ int64_t CWINFileSMB::GetPosition()
bool CWINFileSMB::Delete(const CURL& url)
{
- CStdString strFile=GetLocal(url);
-
- CStdStringW strWFile;
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
- return ::DeleteFileW(strWFile.c_str()) ? true : false;
+ return ::DeleteFileW(CWIN32Util::ConvertPathToWin32Form(GetLocal(url)).c_str()) ? true : false;
}
bool CWINFileSMB::Rename(const CURL& url, const CURL& urlnew)
{
- CStdString strFile=GetLocal(url);
- CStdString strNewFile=GetLocal(urlnew);
-
- CStdStringW strWFile;
- CStdStringW strWNewFile;
- g_charsetConverter.utf8ToW(strFile, strWFile, false);
- g_charsetConverter.utf8ToW(strNewFile, strWNewFile, false);
- return ::MoveFileW(strWFile.c_str(), strWNewFile.c_str()) ? true : false;
+ return ::MoveFileW(CWIN32Util::ConvertPathToWin32Form(GetLocal(url)).c_str(), CWIN32Util::ConvertPathToWin32Form(GetLocal(urlnew)).c_str()) ? true : false;
}
bool CWINFileSMB::SetHidden(const CURL &url, bool hidden)
{
- CStdStringW path;
- g_charsetConverter.utf8ToW(GetLocal(url), path, false);
- DWORD attributes = hidden ? FILE_ATTRIBUTE_HIDDEN : FILE_ATTRIBUTE_NORMAL;
- if (SetFileAttributesW(path.c_str(), attributes))
+ if (SetFileAttributesW(CWIN32Util::ConvertPathToWin32Form(GetLocal(url)).c_str(), hidden ? FILE_ATTRIBUTE_HIDDEN : FILE_ATTRIBUTE_NORMAL))
return true;
return false;
}
@@ -334,14 +308,14 @@ int CWINFileSMB::Truncate(int64_t size)
HANDLE hFileDup;
if (0 == DuplicateHandle(GetCurrentProcess(), (HANDLE)m_hFile, GetCurrentProcess(), &hFileDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
{
- CLog::Log(LOGERROR, __FUNCTION__" - DuplicateHandle()");
+ CLog::Log(LOGERROR, __FUNCTION__ ": - DuplicateHandle()");
return -1;
}
fd = _open_osfhandle((intptr_t)((HANDLE)hFileDup), 0);
if (fd == -1)
{
- CLog::Log(LOGERROR, "CWINFileSMB Stat: fd == -1");
+ CLog::Log(LOGERROR, __FUNCTION__ ": Stat: fd == -1");
return -1;
}
int result = _chsize_s(fd, (long) size);
View
2  xbmc/filesystem/windows/WINFileSMB.h
@@ -58,7 +58,7 @@ class CWINFileSMB : public IFile
virtual int IoControl(EIoControl request, void* param);
protected:
- CStdString GetLocal(const CURL &url); /* crate a properly format path from an url */
+ std::string GetLocal(const CURL &url); /* create a properly format path from an url */
AUTOPTR::CAutoPtrHandle m_hFile;
int64_t m_i64FilePos;
};
View
68 xbmc/filesystem/windows/WINSMBDirectory.cpp
@@ -49,20 +49,13 @@ CWINSMBDirectory::~CWINSMBDirectory(void)
{
}
-CStdString CWINSMBDirectory::GetLocal(const CStdString& strPath)
+std::string CWINSMBDirectory::GetLocal(const std::string& strPath)
{
CURL url(strPath);
- CStdString path( url.GetFileName() );
- if( url.GetProtocol().Equals("smb", false) )
- {
- CStdString host( url.GetHostName() );
+ std::string path(url.GetFileName());
+ if (url.GetProtocol().Equals("smb", false) && !url.GetHostName().empty())
+ path = "\\\\?\\UNC\\" + (std::string&)url.GetHostName() + "\\" + path;
- if(host.size() > 0)
- {
- path = "\\\\?\\UNC\\" + host + "\\" + path;
- }
- }
- path.Replace('/', '\\');
return path;
}
@@ -70,7 +63,7 @@ bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &i
{
WIN32_FIND_DATAW wfd;
- CStdString strPath=strPath1;
+ std::string strPath=strPath1;
CURL url(strPath);
@@ -85,9 +78,9 @@ bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &i
return false;
ConnectToShare(url);
- CStdString strHost = "\\\\" + url.GetHostName();
- CStdStringW strHostW;
- g_charsetConverter.utf8ToW(strHost,strHostW);
+ std::string strHost = "\\\\" + url.GetHostName();
+ std::wstring strHostW;
+ g_charsetConverter.utf8ToW(strHost,strHostW, false, false, true);
lpnr->lpRemoteName = (LPWSTR)strHostW.c_str();
m_bHost = true;
ret = EnumerateFunc(lpnr, items);
@@ -102,14 +95,14 @@ bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &i
memset(&wfd, 0, sizeof(wfd));
//rebuild the URL
- CStdString strUNCShare = "\\\\?\\UNC\\" + url.GetHostName() + "\\" + url.GetFileName();
- strUNCShare.Replace("/", "\\");
+ std::string strUNCShare = "\\\\?\\UNC\\" + (std::string)url.GetHostName() + "\\" + CUtil::FixSlashes(url.GetFileName(), true, false);
+
if(!URIUtils::HasSlashAtEnd(strUNCShare))
strUNCShare.append("\\");
- CStdStringW strSearchMask;
- g_charsetConverter.utf8ToW(strUNCShare, strSearchMask, false);
- strSearchMask += "*";
+ std::wstring strSearchMask;
+ g_charsetConverter.utf8ToW(strUNCShare, strSearchMask, false, false, true);
+ strSearchMask += L"*";
FILETIME localTime;
CAutoPtrFind hFind ( FindFirstFileW(strSearchMask.c_str(), &wfd));
@@ -125,7 +118,7 @@ bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &i
hFind.attach(FindFirstFileW(strSearchMask.c_str(), &wfd));
}
else
- return Exists(strPath1);
+ return Exists(strPath1.c_str());
}
if (hFind.isValid())
@@ -134,14 +127,14 @@ bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &i
{
if (wfd.cFileName[0] != 0)
{
- CStdString strLabel;
- g_charsetConverter.wToUTF8(wfd.cFileName,strLabel);
+ std::string strLabel;
+ g_charsetConverter.wToUTF8(wfd.cFileName,strLabel, true);
if ( (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
if (strLabel != "." && strLabel != "..")
{
CFileItemPtr pItem(new CFileItem(strLabel));
- CStdString path = URIUtils::AddFileToFolder(strPath, strLabel);
+ std::string path = URIUtils::AddFileToFolder(strPath, strLabel);
URIUtils::AddSlashAtEnd(path);
pItem->SetPath(path);
pItem->m_bIsFolder = true;
@@ -176,10 +169,7 @@ bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &i
bool CWINSMBDirectory::Create(const char* strPath)
{
- CStdString strPath1 = GetLocal(strPath);
- CStdStringW strWPath1;
- g_charsetConverter.utf8ToW(strPath1, strWPath1, false);
- if(::CreateDirectoryW(strWPath1, NULL))
+ if(::CreateDirectoryW(CWIN32Util::ConvertPathToWin32Form(GetLocal(strPath)).c_str(), NULL))
return true;
else if(GetLastError() == ERROR_ALREADY_EXISTS)
return true;
@@ -189,18 +179,12 @@ bool CWINSMBDirectory::Create(const char* strPath)