• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
isDirSeparator(int ch)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.
isPathSeparator(int ch)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.
rootPrefixSize(const char * path)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.
isAbsolute(const char * path)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.
decompose(const char * path)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.
recompose(const StringVector & components)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