16d528ed9Sopenharmony_ci// Copyright (c) 2012 The Chromium Authors. All rights reserved.
26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
36d528ed9Sopenharmony_ci// found in the LICENSE file.
46d528ed9Sopenharmony_ci
56d528ed9Sopenharmony_ci// FilePath is a container for pathnames stored in a platform's native string
66d528ed9Sopenharmony_ci// type, providing containers for manipulation in according with the
76d528ed9Sopenharmony_ci// platform's conventions for pathnames.  It supports the following path
86d528ed9Sopenharmony_ci// types:
96d528ed9Sopenharmony_ci//
106d528ed9Sopenharmony_ci//                   POSIX            Windows
116d528ed9Sopenharmony_ci//                   ---------------  ----------------------------------
126d528ed9Sopenharmony_ci// Fundamental type  char[]           char16_t[]
136d528ed9Sopenharmony_ci// Encoding          unspecified*     UTF-16
146d528ed9Sopenharmony_ci// Separator         /                \, tolerant of /
156d528ed9Sopenharmony_ci// Drive letters     no               case-insensitive A-Z followed by :
166d528ed9Sopenharmony_ci// Alternate root    // (surprise!)   \\, for UNC paths
176d528ed9Sopenharmony_ci//
186d528ed9Sopenharmony_ci// * The encoding need not be specified on POSIX systems, although some
196d528ed9Sopenharmony_ci//   POSIX-compliant systems do specify an encoding.  Mac OS X uses UTF-8.
206d528ed9Sopenharmony_ci//   Chrome OS also uses UTF-8.
216d528ed9Sopenharmony_ci//   Linux does not specify an encoding, but in practice, the locale's
226d528ed9Sopenharmony_ci//   character set may be used.
236d528ed9Sopenharmony_ci//
246d528ed9Sopenharmony_ci// For more arcane bits of path trivia, see below.
256d528ed9Sopenharmony_ci//
266d528ed9Sopenharmony_ci// FilePath objects are intended to be used anywhere paths are.  An
276d528ed9Sopenharmony_ci// application may pass FilePath objects around internally, masking the
286d528ed9Sopenharmony_ci// underlying differences between systems, only differing in implementation
296d528ed9Sopenharmony_ci// where interfacing directly with the system.  For example, a single
306d528ed9Sopenharmony_ci// OpenFile(const FilePath &) function may be made available, allowing all
316d528ed9Sopenharmony_ci// callers to operate without regard to the underlying implementation.  On
326d528ed9Sopenharmony_ci// POSIX-like platforms, OpenFile might wrap fopen, and on Windows, it might
336d528ed9Sopenharmony_ci// wrap _wfopen_s, perhaps both by calling file_path.value().c_str().  This
346d528ed9Sopenharmony_ci// allows each platform to pass pathnames around without requiring conversions
356d528ed9Sopenharmony_ci// between encodings, which has an impact on performance, but more imporantly,
366d528ed9Sopenharmony_ci// has an impact on correctness on platforms that do not have well-defined
376d528ed9Sopenharmony_ci// encodings for pathnames.
386d528ed9Sopenharmony_ci//
396d528ed9Sopenharmony_ci// Several methods are available to perform common operations on a FilePath
406d528ed9Sopenharmony_ci// object, such as determining the parent directory (DirName), isolating the
416d528ed9Sopenharmony_ci// final path component (BaseName), and appending a relative pathname string
426d528ed9Sopenharmony_ci// to an existing FilePath object (Append).  These methods are highly
436d528ed9Sopenharmony_ci// recommended over attempting to split and concatenate strings directly.
446d528ed9Sopenharmony_ci// These methods are based purely on string manipulation and knowledge of
456d528ed9Sopenharmony_ci// platform-specific pathname conventions, and do not consult the filesystem
466d528ed9Sopenharmony_ci// at all, making them safe to use without fear of blocking on I/O operations.
476d528ed9Sopenharmony_ci// These methods do not function as mutators but instead return distinct
486d528ed9Sopenharmony_ci// instances of FilePath objects, and are therefore safe to use on const
496d528ed9Sopenharmony_ci// objects.  The objects themselves are safe to share between threads.
506d528ed9Sopenharmony_ci//
516d528ed9Sopenharmony_ci// To aid in initialization of FilePath objects from string literals, a
526d528ed9Sopenharmony_ci// FILE_PATH_LITERAL macro is provided, which accounts for the difference
536d528ed9Sopenharmony_ci// between char[]-based pathnames on POSIX systems and char16_t[]-based
546d528ed9Sopenharmony_ci// pathnames on Windows.
556d528ed9Sopenharmony_ci//
566d528ed9Sopenharmony_ci// As a precaution against premature truncation, paths can't contain NULs.
576d528ed9Sopenharmony_ci//
586d528ed9Sopenharmony_ci// Because a FilePath object should not be instantiated at the global scope,
596d528ed9Sopenharmony_ci// instead, use a FilePath::CharType[] and initialize it with
606d528ed9Sopenharmony_ci// FILE_PATH_LITERAL.  At runtime, a FilePath object can be created from the
616d528ed9Sopenharmony_ci// character array.  Example:
626d528ed9Sopenharmony_ci//
636d528ed9Sopenharmony_ci// | const FilePath::CharType kLogFileName[] = FILE_PATH_LITERAL("log.txt");
646d528ed9Sopenharmony_ci// |
656d528ed9Sopenharmony_ci// | void Function() {
666d528ed9Sopenharmony_ci// |   FilePath log_file_path(kLogFileName);
676d528ed9Sopenharmony_ci// |   [...]
686d528ed9Sopenharmony_ci// | }
696d528ed9Sopenharmony_ci//
706d528ed9Sopenharmony_ci// WARNING: FilePaths should ALWAYS be displayed with LTR directionality, even
716d528ed9Sopenharmony_ci// when the UI language is RTL. This means you always need to pass filepaths
726d528ed9Sopenharmony_ci// through base::i18n::WrapPathWithLTRFormatting() before displaying it in the
736d528ed9Sopenharmony_ci// RTL UI.
746d528ed9Sopenharmony_ci//
756d528ed9Sopenharmony_ci// This is a very common source of bugs, please try to keep this in mind.
766d528ed9Sopenharmony_ci//
776d528ed9Sopenharmony_ci// ARCANE BITS OF PATH TRIVIA
786d528ed9Sopenharmony_ci//
796d528ed9Sopenharmony_ci//  - A double leading slash is actually part of the POSIX standard.  Systems
806d528ed9Sopenharmony_ci//    are allowed to treat // as an alternate root, as Windows does for UNC
816d528ed9Sopenharmony_ci//    (network share) paths.  Most POSIX systems don't do anything special
826d528ed9Sopenharmony_ci//    with two leading slashes, but FilePath handles this case properly
836d528ed9Sopenharmony_ci//    in case it ever comes across such a system.  FilePath needs this support
846d528ed9Sopenharmony_ci//    for Windows UNC paths, anyway.
856d528ed9Sopenharmony_ci//    References:
866d528ed9Sopenharmony_ci//    The Open Group Base Specifications Issue 7, sections 3.267 ("Pathname")
876d528ed9Sopenharmony_ci//    and 4.12 ("Pathname Resolution"), available at:
886d528ed9Sopenharmony_ci//    http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_267
896d528ed9Sopenharmony_ci//    http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_12
906d528ed9Sopenharmony_ci//
916d528ed9Sopenharmony_ci//  - Windows treats c:\\ the same way it treats \\.  This was intended to
926d528ed9Sopenharmony_ci//    allow older applications that require drive letters to support UNC paths
936d528ed9Sopenharmony_ci//    like \\server\share\path, by permitting c:\\server\share\path as an
946d528ed9Sopenharmony_ci//    equivalent.  Since the OS treats these paths specially, FilePath needs
956d528ed9Sopenharmony_ci//    to do the same.  Since Windows can use either / or \ as the separator,
966d528ed9Sopenharmony_ci//    FilePath treats c://, c:\\, //, and \\ all equivalently.
976d528ed9Sopenharmony_ci//    Reference:
986d528ed9Sopenharmony_ci//    The Old New Thing, "Why is a drive letter permitted in front of UNC
996d528ed9Sopenharmony_ci//    paths (sometimes)?", available at:
1006d528ed9Sopenharmony_ci//    http://blogs.msdn.com/oldnewthing/archive/2005/11/22/495740.aspx
1016d528ed9Sopenharmony_ci
1026d528ed9Sopenharmony_ci#ifndef BASE_FILES_FILE_PATH_H_
1036d528ed9Sopenharmony_ci#define BASE_FILES_FILE_PATH_H_
1046d528ed9Sopenharmony_ci
1056d528ed9Sopenharmony_ci#include <stddef.h>
1066d528ed9Sopenharmony_ci
1076d528ed9Sopenharmony_ci#include <iosfwd>
1086d528ed9Sopenharmony_ci#include <string>
1096d528ed9Sopenharmony_ci#include <string_view>
1106d528ed9Sopenharmony_ci#include <vector>
1116d528ed9Sopenharmony_ci
1126d528ed9Sopenharmony_ci#include "base/compiler_specific.h"
1136d528ed9Sopenharmony_ci#include "util/build_config.h"
1146d528ed9Sopenharmony_ci
1156d528ed9Sopenharmony_ci// Windows-style drive letter support and pathname separator characters can be
1166d528ed9Sopenharmony_ci// enabled and disabled independently, to aid testing.  These #defines are
1176d528ed9Sopenharmony_ci// here so that the same setting can be used in both the implementation and
1186d528ed9Sopenharmony_ci// in the unit test.
1196d528ed9Sopenharmony_ci#if defined(OS_WIN)
1206d528ed9Sopenharmony_ci#define FILE_PATH_USES_DRIVE_LETTERS
1216d528ed9Sopenharmony_ci#define FILE_PATH_USES_WIN_SEPARATORS
1226d528ed9Sopenharmony_ci#endif  // OS_WIN
1236d528ed9Sopenharmony_ci
1246d528ed9Sopenharmony_ci// To print path names portably use PRIsFP (based on PRIuS and friends from
1256d528ed9Sopenharmony_ci// C99 and format_macros.h) like this:
1266d528ed9Sopenharmony_ci// base::StringPrintf("Path is %" PRIsFP ".\n", PATH_CSTR(path);
1276d528ed9Sopenharmony_ci#if defined(OS_WIN)
1286d528ed9Sopenharmony_ci#define PRIsFP "ls"
1296d528ed9Sopenharmony_ci#define PATH_CSTR(x) reinterpret_cast<const wchar_t*>(x.value().c_str())
1306d528ed9Sopenharmony_ci#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
1316d528ed9Sopenharmony_ci#define PRIsFP "s"
1326d528ed9Sopenharmony_ci#define PATH_CSTR(x) (x.value().c_str())
1336d528ed9Sopenharmony_ci#endif  // OS_WIN
1346d528ed9Sopenharmony_ci
1356d528ed9Sopenharmony_cinamespace base {
1366d528ed9Sopenharmony_ci
1376d528ed9Sopenharmony_ciclass Pickle;
1386d528ed9Sopenharmony_ciclass PickleIterator;
1396d528ed9Sopenharmony_ci
1406d528ed9Sopenharmony_ci// An abstraction to isolate users from the differences between native
1416d528ed9Sopenharmony_ci// pathnames on different platforms.
1426d528ed9Sopenharmony_ciclass FilePath {
1436d528ed9Sopenharmony_ci public:
1446d528ed9Sopenharmony_ci#if defined(OS_WIN)
1456d528ed9Sopenharmony_ci  // On Windows, for Unicode-aware applications, native pathnames are char16_t
1466d528ed9Sopenharmony_ci  // arrays encoded in UTF-16.
1476d528ed9Sopenharmony_ci  typedef std::u16string StringType;
1486d528ed9Sopenharmony_ci#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
1496d528ed9Sopenharmony_ci  // On most platforms, native pathnames are char arrays, and the encoding
1506d528ed9Sopenharmony_ci  // may or may not be specified.  On Mac OS X, native pathnames are encoded
1516d528ed9Sopenharmony_ci  // in UTF-8.
1526d528ed9Sopenharmony_ci  typedef std::string StringType;
1536d528ed9Sopenharmony_ci#endif  // OS_WIN
1546d528ed9Sopenharmony_ci
1556d528ed9Sopenharmony_ci  using CharType = StringType::value_type;
1566d528ed9Sopenharmony_ci  using StringViewType = std::basic_string_view<CharType>;
1576d528ed9Sopenharmony_ci
1586d528ed9Sopenharmony_ci  // Null-terminated array of separators used to separate components in
1596d528ed9Sopenharmony_ci  // hierarchical paths.  Each character in this array is a valid separator,
1606d528ed9Sopenharmony_ci  // but kSeparators[0] is treated as the canonical separator and will be used
1616d528ed9Sopenharmony_ci  // when composing pathnames.
1626d528ed9Sopenharmony_ci  static const CharType kSeparators[];
1636d528ed9Sopenharmony_ci
1646d528ed9Sopenharmony_ci  // std::size(kSeparators).
1656d528ed9Sopenharmony_ci  static const size_t kSeparatorsLength;
1666d528ed9Sopenharmony_ci
1676d528ed9Sopenharmony_ci  // A special path component meaning "this directory."
1686d528ed9Sopenharmony_ci  static const CharType kCurrentDirectory[];
1696d528ed9Sopenharmony_ci
1706d528ed9Sopenharmony_ci  // A special path component meaning "the parent directory."
1716d528ed9Sopenharmony_ci  static const CharType kParentDirectory[];
1726d528ed9Sopenharmony_ci
1736d528ed9Sopenharmony_ci  // The character used to identify a file extension.
1746d528ed9Sopenharmony_ci  static const CharType kExtensionSeparator;
1756d528ed9Sopenharmony_ci
1766d528ed9Sopenharmony_ci  FilePath();
1776d528ed9Sopenharmony_ci  FilePath(const FilePath& that);
1786d528ed9Sopenharmony_ci  explicit FilePath(StringViewType path);
1796d528ed9Sopenharmony_ci  ~FilePath();
1806d528ed9Sopenharmony_ci  FilePath& operator=(const FilePath& that);
1816d528ed9Sopenharmony_ci
1826d528ed9Sopenharmony_ci  // Constructs FilePath with the contents of |that|, which is left in valid but
1836d528ed9Sopenharmony_ci  // unspecified state.
1846d528ed9Sopenharmony_ci  FilePath(FilePath&& that) noexcept;
1856d528ed9Sopenharmony_ci  // Replaces the contents with those of |that|, which is left in valid but
1866d528ed9Sopenharmony_ci  // unspecified state.
1876d528ed9Sopenharmony_ci  FilePath& operator=(FilePath&& that);
1886d528ed9Sopenharmony_ci
1896d528ed9Sopenharmony_ci  bool operator==(const FilePath& that) const;
1906d528ed9Sopenharmony_ci
1916d528ed9Sopenharmony_ci  bool operator!=(const FilePath& that) const;
1926d528ed9Sopenharmony_ci
1936d528ed9Sopenharmony_ci  // Required for some STL containers and operations
1946d528ed9Sopenharmony_ci  bool operator<(const FilePath& that) const { return path_ < that.path_; }
1956d528ed9Sopenharmony_ci
1966d528ed9Sopenharmony_ci  const StringType& value() const { return path_; }
1976d528ed9Sopenharmony_ci
1986d528ed9Sopenharmony_ci  bool empty() const { return path_.empty(); }
1996d528ed9Sopenharmony_ci
2006d528ed9Sopenharmony_ci  void clear() { path_.clear(); }
2016d528ed9Sopenharmony_ci
2026d528ed9Sopenharmony_ci  // Returns true if |character| is in kSeparators.
2036d528ed9Sopenharmony_ci  static bool IsSeparator(CharType character);
2046d528ed9Sopenharmony_ci
2056d528ed9Sopenharmony_ci  // Returns a vector of all of the components of the provided path. It is
2066d528ed9Sopenharmony_ci  // equivalent to calling DirName().value() on the path's root component,
2076d528ed9Sopenharmony_ci  // and BaseName().value() on each child component.
2086d528ed9Sopenharmony_ci  //
2096d528ed9Sopenharmony_ci  // To make sure this is lossless so we can differentiate absolute and
2106d528ed9Sopenharmony_ci  // relative paths, the root slash will be included even though no other
2116d528ed9Sopenharmony_ci  // slashes will be. The precise behavior is:
2126d528ed9Sopenharmony_ci  //
2136d528ed9Sopenharmony_ci  // Posix:  "/foo/bar"  ->  [ "/", "foo", "bar" ]
2146d528ed9Sopenharmony_ci  // Windows:  "C:\foo\bar"  ->  [ "C:", "\\", "foo", "bar" ]
2156d528ed9Sopenharmony_ci  void GetComponents(std::vector<FilePath::StringType>* components) const;
2166d528ed9Sopenharmony_ci
2176d528ed9Sopenharmony_ci  // Returns true if this FilePath is a strict parent of the |child|. Absolute
2186d528ed9Sopenharmony_ci  // and relative paths are accepted i.e. is /foo parent to /foo/bar and
2196d528ed9Sopenharmony_ci  // is foo parent to foo/bar. Does not convert paths to absolute, follow
2206d528ed9Sopenharmony_ci  // symlinks or directory navigation (e.g. ".."). A path is *NOT* its own
2216d528ed9Sopenharmony_ci  // parent.
2226d528ed9Sopenharmony_ci  bool IsParent(const FilePath& child) const;
2236d528ed9Sopenharmony_ci
2246d528ed9Sopenharmony_ci  // If IsParent(child) holds, appends to path (if non-NULL) the
2256d528ed9Sopenharmony_ci  // relative path to child and returns true.  For example, if parent
2266d528ed9Sopenharmony_ci  // holds "/Users/johndoe/Library/Application Support", child holds
2276d528ed9Sopenharmony_ci  // "/Users/johndoe/Library/Application Support/Google/Chrome/Default", and
2286d528ed9Sopenharmony_ci  // *path holds "/Users/johndoe/Library/Caches", then after
2296d528ed9Sopenharmony_ci  // parent.AppendRelativePath(child, path) is called *path will hold
2306d528ed9Sopenharmony_ci  // "/Users/johndoe/Library/Caches/Google/Chrome/Default".  Otherwise,
2316d528ed9Sopenharmony_ci  // returns false.
2326d528ed9Sopenharmony_ci  bool AppendRelativePath(const FilePath& child, FilePath* path) const;
2336d528ed9Sopenharmony_ci
2346d528ed9Sopenharmony_ci  // Returns a FilePath corresponding to the directory containing the path
2356d528ed9Sopenharmony_ci  // named by this object, stripping away the file component.  If this object
2366d528ed9Sopenharmony_ci  // only contains one component, returns a FilePath identifying
2376d528ed9Sopenharmony_ci  // kCurrentDirectory.  If this object already refers to the root directory,
2386d528ed9Sopenharmony_ci  // returns a FilePath identifying the root directory. Please note that this
2396d528ed9Sopenharmony_ci  // doesn't resolve directory navigation, e.g. the result for "../a" is "..".
2406d528ed9Sopenharmony_ci  [[nodiscard]] FilePath DirName() const;
2416d528ed9Sopenharmony_ci
2426d528ed9Sopenharmony_ci  // Returns a FilePath corresponding to the last path component of this
2436d528ed9Sopenharmony_ci  // object, either a file or a directory.  If this object already refers to
2446d528ed9Sopenharmony_ci  // the root directory, returns a FilePath identifying the root directory;
2456d528ed9Sopenharmony_ci  // this is the only situation in which BaseName will return an absolute path.
2466d528ed9Sopenharmony_ci  [[nodiscard]] FilePath BaseName() const;
2476d528ed9Sopenharmony_ci
2486d528ed9Sopenharmony_ci  // Returns ".jpg" for path "C:\pics\jojo.jpg", or an empty string if
2496d528ed9Sopenharmony_ci  // the file has no extension.  If non-empty, Extension() will always start
2506d528ed9Sopenharmony_ci  // with precisely one ".".  The following code should always work regardless
2516d528ed9Sopenharmony_ci  // of the value of path.  For common double-extensions like .tar.gz and
2526d528ed9Sopenharmony_ci  // .user.js, this method returns the combined extension.  For a single
2536d528ed9Sopenharmony_ci  // component, use FinalExtension().
2546d528ed9Sopenharmony_ci  // new_path = path.RemoveExtension().value().append(path.Extension());
2556d528ed9Sopenharmony_ci  // ASSERT(new_path == path.value());
2566d528ed9Sopenharmony_ci  // NOTE: this is different from the original file_util implementation which
2576d528ed9Sopenharmony_ci  // returned the extension without a leading "." ("jpg" instead of ".jpg")
2586d528ed9Sopenharmony_ci  [[nodiscard]] StringType Extension() const;
2596d528ed9Sopenharmony_ci
2606d528ed9Sopenharmony_ci  // Returns the path's file extension, as in Extension(), but will
2616d528ed9Sopenharmony_ci  // never return a double extension.
2626d528ed9Sopenharmony_ci  //
2636d528ed9Sopenharmony_ci  // TODO(davidben): Check all our extension-sensitive code to see if
2646d528ed9Sopenharmony_ci  // we can rename this to Extension() and the other to something like
2656d528ed9Sopenharmony_ci  // LongExtension(), defaulting to short extensions and leaving the
2666d528ed9Sopenharmony_ci  // long "extensions" to logic like base::GetUniquePathNumber().
2676d528ed9Sopenharmony_ci  [[nodiscard]] StringType FinalExtension() const;
2686d528ed9Sopenharmony_ci
2696d528ed9Sopenharmony_ci  // Returns "C:\pics\jojo" for path "C:\pics\jojo.jpg"
2706d528ed9Sopenharmony_ci  // NOTE: this is slightly different from the similar file_util implementation
2716d528ed9Sopenharmony_ci  // which returned simply 'jojo'.
2726d528ed9Sopenharmony_ci  [[nodiscard]] FilePath RemoveExtension() const;
2736d528ed9Sopenharmony_ci
2746d528ed9Sopenharmony_ci  // Removes the path's file extension, as in RemoveExtension(), but
2756d528ed9Sopenharmony_ci  // ignores double extensions.
2766d528ed9Sopenharmony_ci  [[nodiscard]] FilePath RemoveFinalExtension() const;
2776d528ed9Sopenharmony_ci
2786d528ed9Sopenharmony_ci  // Inserts |suffix| after the file name portion of |path| but before the
2796d528ed9Sopenharmony_ci  // extension.  Returns "" if BaseName() == "." or "..".
2806d528ed9Sopenharmony_ci  // Examples:
2816d528ed9Sopenharmony_ci  // path == "C:\pics\jojo.jpg" suffix == " (1)", returns "C:\pics\jojo (1).jpg"
2826d528ed9Sopenharmony_ci  // path == "jojo.jpg"         suffix == " (1)", returns "jojo (1).jpg"
2836d528ed9Sopenharmony_ci  // path == "C:\pics\jojo"     suffix == " (1)", returns "C:\pics\jojo (1)"
2846d528ed9Sopenharmony_ci  // path == "C:\pics.old\jojo" suffix == " (1)", returns "C:\pics.old\jojo (1)"
2856d528ed9Sopenharmony_ci  [[nodiscard]] FilePath InsertBeforeExtension(StringViewType suffix) const;
2866d528ed9Sopenharmony_ci  [[nodiscard]] FilePath InsertBeforeExtensionASCII(
2876d528ed9Sopenharmony_ci      std::string_view suffix) const;
2886d528ed9Sopenharmony_ci
2896d528ed9Sopenharmony_ci  // Adds |extension| to |file_name|. Returns the current FilePath if
2906d528ed9Sopenharmony_ci  // |extension| is empty. Returns "" if BaseName() == "." or "..".
2916d528ed9Sopenharmony_ci  [[nodiscard]] FilePath AddExtension(StringViewType extension) const;
2926d528ed9Sopenharmony_ci
2936d528ed9Sopenharmony_ci  // Replaces the extension of |file_name| with |extension|.  If |file_name|
2946d528ed9Sopenharmony_ci  // does not have an extension, then |extension| is added.  If |extension| is
2956d528ed9Sopenharmony_ci  // empty, then the extension is removed from |file_name|.
2966d528ed9Sopenharmony_ci  // Returns "" if BaseName() == "." or "..".
2976d528ed9Sopenharmony_ci  [[nodiscard]] FilePath ReplaceExtension(StringViewType extension) const;
2986d528ed9Sopenharmony_ci
2996d528ed9Sopenharmony_ci  // Returns a FilePath by appending a separator and the supplied path
3006d528ed9Sopenharmony_ci  // component to this object's path.  Append takes care to avoid adding
3016d528ed9Sopenharmony_ci  // excessive separators if this object's path already ends with a separator.
3026d528ed9Sopenharmony_ci  // If this object's path is kCurrentDirectory, a new FilePath corresponding
3036d528ed9Sopenharmony_ci  // only to |component| is returned.  |component| must be a relative path;
3046d528ed9Sopenharmony_ci  // it is an error to pass an absolute path.
3056d528ed9Sopenharmony_ci  [[nodiscard]] FilePath Append(StringViewType component) const;
3066d528ed9Sopenharmony_ci  [[nodiscard]] FilePath Append(const FilePath& component) const;
3076d528ed9Sopenharmony_ci
3086d528ed9Sopenharmony_ci  // Although Windows StringType is std::u16string, since the encoding it uses
3096d528ed9Sopenharmony_ci  // for paths is well defined, it can handle ASCII path components as well. Mac
3106d528ed9Sopenharmony_ci  // uses UTF8, and since ASCII is a subset of that, it works there as well. On
3116d528ed9Sopenharmony_ci  // Linux, although it can use any 8-bit encoding for paths, we assume that
3126d528ed9Sopenharmony_ci  // ASCII is a valid subset, regardless of the encoding, since many operating
3136d528ed9Sopenharmony_ci  // system paths will always be ASCII.
3146d528ed9Sopenharmony_ci  [[nodiscard]] FilePath AppendASCII(std::string_view component) const;
3156d528ed9Sopenharmony_ci
3166d528ed9Sopenharmony_ci  // Returns true if this FilePath contains an absolute path.  On Windows, an
3176d528ed9Sopenharmony_ci  // absolute path begins with either a drive letter specification followed by
3186d528ed9Sopenharmony_ci  // a separator character, or with two separator characters.  On POSIX
3196d528ed9Sopenharmony_ci  // platforms, an absolute path begins with a separator character.
3206d528ed9Sopenharmony_ci  bool IsAbsolute() const;
3216d528ed9Sopenharmony_ci
3226d528ed9Sopenharmony_ci  // Returns true if the patch ends with a path separator character.
3236d528ed9Sopenharmony_ci  [[nodiscard]] bool EndsWithSeparator() const;
3246d528ed9Sopenharmony_ci
3256d528ed9Sopenharmony_ci  // Returns a copy of this FilePath that ends with a trailing separator. If
3266d528ed9Sopenharmony_ci  // the input path is empty, an empty FilePath will be returned.
3276d528ed9Sopenharmony_ci  [[nodiscard]] FilePath AsEndingWithSeparator() const;
3286d528ed9Sopenharmony_ci
3296d528ed9Sopenharmony_ci  // Returns a copy of this FilePath that does not end with a trailing
3306d528ed9Sopenharmony_ci  // separator.
3316d528ed9Sopenharmony_ci  [[nodiscard]] FilePath StripTrailingSeparators() const;
3326d528ed9Sopenharmony_ci
3336d528ed9Sopenharmony_ci  // Returns true if this FilePath contains an attempt to reference a parent
3346d528ed9Sopenharmony_ci  // directory (e.g. has a path component that is "..").
3356d528ed9Sopenharmony_ci  bool ReferencesParent() const;
3366d528ed9Sopenharmony_ci
3376d528ed9Sopenharmony_ci  // Return a Unicode human-readable version of this path.
3386d528ed9Sopenharmony_ci  // Warning: you can *not*, in general, go from a display name back to a real
3396d528ed9Sopenharmony_ci  // path.  Only use this when displaying paths to users, not just when you
3406d528ed9Sopenharmony_ci  // want to stuff a std::u16string into some other API.
3416d528ed9Sopenharmony_ci  std::u16string LossyDisplayName() const;
3426d528ed9Sopenharmony_ci
3436d528ed9Sopenharmony_ci  // Return the path as ASCII, or the empty string if the path is not ASCII.
3446d528ed9Sopenharmony_ci  // This should only be used for cases where the FilePath is representing a
3456d528ed9Sopenharmony_ci  // known-ASCII filename.
3466d528ed9Sopenharmony_ci  std::string MaybeAsASCII() const;
3476d528ed9Sopenharmony_ci
3486d528ed9Sopenharmony_ci  // Return the path as 8-bit. On Linux this isn't guaranteed to be UTF-8.
3496d528ed9Sopenharmony_ci  std::string As8Bit() const;
3506d528ed9Sopenharmony_ci
3516d528ed9Sopenharmony_ci  // Normalize all path separators to backslash on Windows
3526d528ed9Sopenharmony_ci  // (if FILE_PATH_USES_WIN_SEPARATORS is true), or do nothing on POSIX systems.
3536d528ed9Sopenharmony_ci  FilePath NormalizePathSeparators() const;
3546d528ed9Sopenharmony_ci
3556d528ed9Sopenharmony_ci  // Normalize all path separattors to given type on Windows
3566d528ed9Sopenharmony_ci  // (if FILE_PATH_USES_WIN_SEPARATORS is true), or do nothing on POSIX systems.
3576d528ed9Sopenharmony_ci  FilePath NormalizePathSeparatorsTo(CharType separator) const;
3586d528ed9Sopenharmony_ci
3596d528ed9Sopenharmony_ci private:
3606d528ed9Sopenharmony_ci  // Remove trailing separators from this object.  If the path is absolute, it
3616d528ed9Sopenharmony_ci  // will never be stripped any more than to refer to the absolute root
3626d528ed9Sopenharmony_ci  // directory, so "////" will become "/", not "".  A leading pair of
3636d528ed9Sopenharmony_ci  // separators is never stripped, to support alternate roots.  This is used to
3646d528ed9Sopenharmony_ci  // support UNC paths on Windows.
3656d528ed9Sopenharmony_ci  void StripTrailingSeparatorsInternal();
3666d528ed9Sopenharmony_ci
3676d528ed9Sopenharmony_ci  StringType path_;
3686d528ed9Sopenharmony_ci};
3696d528ed9Sopenharmony_ci
3706d528ed9Sopenharmony_ci}  // namespace base
3716d528ed9Sopenharmony_ci
3726d528ed9Sopenharmony_ci// Macros for string literal initialization of FilePath::CharType[].
3736d528ed9Sopenharmony_ci#if defined(OS_WIN)
3746d528ed9Sopenharmony_ci#define FILE_PATH_LITERAL(x) u##x
3756d528ed9Sopenharmony_ci#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
3766d528ed9Sopenharmony_ci#define FILE_PATH_LITERAL(x) x
3776d528ed9Sopenharmony_ci#endif  // OS_WIN
3786d528ed9Sopenharmony_ci
3796d528ed9Sopenharmony_cinamespace std {
3806d528ed9Sopenharmony_ci
3816d528ed9Sopenharmony_citemplate <>
3826d528ed9Sopenharmony_cistruct hash<base::FilePath> {
3836d528ed9Sopenharmony_ci  typedef base::FilePath argument_type;
3846d528ed9Sopenharmony_ci  typedef std::size_t result_type;
3856d528ed9Sopenharmony_ci  result_type operator()(argument_type const& f) const {
3866d528ed9Sopenharmony_ci    return hash<base::FilePath::StringType>()(f.value());
3876d528ed9Sopenharmony_ci  }
3886d528ed9Sopenharmony_ci};
3896d528ed9Sopenharmony_ci
3906d528ed9Sopenharmony_ci}  // namespace std
3916d528ed9Sopenharmony_ci
3926d528ed9Sopenharmony_ci#endif  // BASE_FILES_FILE_PATH_H_
393