|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 #ifndef BASE_PLATFORM_FILE_H_ |
|
6 #define BASE_PLATFORM_FILE_H_ |
|
7 |
|
8 #include "build/build_config.h" |
|
9 #if defined(OS_WIN) |
|
10 #include <windows.h> |
|
11 #endif |
|
12 |
|
13 #include <string> |
|
14 |
|
15 #include "base/base_export.h" |
|
16 #include "base/basictypes.h" |
|
17 #include "base/files/file_path.h" |
|
18 #include "base/time/time.h" |
|
19 |
|
20 namespace base { |
|
21 |
|
22 // PLATFORM_FILE_(OPEN|CREATE).* are mutually exclusive. You should specify |
|
23 // exactly one of the five (possibly combining with other flags) when opening |
|
24 // or creating a file. |
|
25 // PLATFORM_FILE_(WRITE|APPEND) are mutually exclusive. This is so that APPEND |
|
26 // behavior will be consistent with O_APPEND on POSIX. |
|
27 enum PlatformFileFlags { |
|
28 PLATFORM_FILE_OPEN = 1 << 0, // Opens a file, only if it exists. |
|
29 PLATFORM_FILE_CREATE = 1 << 1, // Creates a new file, only if it |
|
30 // does not already exist. |
|
31 PLATFORM_FILE_OPEN_ALWAYS = 1 << 2, // May create a new file. |
|
32 PLATFORM_FILE_CREATE_ALWAYS = 1 << 3, // May overwrite an old file. |
|
33 PLATFORM_FILE_OPEN_TRUNCATED = 1 << 4, // Opens a file and truncates it, |
|
34 // only if it exists. |
|
35 PLATFORM_FILE_READ = 1 << 5, |
|
36 PLATFORM_FILE_WRITE = 1 << 6, |
|
37 PLATFORM_FILE_APPEND = 1 << 7, |
|
38 PLATFORM_FILE_EXCLUSIVE_READ = 1 << 8, // EXCLUSIVE is opposite of Windows |
|
39 // SHARE |
|
40 PLATFORM_FILE_EXCLUSIVE_WRITE = 1 << 9, |
|
41 PLATFORM_FILE_ASYNC = 1 << 10, |
|
42 PLATFORM_FILE_TEMPORARY = 1 << 11, // Used on Windows only |
|
43 PLATFORM_FILE_HIDDEN = 1 << 12, // Used on Windows only |
|
44 PLATFORM_FILE_DELETE_ON_CLOSE = 1 << 13, |
|
45 |
|
46 PLATFORM_FILE_WRITE_ATTRIBUTES = 1 << 14, // Used on Windows only |
|
47 PLATFORM_FILE_ENUMERATE = 1 << 15, // May enumerate directory |
|
48 |
|
49 PLATFORM_FILE_SHARE_DELETE = 1 << 16, // Used on Windows only |
|
50 |
|
51 PLATFORM_FILE_TERMINAL_DEVICE = 1 << 17, // Serial port flags |
|
52 PLATFORM_FILE_BACKUP_SEMANTICS = 1 << 18, // Used on Windows only |
|
53 |
|
54 PLATFORM_FILE_EXECUTE = 1 << 19, // Used on Windows only |
|
55 }; |
|
56 |
|
57 // PLATFORM_FILE_ERROR_ACCESS_DENIED is returned when a call fails because of |
|
58 // a filesystem restriction. PLATFORM_FILE_ERROR_SECURITY is returned when a |
|
59 // browser policy doesn't allow the operation to be executed. |
|
60 enum PlatformFileError { |
|
61 PLATFORM_FILE_OK = 0, |
|
62 PLATFORM_FILE_ERROR_FAILED = -1, |
|
63 PLATFORM_FILE_ERROR_IN_USE = -2, |
|
64 PLATFORM_FILE_ERROR_EXISTS = -3, |
|
65 PLATFORM_FILE_ERROR_NOT_FOUND = -4, |
|
66 PLATFORM_FILE_ERROR_ACCESS_DENIED = -5, |
|
67 PLATFORM_FILE_ERROR_TOO_MANY_OPENED = -6, |
|
68 PLATFORM_FILE_ERROR_NO_MEMORY = -7, |
|
69 PLATFORM_FILE_ERROR_NO_SPACE = -8, |
|
70 PLATFORM_FILE_ERROR_NOT_A_DIRECTORY = -9, |
|
71 PLATFORM_FILE_ERROR_INVALID_OPERATION = -10, |
|
72 PLATFORM_FILE_ERROR_SECURITY = -11, |
|
73 PLATFORM_FILE_ERROR_ABORT = -12, |
|
74 PLATFORM_FILE_ERROR_NOT_A_FILE = -13, |
|
75 PLATFORM_FILE_ERROR_NOT_EMPTY = -14, |
|
76 PLATFORM_FILE_ERROR_INVALID_URL = -15, |
|
77 PLATFORM_FILE_ERROR_IO = -16, |
|
78 // Put new entries here and increment PLATFORM_FILE_ERROR_MAX. |
|
79 PLATFORM_FILE_ERROR_MAX = -17 |
|
80 }; |
|
81 |
|
82 // This explicit mapping matches both FILE_ on Windows and SEEK_ on Linux. |
|
83 enum PlatformFileWhence { |
|
84 PLATFORM_FILE_FROM_BEGIN = 0, |
|
85 PLATFORM_FILE_FROM_CURRENT = 1, |
|
86 PLATFORM_FILE_FROM_END = 2 |
|
87 }; |
|
88 |
|
89 // Used to hold information about a given file. |
|
90 // If you add more fields to this structure (platform-specific fields are OK), |
|
91 // make sure to update all functions that use it in file_util_{win|posix}.cc |
|
92 // too, and the ParamTraits<base::PlatformFileInfo> implementation in |
|
93 // chrome/common/common_param_traits.cc. |
|
94 struct BASE_EXPORT PlatformFileInfo { |
|
95 PlatformFileInfo(); |
|
96 ~PlatformFileInfo(); |
|
97 |
|
98 // The size of the file in bytes. Undefined when is_directory is true. |
|
99 int64 size; |
|
100 |
|
101 // True if the file corresponds to a directory. |
|
102 bool is_directory; |
|
103 |
|
104 // True if the file corresponds to a symbolic link. |
|
105 bool is_symbolic_link; |
|
106 |
|
107 // The last modified time of a file. |
|
108 base::Time last_modified; |
|
109 |
|
110 // The last accessed time of a file. |
|
111 base::Time last_accessed; |
|
112 |
|
113 // The creation time of a file. |
|
114 base::Time creation_time; |
|
115 }; |
|
116 |
|
117 #if defined(OS_WIN) |
|
118 typedef HANDLE PlatformFile; |
|
119 const PlatformFile kInvalidPlatformFileValue = INVALID_HANDLE_VALUE; |
|
120 PlatformFileError LastErrorToPlatformFileError(DWORD saved_errno); |
|
121 #elif defined(OS_POSIX) |
|
122 typedef int PlatformFile; |
|
123 const PlatformFile kInvalidPlatformFileValue = -1; |
|
124 PlatformFileError ErrnoToPlatformFileError(int saved_errno); |
|
125 #endif |
|
126 |
|
127 // Creates or opens the given file. If |created| is provided, it will be set to |
|
128 // true if a new file was created [or an old one truncated to zero length to |
|
129 // simulate a new file, which can happen with PLATFORM_FILE_CREATE_ALWAYS], and |
|
130 // false otherwise. |error| can be NULL. |
|
131 // |
|
132 // This function fails with 'access denied' if the |name| contains path |
|
133 // traversal ('..') components. |
|
134 BASE_EXPORT PlatformFile CreatePlatformFile(const FilePath& name, |
|
135 int flags, |
|
136 bool* created, |
|
137 PlatformFileError* error); |
|
138 |
|
139 // Same as CreatePlatformFile but allows paths with traversal (like \..\) |
|
140 // components. Use only with extreme care. |
|
141 BASE_EXPORT PlatformFile CreatePlatformFileUnsafe(const FilePath& name, |
|
142 int flags, |
|
143 bool* created, |
|
144 PlatformFileError* error); |
|
145 |
|
146 BASE_EXPORT FILE* FdopenPlatformFile(PlatformFile file, const char* mode); |
|
147 |
|
148 // Closes a file handle. Returns |true| on success and |false| otherwise. |
|
149 BASE_EXPORT bool ClosePlatformFile(PlatformFile file); |
|
150 |
|
151 // Changes current position in the file to an |offset| relative to an origin |
|
152 // defined by |whence|. Returns the resultant current position in the file |
|
153 // (relative to the start) or -1 in case of error. |
|
154 BASE_EXPORT int64 SeekPlatformFile(PlatformFile file, |
|
155 PlatformFileWhence whence, |
|
156 int64 offset); |
|
157 |
|
158 // Reads the given number of bytes (or until EOF is reached) starting with the |
|
159 // given offset. Returns the number of bytes read, or -1 on error. Note that |
|
160 // this function makes a best effort to read all data on all platforms, so it is |
|
161 // not intended for stream oriented files but instead for cases when the normal |
|
162 // expectation is that actually |size| bytes are read unless there is an error. |
|
163 BASE_EXPORT int ReadPlatformFile(PlatformFile file, int64 offset, |
|
164 char* data, int size); |
|
165 |
|
166 // Same as above but without seek. |
|
167 BASE_EXPORT int ReadPlatformFileAtCurrentPos(PlatformFile file, |
|
168 char* data, int size); |
|
169 |
|
170 // Reads the given number of bytes (or until EOF is reached) starting with the |
|
171 // given offset, but does not make any effort to read all data on all platforms. |
|
172 // Returns the number of bytes read, or -1 on error. |
|
173 BASE_EXPORT int ReadPlatformFileNoBestEffort(PlatformFile file, int64 offset, |
|
174 char* data, int size); |
|
175 |
|
176 // Same as above but without seek. |
|
177 BASE_EXPORT int ReadPlatformFileCurPosNoBestEffort(PlatformFile file, |
|
178 char* data, int size); |
|
179 |
|
180 // Writes the given buffer into the file at the given offset, overwritting any |
|
181 // data that was previously there. Returns the number of bytes written, or -1 |
|
182 // on error. Note that this function makes a best effort to write all data on |
|
183 // all platforms. |
|
184 // Ignores the offset and writes to the end of the file if the file was opened |
|
185 // with PLATFORM_FILE_APPEND. |
|
186 BASE_EXPORT int WritePlatformFile(PlatformFile file, int64 offset, |
|
187 const char* data, int size); |
|
188 |
|
189 // Save as above but without seek. |
|
190 BASE_EXPORT int WritePlatformFileAtCurrentPos(PlatformFile file, |
|
191 const char* data, int size); |
|
192 |
|
193 // Save as above but does not make any effort to write all data on all |
|
194 // platforms. Returns the number of bytes written, or -1 on error. |
|
195 BASE_EXPORT int WritePlatformFileCurPosNoBestEffort(PlatformFile file, |
|
196 const char* data, int size); |
|
197 |
|
198 // Truncates the given file to the given length. If |length| is greater than |
|
199 // the current size of the file, the file is extended with zeros. If the file |
|
200 // doesn't exist, |false| is returned. |
|
201 BASE_EXPORT bool TruncatePlatformFile(PlatformFile file, int64 length); |
|
202 |
|
203 // Flushes the buffers of the given file. |
|
204 BASE_EXPORT bool FlushPlatformFile(PlatformFile file); |
|
205 |
|
206 // Touches the given file. |
|
207 BASE_EXPORT bool TouchPlatformFile(PlatformFile file, |
|
208 const Time& last_access_time, |
|
209 const Time& last_modified_time); |
|
210 |
|
211 // Returns some information for the given file. |
|
212 BASE_EXPORT bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info); |
|
213 |
|
214 // Use this class to pass ownership of a PlatformFile to a receiver that may or |
|
215 // may not want to accept it. This class does not own the storage for the |
|
216 // PlatformFile. |
|
217 // |
|
218 // EXAMPLE: |
|
219 // |
|
220 // void MaybeProcessFile(PassPlatformFile pass_file) { |
|
221 // if (...) { |
|
222 // PlatformFile file = pass_file.ReleaseValue(); |
|
223 // // Now, we are responsible for closing |file|. |
|
224 // } |
|
225 // } |
|
226 // |
|
227 // void OpenAndMaybeProcessFile(const FilePath& path) { |
|
228 // PlatformFile file = CreatePlatformFile(path, ...); |
|
229 // MaybeProcessFile(PassPlatformFile(&file)); |
|
230 // if (file != kInvalidPlatformFileValue) |
|
231 // ClosePlatformFile(file); |
|
232 // } |
|
233 // |
|
234 class BASE_EXPORT PassPlatformFile { |
|
235 public: |
|
236 explicit PassPlatformFile(PlatformFile* value) : value_(value) { |
|
237 } |
|
238 |
|
239 // Called to retrieve the PlatformFile stored in this object. The caller |
|
240 // gains ownership of the PlatformFile and is now responsible for closing it. |
|
241 // Any subsequent calls to this method will return an invalid PlatformFile. |
|
242 PlatformFile ReleaseValue() { |
|
243 PlatformFile temp = *value_; |
|
244 *value_ = kInvalidPlatformFileValue; |
|
245 return temp; |
|
246 } |
|
247 |
|
248 private: |
|
249 PlatformFile* value_; |
|
250 }; |
|
251 |
|
252 } // namespace base |
|
253 |
|
254 #endif // BASE_PLATFORM_FILE_H_ |