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.
25struct FileReader {
26 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.
45struct 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.
71struct RealDiskInterface : public DiskInterface {
72 RealDiskInterface()
73#ifdef _WIN32
74 : use_cache_(false)
75#endif
76 {}
77 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