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

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

Issue 10399077: URI encoder/decoder - copied from other repo. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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 | « no previous file | lib/uri/uri.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 /**
6 * Javascript-like URI encode/decode functions.
7 * The documentation here borrows heavily from the original Javascript
8 * doumentation on MDN at:
9 * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects
10 */
11
12 /**
13 * A JavaScript-like URI encoder. Encodes Uniform Resource Identifier [uri]
14 * by replacing each instance of certain characters by one, two, three, or four
15 * escape sequences representing the UTF-8 encoding of the character (will
16 * only be four escape sequences for characters composed of two "surrogate"
17 * characters). This assumes that [uri] is a complete URI, so does not encode
18 * reserved characters that have special meaning in the URI: [:#;,/?:@&=+\$:]
19 * It returns the escaped URI.
20 */
21 String encodeUri(String uri) {
22 return _uriEncode(
23 "-_.!~*'()#;,/?:@&=+\$0123456789"
24 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", uri);
25 }
26
27 /**
28 * An implementation of JavaScript's decodeURIComponent function.
29 * Decodes a Uniform Resource Identifier [uri] previously created by
30 * encodeURI or by a similar routine. It replaces each escape sequence
31 * in [uri] with the character that it represents. It does not decode
32 * escape sequences that could not have been introduced by encodeURI.
33 * It returns the unescaped URI.
34 */
35 String decodeUri(String uri) {
36 return _uriDecode(uri);
37 }
38
39 /**
40 * A javaScript-like URI component encoder, this encodes a URI
41 * [component] by replacing each instance of certain characters by one,
42 * two, three, or four escape sequences representing the UTF-8 encoding of
43 * the character (will only be four escape sequences for characters composed
44 * of two "surrogate" characters).
45 * To avoid unexpected requests to the server, you should call
46 * encodeURIComponent on any user-entered parameters that will be passed as
47 * part of a URI. For example, a user could type "Thyme &time=again" for a
48 * variable comment. Not using encodeURIComponent on this variable will give
49 * comment=Thyme%20&time=again. Note that the ampersand and the equal sign
50 * mark a new key and value pair. So instead of having a POST comment key
51 * equal to "Thyme &time=again", you have two POST keys, one equal to "Thyme "
52 * and another (time) equal to again.
53 * It returns the escaped string.
54 */
55 String encodeUriComponent(String component) {
56 return _uriEncode(
57 "-_.!~*'()0123456789"
58 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", component);
59 }
60
61 /**
62 * An implementation of JavaScript's decodeURIComponent function.
63 * Decodes a Uniform Resource Identifier (URI) [component] previously
64 * created by encodeURIComponent or by a similar routine.
65 * It returns the unescaped string.
66 */
67 String decodeUriComponent(String encodedComponent) {
68 return _uriDecode(encodedComponent);
69 }
70
71 /**
72 * This is the internal implementation of JavaScript's encodeURI function.
73 * It encodes all characters in the string [text] except for those
74 * that appear in [canonical], and returns the escaped string.
75 */
76 String _uriEncode(String canonical, String text) {
77 final String hex = '0123456789ABCDEF';
78 var byteToHex = (int v) => '%${hex[v >> 4]}${hex[v&0xf]}';
79 StringBuffer result = new StringBuffer();
80 for (int i = 0; i < text.length; i++) {
81 if (canonical.indexOf(text[i]) >= 0) {
82 result.add(text[i]);
83 } else {
84 int ch = text.charCodeAt(i);
85 if (ch >= 0xD800 && ch < 0xDC00) {
86 // Low surrogate. We expect a next char high surrogate.
87 ++i;
88 int nextCh = text.length == i ? 0 : text.charCodeAt(i);
89 if (nextCh >= 0xDC00 && nextCh < 0xE000) {
90 // convert the pair to a U+10000 codepoint
91 ch = 0x10000 + ((ch-0xD800) << 10) + (nextCh - 0xDC00);
92 } else {
93 throw new IllegalArgumentException('Malformed URI');
94 }
95 }
96 for (int codepoint in codepointsToUtf8([ch])) {
97 result.add(byteToHex(codepoint));
98 }
99 }
100 }
101 return result.toString();
102 }
103
104 /**
105 * Convert a byte (2 character hex sequence) in string [s] starting
106 * at position [pos] to its ordinal value
107 */
108
109 int _hexCharPairToByte(String s, int pos) {
110 // An alternative to calling parseInt twice would be to take a
111 // two character substring and call it once, but that may be less
112 // efficient.
113 int d1 = Math.parseInt("0x${s[pos]}");
114 int d2 = Math.parseInt("0x${s[pos+1]}");
115 return d1 * 16 + d2;
116 }
117
118 /**
119 * A JavaScript-like decodeURI function. It unescapes the string [text] and
120 * returns the unescaped string.
121 */
122 String _uriDecode(String text) {
123 StringBuffer result = new StringBuffer();
124 List<int> codepoints = new List<int>();
125 for (int i = 0; i < text.length;) {
126 String ch = text[i];
127 if (ch != '%') {
128 result.add(ch);
129 i++;
130 } else {
131 codepoints.clear();
132 while (ch == '%') {
133 if (++i > text.length - 2) {
134 throw new IllegalArgumentException('Truncated URI');
135 }
136 codepoints.add(_hexCharPairToByte(text, i));
137 i += 2;
138 if (i == text.length)
139 break;
140 ch = text[i];
141 }
142 result.add(decodeUtf8(codepoints));
143 }
144 }
145 return result.toString();
146 }
147
OLDNEW
« no previous file with comments | « no previous file | lib/uri/uri.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698