diff --git a/source/vibe/inet/path.d b/source/vibe/inet/path.d index 39f5e3ddcd..526a98fc1a 100644 --- a/source/vibe/inet/path.d +++ b/source/vibe/inet/path.d @@ -32,7 +32,7 @@ struct Path { this(string pathstr) { m_nodes = cast(immutable)splitPath(pathstr); - m_absolute = (pathstr.startsWith("/") || m_nodes.length > 0 && m_nodes[0].toString().indexOf(':')>0); + m_absolute = (pathstr.startsWith("/") || m_nodes.length > 0 && (m_nodes[0].toString().canFind(':') || m_nodes[0] == "\\")); m_endsWithSlash = pathstr.endsWith("/"); foreach( e; m_nodes ) assert(e.toString().length > 0, "Empty path nodes not allowed: "~pathstr); } @@ -225,6 +225,66 @@ struct Path { } } + +unittest +{ + { + auto unc = "\\\\server\\share\\path"; + auto uncp = Path(unc); + version(Windows) assert(uncp.toNativeString() == unc); + assert(uncp.absolute); + assert(!uncp.endsWithSlash); + } + + { + auto abspath = "/test/path/"; + auto abspathp = Path(abspath); + assert(abspathp.toString() == abspath); + version(Windows) {} else assert(abspathp.toNativeString() == abspath); + assert(abspathp.absolute); + assert(abspathp.endsWithSlash); + assert(abspathp.length == 2); + assert(abspathp[0] == "test"); + assert(abspathp[1] == "path"); + } + + { + auto relpath = "test/path/"; + auto relpathp = Path(relpath); + assert(relpathp.toString() == relpath); + version(Windows) assert(relpathp.toNativeString() == "test\\path\\"); + else assert(relpathp.toNativeString() == relpath); + assert(!relpathp.absolute); + assert(relpathp.endsWithSlash); + assert(relpathp.length == 2); + assert(relpathp[0] == "test"); + assert(relpathp[1] == "path"); + } + + { + auto winpath = "C:\\windows\\test"; + auto winpathp = Path(winpath); + assert(winpathp.toString() == "/C:/windows/test"); + version(Windows) assert(winpathp.toNativeString() == winpath); + else assert(winpathp.toNativeString() == "/C:/windows/test"); + assert(winpathp.absolute); + assert(!winpathp.endsWithSlash); + assert(winpathp.length == 3); + assert(winpathp[0] == "C:"); + assert(winpathp[1] == "windows"); + assert(winpathp[2] == "test"); + } + + { + auto dotpath = "/test/../test2/././x/y"; + auto dotpathp = Path(dotpath); + assert(dotpathp.toString() == "/test/../test2/././x/y"); + dotpathp.normalize(); + assert(dotpathp.toString() == "/test2/x/y"); + } +} + + struct PathEntry { private { string m_name; @@ -232,7 +292,7 @@ struct PathEntry { this(string str) { - assert(!str.canFind('/') && !str.canFind('\\')); + assert(!str.canFind('/') && (!str.canFind('\\') || str.length == 1), "Invalid path entry: " ~ str); m_name = str; } @@ -284,9 +344,17 @@ PathEntry[] splitPath(string path) storage = cast(PathEntry[])mem; } else*/ storage = new PathEntry[nelements]; - // read and return the elements size_t startidx = 0; size_t eidx = 0; + + // detect UNC path + if(path.startsWith("\\")) + { + storage[eidx++] = PathEntry(path[0 .. 1]); + path = path[1 .. $]; + } + + // read and return the elements foreach( i, char ch; path ) if( ch == '\\' || ch == '/' ){ enforce(i - startidx > 0, "Empty path entries not allowed."); @@ -298,3 +366,5 @@ PathEntry[] splitPath(string path) assert(eidx == nelements); return storage; } + +