1 // Copyright 2011 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef NINJA_DISK_INTERFACE_H_ 16 #define NINJA_DISK_INTERFACE_H_ 17 18 #include <map> 19 #include <string> 20 21 #include "timestamp.h" 22 23 /// Interface for reading files from disk. See DiskInterface for details. 24 /// This base offers the minimum interface needed just to read files. 25 struct FileReader { ~FileReaderFileReader26 virtual ~FileReader() {} 27 28 /// Result of ReadFile. 29 enum Status { 30 Okay, 31 NotFound, 32 OtherError 33 }; 34 35 /// Read and store in given string. On success, return Okay. 36 /// On error, return another Status and fill |err|. 37 virtual Status ReadFile(const std::string& path, std::string* contents, 38 std::string* err) = 0; 39 }; 40 41 /// Interface for accessing the disk. 42 /// 43 /// Abstract so it can be mocked out for tests. The real implementation 44 /// is RealDiskInterface. 45 struct DiskInterface: public FileReader { 46 /// stat() a file, returning the mtime, or 0 if missing and -1 on 47 /// other errors. 48 virtual TimeStamp Stat(const std::string& path, std::string* err) const = 0; 49 50 /// Create a directory, returning false on failure. 51 virtual bool MakeDir(const std::string& path) = 0; 52 53 /// Create a file, with the specified name and contents 54 /// Returns true on success, false on failure 55 virtual bool WriteFile(const std::string& path, 56 const std::string& contents) = 0; 57 58 /// Remove the file named @a path. It behaves like 'rm -f path' so no errors 59 /// are reported if it does not exists. 60 /// @returns 0 if the file has been removed, 61 /// 1 if the file does not exist, and 62 /// -1 if an error occurs. 63 virtual int RemoveFile(const std::string& path) = 0; 64 65 /// Create all the parent directories for path; like mkdir -p 66 /// `basename path`. 67 bool MakeDirs(const std::string& path); 68 }; 69 70 /// Implementation of DiskInterface that actually hits the disk. 71 struct RealDiskInterface : public DiskInterface { RealDiskInterfaceRealDiskInterface72 RealDiskInterface() 73 #ifdef _WIN32 74 : use_cache_(false) 75 #endif 76 {} ~RealDiskInterfaceRealDiskInterface77 virtual ~RealDiskInterface() {} 78 virtual TimeStamp Stat(const std::string& path, std::string* err) const; 79 virtual bool MakeDir(const std::string& path); 80 virtual bool WriteFile(const std::string& path, const std::string& contents); 81 virtual Status ReadFile(const std::string& path, std::string* contents, 82 std::string* err); 83 virtual int RemoveFile(const std::string& path); 84 85 /// Whether stat information can be cached. Only has an effect on Windows. 86 void AllowStatCache(bool allow); 87 88 private: 89 #ifdef _WIN32 90 /// Whether stat information can be cached. 91 bool use_cache_; 92 93 typedef std::map<std::string, TimeStamp> DirCache; 94 // TODO: Neither a map nor a hashmap seems ideal here. If the statcache 95 // works out, come up with a better data structure. 96 typedef std::map<std::string, DirCache> Cache; 97 mutable Cache cache_; 98 #endif 99 }; 100 101 #endif // NINJA_DISK_INTERFACE_H_ 102