Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: utils/uri/uri.dart

Issue 9325085: Move utils/{uri, utf8} to lib/{uri, utf8} . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/create_sdk.py ('k') | utils/utf8/utf8.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #library('uri');
6
7 /**
8 * A parsed URI, inspired by:
9 * http://closure-library.googlecode.com/svn/docs/class_goog_Uri.html
10 */
11 class Uri {
12 final String scheme;
13 final String userInfo;
14 final String domain;
15 final int port;
16 final String path;
17 final String query;
18 final String fragment;
19
20 Uri.fromString(String uri) : this._fromMatch(_splitRe.firstMatch(uri));
21
22 Uri._fromMatch(Match m) : this(_emptyIfNull(m[_COMPONENT_SCHEME]),
23 _emptyIfNull(m[_COMPONENT_USER_INFO]),
24 _emptyIfNull(m[_COMPONENT_DOMAIN]),
25 _parseIntOrZero(m[_COMPONENT_PORT]),
26 _emptyIfNull(m[_COMPONENT_PATH]),
27 _emptyIfNull(m[_COMPONENT_QUERY_DATA]),
28 _emptyIfNull(m[_COMPONENT_FRAGMENT]));
29
30 const Uri([String this.scheme = "", String this.userInfo ="",
31 String this.domain = "", int this.port = 0,
32 String this.path = "", String this.query = "",
33 String this.fragment = ""]);
34
35 static String _emptyIfNull(String val) => val != null ? val : '';
36
37 static int _parseIntOrZero(String val) {
38 if (val !== null && val != '') {
39 return Math.parseInt(val);
40 } else {
41 return 0;
42 }
43 }
44
45 // NOTE: This code was ported from: closure-library/closure/goog/uri/utils.js
46 static final RegExp _splitRe = const RegExp(
47 '^' +
48 '(?:' +
49 '([^:/?#.]+)' + // scheme - ignore special characters
50 // used by other URL parts such as :,
51 // ?, /, #, and .
52 ':)?' +
53 '(?://' +
54 '(?:([^/?#]*)@)?' + // userInfo
55 '([\\w\\d\\-\\u0100-\\uffff.%]*)' +
56 // domain - restrict to letters,
57 // digits, dashes, dots, percent
58 // escapes, and unicode characters.
59 '(?::([0-9]+))?' + // port
60 ')?' +
61 '([^?#]+)?' + // path
62 '(?:\\?([^#]*))?' + // query
63 '(?:#(.*))?' + // fragment
64 '\$');
65
66 static final _COMPONENT_SCHEME = 1;
67 static final _COMPONENT_USER_INFO = 2;
68 static final _COMPONENT_DOMAIN = 3;
69 static final _COMPONENT_PORT = 4;
70 static final _COMPONENT_PATH = 5;
71 static final _COMPONENT_QUERY_DATA = 6;
72 static final _COMPONENT_FRAGMENT = 7;
73
74 /**
75 * Determines whether a URI is absolute.
76 *
77 * See: http://tools.ietf.org/html/rfc3986#section-4.3
78 */
79 bool isAbsolute() {
80 if ("" == scheme) return false;
81 if ("" != fragment) return false;
82 return true;
83
84 /* absolute-URI = scheme ":" hier-part [ "?" query ]
85 * hier-part = "//" authority path-abempty
86 * / path-absolute
87 * / path-rootless
88 * / path-empty
89 *
90 * path = path-abempty ; begins with "/" or is empty
91 * / path-absolute ; begins with "/" but not "//"
92 * / path-noscheme ; begins with a non-colon segment
93 * / path-rootless ; begins with a segment
94 * / path-empty ; zero characters
95 *
96 * path-abempty = *( "/" segment )
97 * path-absolute = "/" [ segment-nz *( "/" segment ) ]
98 * path-noscheme = segment-nz-nc *( "/" segment )
99 * path-rootless = segment-nz *( "/" segment )
100 * path-empty = 0<pchar>
101 * segment = *pchar
102 * segment-nz = 1*pchar
103 * segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
104 * ; non-zero-length segment without any colon ":"
105 *
106 * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
107 */
108 }
109
110 Uri resolve(String uri) {
111 return resolveUri(new Uri.fromString(uri));
112 }
113
114 Uri resolveUri(Uri reference) {
115 // From RFC 3986.
116 String targetScheme;
117 String targetUserInfo;
118 String targetDomain;
119 int targetPort;
120 String targetPath;
121 String targetQuery;
122 if (reference.scheme != "") {
123 targetScheme = reference.scheme;
124 targetUserInfo = reference.userInfo;
125 targetDomain = reference.domain;
126 targetPort = reference.port;
127 targetPath = removeDotSegments(reference.path);
128 targetQuery = reference.query;
129 } else {
130 if (reference.hasAuthority()) {
131 targetUserInfo = reference.userInfo;
132 targetDomain = reference.domain;
133 targetPort = reference.port;
134 targetPath = removeDotSegments(reference.path);
135 targetQuery = reference.query;
136 } else {
137 if (reference.path == "") {
138 targetPath = this.path;
139 if (reference.query != "") {
140 targetQuery = reference.query;
141 } else {
142 targetQuery = this.query;
143 }
144 } else {
145 if (reference.path.startsWith("/")) {
146 targetPath = removeDotSegments(reference.path);
147 } else {
148 targetPath = removeDotSegments(merge(this.path, reference.path));
149 }
150 targetQuery = reference.query;
151 }
152 targetUserInfo = this.userInfo;
153 targetDomain = this.domain;
154 targetPort = this.port;
155 }
156 targetScheme = this.scheme;
157 }
158 return new Uri(targetScheme, targetUserInfo, targetDomain, targetPort,
159 targetPath, targetQuery, reference.fragment);
160 }
161
162 bool hasAuthority() {
163 return (userInfo != "") || (domain != "") || (port != 0);
164 }
165
166 String toString() {
167 StringBuffer sb = new StringBuffer();
168 _addIfNonEmpty(sb, scheme, scheme, ':');
169 if (hasAuthority() || (scheme == "file")) {
170 sb.add("//");
171 _addIfNonEmpty(sb, userInfo, userInfo, "@");
172 sb.add(domain === null ? "null" : domain);
173 if (port != 0) {
174 sb.add(":");
175 sb.add(port.toString());
176 }
177 }
178 sb.add(path === null ? "null" : path);
179 _addIfNonEmpty(sb, query, "?", query);
180 _addIfNonEmpty(sb, fragment, "#", fragment);
181 return sb.toString();
182 }
183
184 static void _addIfNonEmpty(StringBuffer sb, String test,
185 String first, String second) {
186 if ("" != test) {
187 sb.add(first === null ? "null" : first);
188 sb.add(second === null ? "null" : second);
189 }
190 }
191 }
192
193 String merge(String base, String reference) {
194 if (base == "") return "/$reference";
195 return base.substring(0, base.lastIndexOf("/") + 1) + "$reference";
196 }
197
198 String removeDotSegments(String path) {
199 List<String> output = [];
200 bool appendSlash = false;
201 for (String segment in path.split("/")) {
202 appendSlash = false;
203 if (segment == "..") {
204 if (!output.isEmpty() &&
205 ((output.length != 1) || (output[0] != ""))) output.removeLast();
206 appendSlash = true;
207 } else if ("." == segment) {
208 appendSlash = true;
209 } else {
210 output.add(segment);
211 }
212 }
213 if (appendSlash) output.add("");
214 return Strings.join(output, "/");
215 }
OLDNEW
« no previous file with comments | « tools/create_sdk.py ('k') | utils/utf8/utf8.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698