1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef URL_URL_FILE_H_
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define URL_URL_FILE_H_
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Provides shared functions used by the internals of the parser and
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// canonicalizer for file URLs. Do not use outside of these modules.
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "url/url_parse_internal.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace url {
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef WIN32
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// We allow both "c:" and "c|" as drive identifiers.
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)inline bool IsWindowsDriveSeparator(base::char16 ch) {
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ch == ':' || ch == '|';
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)inline bool IsWindowsDriveLetter(base::char16 ch) {
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // WIN32
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Returns the index of the next slash in the input after the given index, or
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// spec_len if the end of the input is reached.
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<typename CHAR>
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)inline int FindNextSlash(const CHAR* spec, int begin_index, int spec_len) {
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int idx = begin_index;
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (idx < spec_len && !IsURLSlash(spec[idx]))
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    idx++;
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return idx;
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef WIN32
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Returns true if the start_offset in the given spec looks like it begins a
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// drive spec, for example "c:". This function explicitly handles start_offset
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// values that are equal to or larger than the spec_len to simplify callers.
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// If this returns true, the spec is guaranteed to have a valid drive letter
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// plus a colon starting at |start_offset|.
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<typename CHAR>
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)inline bool DoesBeginWindowsDriveSpec(const CHAR* spec, int start_offset,
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      int spec_len) {
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int remaining_len = spec_len - start_offset;
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (remaining_len < 2)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;  // Not enough room.
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!IsWindowsDriveLetter(spec[start_offset]))
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;  // Doesn't start with a valid drive letter.
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!IsWindowsDriveSeparator(spec[start_offset + 1]))
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;  // Isn't followed with a drive separator.
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Returns true if the start_offset in the given text looks like it begins a
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// UNC path, for example "\\". This function explicitly handles start_offset
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// values that are equal to or larger than the spec_len to simplify callers.
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// When strict_slashes is set, this function will only accept backslashes as is
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// standard for Windows. Otherwise, it will accept forward slashes as well
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// which we use for a lot of URL handling.
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<typename CHAR>
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)inline bool DoesBeginUNCPath(const CHAR* text,
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             int start_offset,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             int len,
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             bool strict_slashes) {
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int remaining_len = len - start_offset;
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (remaining_len < 2)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (strict_slashes)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return text[start_offset] == '\\' && text[start_offset + 1] == '\\';
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return IsURLSlash(text[start_offset]) && IsURLSlash(text[start_offset + 1]);
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // WIN32
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace url
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // URL_URL_FILE_H_
84