1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FilePath is a container for pathnames stored in a platform's native string 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// type, providing containers for manipulation in according with the 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// platform's conventions for pathnames. It supports the following path 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// types: 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// POSIX Windows 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// --------------- ---------------------------------- 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Fundamental type char[] wchar_t[] 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Encoding unspecified* UTF-16 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Separator / \, tolerant of / 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Drive letters no case-insensitive A-Z followed by : 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Alternate root // (surprise!) \\, for UNC paths 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// * The encoding need not be specified on POSIX systems, although some 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// POSIX-compliant systems do specify an encoding. Mac OS X uses UTF-8. 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Linux does not specify an encoding, but in practice, the locale's 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// character set may be used. 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// For more arcane bits of path trivia, see below. 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FilePath objects are intended to be used anywhere paths are. An 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// application may pass FilePath objects around internally, masking the 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// underlying differences between systems, only differing in implementation 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// where interfacing directly with the system. For example, a single 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// OpenFile(const FilePath &) function may be made available, allowing all 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// callers to operate without regard to the underlying implementation. On 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// POSIX-like platforms, OpenFile might wrap fopen, and on Windows, it might 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// wrap _wfopen_s, perhaps both by calling file_path.value().c_str(). This 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// allows each platform to pass pathnames around without requiring conversions 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// between encodings, which has an impact on performance, but more imporantly, 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// has an impact on correctness on platforms that do not have well-defined 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// encodings for pathnames. 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Several methods are available to perform common operations on a FilePath 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// object, such as determining the parent directory (DirName), isolating the 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// final path component (BaseName), and appending a relative pathname string 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to an existing FilePath object (Append). These methods are highly 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// recommended over attempting to split and concatenate strings directly. 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// These methods are based purely on string manipulation and knowledge of 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// platform-specific pathname conventions, and do not consult the filesystem 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// at all, making them safe to use without fear of blocking on I/O operations. 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// These methods do not function as mutators but instead return distinct 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// instances of FilePath objects, and are therefore safe to use on const 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// objects. The objects themselves are safe to share between threads. 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// To aid in initialization of FilePath objects from string literals, a 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FILE_PATH_LITERAL macro is provided, which accounts for the difference 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// between char[]-based pathnames on POSIX systems and wchar_t[]-based 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// pathnames on Windows. 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Because a FilePath object should not be instantiated at the global scope, 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// instead, use a FilePath::CharType[] and initialize it with 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FILE_PATH_LITERAL. At runtime, a FilePath object can be created from the 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// character array. Example: 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// | const FilePath::CharType kLogFileName[] = FILE_PATH_LITERAL("log.txt"); 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// | 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// | void Function() { 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// | FilePath log_file_path(kLogFileName); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// | [...] 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// | } 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WARNING: FilePaths should ALWAYS be displayed with LTR directionality, even 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// when the UI language is RTL. This means you always need to pass filepaths 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// through base::i18n::WrapPathWithLTRFormatting() before displaying it in the 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RTL UI. 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is a very common source of bugs, please try to keep this in mind. 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ARCANE BITS OF PATH TRIVIA 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - A double leading slash is actually part of the POSIX standard. Systems 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// are allowed to treat // as an alternate root, as Windows does for UNC 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (network share) paths. Most POSIX systems don't do anything special 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// with two leading slashes, but FilePath handles this case properly 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// in case it ever comes across such a system. FilePath needs this support 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// for Windows UNC paths, anyway. 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// References: 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The Open Group Base Specifications Issue 7, sections 3.266 ("Pathname") 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and 4.12 ("Pathname Resolution"), available at: 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_266 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_12 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - Windows treats c:\\ the same way it treats \\. This was intended to 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// allow older applications that require drive letters to support UNC paths 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// like \\server\share\path, by permitting c:\\server\share\path as an 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// equivalent. Since the OS treats these paths specially, FilePath needs 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to do the same. Since Windows can use either / or \ as the separator, 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FilePath treats c://, c:\\, //, and \\ all equivalently. 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Reference: 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The Old New Thing, "Why is a drive letter permitted in front of UNC 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// paths (sometimes)?", available at: 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// http://blogs.msdn.com/oldnewthing/archive/2005/11/22/495740.aspx 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef BASE_FILE_PATH_H_ 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define BASE_FILE_PATH_H_ 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <stddef.h> 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector> 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base_api.h" 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/compiler_specific.h" 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/hash_tables.h" 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string16.h" 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_piece.h" // For implicit conversions. 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "build/build_config.h" 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Windows-style drive letter support and pathname separator characters can be 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// enabled and disabled independently, to aid testing. These #defines are 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// here so that the same setting can be used in both the implementation and 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// in the unit test. 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define FILE_PATH_USES_DRIVE_LETTERS 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define FILE_PATH_USES_WIN_SEPARATORS 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // OS_WIN 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass Pickle; 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// An abstraction to isolate users from the differences between native 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// pathnames on different platforms. 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API FilePath { 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_POSIX) 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // On most platforms, native pathnames are char arrays, and the encoding 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // may or may not be specified. On Mac OS X, native pathnames are encoded 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in UTF-8. 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::string StringType; 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_WIN) 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // On Windows, for Unicode-aware applications, native pathnames are wchar_t 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // arrays encoded in UTF-16. 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::wstring StringType; 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // OS_WIN 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef StringType::value_type CharType; 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Null-terminated array of separators used to separate components in 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // hierarchical paths. Each character in this array is a valid separator, 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // but kSeparators[0] is treated as the canonical separator and will be used 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // when composing pathnames. 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const CharType kSeparators[]; 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A special path component meaning "this directory." 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const CharType kCurrentDirectory[]; 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A special path component meaning "the parent directory." 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const CharType kParentDirectory[]; 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The character used to identify a file extension. 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const CharType kExtensionSeparator; 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath(); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath(const FilePath& that); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit FilePath(const StringType& path); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~FilePath(); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath& operator=(const FilePath& that); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator==(const FilePath& that) const; 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator!=(const FilePath& that) const; 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Required for some STL containers and operations 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator<(const FilePath& that) const { 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return path_ < that.path_; 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const StringType& value() const { return path_; } 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool empty() const { return path_.empty(); } 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void clear() { path_.clear(); } 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if |character| is in kSeparators. 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool IsSeparator(CharType character); 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns a vector of all of the components of the provided path. It is 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // equivalent to calling DirName().value() on the path's root component, 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and BaseName().value() on each child component. 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void GetComponents(std::vector<FilePath::StringType>* components) const; 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if this FilePath is a strict parent of the |child|. Absolute 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and relative paths are accepted i.e. is /foo parent to /foo/bar and 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // is foo parent to foo/bar. Does not convert paths to absolute, follow 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // symlinks or directory navigation (e.g. ".."). A path is *NOT* its own 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // parent. 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsParent(const FilePath& child) const; 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If IsParent(child) holds, appends to path (if non-NULL) the 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // relative path to child and returns true. For example, if parent 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // holds "/Users/johndoe/Library/Application Support", child holds 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // "/Users/johndoe/Library/Application Support/Google/Chrome/Default", and 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // *path holds "/Users/johndoe/Library/Caches", then after 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // parent.AppendRelativePath(child, path) is called *path will hold 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // "/Users/johndoe/Library/Caches/Google/Chrome/Default". Otherwise, 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns false. 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool AppendRelativePath(const FilePath& child, FilePath* path) const; 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns a FilePath corresponding to the directory containing the path 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // named by this object, stripping away the file component. If this object 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // only contains one component, returns a FilePath identifying 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // kCurrentDirectory. If this object already refers to the root directory, 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns a FilePath identifying the root directory. 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath DirName() const; 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns a FilePath corresponding to the last path component of this 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // object, either a file or a directory. If this object already refers to 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the root directory, returns a FilePath identifying the root directory; 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this is the only situation in which BaseName will return an absolute path. 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath BaseName() const; 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns ".jpg" for path "C:\pics\jojo.jpg", or an empty string if 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the file has no extension. If non-empty, Extension() will always start 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // with precisely one ".". The following code should always work regardless 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of the value of path. 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // new_path = path.RemoveExtension().value().append(path.Extension()); 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ASSERT(new_path == path.value()); 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // NOTE: this is different from the original file_util implementation which 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returned the extension without a leading "." ("jpg" instead of ".jpg") 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StringType Extension() const; 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns "C:\pics\jojo" for path "C:\pics\jojo.jpg" 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // NOTE: this is slightly different from the similar file_util implementation 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // which returned simply 'jojo'. 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath RemoveExtension() const; 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Inserts |suffix| after the file name portion of |path| but before the 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // extension. Returns "" if BaseName() == "." or "..". 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Examples: 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // path == "C:\pics\jojo.jpg" suffix == " (1)", returns "C:\pics\jojo (1).jpg" 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // path == "jojo.jpg" suffix == " (1)", returns "jojo (1).jpg" 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // path == "C:\pics\jojo" suffix == " (1)", returns "C:\pics\jojo (1)" 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // path == "C:\pics.old\jojo" suffix == " (1)", returns "C:\pics.old\jojo (1)" 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath InsertBeforeExtension(const StringType& suffix) const; 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath InsertBeforeExtensionASCII(const base::StringPiece& suffix) const; 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Replaces the extension of |file_name| with |extension|. If |file_name| 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // does not have an extension, them |extension| is added. If |extension| is 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // empty, then the extension is removed from |file_name|. 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns "" if BaseName() == "." or "..". 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath ReplaceExtension(const StringType& extension) const; 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the file path matches the specified extension. The test is 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // case insensitive. Don't forget the leading period if appropriate. 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool MatchesExtension(const StringType& extension) const; 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns a FilePath by appending a separator and the supplied path 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // component to this object's path. Append takes care to avoid adding 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // excessive separators if this object's path already ends with a separator. 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If this object's path is kCurrentDirectory, a new FilePath corresponding 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // only to |component| is returned. |component| must be a relative path; 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // it is an error to pass an absolute path. 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath Append(const StringType& component) const WARN_UNUSED_RESULT; 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath Append(const FilePath& component) const WARN_UNUSED_RESULT; 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Although Windows StringType is std::wstring, since the encoding it uses for 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // paths is well defined, it can handle ASCII path components as well. 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Mac uses UTF8, and since ASCII is a subset of that, it works there as well. 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // On Linux, although it can use any 8-bit encoding for paths, we assume that 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ASCII is a valid subset, regardless of the encoding, since many operating 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // system paths will always be ASCII. 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath AppendASCII(const base::StringPiece& component) 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const WARN_UNUSED_RESULT; 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if this FilePath contains an absolute path. On Windows, an 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // absolute path begins with either a drive letter specification followed by 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a separator character, or with two separator characters. On POSIX 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // platforms, an absolute path begins with a separator character. 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsAbsolute() const; 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns a copy of this FilePath that does not end with a trailing 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // separator. 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath StripTrailingSeparators() const; 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if this FilePath contains any attempt to reference a parent 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // directory (i.e. has a path component that is ".." 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ReferencesParent() const; 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Return a Unicode human-readable version of this path. 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Warning: you can *not*, in general, go from a display name back to a real 28572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // path. Only use this when displaying paths to users, not just when you 28672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // want to stuff a string16 into some other API. 28772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 LossyDisplayName() const; 28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 289dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Return the path as ASCII, or the empty string if the path is not ASCII. 290dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // This should only be used for cases where the FilePath is representing a 291dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // known-ASCII filename. 292dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string MaybeAsASCII() const; 293dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Older Chromium code assumes that paths are always wstrings. 295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This function converts wstrings to FilePaths, and is 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // useful to smooth porting that old code to the FilePath API. 297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // It has "Hack" its name so people feel bad about using it. 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http://code.google.com/p/chromium/issues/detail?id=24672 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If you are trying to be a good citizen and remove these, ask yourself: 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // - Am I interacting with other Chrome code that deals with files? Then 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // try to convert the API into using FilePath. 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // - Am I interacting with OS-native calls? Then use value() to get at an 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // OS-native string format. 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // - Am I using well-known file names, like "config.ini"? Then use the 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ASCII functions (we require paths to always be supersets of ASCII). 30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // - Am I displaying a string to the user in some UI? Then use the 30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // LossyDisplayName() function, but keep in mind that you can't 30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // ever use the result of that again as a path. 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static FilePath FromWStringHack(const std::wstring& wstring); 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Static helper method to write a StringType to a pickle. 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void WriteStringTypeToPickle(Pickle* pickle, 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const FilePath::StringType& path); 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool ReadStringTypeFromPickle(Pickle* pickle, void** iter, 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath::StringType* path); 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void WriteToPickle(Pickle* pickle); 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ReadFromPickle(Pickle* pickle, void** iter); 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(FILE_PATH_USES_WIN_SEPARATORS) 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Normalize all path separators to backslash. 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath NormalizeWindowsPathSeparators() const; 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Compare two strings in the same way the file system does. 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that these always ignore case, even on file systems that are case- 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // sensitive. If case-sensitive comparison is ever needed, add corresponding 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // methods here. 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The methods are written as a static method so that they can also be used 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // on parts of a file path, e.g., just the extension. 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // CompareIgnoreCase() returns -1, 0 or 1 for less-than, equal-to and 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // greater-than respectively. 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static int CompareIgnoreCase(const StringType& string1, 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const StringType& string2); 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool CompareEqualIgnoreCase(const StringType& string1, 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const StringType& string2) { 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CompareIgnoreCase(string1, string2) == 0; 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool CompareLessIgnoreCase(const StringType& string1, 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const StringType& string2) { 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CompareIgnoreCase(string1, string2) < 0; 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_MACOSX) 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the string in the special canonical decomposed form as defined for 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HFS, which is close to, but not quite, decomposition form D. See 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // http://developer.apple.com/mac/library/technotes/tn/tn1150.html#UnicodeSubtleties 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // for further comments. 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the epmty string if the conversion failed. 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static StringType GetHFSDecomposedForm(const FilePath::StringType& string); 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Special UTF-8 version of FastUnicodeCompare. Cf: 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // http://developer.apple.com/mac/library/technotes/tn/tn1150.html#StringComparisonAlgorithm 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // IMPORTANT: The input strings must be in the special HFS decomposed form! 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (cf. above GetHFSDecomposedForm method) 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static int HFSFastUnicodeCompare(const StringType& string1, 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const StringType& string2); 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Remove trailing separators from this object. If the path is absolute, it 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // will never be stripped any more than to refer to the absolute root 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // directory, so "////" will become "/", not "". A leading pair of 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // separators is never stripped, to support alternate roots. This is used to 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // support UNC paths on Windows. 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void StripTrailingSeparatorsInternal(); 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StringType path_; 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Macros for string literal initialization of FilePath::CharType[], and for 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// using a FilePath::CharType[] in a printf-style format string. 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_POSIX) 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define FILE_PATH_LITERAL(x) x 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define PRFilePath "s" 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define PRFilePathLiteral "%s" 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_WIN) 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define FILE_PATH_LITERAL(x) L ## x 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define PRFilePath "ls" 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define PRFilePathLiteral L"%ls" 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // OS_WIN 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Provide a hash function so that hash_sets and maps can contain FilePath 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// objects. 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(COMPILER_GCC) 38749139a52abc21019da7fcbafdef393ad960ea0e2Patrick Scottnamespace __gnu_cxx { 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<> 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct hash<FilePath> { 391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t operator()(const FilePath& f) const { 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return hash<FilePath::StringType>()(f.value()); 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace __gnu_cxx 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(COMPILER_MSVC) 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace stdext { 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline size_t hash_value(const FilePath& f) { 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return hash_value(f.value()); 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace stdext 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // COMPILER 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // BASE_FILE_PATH_H_ 408