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

Side by Side Diff: sdk/lib/uri/uri.dart

Issue 12318031: Move json, uri, utf and crypto libraries into the VM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | « sdk/lib/json/json_sources.gypi ('k') | sdk/lib/uri/uri_base.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart.uri; 5 library dart.uri;
6 6
7 import 'dart:math'; 7 import 'dart:math';
8 import 'dart:utf'; 8 import 'dart:utf';
9 9
10 part 'uri_base.dart';
10 part 'encode_decode.dart'; 11 part 'encode_decode.dart';
11 part 'helpers.dart'; 12 part 'helpers.dart';
12
13 /**
14 * A parsed URI, inspired by Closure's [URI][] class. Implements [RFC-3986][].
15 * [uri]: http://closure-library.googlecode.com/svn/docs/class_goog_Uri.html
16 * [RFC-3986]: http://tools.ietf.org/html/rfc3986#section-4.3)
17 */
18 class Uri {
19 final String scheme;
20 final String userInfo;
21 final String domain;
22 final int port;
23 final String path;
24 final String query;
25 final String fragment;
26
27 /**
28 * Deprecated. Please use [parse] instead.
29 */
30 Uri.fromString(String uri) : this._fromMatch(_splitRe.firstMatch(uri));
31
32 static Uri parse(String uri) => new Uri._fromMatch(_splitRe.firstMatch(uri));
33
34 Uri._fromMatch(Match m) :
35 this.fromComponents(scheme: _emptyIfNull(m[_COMPONENT_SCHEME]),
36 userInfo: _emptyIfNull(m[_COMPONENT_USER_INFO]),
37 domain: _emptyIfNull(m[_COMPONENT_DOMAIN]),
38 port: _parseIntOrZero(m[_COMPONENT_PORT]),
39 path: _emptyIfNull(m[_COMPONENT_PATH]),
40 query: _emptyIfNull(m[_COMPONENT_QUERY_DATA]),
41 fragment: _emptyIfNull(m[_COMPONENT_FRAGMENT]));
42
43 const Uri.fromComponents({this.scheme: "",
44 this.userInfo: "",
45 this.domain: "",
46 this.port: 0,
47 this.path: "",
48 this.query: "",
49 this.fragment: ""});
50
51 Uri(String uri) : this.fromString(uri);
52
53 static String _emptyIfNull(String val) => val != null ? val : '';
54
55 static int _parseIntOrZero(String val) {
56 if (val != null && val != '') {
57 return int.parse(val);
58 } else {
59 return 0;
60 }
61 }
62
63 // NOTE: This code was ported from: closure-library/closure/goog/uri/utils.js
64 static final RegExp _splitRe = new RegExp(
65 '^'
66 '(?:'
67 '([^:/?#.]+)' // scheme - ignore special characters
68 // used by other URL parts such as :,
69 // ?, /, #, and .
70 ':)?'
71 '(?://'
72 '(?:([^/?#]*)@)?' // userInfo
73 '([\\w\\d\\-\\u0100-\\uffff.%]*)'
74 // domain - restrict to letters,
75 // digits, dashes, dots, percent
76 // escapes, and unicode characters.
77 '(?::([0-9]+))?' // port
78 ')?'
79 '([^?#]+)?' // path
80 '(?:\\?([^#]*))?' // query
81 '(?:#(.*))?' // fragment
82 '\$');
83
84 static const _COMPONENT_SCHEME = 1;
85 static const _COMPONENT_USER_INFO = 2;
86 static const _COMPONENT_DOMAIN = 3;
87 static const _COMPONENT_PORT = 4;
88 static const _COMPONENT_PATH = 5;
89 static const _COMPONENT_QUERY_DATA = 6;
90 static const _COMPONENT_FRAGMENT = 7;
91
92 /**
93 * Returns `true` if the URI is absolute.
94 */
95 bool get isAbsolute {
96 if ("" == scheme) return false;
97 if ("" != fragment) return false;
98 return true;
99
100 /* absolute-URI = scheme ":" hier-part [ "?" query ]
101 * hier-part = "//" authority path-abempty
102 * / path-absolute
103 * / path-rootless
104 * / path-empty
105 *
106 * path = path-abempty ; begins with "/" or is empty
107 * / path-absolute ; begins with "/" but not "//"
108 * / path-noscheme ; begins with a non-colon segment
109 * / path-rootless ; begins with a segment
110 * / path-empty ; zero characters
111 *
112 * path-abempty = *( "/" segment )
113 * path-absolute = "/" [ segment-nz *( "/" segment ) ]
114 * path-noscheme = segment-nz-nc *( "/" segment )
115 * path-rootless = segment-nz *( "/" segment )
116 * path-empty = 0<pchar>
117 * segment = *pchar
118 * segment-nz = 1*pchar
119 * segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
120 * ; non-zero-length segment without any colon ":"
121 *
122 * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
123 */
124 }
125
126 Uri resolve(String uri) {
127 return resolveUri(Uri.parse(uri));
128 }
129
130 Uri resolveUri(Uri reference) {
131 // From RFC 3986.
132 String targetScheme;
133 String targetUserInfo;
134 String targetDomain;
135 int targetPort;
136 String targetPath;
137 String targetQuery;
138 if (reference.scheme != "") {
139 targetScheme = reference.scheme;
140 targetUserInfo = reference.userInfo;
141 targetDomain = reference.domain;
142 targetPort = reference.port;
143 targetPath = removeDotSegments(reference.path);
144 targetQuery = reference.query;
145 } else {
146 if (reference.hasAuthority) {
147 targetUserInfo = reference.userInfo;
148 targetDomain = reference.domain;
149 targetPort = reference.port;
150 targetPath = removeDotSegments(reference.path);
151 targetQuery = reference.query;
152 } else {
153 if (reference.path == "") {
154 targetPath = this.path;
155 if (reference.query != "") {
156 targetQuery = reference.query;
157 } else {
158 targetQuery = this.query;
159 }
160 } else {
161 if (reference.path.startsWith("/")) {
162 targetPath = removeDotSegments(reference.path);
163 } else {
164 targetPath = removeDotSegments(merge(this.path, reference.path));
165 }
166 targetQuery = reference.query;
167 }
168 targetUserInfo = this.userInfo;
169 targetDomain = this.domain;
170 targetPort = this.port;
171 }
172 targetScheme = this.scheme;
173 }
174 return new Uri.fromComponents(scheme: targetScheme,
175 userInfo: targetUserInfo,
176 domain: targetDomain,
177 port: targetPort,
178 path: targetPath,
179 query: targetQuery,
180 fragment: reference.fragment);
181 }
182
183 bool get hasAuthority {
184 return (userInfo != "") || (domain != "") || (port != 0);
185 }
186
187 /**
188 * For http/https schemes returns URI's [origin][] - scheme://domain:port.
189 * For all other schemes throws ArgumentError.
190 * [origin]: http://www.w3.org/TR/2011/WD-html5-20110405/origin-0.html#origin
191 */
192 String get origin {
193 if (scheme == "") {
194 // TODO(aprelev@gmail.com): Use StateException instead
195 throw new ArgumentError("Cannot use origin without a scheme");
196 }
197 if (scheme != "http" && scheme != "https") {
198 // TODO(aprelev@gmail.com): Use StateException instead
199 throw new ArgumentError(
200 "origin is applicable to http/https schemes only. Not \'$scheme\'");
201 }
202 StringBuffer sb = new StringBuffer();
203 sb.add(scheme);
204 sb.add(":");
205 if (domain == null || domain == "") {
206 // TODO(aprelev@gmail.com): Use StateException instead
207 throw new ArgumentError("Cannot use origin without a domain");
208 }
209
210 sb.add("//");
211 sb.add(domain);
212 if (port != 0) {
213 sb.add(":");
214 sb.add(port);
215 }
216 return sb.toString();
217 }
218
219 String toString() {
220 StringBuffer sb = new StringBuffer();
221 _addIfNonEmpty(sb, scheme, scheme, ':');
222 if (hasAuthority || (scheme == "file")) {
223 sb.add("//");
224 _addIfNonEmpty(sb, userInfo, userInfo, "@");
225 sb.add(domain == null ? "null" : domain);
226 if (port != 0) {
227 sb.add(":");
228 sb.add(port.toString());
229 }
230 }
231 sb.add(path == null ? "null" : path);
232 _addIfNonEmpty(sb, query, "?", query);
233 _addIfNonEmpty(sb, fragment, "#", fragment);
234 return sb.toString();
235 }
236
237 bool operator==(other) {
238 if (other is! Uri) return false;
239 Uri uri = other;
240 return scheme == uri.scheme &&
241 userInfo == uri.userInfo &&
242 domain == uri.domain &&
243 port == uri.port &&
244 path == uri.path &&
245 query == uri.query &&
246 fragment == uri.fragment;
247 }
248
249 int get hashCode {
250 int combine(part, current) {
251 // The sum is truncated to 30 bits to make sure it fits into a Smi.
252 return (current * 31 + part.hashCode) & 0x3FFFFFFF;
253 }
254 return combine(scheme, combine(userInfo, combine(domain, combine(port,
255 combine(path, combine(query, combine(fragment, 1)))))));
256 }
257
258 static void _addIfNonEmpty(StringBuffer sb, String test,
259 String first, String second) {
260 if ("" != test) {
261 sb.add(first == null ? "null" : first);
262 sb.add(second == null ? "null" : second);
263 }
264 }
265 }
OLDNEW
« no previous file with comments | « sdk/lib/json/json_sources.gypi ('k') | sdk/lib/uri/uri_base.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698