1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/file_path.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,271 @@ 1.4 +// Copyright (c) 2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +// FilePath is a container for pathnames stored in a platform's native string 1.9 +// type, providing containers for manipulation in according with the 1.10 +// platform's conventions for pathnames. It supports the following path 1.11 +// types: 1.12 +// 1.13 +// POSIX Windows 1.14 +// --------------- ---------------------------------- 1.15 +// Fundamental type char[] wchar_t[] 1.16 +// Encoding unspecified* UTF-16 1.17 +// Separator / \, tolerant of / 1.18 +// Drive letters no case-insensitive A-Z followed by : 1.19 +// Alternate root // (surprise!) \\, for UNC paths 1.20 +// 1.21 +// * The encoding need not be specified on POSIX systems, although some 1.22 +// POSIX-compliant systems do specify an encoding. Mac OS X uses UTF-8. 1.23 +// Linux does not specify an encoding, but in practice, the locale's 1.24 +// character set may be used. 1.25 +// 1.26 +// FilePath objects are intended to be used anywhere paths are. An 1.27 +// application may pass FilePath objects around internally, masking the 1.28 +// underlying differences between systems, only differing in implementation 1.29 +// where interfacing directly with the system. For example, a single 1.30 +// OpenFile(const FilePath &) function may be made available, allowing all 1.31 +// callers to operate without regard to the underlying implementation. On 1.32 +// POSIX-like platforms, OpenFile might wrap fopen, and on Windows, it might 1.33 +// wrap _wfopen_s, perhaps both by calling file_path.value().c_str(). This 1.34 +// allows each platform to pass pathnames around without requiring conversions 1.35 +// between encodings, which has an impact on performance, but more imporantly, 1.36 +// has an impact on correctness on platforms that do not have well-defined 1.37 +// encodings for pathnames. 1.38 +// 1.39 +// Several methods are available to perform common operations on a FilePath 1.40 +// object, such as determining the parent directory (DirName), isolating the 1.41 +// final path component (BaseName), and appending a relative pathname string 1.42 +// to an existing FilePath object (Append). These methods are highly 1.43 +// recommended over attempting to split and concatenate strings directly. 1.44 +// These methods are based purely on string manipulation and knowledge of 1.45 +// platform-specific pathname conventions, and do not consult the filesystem 1.46 +// at all, making them safe to use without fear of blocking on I/O operations. 1.47 +// These methods do not function as mutators but instead return distinct 1.48 +// instances of FilePath objects, and are therefore safe to use on const 1.49 +// objects. The objects themselves are safe to share between threads. 1.50 +// 1.51 +// To aid in initialization of FilePath objects from string literals, a 1.52 +// FILE_PATH_LITERAL macro is provided, which accounts for the difference 1.53 +// between char[]-based pathnames on POSIX systems and wchar_t[]-based 1.54 +// pathnames on Windows. 1.55 +// 1.56 +// Because a FilePath object should not be instantiated at the global scope, 1.57 +// instead, use a FilePath::CharType[] and initialize it with 1.58 +// FILE_PATH_LITERAL. At runtime, a FilePath object can be created from the 1.59 +// character array. Example: 1.60 +// 1.61 +// | const FilePath::CharType kLogFileName[] = FILE_PATH_LITERAL("log.txt"); 1.62 +// | 1.63 +// | void Function() { 1.64 +// | FilePath log_file_path(kLogFileName); 1.65 +// | [...] 1.66 +// | } 1.67 + 1.68 +#ifndef BASE_FILE_PATH_H_ 1.69 +#define BASE_FILE_PATH_H_ 1.70 + 1.71 +#include <string> 1.72 + 1.73 +#include "base/basictypes.h" 1.74 +#include "base/compiler_specific.h" 1.75 +#include "base/hash_tables.h" 1.76 + 1.77 +// Windows-style drive letter support and pathname separator characters can be 1.78 +// enabled and disabled independently, to aid testing. These #defines are 1.79 +// here so that the same setting can be used in both the implementation and 1.80 +// in the unit test. 1.81 +#if defined(OS_WIN) 1.82 +#define FILE_PATH_USES_DRIVE_LETTERS 1.83 +#define FILE_PATH_USES_WIN_SEPARATORS 1.84 +#endif // OS_WIN 1.85 + 1.86 +// An abstraction to isolate users from the differences between native 1.87 +// pathnames on different platforms. 1.88 +class FilePath { 1.89 + public: 1.90 +#if defined(OS_POSIX) 1.91 + // On most platforms, native pathnames are char arrays, and the encoding 1.92 + // may or may not be specified. On Mac OS X, native pathnames are encoded 1.93 + // in UTF-8. 1.94 + typedef std::string StringType; 1.95 +#elif defined(OS_WIN) 1.96 + // On Windows, for Unicode-aware applications, native pathnames are wchar_t 1.97 + // arrays encoded in UTF-16. 1.98 + typedef std::wstring StringType; 1.99 +#endif // OS_WIN 1.100 + 1.101 + typedef StringType::value_type CharType; 1.102 + 1.103 + // Null-terminated array of separators used to separate components in 1.104 + // hierarchical paths. Each character in this array is a valid separator, 1.105 + // but kSeparators[0] is treated as the canonical separator and will be used 1.106 + // when composing pathnames. 1.107 + static const CharType kSeparators[]; 1.108 + 1.109 + // A special path component meaning "this directory." 1.110 + static const CharType kCurrentDirectory[]; 1.111 + 1.112 + // A special path component meaning "the parent directory." 1.113 + static const CharType kParentDirectory[]; 1.114 + 1.115 + // The character used to identify a file extension. 1.116 + static const CharType kExtensionSeparator; 1.117 + 1.118 + FilePath() {} 1.119 + FilePath(const FilePath& that) : path_(that.path_) {} 1.120 + explicit FilePath(const StringType& path) : path_(path) {} 1.121 + 1.122 + FilePath& operator=(const FilePath& that) { 1.123 + path_ = that.path_; 1.124 + return *this; 1.125 + } 1.126 + 1.127 + bool operator==(const FilePath& that) const { 1.128 + return path_ == that.path_; 1.129 + } 1.130 + 1.131 + bool operator!=(const FilePath& that) const { 1.132 + return path_ != that.path_; 1.133 + } 1.134 + 1.135 + // Required for some STL containers and operations 1.136 + bool operator<(const FilePath& that) const { 1.137 + return path_ < that.path_; 1.138 + } 1.139 + 1.140 + const StringType& value() const { return path_; } 1.141 + 1.142 + bool empty() const { return path_.empty(); } 1.143 + 1.144 + // Returns true if |character| is in kSeparators. 1.145 + static bool IsSeparator(CharType character); 1.146 + 1.147 + // Returns a FilePath corresponding to the directory containing the path 1.148 + // named by this object, stripping away the file component. If this object 1.149 + // only contains one component, returns a FilePath identifying 1.150 + // kCurrentDirectory. If this object already refers to the root directory, 1.151 + // returns a FilePath identifying the root directory. 1.152 + FilePath DirName() const; 1.153 + 1.154 + // Returns a FilePath corresponding to the last path component of this 1.155 + // object, either a file or a directory. If this object already refers to 1.156 + // the root directory, returns a FilePath identifying the root directory; 1.157 + // this is the only situation in which BaseName will return an absolute path. 1.158 + FilePath BaseName() const; 1.159 + 1.160 + // Returns ".jpg" for path "C:\pics\jojo.jpg", or an empty string if 1.161 + // the file has no extension. If non-empty, Extension() will always start 1.162 + // with precisely one ".". The following code should always work regardless 1.163 + // of the value of path. 1.164 + // new_path = path.RemoveExtension().value().append(path.Extension()); 1.165 + // ASSERT(new_path == path.value()); 1.166 + // NOTE: this is different from the original file_util implementation which 1.167 + // returned the extension without a leading "." ("jpg" instead of ".jpg") 1.168 + StringType Extension() const; 1.169 + 1.170 + // Returns "C:\pics\jojo" for path "C:\pics\jojo.jpg" 1.171 + // NOTE: this is slightly different from the similar file_util implementation 1.172 + // which returned simply 'jojo'. 1.173 + FilePath RemoveExtension() const; 1.174 + 1.175 + // Inserts |suffix| after the file name portion of |path| but before the 1.176 + // extension. Returns "" if BaseName() == "." or "..". 1.177 + // Examples: 1.178 + // path == "C:\pics\jojo.jpg" suffix == " (1)", returns "C:\pics\jojo (1).jpg" 1.179 + // path == "jojo.jpg" suffix == " (1)", returns "jojo (1).jpg" 1.180 + // path == "C:\pics\jojo" suffix == " (1)", returns "C:\pics\jojo (1)" 1.181 + // path == "C:\pics.old\jojo" suffix == " (1)", returns "C:\pics.old\jojo (1)" 1.182 + FilePath InsertBeforeExtension(const StringType& suffix) const; 1.183 + 1.184 + // Replaces the extension of |file_name| with |extension|. If |file_name| 1.185 + // does not have an extension, them |extension| is added. If |extension| is 1.186 + // empty, then the extension is removed from |file_name|. 1.187 + // Returns "" if BaseName() == "." or "..". 1.188 + FilePath ReplaceExtension(const StringType& extension) const; 1.189 + 1.190 + // Returns a FilePath by appending a separator and the supplied path 1.191 + // component to this object's path. Append takes care to avoid adding 1.192 + // excessive separators if this object's path already ends with a separator. 1.193 + // If this object's path is kCurrentDirectory, a new FilePath corresponding 1.194 + // only to |component| is returned. |component| must be a relative path; 1.195 + // it is an error to pass an absolute path. 1.196 + FilePath Append(const StringType& component) const WARN_UNUSED_RESULT; 1.197 + FilePath Append(const FilePath& component) const WARN_UNUSED_RESULT; 1.198 + 1.199 + // Although Windows StringType is std::wstring, since the encoding it uses for 1.200 + // paths is well defined, it can handle ASCII path components as well. 1.201 + // Mac uses UTF8, and since ASCII is a subset of that, it works there as well. 1.202 + // On Linux, although it can use any 8-bit encoding for paths, we assume that 1.203 + // ASCII is a valid subset, regardless of the encoding, since many operating 1.204 + // system paths will always be ASCII. 1.205 + FilePath AppendASCII(const std::string& component) const WARN_UNUSED_RESULT; 1.206 + 1.207 + // Returns true if this FilePath contains an absolute path. On Windows, an 1.208 + // absolute path begins with either a drive letter specification followed by 1.209 + // a separator character, or with two separator characters. On POSIX 1.210 + // platforms, an absolute path begins with a separator character. 1.211 + bool IsAbsolute() const; 1.212 + 1.213 + // Returns a copy of this FilePath that does not end with a trailing 1.214 + // separator. 1.215 + FilePath StripTrailingSeparators() const; 1.216 + 1.217 + // Calls open on given ifstream instance 1.218 + void OpenInputStream(std::ifstream &stream) const; 1.219 + 1.220 + // Older Chromium code assumes that paths are always wstrings. 1.221 + // This function converts a wstring to a FilePath, and is useful to smooth 1.222 + // porting that old code to the FilePath API. 1.223 + // It has "Hack" in its name so people feel bad about using it. 1.224 + // TODO(port): remove these functions. 1.225 + static FilePath FromWStringHack(const std::wstring& wstring); 1.226 + 1.227 + // Older Chromium code assumes that paths are always wstrings. 1.228 + // This function produces a wstring from a FilePath, and is useful to smooth 1.229 + // porting that old code to the FilePath API. 1.230 + // It has "Hack" in its name so people feel bad about using it. 1.231 + // TODO(port): remove these functions. 1.232 + std::wstring ToWStringHack() const; 1.233 + 1.234 + private: 1.235 + // Remove trailing separators from this object. If the path is absolute, it 1.236 + // will never be stripped any more than to refer to the absolute root 1.237 + // directory, so "////" will become "/", not "". A leading pair of 1.238 + // separators is never stripped, to support alternate roots. This is used to 1.239 + // support UNC paths on Windows. 1.240 + void StripTrailingSeparatorsInternal(); 1.241 + 1.242 + StringType path_; 1.243 +}; 1.244 + 1.245 +// Macros for string literal initialization of FilePath::CharType[]. 1.246 +#if defined(OS_POSIX) 1.247 +#define FILE_PATH_LITERAL(x) x 1.248 +#elif defined(OS_WIN) 1.249 +#define FILE_PATH_LITERAL(x) L ## x 1.250 +#endif // OS_WIN 1.251 + 1.252 +// Implement hash function so that we can use FilePaths in hashsets and maps. 1.253 +#if defined(COMPILER_GCC) && !defined(ANDROID) 1.254 +namespace __gnu_cxx { 1.255 + 1.256 +template<> 1.257 +struct hash<FilePath> { 1.258 + size_t operator()(const FilePath& f) const { 1.259 + return hash<FilePath::StringType>()(f.value()); 1.260 + } 1.261 +}; 1.262 + 1.263 +} // namespace __gnu_cxx 1.264 +#elif defined(COMPILER_MSVC) 1.265 +namespace stdext { 1.266 + 1.267 +inline size_t hash_value(const FilePath& f) { 1.268 + return hash_value(f.value()); 1.269 +} 1.270 + 1.271 +} // namespace stdext 1.272 +#endif // COMPILER 1.273 + 1.274 +#endif // BASE_FILE_PATH_H_