@@ -12,6 +12,7 @@ const maxInt = std.math.maxInt;
12
12
pub const File = struct {
13
13
/// The OS-specific file descriptor or file handle.
14
14
handle : os.fd_t ,
15
+ openMode : OpenMode ,
15
16
16
17
pub const Mode = switch (builtin .os ) {
17
18
Os .windows = > void ,
@@ -25,34 +26,41 @@ pub const File = struct {
25
26
26
27
pub const OpenError = windows .CreateFileError || os .OpenError ;
27
28
29
+ const OpenMode = packed struct {
30
+ read : bool ,
31
+ write : bool ,
32
+ clobber : bool ,
33
+ _ :u5 //Pad out to a full byte
34
+ };
28
35
29
36
pub const READ = 1 ;
30
37
pub const WRITE = 2 ;
31
38
pub const CLOBBER = 4 ;
32
39
33
- pub fn openW (path : [* ]const u16 , comptime flags : u32 ) OpenError ! File {
40
+ pub fn openW (path : [* ]const u16 , comptime flags : u8 ) OpenError ! File {
34
41
assert (windows .is_the_target );
35
42
43
+ const openMode : OpenMode = @bitCast (OpenMode , flags );
36
44
comptime var desiredAccess : u32 = 0 ;
37
45
comptime var creationDisposition : u32 = windows .OPEN_EXISTING ;
38
46
39
47
comptime {
40
- if (( flags & CLOBBER ) > 0 and ! (( flags & WRITE ) > 0 ) ) {
41
- @compileError ("Cannot clobber a read only file! Did you forget to add '| WRITE'?" );
48
+ if (openMode . clobber and ! openMode . write ) {
49
+ @compileError ("Cannot clobber a read only file! Did you forget to add '| File. WRITE'?" );
42
50
}
43
51
44
- if (flags & READ > 0 ) {
52
+ if (openMode . read ) {
45
53
desiredAccess |= windows .GENERIC_READ ;
46
54
}
47
- if (flags & WRITE > 0 ) {
55
+ if (openMode . write ) {
48
56
desiredAccess |= windows .GENERIC_WRITE ;
49
57
}
50
58
51
- if (flags & CLOBBER > 0 ) {
59
+ if (openMode . clobber ) {
52
60
creationDisposition = windows .CREATE_ALWAYS ;
53
61
}
54
62
55
- if (flags & WRITE > 0 ) {
63
+ if (openMode . write ) {
56
64
creationDisposition = windows .OPEN_ALWAYS ;
57
65
}
58
66
}
@@ -67,51 +75,49 @@ pub const File = struct {
67
75
null
68
76
);
69
77
70
- return openHandle (handle );
78
+ return openHandle (handle , flags );
71
79
}
72
80
73
- pub fn openC (path : []const u8 , comptime flags : u32 ) OpenError ! File {
81
+ pub fn openC (path : []const u8 , comptime flags : u8 ) OpenError ! File {
74
82
if (windows .is_the_target ) {
75
83
const path_w = try windows .cStrToPrefixedFileW (path );
76
84
return openW (& path_w , flags );
77
85
}
78
86
87
+ const openMode = @bitCast (flags , OpenMode );
79
88
comptime var posixFlags : u32 = O_LARGEFILE ;
80
89
81
90
comptime {
82
- if (( flags & CLOBBER ) > 0 and ! (( flags & WRITE ) > 0 ) ) {
83
- @compileError ("Cannot clobber a read only file! Did you forget to add '| WRITE'?" );
91
+ if (openMode . clobber and ! openMode . write ) {
92
+ @compileError ("Cannot clobber a read only file! Did you forget to add '| File. WRITE'?" );
84
93
}
85
94
86
- if (flags & READ > 0 ) {
87
- if (flags & WRITE > 0 ) {
95
+ if (openMode . read ) {
96
+ if (openMode . write ) {
88
97
posixFlags |= O_RDWR ;
89
98
}
90
99
else {
91
100
posixFlags |= O_RDONLY ;
92
101
}
93
102
}
94
- else if (flags & WRITE > 0 ) {
103
+ else if (openMode . write ) {
95
104
posixFlags |= O_WRONLY ;
96
105
}
97
- else {
98
- assert (true );
99
- }
100
106
101
- if (flags & WRITE > 0 ) {
107
+ if (openMode . write ) {
102
108
posixFlags |= O_CREAT ;
103
109
}
104
110
105
- if (flags & CLOBBER > 0 ) {
111
+ if (openMode . clobber ) {
106
112
posixFlags |= O_TRUNC ;
107
113
}
108
114
}
109
115
110
116
const fd = try os .openC (path , posixFlags , 0 );
111
- return openHandle (fd );
117
+ return openHandle (fd , flags );
112
118
}
113
119
114
- pub fn open (path : []const u8 , comptime flags : u32 ) OpenError ! File {
120
+ pub fn open (path : []const u8 , comptime flags : u8 ) OpenError ! File {
115
121
if (windows .is_the_target ) {
116
122
const path_w = try windows .sliceToPrefixedFileW (path );
117
123
return openW (& path_w , flags );
@@ -120,8 +126,8 @@ pub const File = struct {
120
126
return openC (& path_c , flags );
121
127
}
122
128
123
- pub fn openHandle (handle : os.fd_t ) File {
124
- return File { .handle = handle };
129
+ pub fn openHandle (handle : os.fd_t , flags : u8 ) File {
130
+ return File { .handle = handle , . openMode = @bitCast ( OpenMode , flags ) };
125
131
}
126
132
127
133
/// Test for the existence of `path`.
@@ -276,12 +282,18 @@ pub const File = struct {
276
282
pub const ReadError = os .ReadError ;
277
283
278
284
pub fn read (self : File , buffer : []u8 ) ReadError ! usize {
285
+ if (! self .openMode .read ) {
286
+ return ReadError .IncorrectOpenMode ;
287
+ }
279
288
return os .read (self .handle , buffer );
280
289
}
281
290
282
291
pub const WriteError = os .WriteError ;
283
292
284
293
pub fn write (self : File , bytes : []const u8 ) WriteError ! void {
294
+ if (! self .openMode .write ) {
295
+ return WriteError .IncorrectOpenMode ;
296
+ }
285
297
return os .write (self .handle , bytes );
286
298
}
287
299
0 commit comments