| OLD | NEW |
| 1 /* Based on nsURLParsers.cc from Mozilla | 1 /* Based on nsURLParsers.cc from Mozilla |
| 2 * ------------------------------------- | 2 * ------------------------------------- |
| 3 * The contents of this file are subject to the Mozilla Public License Version | 3 * The contents of this file are subject to the Mozilla Public License Version |
| 4 * 1.1 (the "License"); you may not use this file except in compliance with | 4 * 1.1 (the "License"); you may not use this file except in compliance with |
| 5 * the License. You may obtain a copy of the License at | 5 * the License. You may obtain a copy of the License at |
| 6 * http://www.mozilla.org/MPL/ | 6 * http://www.mozilla.org/MPL/ |
| 7 * | 7 * |
| 8 * Software distributed under the License is distributed on an "AS IS" basis, | 8 * Software distributed under the License is distributed on an "AS IS" basis, |
| 9 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | 9 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| 10 * for the specific language governing rights and limitations under the | 10 * for the specific language governing rights and limitations under the |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 ParseServerInfo(spec, MakeRange(i + 1, auth.begin + auth.len), | 168 ParseServerInfo(spec, MakeRange(i + 1, auth.begin + auth.len), |
| 169 hostname, port_num); | 169 hostname, port_num); |
| 170 } else { | 170 } else { |
| 171 // No user info, everything is server info. | 171 // No user info, everything is server info. |
| 172 username->reset(); | 172 username->reset(); |
| 173 password->reset(); | 173 password->reset(); |
| 174 ParseServerInfo(spec, auth, hostname, port_num); | 174 ParseServerInfo(spec, auth, hostname, port_num); |
| 175 } | 175 } |
| 176 } | 176 } |
| 177 | 177 |
| 178 template <typename CHAR> |
| 179 inline void FindQueryAndRefParts(const CHAR* spec, |
| 180 const Component& path, |
| 181 int* query_separator, |
| 182 int* ref_separator) { |
| 183 int path_end = path.begin + path.len; |
| 184 for (int i = path.begin; i < path_end; i++) { |
| 185 switch (spec[i]) { |
| 186 case '?': |
| 187 // Only match the query string if it precedes the reference fragment |
| 188 // and when we haven't found one already. |
| 189 if (*query_separator < 0) |
| 190 *query_separator = i; |
| 191 break; |
| 192 case '#': |
| 193 // Record the first # sign only. |
| 194 if (*ref_separator < 0) { |
| 195 *ref_separator = i; |
| 196 return; |
| 197 } |
| 198 break; |
| 199 } |
| 200 } |
| 201 } |
| 202 |
| 178 template<typename CHAR> | 203 template<typename CHAR> |
| 179 void ParsePath(const CHAR* spec, | 204 void ParsePath(const CHAR* spec, |
| 180 const Component& path, | 205 const Component& path, |
| 181 Component* filepath, | 206 Component* filepath, |
| 182 Component* query, | 207 Component* query, |
| 183 Component* ref) { | 208 Component* ref) { |
| 184 // path = [/]<segment1>/<segment2>/<...>/<segmentN>;<param>?<query>#<ref> | 209 // path = [/]<segment1>/<segment2>/<...>/<segmentN>;<param>?<query>#<ref> |
| 185 | 210 |
| 186 // Special case when there is no path. | 211 // Special case when there is no path. |
| 187 if (path.len == -1) { | 212 if (path.len == -1) { |
| 188 filepath->reset(); | 213 filepath->reset(); |
| 189 query->reset(); | 214 query->reset(); |
| 190 ref->reset(); | 215 ref->reset(); |
| 191 return; | 216 return; |
| 192 } | 217 } |
| 193 DCHECK(path.len > 0) << "We should never have 0 length paths"; | 218 DCHECK(path.len > 0) << "We should never have 0 length paths"; |
| 194 | 219 |
| 195 // Search for first occurrence of either ? or #. | 220 // Search for first occurrence of either ? or #. |
| 196 int path_end = path.begin + path.len; | |
| 197 | |
| 198 int query_separator = -1; // Index of the '?' | 221 int query_separator = -1; // Index of the '?' |
| 199 int ref_separator = -1; // Index of the '#' | 222 int ref_separator = -1; // Index of the '#' |
| 200 for (int i = path.begin; i < path_end; i++) { | 223 FindQueryAndRefParts(spec, path, &query_separator, &ref_separator); |
| 201 switch (spec[i]) { | |
| 202 case '?': | |
| 203 // Only match the query string if it precedes the reference fragment | |
| 204 // and when we haven't found one already. | |
| 205 if (ref_separator < 0 && query_separator < 0) | |
| 206 query_separator = i; | |
| 207 break; | |
| 208 case '#': | |
| 209 // Record the first # sign only. | |
| 210 if (ref_separator < 0) | |
| 211 ref_separator = i; | |
| 212 break; | |
| 213 } | |
| 214 } | |
| 215 | 224 |
| 216 // Markers pointing to the character after each of these corresponding | 225 // Markers pointing to the character after each of these corresponding |
| 217 // components. The code below words from the end back to the beginning, | 226 // components. The code below words from the end back to the beginning, |
| 218 // and will update these indices as it finds components that exist. | 227 // and will update these indices as it finds components that exist. |
| 219 int file_end, query_end; | 228 int file_end, query_end; |
| 220 | 229 |
| 221 // Ref fragment: from the # to the end of the path. | 230 // Ref fragment: from the # to the end of the path. |
| 231 int path_end = path.begin + path.len; |
| 222 if (ref_separator >= 0) { | 232 if (ref_separator >= 0) { |
| 223 file_end = query_end = ref_separator; | 233 file_end = query_end = ref_separator; |
| 224 *ref = MakeRange(ref_separator + 1, path_end); | 234 *ref = MakeRange(ref_separator + 1, path_end); |
| 225 } else { | 235 } else { |
| 226 file_end = query_end = path_end; | 236 file_end = query_end = path_end; |
| 227 ref->reset(); | 237 ref->reset(); |
| 228 } | 238 } |
| 229 | 239 |
| 230 // Query fragment: everything from the ? to the next boundary (either the end | 240 // Query fragment: everything from the ? to the next boundary (either the end |
| 231 // of the path or the ref fragment). | 241 // of the path or the ref fragment). |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 } | 935 } |
| 926 | 936 |
| 927 void ParseAfterScheme(const base::char16* spec, | 937 void ParseAfterScheme(const base::char16* spec, |
| 928 int spec_len, | 938 int spec_len, |
| 929 int after_scheme, | 939 int after_scheme, |
| 930 Parsed* parsed) { | 940 Parsed* parsed) { |
| 931 DoParseAfterScheme(spec, spec_len, after_scheme, parsed); | 941 DoParseAfterScheme(spec, spec_len, after_scheme, parsed); |
| 932 } | 942 } |
| 933 | 943 |
| 934 } // namespace url | 944 } // namespace url |
| OLD | NEW |