authorgravatar for sreeharisreedev1@gmail.comSreehari Sreedev <sreeharisreedev1@gmail.com> 2021-07-18 02:13:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-04 22:29:53-04:00
log598db831f3ea1267d469162db1a54c2d62ff3e87
treece0f76930a3c4f4bd37101f14584e3aebafed345
parentc23768ab2c18354479618d99f7f32ce8a6d4b62f

FileProtocol: add Reader, Writer, SeekableStream


1 files changed, 72 insertions(+), 1 deletions(-)

lib/std/os/uefi/protocols/file_protocol.zig+72-1
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1const uefi = @import("std").os.uefi;1const std = @import("std");
2const uefi = std.os.uefi;
3const io = std.io;
2const Guid = uefi.Guid;4const Guid = uefi.Guid;
3const Time = uefi.Time;5const Time = uefi.Time;
4const Status = uefi.Status;6const Status = uefi.Status;
...@@ -16,6 +18,27 @@ pub const FileProtocol = extern struct {...@@ -16,6 +18,27 @@ pub const FileProtocol = extern struct {
16 _set_info: fn (*const FileProtocol, *align(8) const Guid, usize, [*]const u8) callconv(.C) Status,18 _set_info: fn (*const FileProtocol, *align(8) const Guid, usize, [*]const u8) callconv(.C) Status,
17 _flush: fn (*const FileProtocol) callconv(.C) Status,19 _flush: fn (*const FileProtocol) callconv(.C) Status,
1820
21 pub const SeekError = error{SeekError};
22 pub const GetSeekPosError = error{GetSeekPosError};
23 pub const ReadError = error{ReadError};
24 pub const WriteError = error{WriteError};
25
26 pub const SeekableStream = io.SeekableStream(*const FileProtocol, SeekError, GetSeekPosError, seekTo, seekBy, getPos, getEndPos);
27 pub const Reader = io.Reader(*const FileProtocol, ReadError, readFn);
28 pub const Writer = io.Writer(*const FileProtocol, WriteError, writeFn);
29
30 pub fn seekableStream(self: *FileProtocol) SeekableStream {
31 return .{ .context = self };
32 }
33
34 pub fn reader(self: *FileProtocol) Reader {
35 return .{ .context = self };
36 }
37
38 pub fn writer(self: *FileProtocol) Writer {
39 return .{ .context = self };
40 }
41
19 pub fn open(self: *const FileProtocol, new_handle: **const FileProtocol, file_name: [*:0]const u16, open_mode: u64, attributes: u64) Status {42 pub fn open(self: *const FileProtocol, new_handle: **const FileProtocol, file_name: [*:0]const u16, open_mode: u64, attributes: u64) Status {
20 return self._open(self, new_handle, file_name, open_mode, attributes);43 return self._open(self, new_handle, file_name, open_mode, attributes);
21 }44 }
...@@ -32,18 +55,66 @@ pub const FileProtocol = extern struct {...@@ -32,18 +55,66 @@ pub const FileProtocol = extern struct {
32 return self._read(self, buffer_size, buffer);55 return self._read(self, buffer_size, buffer);
33 }56 }
3457
58 fn readFn(self: *const FileProtocol, buffer: []u8) ReadError!usize {
59 var size: usize = buffer.len;
60 if (.Success != self.read(&size, buffer.ptr)) return ReadError.ReadError;
61 return size;
62 }
63
35 pub fn write(self: *const FileProtocol, buffer_size: *usize, buffer: [*]const u8) Status {64 pub fn write(self: *const FileProtocol, buffer_size: *usize, buffer: [*]const u8) Status {
36 return self._write(self, buffer_size, buffer);65 return self._write(self, buffer_size, buffer);
37 }66 }
3867
68 fn writeFn(self: *const FileProtocol, bytes: []const u8) WriteError!usize {
69 var size: usize = bytes.len;
70 if (.Success != self.write(&size, bytes.ptr)) return WriteError.WriteError;
71 return size;
72 }
73
39 pub fn getPosition(self: *const FileProtocol, position: *u64) Status {74 pub fn getPosition(self: *const FileProtocol, position: *u64) Status {
40 return self._get_position(self, position);75 return self._get_position(self, position);
41 }76 }
4277
78 fn getPos(self: *const FileProtocol) GetSeekPosError!u64 {
79 var pos: u64 = undefined;
80 if (.Success != self.getPosition(&pos)) return GetSeekPosError.GetSeekPosError;
81 return pos;
82 }
83
84 fn getEndPos(self: *const FileProtocol) GetSeekPosError!u64 {
85 // preserve the old file position
86 var pos: u64 = undefined;
87 if (.Success != self.getPosition(&pos)) return GetSeekPosError.GetSeekPosError;
88 // seek to end of file to get position = file size
89 if (.Success != self.setPosition(efi_file_position_end_of_file)) return GetSeekPosError.GetSeekPosError;
90 // restore the old position
91 if (.Success != self.setPosition(pos)) return GetSeekPosError.GetSeekPosError;
92 // return the file size = position
93 return pos;
94 }
95
43 pub fn setPosition(self: *const FileProtocol, position: u64) Status {96 pub fn setPosition(self: *const FileProtocol, position: u64) Status {
44 return self._set_position(self, position);97 return self._set_position(self, position);
45 }98 }
4699
100 fn seekTo(self: *const FileProtocol, pos: u64) SeekError!void {
101 if (.Success != self.setPosition(pos)) return SeekError.SeekError;
102 }
103
104 fn seekBy(self: *const FileProtocol, offset: i64) SeekError!void {
105 // save the old position and calculate the delta
106 var pos: u64 = undefined;
107 if (.Success != self.getPosition(&pos)) return SeekError.SeekError;
108 const seek_back = offset < 0;
109 const amt = std.math.absCast(offset);
110 if (seek_back) {
111 pos += amt;
112 } else {
113 pos -= amt;
114 }
115 if (.Success != self.setPosition(pos)) return SeekError.SeekError;
116 }
117
47 pub fn getInfo(self: *const FileProtocol, information_type: *align(8) const Guid, buffer_size: *usize, buffer: [*]u8) Status {118 pub fn getInfo(self: *const FileProtocol, information_type: *align(8) const Guid, buffer_size: *usize, buffer: [*]u8) Status {
48 return self._get_info(self, information_type, buffer_size, buffer);119 return self._get_info(self, information_type, buffer_size, buffer);
49 }120 }