| ... | @@ -52,12 +52,15 @@ pub const File = extern struct { | ... | @@ -52,12 +52,15 @@ pub const File = extern struct { |
| 52 | AccessDenied, | 52 | AccessDenied, |
| 53 | VolumeFull, | 53 | VolumeFull, |
| 54 | }; | 54 | }; |
| 55 | pub const GetInfoError = uefi.UnexpectedError || error{ | 55 | pub const GetInfoSizeError = uefi.UnexpectedError || error{ |
| 56 | Unsupported, | 56 | Unsupported, |
| 57 | NoMedia, | 57 | NoMedia, |
| 58 | DeviceError, | 58 | DeviceError, |
| 59 | VolumeCorrupted, | 59 | VolumeCorrupted, |
| 60 | }; | 60 | }; |
| | 61 | pub const GetInfoError = GetInfoSizeError || error{ |
| | 62 | BufferTooSmall, |
| | 63 | }; |
| 61 | pub const SetInfoError = uefi.UnexpectedError || error{ | 64 | pub const SetInfoError = uefi.UnexpectedError || error{ |
| 62 | Unsupported, | 65 | Unsupported, |
| 63 | NoMedia, | 66 | NoMedia, |
| ... | @@ -215,25 +218,39 @@ pub const File = extern struct { | ... | @@ -215,25 +218,39 @@ pub const File = extern struct { |
| 215 | try self.setPosition(pos); | 218 | try self.setPosition(pos); |
| 216 | } | 219 | } |
| 217 | | 220 | |
| 218 | /// If the underlying function returns `.buffer_too_small`, then this function | 221 | pub fn getInfoSize(self: *const File, comptime info: std.meta.Tag(Info)) GetInfoError!usize { |
| 219 | /// returns `.{ len, null }`. Otherwise, the 2nd value of the tuple contains | 222 | const InfoType = @FieldType(Info, @tagName(info)); |
| 220 | /// the casted reference from the buffer. | 223 | |
| | 224 | var len: usize = 0; |
| | 225 | switch (self._get_info(self, &InfoType.guid, &len, null)) { |
| | 226 | .success, .buffer_too_small => return len, |
| | 227 | .unsupported => return Error.Unsupported, |
| | 228 | .no_media => return Error.NoMedia, |
| | 229 | .device_error => return Error.DeviceError, |
| | 230 | .volume_corrupted => return Error.VolumeCorrupted, |
| | 231 | else => |status| return uefi.unexpectedStatus(status), |
| | 232 | } |
| | 233 | } |
| | 234 | |
| | 235 | /// If `buffer` is too small to contain all of the info, this function returns |
| | 236 | /// `Error.BufferTooSmall`. You should call `getInfoSize` first to determine |
| | 237 | /// how big the buffer should be to safely call this function. |
| 221 | pub fn getInfo( | 238 | pub fn getInfo( |
| 222 | self: *const File, | 239 | self: *const File, |
| 223 | comptime info: std.meta.Tag(Info), | 240 | comptime info: std.meta.Tag(Info), |
| 224 | buffer: ?[]u8, | 241 | buffer: []u8, |
| 225 | ) GetInfoError!struct { usize, @FieldType(Info, @tagName(info)) } { | 242 | ) GetInfoError!struct { usize, @FieldType(Info, @tagName(info)) } { |
| 226 | const InfoType = @FieldType(Info, @tagName(info)); | 243 | const InfoType = @FieldType(Info, @tagName(info)); |
| 227 | | 244 | |
| 228 | var len = if (buffer) |b| b.len else 0; | 245 | var len = buffer.len; |
| 229 | switch (self._get_info( | 246 | switch (self._get_info( |
| 230 | self, | 247 | self, |
| 231 | &InfoType.guid, | 248 | &InfoType.guid, |
| 232 | &len, | 249 | &len, |
| 233 | if (buffer) |b| b else null, | 250 | buffer.ptr, |
| 234 | )) { | 251 | )) { |
| 235 | .success => return .{ len, @as(*InfoType, @ptrCast(buffer.ptr)) }, | 252 | .success => return @as(*InfoType, @ptrCast(buffer.ptr)), |
| 236 | .buffer_too_small => return .{ len, null }, | 253 | .buffer_too_small => return Error.BufferTooSmall, |
| 237 | .unsupported => return Error.Unsupported, | 254 | .unsupported => return Error.Unsupported, |
| 238 | .no_media => return Error.NoMedia, | 255 | .no_media => return Error.NoMedia, |
| 239 | .device_error => return Error.DeviceError, | 256 | .device_error => return Error.DeviceError, |