1 // Copyright 2014 The Android Open Source Project 2 // 3 // This software is licensed under the terms of the GNU General Public 4 // License version 2, as published by the Free Software Foundation, and 5 // may be copied, distributed, and modified under those terms. 6 // 7 // This program is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 // GNU General Public License for more details. 11 12 #ifndef ANDROID_BASE_FILES_PATH_UTIL_H 13 #define ANDROID_BASE_FILES_PATH_UTIL_H 14 15 #include "android/base/containers/StringVector.h" 16 #include "android/base/String.h" 17 18 namespace android { 19 namespace base { 20 21 // Utility functions to manage file paths. None of these should touch the 22 // file system. All methods must be static. 23 class PathUtils { 24 public: 25 // An enum listing the supported host file system types. 26 // HOST_POSIX means a Posix-like file system. 27 // HOST_WIN32 means a Windows-like file system. 28 // HOST_TYPE means the current host type (one of the above). 29 // NOTE: If you update this list, modify kHostTypeCount below too. 30 enum HostType { 31 HOST_POSIX = 0, 32 HOST_WIN32 = 1, 33 #ifdef _WIN32 34 HOST_TYPE = HOST_WIN32, 35 #else 36 HOST_TYPE = HOST_POSIX, 37 #endif 38 }; 39 40 // The number of distinct items in the HostType enumeration above. 41 static const int kHostTypeCount = 2; 42 43 // Return true if |ch| is a directory separator for a given |hostType|. 44 static bool isDirSeparator(int ch, HostType hostType); 45 46 // Return true if |ch| is a directory separator for the current platform. 47 static inline bool isDirSeparator(int ch) { 48 return isDirSeparator(ch, HOST_TYPE); 49 } 50 51 // Return true if |ch| is a path separator for a given |hostType|. 52 static bool isPathSeparator(int ch, HostType hostType); 53 54 // Return true if |ch| is a path separator for the current platform. 55 static inline bool isPathSeparator(int ch) { 56 return isPathSeparator(ch, HOST_TYPE); 57 } 58 59 // If |path} starts with a root prefix, return its size in bytes, or 60 // 0 otherwise. The definition of valid root prefixes depends on the 61 // value of |hostType|. For HOST_POSIX, it's any path that begins 62 // with a slash (/). For HOST_WIN32, the following prefixes are 63 // recognized: 64 // <drive>: 65 // <drive>:<sep> 66 // <sep><sep>volumeName<sep> 67 static size_t rootPrefixSize(const char* path, HostType hostType); 68 69 // Return the root prefix for the current platform. See above for 70 // documentation. 71 static inline size_t rootPrefixSize(const char* path) { 72 return rootPrefixSize(path, HOST_TYPE); 73 } 74 75 // Return true iff |path| is an absolute path for a given |hostType|. 76 static bool isAbsolute(const char* path, HostType hostType); 77 78 // Return true iff |path| is an absolute path for the current host. 79 static inline bool isAbsolute(const char* path) { 80 return isAbsolute(path, HOST_TYPE); 81 } 82 83 // Decompose |path| into individual components. If |path| has a root 84 // prefix, it will always be the first component. I.e. for Posix 85 // systems this will be '/' (for absolute paths). For Win32 systems, 86 // it could be 'C:" (for a path relative to a root volume) or "C:\" 87 // for an absolute path from volume C)., 88 // On success, return true and sets |out| to a vector of strings, 89 // each one being a path component (prefix or subdirectory or file 90 // name). Directory separators do not appear in components, except 91 // for the root prefix, if any. 92 static StringVector decompose(const char* path, HostType hostType); 93 94 // Decompose |path| into individual components for the host platform. 95 // See comments above for more details. 96 static inline StringVector decompose(const char* path) { 97 return decompose(path, HOST_TYPE); 98 } 99 100 // Recompose a path from individual components into a file path string. 101 // |components| is a vector of strings, and |hostType| the target 102 // host type to use. Return a new file path string. Note that if the 103 // first component is a root prefix, it will be kept as is, i.e.: 104 // [ 'C:', 'foo' ] -> 'C:foo' on Win32, but not Posix where it will 105 // be 'C:/foo'. 106 static String recompose(const StringVector& components, 107 HostType hostType); 108 109 // Recompose a path from individual components into a file path string 110 // for the current host. |components| is a vector os strings. 111 // Returns a new file path string. 112 static inline String recompose(const StringVector& components) { 113 return recompose(components, HOST_TYPE); 114 } 115 116 // Given a list of components returned by decompose(), simplify it 117 // by removing instances of '.' and '..' when that makes sense. 118 // Note that it is not possible to simplify initial instances of 119 // '..', i.e. "foo/../../bar" -> "../bar" 120 static void simplifyComponents(StringVector* components); 121 }; 122 123 // Useful shortcuts to avoid too much typing. 124 static const PathUtils::HostType kHostPosix = PathUtils::HOST_POSIX; 125 static const PathUtils::HostType kHostWin32 = PathUtils::HOST_WIN32; 126 static const PathUtils::HostType kHostType = PathUtils::HOST_TYPE; 127 128 } // namespace base 129 } // namespace android 130 131 #endif // ANDROID_BASE_FILES_PATH_UTIL_H 132