 Chromium Code Reviews
 Chromium Code Reviews Issue 16848002:
  Add toUri and fromUri functions to pathos.  (Closed) 
  Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
    
  
    Issue 16848002:
  Add toUri and fromUri functions to pathos.  (Closed) 
  Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart| Index: pkg/pathos/lib/path.dart | 
| diff --git a/pkg/pathos/lib/path.dart b/pkg/pathos/lib/path.dart | 
| index 145953f3c8aa619d13f4fbcbaec0c9df65a184dd..a994f6e7cf373a078138d32ea295dd967ce3a2ae 100644 | 
| --- a/pkg/pathos/lib/path.dart | 
| +++ b/pkg/pathos/lib/path.dart | 
| @@ -275,6 +275,45 @@ String relative(String path, {String from}) => | 
| /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' | 
| String withoutExtension(String path) => _builder.withoutExtension(path); | 
| +/// Returns the path represented by [uri]. | 
| +/// | 
| +/// For POSIX and Windows styles, [uri] must be a `file:` URI. For the URL | 
| +/// style, this will just convert [uri] to a string. | 
| +/// | 
| +/// // POSIX | 
| +/// path.fromUri(Uri.parse('file:///path/to/foo')) | 
| +/// // -> '/path/to/foo' | 
| +/// | 
| +/// // Windows | 
| +/// path.fromUri(Uri.parse('file:///C:/path/to/foo')) | 
| +/// // -> r'C:\path\to\foo' | 
| +/// | 
| +/// // URL | 
| +/// path.fromUri(Uri.parse('http://dartlang.org/path/to/foo')) | 
| +/// // -> 'http://dartlang.org/path/to/foo' | 
| +String fromUri(Uri uri) => _builder.fromUri(uri); | 
| + | 
| +/// Returns the URI that represents [path]. | 
| +/// | 
| +/// For POSIX and Windows styles, this will return a `file:` URI. For the URL | 
| +/// style, this will just convert [path] to a [Uri]. | 
| +/// | 
| +/// This will always convert relative paths to absolute ones before converting | 
| +/// to a URI. | 
| +/// | 
| +/// // POSIX | 
| +/// path.toUri('/path/to/foo') | 
| +/// // -> Uri.parse('file:///path/to/foo') | 
| +/// | 
| +/// // Windows | 
| +/// path.toUri(r'C:\path\to\foo') | 
| +/// // -> Uri.parse('file:///C:/path/to/foo') | 
| +/// | 
| +/// // URL | 
| +/// path.toUri('http://dartlang.org/path/to/foo') | 
| +/// // -> Uri.parse('http://dartlang.org/path/to/foo') | 
| +Uri toUri(String path) => _builder.toUri(path); | 
| + | 
| /// Validates that there are no non-null arguments following a null one and | 
| /// throws an appropriate [ArgumentError] on failure. | 
| _validateArgList(String method, List<String> args) { | 
| @@ -673,6 +712,48 @@ class Builder { | 
| return parsed.toString(); | 
| } | 
| + /// Returns the path represented by [uri]. | 
| + /// | 
| + /// For POSIX and Windows styles, [uri] must be a `file:` URI. For the URL | 
| + /// style, this will just convert [uri] to a string. | 
| + /// | 
| + /// // POSIX | 
| + /// builder.fromUri(Uri.parse('file:///path/to/foo')) | 
| + /// // -> '/path/to/foo' | 
| + /// | 
| + /// // Windows | 
| + /// builder.fromUri(Uri.parse('file:///C:/path/to/foo')) | 
| + /// // -> r'C:\path\to\foo' | 
| + /// | 
| + /// // URL | 
| + /// builder.fromUri(Uri.parse('http://dartlang.org/path/to/foo')) | 
| + /// // -> 'http://dartlang.org/path/to/foo' | 
| + String fromUri(Uri uri) => style.pathFromUri(uri); | 
| + | 
| + /// Returns the URI that represents [path]. | 
| + /// | 
| + /// For POSIX and Windows styles, this will return a `file:` URI. For the URL | 
| + /// style, this will just convert [path] to a [Uri]. | 
| + /// | 
| + /// // POSIX | 
| + /// builder.toUri('/path/to/foo') | 
| + /// // -> Uri.parse('file:///path/to/foo') | 
| + /// | 
| + /// // Windows | 
| + /// builder.toUri(r'C:\path\to\foo') | 
| + /// // -> Uri.parse('file:///C:/path/to/foo') | 
| + /// | 
| + /// // URL | 
| + /// builder.toUri('http://dartlang.org/path/to/foo') | 
| + /// // -> Uri.parse('http://dartlang.org/path/to/foo') | 
| + Uri toUri(String path) { | 
| + if (isRelative(path)) { | 
| + return Uri.parse(path.replaceAll(style.separatorPattern, '/')); | 
| + } else { | 
| + return style.pathToUri(join(root, path)); | 
| + } | 
| + } | 
| + | 
| _ParsedPath _parse(String path) { | 
| var before = path; | 
| @@ -714,15 +795,14 @@ class Builder { | 
| class Style { | 
| /// POSIX-style paths use "/" (forward slash) as separators. Absolute paths | 
| /// start with "/". Used by UNIX, Linux, Mac OS X, and others. | 
| - static final posix = new Style._('posix', '/', '/', r'[^/]$', '/'); | 
| + static final posix = new _PosixStyle(); | 
| /// Windows paths use "\" (backslash) as separators. Absolute paths start with | 
| /// a drive letter followed by a colon (example, "C:") or two backslashes | 
| /// ("\\") for UNC paths. | 
| // TODO(rnystrom): The UNC root prefix should include the drive name too, not | 
| // just the "\\". | 
| - static final windows = new Style._('windows', '\\', r'[/\\]', r'[^/\\]$', | 
| - r'\\\\|[a-zA-Z]:[/\\]'); | 
| + static final windows = new _WindowsStyle(); | 
| /// URLs aren't filesystem paths, but they're supported by Pathos to make it | 
| /// easier to manipulate URL paths in the browser. | 
| @@ -730,9 +810,7 @@ class Style { | 
| /// URLs use "/" (forward slash) as separators. Absolute paths either start | 
| /// with a protocol and optional hostname (e.g. `http://dartlang.org`, | 
| /// `file://`) or with "/". | 
| - static final url = new Style._('url', '/', '/', | 
| - r"(^[a-zA-Z][-+.a-zA-Z\d]*://|[^/])$", | 
| - r"[a-zA-Z][-+.a-zA-Z\d]*://[^/]*", r"/"); | 
| + static final url = new _UrlStyle(); | 
| Style._(this.name, this.separator, String separatorPattern, | 
| String needsSeparatorPattern, String rootPattern, | 
| @@ -795,9 +873,78 @@ class Style { | 
| return match[0]; | 
| } | 
| + /// Returns the path represented by [uri] in this style. | 
| + String pathFromUri(Uri uri); | 
| + | 
| + /// Returns the URI that represents [path]. | 
| + /// | 
| + /// [path] is guaranteed to be absolute. Relative paths are handled | 
| 
Bob Nystrom
2013/06/13 00:21:18
"guaranteed" is confusing here. Is it required to
 
nweiz
2013/06/19 00:50:27
This documentation is intended for implementors of
 
Bob Nystrom
2013/06/19 18:02:18
Ah, that makes sense. It isn't strictly true that
 | 
| + /// automatically by [Builder]. | 
| + Uri pathToUri(String path); | 
| + | 
| String toString() => name; | 
| } | 
| +/// The style for POSIX paths. | 
| +class _PosixStyle extends Style { | 
| + _PosixStyle() | 
| + : super._('posix', '/', '/', r'[^/]$', '/'); | 
| 
Bob Nystrom
2013/06/13 00:21:18
Since you are subclassing the styles now, let's ma
 
nweiz
2013/06/19 00:50:27
Done.
 | 
| + | 
| + String pathFromUri(Uri uri) { | 
| + if (uri.scheme == '' || uri.scheme == 'file') return uri.path; | 
| 
Bob Nystrom
2013/06/13 00:21:18
What about URL decoding?
 
nweiz
2013/06/19 00:50:27
Done.
 | 
| + throw new ArgumentError("Uri $uri must have scheme 'file:'."); | 
| + } | 
| + | 
| + Uri pathToUri(String path) => Uri.parse('file://$path'); | 
| 
Bob Nystrom
2013/06/13 00:21:18
new Uri(scheme: "file", path: path);
 
Søren Gjesse
2013/06/13 07:13:32
The path should also be encoded
new Uri(scheme: "
 
nweiz
2013/06/19 00:50:27
Done.
 | 
| +} | 
| + | 
| +/// The style for Windows paths. | 
| +class _WindowsStyle extends Style { | 
| + _WindowsStyle() | 
| + : super._('windows', '\\', r'[/\\]', r'[^/\\]$', r'\\\\|[a-zA-Z]:[/\\]'); | 
| + | 
| + String pathFromUri(Uri uri) { | 
| + if (uri.scheme != '' && uri.scheme != 'file') { | 
| + throw new ArgumentError("Uri $uri must have scheme 'file:'."); | 
| + } | 
| + | 
| + if (uri.host == '') { | 
| + if (uri.path.startsWith('/')) { | 
| + // Drive-letter paths look like "file:///C:/path/to/file". The | 
| + // replaceFirst removes the extra initial slash. | 
| + return uri.path.replaceFirst("/", "").replaceAll("/", "\\"); | 
| + } else { | 
| + return uri.path.replaceAll("/", "\\"); | 
| 
Bob Nystrom
2013/06/13 00:21:18
Doing this replaceAll for both arms seems redundan
 
nweiz
2013/06/19 00:50:27
Done.
 | 
| + } | 
| + } else { | 
| + // Network paths look like "file://hostname/path/to/file". | 
| + return "\\\\${uri.host}${uri.path.replaceAll("/", "\\")}"; | 
| + } | 
| + } | 
| + | 
| + Uri pathToUri(String path) { | 
| + if (path.startsWith('\\\\')) { | 
| + // Network paths become "file://hostname/path/to/file". | 
| + return Uri.parse('file:${path.replaceAll("\\", "/")}'); | 
| 
Bob Nystrom
2013/06/13 00:21:18
Use the regular Uri constructor here instead of ma
 
nweiz
2013/06/19 00:50:27
Done.
 | 
| + } else { | 
| + // Drive-letter paths become "file:///C:/path/to/file". | 
| + return Uri.parse('file:///${path.replaceAll("\\", "/")}'); | 
| + } | 
| + } | 
| +} | 
| + | 
| +/// The style for URL paths. | 
| +class _UrlStyle extends Style { | 
| + _UrlStyle() | 
| + : super._('url', '/', '/', | 
| + r"(^[a-zA-Z][-+.a-zA-Z\d]*://|[^/])$", | 
| + r"[a-zA-Z][-+.a-zA-Z\d]*://[^/]*", r"/"); | 
| + | 
| + String pathFromUri(Uri uri) => uri.toString(); | 
| + | 
| + Uri pathToUri(String path) => Uri.parse(path); | 
| +} | 
| + | 
| // TODO(rnystrom): Make this public? | 
| class _ParsedPath { | 
| /// The [Style] that was used to parse this path. |