Home | History | Annotate | Download | only in files
      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