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

Side by Side Diff: runtime/vm/uri.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 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
« no previous file with comments | « runtime/vm/unit_test.cc ('k') | runtime/vm/uri_test.cc » ('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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 #include "vm/uri.h" 5 #include "vm/uri.h"
6 6
7 #include "vm/zone.h" 7 #include "vm/zone.h"
8 8
9 namespace dart { 9 namespace dart {
10 10
11 static bool IsUnreservedChar(intptr_t value) { 11 static bool IsUnreservedChar(intptr_t value) {
12 return ((value >= 'a' && value <= 'z') || (value >= 'A' && value <= 'Z') || 12 return ((value >= 'a' && value <= 'z') || (value >= 'A' && value <= 'Z') ||
13 (value >= '0' && value <= '9') || value == '-' || value == '.' || 13 (value >= '0' && value <= '9') || value == '-' || value == '.' ||
14 value == '_' || value == '~'); 14 value == '_' || value == '~');
15 } 15 }
16 16
17
18 static bool IsDelimiter(intptr_t value) { 17 static bool IsDelimiter(intptr_t value) {
19 switch (value) { 18 switch (value) {
20 case ':': 19 case ':':
21 case '/': 20 case '/':
22 case '?': 21 case '?':
23 case '#': 22 case '#':
24 case '[': 23 case '[':
25 case ']': 24 case ']':
26 case '@': 25 case '@':
27 case '!': 26 case '!':
28 case '$': 27 case '$':
29 case '&': 28 case '&':
30 case '\'': 29 case '\'':
31 case '(': 30 case '(':
32 case ')': 31 case ')':
33 case '*': 32 case '*':
34 case '+': 33 case '+':
35 case ',': 34 case ',':
36 case ';': 35 case ';':
37 case '=': 36 case '=':
38 return true; 37 return true;
39 default: 38 default:
40 return false; 39 return false;
41 } 40 }
42 } 41 }
43 42
44
45 static bool IsHexDigit(char value) { 43 static bool IsHexDigit(char value) {
46 return ((value >= '0' && value <= '9') || (value >= 'A' && value <= 'F') || 44 return ((value >= '0' && value <= '9') || (value >= 'A' && value <= 'F') ||
47 (value >= 'a' && value <= 'f')); 45 (value >= 'a' && value <= 'f'));
48 } 46 }
49 47
50
51 static int HexValue(char digit) { 48 static int HexValue(char digit) {
52 if ((digit >= '0' && digit <= '9')) { 49 if ((digit >= '0' && digit <= '9')) {
53 return digit - '0'; 50 return digit - '0';
54 } 51 }
55 if ((digit >= 'A' && digit <= 'F')) { 52 if ((digit >= 'A' && digit <= 'F')) {
56 return digit - 'A' + 10; 53 return digit - 'A' + 10;
57 } 54 }
58 if ((digit >= 'a' && digit <= 'f')) { 55 if ((digit >= 'a' && digit <= 'f')) {
59 return digit - 'a' + 10; 56 return digit - 'a' + 10;
60 } 57 }
61 UNREACHABLE(); 58 UNREACHABLE();
62 return 0; 59 return 0;
63 } 60 }
64 61
65
66 static int GetEscapedValue(const char* str, intptr_t pos, intptr_t len) { 62 static int GetEscapedValue(const char* str, intptr_t pos, intptr_t len) {
67 if (pos + 2 >= len) { 63 if (pos + 2 >= len) {
68 // Not enough room for a valid escape sequence. 64 // Not enough room for a valid escape sequence.
69 return -1; 65 return -1;
70 } 66 }
71 if (str[pos] != '%') { 67 if (str[pos] != '%') {
72 // Escape sequences start with '%'. 68 // Escape sequences start with '%'.
73 return -1; 69 return -1;
74 } 70 }
75 71
76 char digit1 = str[pos + 1]; 72 char digit1 = str[pos + 1];
77 char digit2 = str[pos + 2]; 73 char digit2 = str[pos + 2];
78 if (!IsHexDigit(digit1) || !IsHexDigit(digit2)) { 74 if (!IsHexDigit(digit1) || !IsHexDigit(digit2)) {
79 // Invalid escape sequence. Ignore it. 75 // Invalid escape sequence. Ignore it.
80 return -1; 76 return -1;
81 } 77 }
82 return HexValue(digit1) * 16 + HexValue(digit2); 78 return HexValue(digit1) * 16 + HexValue(digit2);
83 } 79 }
84 80
85
86 static char* NormalizeEscapes(const char* str, intptr_t len) { 81 static char* NormalizeEscapes(const char* str, intptr_t len) {
87 // Allocate the buffer. 82 // Allocate the buffer.
88 Zone* zone = Thread::Current()->zone(); 83 Zone* zone = Thread::Current()->zone();
89 // We multiply len by three because a percent-escape sequence is 84 // We multiply len by three because a percent-escape sequence is
90 // three characters long (e.g. ' ' -> '%20). +1 for '\0'. We could 85 // three characters long (e.g. ' ' -> '%20). +1 for '\0'. We could
91 // take two passes through the string and avoid the excess 86 // take two passes through the string and avoid the excess
92 // allocation, but it's zone-memory so it doesn't seem necessary. 87 // allocation, but it's zone-memory so it doesn't seem necessary.
93 char* buffer = zone->Alloc<char>(len * 3 + 1); 88 char* buffer = zone->Alloc<char>(len * 3 + 1);
94 89
95 // Copy the string, normalizing as we go. 90 // Copy the string, normalizing as we go.
(...skipping 26 matching lines...) Expand all
122 OS::SNPrint(buffer + buffer_pos, 4, "%%%02X", c); 117 OS::SNPrint(buffer + buffer_pos, 4, "%%%02X", c);
123 buffer_pos += 3; 118 buffer_pos += 3;
124 } 119 }
125 pos++; 120 pos++;
126 } 121 }
127 } 122 }
128 buffer[buffer_pos] = '\0'; 123 buffer[buffer_pos] = '\0';
129 return buffer; 124 return buffer;
130 } 125 }
131 126
132
133 // Lower-case a string in place. 127 // Lower-case a string in place.
134 static void StringLower(char* str) { 128 static void StringLower(char* str) {
135 const intptr_t len = strlen(str); 129 const intptr_t len = strlen(str);
136 intptr_t i = 0; 130 intptr_t i = 0;
137 while (i < len) { 131 while (i < len) {
138 int escaped_value = GetEscapedValue(str, i, len); 132 int escaped_value = GetEscapedValue(str, i, len);
139 if (escaped_value >= 0) { 133 if (escaped_value >= 0) {
140 // Don't lowercase escape sequences. 134 // Don't lowercase escape sequences.
141 i += 3; 135 i += 3;
142 } else { 136 } else {
143 // I don't use tolower() because I don't want the locale 137 // I don't use tolower() because I don't want the locale
144 // transforming any non-acii characters. 138 // transforming any non-acii characters.
145 char c = str[i]; 139 char c = str[i];
146 if (c >= 'A' && c <= 'Z') { 140 if (c >= 'A' && c <= 'Z') {
147 str[i] = c + ('a' - 'A'); 141 str[i] = c + ('a' - 'A');
148 } 142 }
149 i++; 143 i++;
150 } 144 }
151 } 145 }
152 } 146 }
153 147
154
155 static void ClearParsedUri(ParsedUri* parsed_uri) { 148 static void ClearParsedUri(ParsedUri* parsed_uri) {
156 parsed_uri->scheme = NULL; 149 parsed_uri->scheme = NULL;
157 parsed_uri->userinfo = NULL; 150 parsed_uri->userinfo = NULL;
158 parsed_uri->host = NULL; 151 parsed_uri->host = NULL;
159 parsed_uri->port = NULL; 152 parsed_uri->port = NULL;
160 parsed_uri->path = NULL; 153 parsed_uri->path = NULL;
161 parsed_uri->query = NULL; 154 parsed_uri->query = NULL;
162 parsed_uri->fragment = NULL; 155 parsed_uri->fragment = NULL;
163 } 156 }
164 157
165
166 static intptr_t ParseAuthority(const char* authority, ParsedUri* parsed_uri) { 158 static intptr_t ParseAuthority(const char* authority, ParsedUri* parsed_uri) {
167 Zone* zone = Thread::Current()->zone(); 159 Zone* zone = Thread::Current()->zone();
168 const char* current = authority; 160 const char* current = authority;
169 intptr_t len = 0; 161 intptr_t len = 0;
170 162
171 size_t userinfo_len = strcspn(current, "@/"); 163 size_t userinfo_len = strcspn(current, "@/");
172 if (current[userinfo_len] == '@') { 164 if (current[userinfo_len] == '@') {
173 // The '@' character follows the optional userinfo string. 165 // The '@' character follows the optional userinfo string.
174 parsed_uri->userinfo = NormalizeEscapes(current, userinfo_len); 166 parsed_uri->userinfo = NormalizeEscapes(current, userinfo_len);
175 current += userinfo_len + 1; 167 current += userinfo_len + 1;
(...skipping 13 matching lines...) Expand all
189 const char* port_start = current + host_len + 1; // +1 for ':' 181 const char* port_start = current + host_len + 1; // +1 for ':'
190 size_t port_len = strcspn(port_start, "/"); 182 size_t port_len = strcspn(port_start, "/");
191 parsed_uri->port = zone->MakeCopyOfStringN(port_start, port_len); 183 parsed_uri->port = zone->MakeCopyOfStringN(port_start, port_len);
192 len += 1 + port_len; // +1 for ':' 184 len += 1 + port_len; // +1 for ':'
193 } else { 185 } else {
194 parsed_uri->port = NULL; 186 parsed_uri->port = NULL;
195 } 187 }
196 return len; 188 return len;
197 } 189 }
198 190
199
200 // Performs a simple parse of a uri into its components. 191 // Performs a simple parse of a uri into its components.
201 // See RFC 3986 Section 3: Syntax. 192 // See RFC 3986 Section 3: Syntax.
202 bool ParseUri(const char* uri, ParsedUri* parsed_uri) { 193 bool ParseUri(const char* uri, ParsedUri* parsed_uri) {
203 Zone* zone = Thread::Current()->zone(); 194 Zone* zone = Thread::Current()->zone();
204 195
205 // The first ':' separates the scheme from the rest of the uri. If 196 // The first ':' separates the scheme from the rest of the uri. If
206 // a ':' occurs after the first '/' it doesn't count. 197 // a ':' occurs after the first '/' it doesn't count.
207 size_t scheme_len = strcspn(uri, ":/"); 198 size_t scheme_len = strcspn(uri, ":/");
208 const char* rest = uri; 199 const char* rest = uri;
209 if (uri[scheme_len] == ':') { 200 if (uri[scheme_len] == ':') {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 parsed_uri->userinfo = NULL; 243 parsed_uri->userinfo = NULL;
253 parsed_uri->host = NULL; 244 parsed_uri->host = NULL;
254 parsed_uri->port = NULL; 245 parsed_uri->port = NULL;
255 } 246 }
256 247
257 // The path is the substring between the authority and the query. 248 // The path is the substring between the authority and the query.
258 parsed_uri->path = NormalizeEscapes(path_start, (question_pos - path_start)); 249 parsed_uri->path = NormalizeEscapes(path_start, (question_pos - path_start));
259 return true; 250 return true;
260 } 251 }
261 252
262
263 static char* RemoveLastSegment(char* current, char* base) { 253 static char* RemoveLastSegment(char* current, char* base) {
264 if (current == base) { 254 if (current == base) {
265 return current; 255 return current;
266 } 256 }
267 ASSERT(current > base); 257 ASSERT(current > base);
268 for (current--; current > base; current--) { 258 for (current--; current > base; current--) {
269 if (*current == '/') { 259 if (*current == '/') {
270 // We have found the beginning of the last segment. 260 // We have found the beginning of the last segment.
271 return current; 261 return current;
272 } 262 }
273 } 263 }
274 ASSERT(current == base); 264 ASSERT(current == base);
275 return current; 265 return current;
276 } 266 }
277 267
278
279 static intptr_t SegmentLength(const char* input) { 268 static intptr_t SegmentLength(const char* input) {
280 const char* cp = input; 269 const char* cp = input;
281 270
282 // Include initial slash in the segment, if any. 271 // Include initial slash in the segment, if any.
283 if (*cp == '/') { 272 if (*cp == '/') {
284 cp++; 273 cp++;
285 } 274 }
286 275
287 // Don't include trailing slash in the segment. 276 // Don't include trailing slash in the segment.
288 cp += strcspn(cp, "/"); 277 cp += strcspn(cp, "/");
289 return cp - input; 278 return cp - input;
290 } 279 }
291 280
292
293 // See RFC 3986 Section 5.2.4: Remove Dot Segments. 281 // See RFC 3986 Section 5.2.4: Remove Dot Segments.
294 static const char* RemoveDotSegments(const char* path) { 282 static const char* RemoveDotSegments(const char* path) {
295 const char* input = path; 283 const char* input = path;
296 284
297 // The output path will always be less than or equal to the size of 285 // The output path will always be less than or equal to the size of
298 // the input path. 286 // the input path.
299 Zone* zone = Thread::Current()->zone(); 287 Zone* zone = Thread::Current()->zone();
300 char* buffer = zone->Alloc<char>(strlen(path) + 1); // +1 for '\0' 288 char* buffer = zone->Alloc<char>(strlen(path) + 1); // +1 for '\0'
301 char* output = buffer; 289 char* output = buffer;
302 290
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 } 333 }
346 strncpy(output, input, segment_len); 334 strncpy(output, input, segment_len);
347 output += segment_len; 335 output += segment_len;
348 input += segment_len; 336 input += segment_len;
349 } 337 }
350 } 338 }
351 *output = '\0'; 339 *output = '\0';
352 return buffer; 340 return buffer;
353 } 341 }
354 342
355
356 // See RFC 3986 Section 5.2.3: Merge Paths. 343 // See RFC 3986 Section 5.2.3: Merge Paths.
357 static const char* MergePaths(const char* base_path, const char* ref_path) { 344 static const char* MergePaths(const char* base_path, const char* ref_path) {
358 Zone* zone = Thread::Current()->zone(); 345 Zone* zone = Thread::Current()->zone();
359 if (base_path[0] == '\0') { 346 if (base_path[0] == '\0') {
360 // If the base_path is empty, we prepend '/'. 347 // If the base_path is empty, we prepend '/'.
361 return zone->PrintToString("/%s", ref_path); 348 return zone->PrintToString("/%s", ref_path);
362 } 349 }
363 350
364 // We need to find the last '/' in base_path. 351 // We need to find the last '/' in base_path.
365 const char* last_slash = strrchr(base_path, '/'); 352 const char* last_slash = strrchr(base_path, '/');
(...skipping 17 matching lines...) Expand all
383 370
384 // Copy the ref_path. 371 // Copy the ref_path.
385 strncpy((buffer + truncated_base_len + 1), ref_path, ref_path_len); 372 strncpy((buffer + truncated_base_len + 1), ref_path, ref_path_len);
386 373
387 // Add the trailing '\0'. 374 // Add the trailing '\0'.
388 buffer[len] = '\0'; 375 buffer[len] = '\0';
389 376
390 return buffer; 377 return buffer;
391 } 378 }
392 379
393
394 static char* BuildUri(const ParsedUri& uri) { 380 static char* BuildUri(const ParsedUri& uri) {
395 Zone* zone = Thread::Current()->zone(); 381 Zone* zone = Thread::Current()->zone();
396 ASSERT(uri.path != NULL); 382 ASSERT(uri.path != NULL);
397 383
398 const char* fragment = uri.fragment == NULL ? "" : uri.fragment; 384 const char* fragment = uri.fragment == NULL ? "" : uri.fragment;
399 const char* fragment_separator = uri.fragment == NULL ? "" : "#"; 385 const char* fragment_separator = uri.fragment == NULL ? "" : "#";
400 const char* query = uri.query == NULL ? "" : uri.query; 386 const char* query = uri.query == NULL ? "" : uri.query;
401 const char* query_separator = uri.query == NULL ? "" : "?"; 387 const char* query_separator = uri.query == NULL ? "" : "?";
402 388
403 // If there is no scheme for this uri, just build a relative uri of 389 // If there is no scheme for this uri, just build a relative uri of
(...skipping 25 matching lines...) Expand all
429 415
430 // Uri with authority: 416 // Uri with authority:
431 // "scheme://[userinfo@]host[:port][/]path[?query][#fragment]" 417 // "scheme://[userinfo@]host[:port][/]path[?query][#fragment]"
432 return zone->PrintToString( 418 return zone->PrintToString(
433 "%s://%s%s%s%s%s%s%s%s%s%s%s", // There is *nothing* wrong with this. 419 "%s://%s%s%s%s%s%s%s%s%s%s%s", // There is *nothing* wrong with this.
434 uri.scheme, user, user_separator, uri.host, port_separator, port, 420 uri.scheme, user, user_separator, uri.host, port_separator, port,
435 path_separator, uri.path, query_separator, query, fragment_separator, 421 path_separator, uri.path, query_separator, query, fragment_separator,
436 fragment); 422 fragment);
437 } 423 }
438 424
439
440 // See RFC 3986 Section 5: Reference Resolution 425 // See RFC 3986 Section 5: Reference Resolution
441 bool ResolveUri(const char* ref_uri, 426 bool ResolveUri(const char* ref_uri,
442 const char* base_uri, 427 const char* base_uri,
443 const char** target_uri) { 428 const char** target_uri) {
444 // Parse the reference uri. 429 // Parse the reference uri.
445 ParsedUri ref; 430 ParsedUri ref;
446 if (!ParseUri(ref_uri, &ref)) { 431 if (!ParseUri(ref_uri, &ref)) {
447 *target_uri = NULL; 432 *target_uri = NULL;
448 return false; 433 return false;
449 } 434 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 target.port = base.port; 522 target.port = base.port;
538 target.path = RemoveDotSegments(MergePaths(base.path, ref.path)); 523 target.path = RemoveDotSegments(MergePaths(base.path, ref.path));
539 target.query = ref.query; 524 target.query = ref.query;
540 target.fragment = ref.fragment; 525 target.fragment = ref.fragment;
541 *target_uri = BuildUri(target); 526 *target_uri = BuildUri(target);
542 return true; 527 return true;
543 } 528 }
544 } 529 }
545 530
546 } // namespace dart 531 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/unit_test.cc ('k') | runtime/vm/uri_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698