1 //===- FileInfo.h -----------------------------------------------*- C++ -*-===// 2 // 3 // This source file is part of the Swift.org open source project 4 // 5 // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors 6 // Licensed under Apache License v2.0 with Runtime Library Exception 7 // 8 // See http://swift.org/LICENSE.txt for license information 9 // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors 10 // 11 //===----------------------------------------------------------------------===// 12 // 13 // This file contains the FileInfo wrapper which is shared by the Ninja and 14 // BuildSystem libraries. 15 // 16 // FIXME: I am ambivalent about this living in Basic, I want all non-functional 17 // pieces to generally be pretty isolated (and ideally always mediated by a 18 // delegate access). We may eventually want a specific FileSystem component for 19 // dealing with efficient and abstracted access to the file system and 20 // containing other pieces (like stat caching, or dealing with distribution or 21 // virtualization). 22 // 23 //===----------------------------------------------------------------------===// 24 25 #ifndef LLBUILD_BASIC_FILEINFO_H 26 #define LLBUILD_BASIC_FILEINFO_H 27 28 #include "BinaryCoding.h" 29 30 #include <cstdint> 31 #include <string> 32 33 namespace llbuild { 34 namespace basic { 35 36 /// File timestamp wrapper. 37 struct FileTimestamp { 38 uint64_t seconds; 39 uint64_t nanoseconds; 40 41 bool operator==(const FileTimestamp& rhs) const { 42 return seconds == rhs.seconds && nanoseconds == rhs.nanoseconds; 43 } 44 bool operator!=(const FileTimestamp& rhs) const { 45 return !(*this == rhs); 46 } 47 bool operator<(const FileTimestamp& rhs) const { 48 return (seconds < rhs.seconds || 49 (seconds == rhs.seconds && nanoseconds < rhs.nanoseconds)); 50 } 51 bool operator<=(const FileTimestamp& rhs) const { 52 return (seconds < rhs.seconds || 53 (seconds == rhs.seconds && nanoseconds <= rhs.nanoseconds)); 54 } 55 bool operator>(const FileTimestamp& rhs) const { 56 return rhs < *this; 57 } 58 bool operator>=(const FileTimestamp& rhs) const { 59 return rhs <= *this; 60 } 61 }; 62 63 /// File information which is intended to be used as a proxy for when a file has 64 /// changed. 65 /// 66 /// This structure is intentionally sized to have no packing holes. 67 struct FileInfo { 68 /// The device number. 69 uint64_t device; 70 /// The inode number. 71 uint64_t inode; 72 /// The mode flags of the file. 73 uint64_t mode; 74 /// The size of the file. 75 uint64_t size; 76 /// The modification time of the file. 77 FileTimestamp modTime; 78 79 /// Check if this is a FileInfo representing a missing file. isMissingFileInfo80 bool isMissing() const { 81 // We use an all-zero FileInfo as a sentinel, under the assumption this can 82 // never exist in normal circumstances. 83 return (device == 0 && inode == 0 && mode == 0 && size == 0 && 84 modTime.seconds == 0 && modTime.nanoseconds == 0); 85 } 86 87 /// Check if the FileInfo corresponds to a directory. 88 bool isDirectory() const; 89 90 bool operator==(const FileInfo& rhs) const { 91 return (device == rhs.device && 92 inode == rhs.inode && 93 size == rhs.size && 94 modTime == rhs.modTime); 95 } 96 bool operator!=(const FileInfo& rhs) const { 97 return !(*this == rhs); 98 } 99 100 /// Get the information to represent the state of the given node in the file 101 /// system. 102 /// 103 /// \param asLink If yes, checks the information for the file path without 104 /// looking through symbolic links. 105 /// 106 /// \returns The FileInfo for the given path, which will be missing if the 107 /// path does not exist (or any error was encountered). 108 static FileInfo getInfoForPath(const std::string& path, bool asLink = false); 109 }; 110 111 template<> 112 struct BinaryCodingTraits<FileTimestamp> { 113 static inline void encode(const FileTimestamp& value, BinaryEncoder& coder) { 114 coder.write(value.seconds); 115 coder.write(value.nanoseconds); 116 } 117 static inline void decode(FileTimestamp& value, BinaryDecoder& coder) { 118 coder.read(value.seconds); 119 coder.read(value.nanoseconds); 120 } 121 }; 122 123 template<> 124 struct BinaryCodingTraits<FileInfo> { 125 static inline void encode(const FileInfo& value, BinaryEncoder& coder) { 126 coder.write(value.device); 127 coder.write(value.inode); 128 coder.write(value.mode); 129 coder.write(value.size); 130 coder.write(value.modTime); 131 } 132 static inline void decode(FileInfo& value, BinaryDecoder& coder) { 133 coder.read(value.device); 134 coder.read(value.inode); 135 coder.read(value.mode); 136 coder.read(value.size); 137 coder.read(value.modTime); 138 } 139 }; 140 141 } 142 } 143 144 #endif 145