public LocalFile(Uri uri, FileSystemInfo file) : base(uri) { this.m_file = file; if (System.IO.Directory.Exists(file.FullName)) { if (!uri.isDir()) throw IOErr.make("Must use trailing slash for dir: " + uri).val; } else if (System.IO.File.Exists(file.FullName)) { if (uri.isDir()) throw IOErr.make("Cannot use trailing slash for file: " + uri).val; } }
public static string uriToPath(Uri uri) { string path = uri.m_pathStr; bool dir = uri.isDir(); int len = path.Length; StringBuilder s = new StringBuilder(path.Length); for (int i=0; i<len; ++i) { int c = path[i]; if (i == 0 && c == '/' && path.Contains(":")) continue; // skip abs if (i == len-1 && c == '/' && dir) continue; // skip trailing slash switch (c) { case '\\': break; case '/': s.Append('\\'); break; default: s.Append((char)c); break; } } return s.ToString(); }
static void merge(Sections t, Uri baseUri, Uri r) { bool baseIsAbs = baseUri.isPathAbs(); bool baseIsDir = baseUri.isDir(); bool rIsDir = r.isDir(); List rPath = r.m_path; bool dotLast = false; // compute the target path taking into account whether // the base is a dir and any dot segments in relative ref List tPath; if (baseUri.m_path.sz() == 0) { tPath = r.m_path; } else { tPath = baseUri.m_path.rw(); if (!baseIsDir) tPath.pop(); for (int i=0; i<rPath.sz(); ++i) { string rSeg = (string)rPath.get(i); if (rSeg == ".") { dotLast = true; continue; } if (rSeg == "..") { if (!tPath.isEmpty()) { tPath.pop(); dotLast = true; continue; } if (baseIsAbs) continue; } tPath.add(rSeg); dotLast = false; } //tPath = tPath; } t.path = tPath; t.pathStr = toPathStr(baseIsAbs, tPath, rIsDir || dotLast); }
public static FileSystemInfo uriToFile(Uri uri) { if (uri.scheme() != null && uri.scheme() != "file") throw ArgErr.make("Invalid Uri scheme for local file: " + uri).val; string path = uriToPath(uri); if (System.IO.Directory.Exists(path)) return new DirectoryInfo(path); if (System.IO.File.Exists(path)) return new FileInfo(path); if (uri.isDir()) return new DirectoryInfo(path); return new FileInfo(path); }
////////////////////////////////////////////////////////////////////////// // Relativize ////////////////////////////////////////////////////////////////////////// public Uri relTo(Uri baseUri) { if (!OpUtil.compareEQ(this.m_scheme, baseUri.m_scheme) || !OpUtil.compareEQ(this.m_userInfo, baseUri.m_userInfo) || !OpUtil.compareEQ(this.m_host, baseUri.m_host) || !OpUtil.compareEQ(this.m_port, baseUri.m_port)) return this; // at this point we know we have the same scheme and auth, and // we're going to create a new URI which is a subset of this one Sections t = new Sections(); t.query = this.m_query; t.queryStr = this.m_queryStr; t.frag = this.m_frag; // find divergence int d=0; int len = Math.Min(this.m_path.sz(), baseUri.m_path.sz()); for (; d<len; ++d) if (!this.m_path.get(d).Equals(baseUri.m_path.get(d))) break; // if diverenge is at root, then no commonality if (d == 0) { // `/a/b/c`.relTo(`/`) should be `a/b/c` if (baseUri.m_path.isEmpty() && this.m_pathStr.StartsWith("/")) { t.path = this.m_path; t.pathStr = this.m_pathStr.Substring(1); } else { t.path = this.m_path; t.pathStr = this.m_pathStr; } } // if paths are exactly the same else if (d == this.m_path.sz() && d == baseUri.m_path.sz()) { t.path = emptyPath(); t.pathStr = string.Empty; } // create sub-path at divergence point else { // slice my path t.path = this.m_path.getRange(Range.makeInclusive(d, -1)); // insert .. backup if needed int backup = baseUri.m_path.sz() - d; if (!baseUri.isDir()) backup--; while (backup-- > 0) t.path.insert(0, dotDot); // format the new path string t.pathStr = toPathStr(false, t.path, this.isDir()); } return new Uri(t); }