forked from youtube/cobalt_sandbox
-
Notifications
You must be signed in to change notification settings - Fork 0
/
file.h
330 lines (292 loc) · 12.6 KB
/
file.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Module Overview: Starboard File module
//
// Defines file system input/output functions.
#ifndef STARBOARD_FILE_H_
#define STARBOARD_FILE_H_
#include "starboard/export.h"
#include "starboard/time.h"
#include "starboard/types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Private structure representing an open file.
typedef struct SbFilePrivate SbFilePrivate;
// A handle to an open file.
typedef SbFilePrivate* SbFile;
// Flags that define how a file is used in the application. These flags should
// be or'd together when passed to SbFileOpen to open or create a file.
//
// The following five flags are mutually exclusive. You must specify exactly one
// of them:
// - |kSbFileOpenAlways|
// - |kSbFileOpenOnly|
// - |kSbFileOpenTruncated|
// - |kSbFileCreateAlways|
// - |kSbFileCreateOnly|
//
// In addition, one or more of the following flags must be specified:
// - |kSbFileRead|
// - |kSbFileWrite|
//
// The |kSbFileAsync| flag is optional.
typedef enum SbFileFlags {
kSbFileOpenOnly = 1 << 0, // Opens a file, only if it exists.
kSbFileCreateOnly = 1 << 1, // Creates a new file, only if it
// does not already exist.
kSbFileOpenAlways = 1 << 2, // Opens an existing file at the specified
// path or creates a new file at that path.
kSbFileCreateAlways = 1 << 3, // Creates a new file at the specified path
// or overwrites an existing file at that
// path.
kSbFileOpenTruncated = 1 << 4, // Opens a file and truncates it to zero,
// only if it exists.
kSbFileRead = 1 << 5,
kSbFileWrite = 1 << 6,
kSbFileAsync = 1 << 7, // May allow asynchronous I/O on some
// platforms, meaning that calls to
// Read or Write will only return the
// data that is readily available.
} SbFileFlags;
// kSbFileErrorAccessDenied is returned when a call fails because of a
// filesystem restriction. kSbFileErrorSecurity is returned when a security
// policy doesn't allow the operation to be executed.
typedef enum SbFileError {
kSbFileOk = 0,
kSbFileErrorFailed = -1,
kSbFileErrorInUse = -2,
kSbFileErrorExists = -3,
kSbFileErrorNotFound = -4,
kSbFileErrorAccessDenied = -5,
kSbFileErrorTooManyOpened = -6,
kSbFileErrorNoMemory = -7,
kSbFileErrorNoSpace = -8,
kSbFileErrorNotADirectory = -9,
kSbFileErrorInvalidOperation = -10,
kSbFileErrorSecurity = -11,
kSbFileErrorAbort = -12,
kSbFileErrorNotAFile = -13,
kSbFileErrorNotEmpty = -14,
kSbFileErrorInvalidUrl = -15,
kSbFileErrorIO = -16,
kSbFileErrorMax = -17,
} SbFileError;
// This explicit mapping matches both FILE_ on Windows and SEEK_ on Linux.
typedef enum SbFileWhence {
kSbFileFromBegin = 0,
kSbFileFromCurrent = 1,
kSbFileFromEnd = 2,
} SbFileWhence;
// Used to hold information about a file.
typedef struct SbFileInfo {
// The size of the file in bytes. Undefined when is_directory is true.
int64_t size;
// Whether the file corresponds to a directory.
bool is_directory;
// Whether the file corresponds to a symbolic link.
bool is_symbolic_link;
// The last modified time of a file.
SbTime last_modified;
// The last accessed time of a file.
SbTime last_accessed;
// The creation time of a file.
SbTime creation_time;
} SbFileInfo;
// Well-defined value for an invalid file handle.
#define kSbFileInvalid (SbFile) NULL
// Returns whether the given file handle is valid.
static SB_C_INLINE bool SbFileIsValid(SbFile file) {
return file != kSbFileInvalid;
}
// Opens the file at |path|, which must be absolute, creating it if specified by
// |flags|. The read/write position is at the beginning of the file.
//
// Note that this function only guarantees the correct behavior when |path|
// points to a file. The behavior is undefined if |path| points to a directory.
//
// |path|: The absolute path of the file to be opened.
// |flags|: |SbFileFlags| that determine how the file is used in the
// application. Among other things, |flags| can indicate whether the
// application should create |path| if |path| does not already exist.
// |out_created|: Starboard sets this value to |true| if a new file is created
// or if an old file is truncated to zero length to simulate a new file,
// which can happen if the |kSbFileCreateAlways| flag is set. Otherwise,
// Starboard sets this value to |false|.
// |out_error|: If |path| cannot be created, this is set to |kSbFileInvalid|.
// Otherwise, it is |NULL|.
SB_EXPORT SbFile SbFileOpen(const char* path,
int flags,
bool* out_created,
SbFileError* out_error);
// Closes |file|. The return value indicates whether the file was closed
// successfully.
//
// |file|: The absolute path of the file to be closed.
SB_EXPORT bool SbFileClose(SbFile file);
// Replaces the content of the file at |path| with |data|. Returns whether the
// contents of the file were replaced. The replacement of the content is an
// atomic operation. The file will either have all of the data, or none.
//
// |path|: The path to the file whose contents should be replaced.
// |data|: The data to replace the file contents with.
// |data_size|: The amount of |data|, in bytes, to be written to the file.
SB_EXPORT bool SbFileAtomicReplace(const char* path,
const char* data,
int64_t data_size);
// Changes the current read/write position in |file|. The return value
// identifies the resultant current read/write position in the file (relative
// to the start) or |-1| in case of an error. This function might not support
// seeking past the end of the file on some platforms.
//
// |file|: The SbFile in which the read/write position will be changed.
// |whence|: The starting read/write position. The position is modified relative
// to this value.
// |offset|: The amount that the read/write position is changed, relative to
// |whence|.
SB_EXPORT int64_t SbFileSeek(SbFile file, SbFileWhence whence, int64_t offset);
// Reads |size| bytes (or until EOF is reached) from |file| into |data|,
// starting at the file's current position.
//
// The return value specifies the number of bytes read or |-1| if there was
// an error. Note that this function does NOT make a best effort to read all
// data on all platforms; rather, it just reads however many bytes are quickly
// available. However, this function can be run in a loop to make it a
// best-effort read.
//
// |file|: The SbFile from which to read data.
// |data|: The variable to which data is read.
// |size|: The amount of data (in bytes) to read.
SB_EXPORT int SbFileRead(SbFile file, char* data, int size);
// Writes the given buffer into |file| at the file's current position,
// overwriting any data that was previously there.
//
// The return value identifies the number of bytes written, or |-1| on error.
// Note that this function does NOT make a best effort to write all data;
// rather, it writes however many bytes can be written quickly. Generally, this
// means that it writes however many bytes as possible without blocking on IO.
// Run this function in a loop to ensure that all data is written.
//
// |file|: The SbFile to which data will be written.
// |data|: The data to be written.
// |size|: The amount of data (in bytes) to write.
SB_EXPORT int SbFileWrite(SbFile file, const char* data, int size);
// Truncates the given |file| to the given |length|. The return value indicates
// whether the file was truncated successfully.
//
// |file|: The file to be truncated.
// |length|: The expected length of the file after it is truncated. If |length|
// is greater than the current size of the file, then the file is extended
// with zeros. If |length| is negative, then the function is a no-op and
// returns |false|.
SB_EXPORT bool SbFileTruncate(SbFile file, int64_t length);
// Flushes the write buffer to |file|. Data written via SbFileWrite is not
// necessarily committed until the SbFile is flushed or closed.
//
// |file|: The SbFile to which the write buffer is flushed.
SB_EXPORT bool SbFileFlush(SbFile file);
// Retrieves information about |file|. The return value indicates whether the
// file information was retrieved successfully.
//
// |file|: The SbFile for which information is retrieved.
// |out_info|: The variable into which the retrieved data is placed. This
// variable is not touched if the operation is not successful.
SB_EXPORT bool SbFileGetInfo(SbFile file, SbFileInfo* out_info);
// Retrieves information about the file at |path|. The return value indicates
// whether the file information was retrieved successfully.
//
// |file|: The absolute path of the file for which information is retrieved.
// |out_info|: The variable into which the retrieved data is placed. This
// variable is not touched if the operation is not successful.
SB_EXPORT bool SbFileGetPathInfo(const char* path, SbFileInfo* out_info);
// Deletes the regular file, symlink, or empty directory at |path|. This
// function is used primarily to clean up after unit tests. On some platforms,
// this function fails if the file in question is being held open.
//
// |path|: The absolute path of the file, symlink, or directory to be deleted.
SB_EXPORT bool SbFileDelete(const char* path);
// Indicates whether a file or directory exists at |path|.
//
// |path|: The absolute path of the file or directory being checked.
SB_EXPORT bool SbFileExists(const char* path);
// Indicates whether SbFileOpen() with the given |flags| is allowed for |path|.
//
// |path|: The absolute path to be checked.
// |flags|: The flags that are being evaluated for the given |path|.
SB_EXPORT bool SbFileCanOpen(const char* path, int flags);
// Converts an ISO |fopen()| mode string into flags that can be equivalently
// passed into SbFileOpen().
//
// |mode|: The mode string to be converted into flags.
SB_EXPORT int SbFileModeStringToFlags(const char* mode);
// Reads |size| bytes (or until EOF is reached) from |file| into |data|,
// starting at the file's current position.
//
// The return value specifies the number of bytes read or |-1| if there was
// an error. Note that, unlike |SbFileRead|, this function does make a best
// effort to read all data on all platforms. As such, it is not intended for
// stream-oriented files but instead for cases when the normal expectation is
// that |size| bytes can be read unless there is an error.
//
// |file|: The SbFile from which to read data.
// |data|: The variable to which data is read.
// |size|: The amount of data (in bytes) to read.
static inline int SbFileReadAll(SbFile file, char* data, int size) {
if (!SbFileIsValid(file) || size < 0) {
return -1;
}
int bytes_read = 0;
int rv;
do {
rv = SbFileRead(file, data + bytes_read, size - bytes_read);
if (rv <= 0) {
break;
}
bytes_read += rv;
} while (bytes_read < size);
return bytes_read ? bytes_read : rv;
}
// Writes the given buffer into |file|, starting at the beginning of the file,
// and overwriting any data that was previously there. Unlike SbFileWrite, this
// function does make a best effort to write all data on all platforms.
//
// The return value identifies the number of bytes written, or |-1| on error.
//
// |file|: The file to which data will be written.
// |data|: The data to be written.
// |size|: The amount of data (in bytes) to write.
static inline int SbFileWriteAll(SbFile file, const char* data, int size) {
if (!SbFileIsValid(file) || size < 0) {
return -1;
}
int bytes_written = 0;
int rv;
do {
rv = SbFileWrite(file, data + bytes_written, size - bytes_written);
if (rv <= 0) {
break;
}
bytes_written += rv;
} while (bytes_written < size);
return bytes_written ? bytes_written : rv;
}
#ifdef __cplusplus
} // extern "C"
#endif
#if SB_API_VERSION < 13 && defined(__cplusplus)
extern "C++" {
#include "starboard/common/file.h"
} // extern "C++"
#endif // SB_API_VERSION < 13 && defined(__cplusplus)
#endif // STARBOARD_FILE_H_