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 using namespace std; 21 22 #include "timestamp.h" 23 24 /// Interface for reading files from disk. See DiskInterface for details. 25 /// This base offers the minimum interface needed just to read files. 26 struct FileReader { ~FileReaderFileReader27 virtual ~FileReader() {} 28 29 /// Result of ReadFile. 30 enum Status { 31 Okay, 32 NotFound, 33 OtherError 34 }; 35 36 /// Read and store in given string. On success, return Okay. 37 /// On error, return another Status and fill |err|. 38 virtual Status ReadFile(const string& path, string* contents, 39 string* err) = 0; 40 }; 41 42 /// Interface for accessing the disk. 43 /// 44 /// Abstract so it can be mocked out for tests. The real implementation 45 /// is RealDiskInterface. 46 struct DiskInterface: public FileReader { 47 /// stat() a file, returning the mtime, or 0 if missing and -1 on 48 /// other errors. 49 virtual TimeStamp Stat(const string& path, string* err) const = 0; 50 51 /// Create a directory, returning false on failure. 52 virtual bool MakeDir(const string& path) = 0; 53 54 /// Create a file, with the specified name and contents 55 /// Returns true on success, false on failure 56 virtual bool WriteFile(const string& path, const 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 string& path) = 0; 64 65 /// Create all the parent directories for path; like mkdir -p 66 /// `basename path`. 67 bool MakeDirs(const 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 string& path, string* err) const; 79 virtual bool MakeDir(const string& path); 80 virtual bool WriteFile(const string& path, const string& contents); 81 virtual Status ReadFile(const string& path, string* contents, string* err); 82 virtual int RemoveFile(const string& path); 83 84 /// Whether stat information can be cached. Only has an effect on Windows. 85 void AllowStatCache(bool allow); 86 87 private: 88 #ifdef _WIN32 89 /// Whether stat information can be cached. 90 bool use_cache_; 91 92 typedef map<string, TimeStamp> DirCache; 93 // TODO: Neither a map nor a hashmap seems ideal here. If the statcache 94 // works out, come up with a better data structure. 95 typedef map<string, DirCache> Cache; 96 mutable Cache cache_; 97 #endif 98 }; 99 100 #endif // NINJA_DISK_INTERFACE_H_ 101