Files
Odin/code/os.odin

108 lines
2.3 KiB
Odin

#import "runtime.odin" as _ // TODO(bill): make the compile import this automatically
#import "win32.odin" as win32
File :: type struct {
Handle :: type win32.HANDLE
handle: Handle
}
open :: proc(name: string) -> (File, bool) {
using win32
buf: [300]byte
copy(buf[:], name as []byte)
f := File{CreateFileA(^buf[0], FILE_GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, 0, null)}
success := f.handle != INVALID_HANDLE_VALUE as File.Handle
return f, success
}
create :: proc(name: string) -> (File, bool) {
using win32
buf: [300]byte
copy(buf[:], name as []byte)
f := File{
handle = CreateFileA(^buf[0], FILE_GENERIC_WRITE, FILE_SHARE_READ, null, CREATE_ALWAYS, 0, null),
}
success := f.handle != INVALID_HANDLE_VALUE as File.Handle
return f, success
}
close :: proc(using f: ^File) {
win32.CloseHandle(handle)
}
write :: proc(using f: ^File, buf: []byte) -> bool {
bytes_written: i32
return win32.WriteFile(handle, buf.data, buf.count as i32, ^bytes_written, null) != 0
}
File_Standard :: type enum {
INPUT,
OUTPUT,
ERROR,
COUNT,
}
__std_files := __set_file_standards();
__set_file_standards :: proc() -> [File_Standard.COUNT as int]File {
return [File_Standard.COUNT as int]File{
File{handle = win32.GetStdHandle(win32.STD_INPUT_HANDLE)},
File{handle = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE)},
File{handle = win32.GetStdHandle(win32.STD_ERROR_HANDLE)},
}
}
get_standard_file :: proc(std: File_Standard) -> ^File {
return ^__std_files[std]
}
read_entire_file :: proc(name: string) -> (string, bool) {
buf: [300]byte
copy(buf[:], name as []byte)
f, file_ok := open(name)
if !file_ok {
return "", false
}
defer close(^f)
length: i64
file_size_ok := win32.GetFileSizeEx(f.handle as win32.HANDLE, ^length) != 0
if !file_size_ok {
return "", false
}
data := new_slice(u8, length)
if data.data == null {
return "", false
}
single_read_length: i32
total_read: i64
for total_read < length {
remaining := length - total_read
to_read: u32
MAX :: 1<<32-1
if remaining <= MAX {
to_read = remaining as u32
} else {
to_read = MAX
}
win32.ReadFile(f.handle as win32.HANDLE, ^data[total_read], to_read, ^single_read_length, null)
if single_read_length <= 0 {
free(data.data)
return "", false
}
total_read += single_read_length as i64
}
return data as string, true
}