mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Mock out open_buffered
This commit is contained in:
@@ -104,6 +104,15 @@ open :: proc(name: string, flags := File_Flags{.Read}, perm := 0o777) -> (^File,
|
|||||||
return _open(name, flags, perm)
|
return _open(name, flags, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
open_buffered :: proc(name: string, buffer_size: uint, flags := File_Flags{.Read}, perm := 0o777) -> (^File, Error) {
|
||||||
|
if buffer_size == 0 {
|
||||||
|
return _open(name, flags, perm)
|
||||||
|
}
|
||||||
|
return _open_buffered(name, buffer_size, flags, perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
new_file :: proc(handle: uintptr, name: string) -> ^File {
|
new_file :: proc(handle: uintptr, name: string) -> ^File {
|
||||||
return _new_file(handle, name) or_else panic("Out of memory")
|
return _new_file(handle, name) or_else panic("Out of memory")
|
||||||
|
|||||||
+72
-10
@@ -1,9 +1,10 @@
|
|||||||
//+private
|
//+private
|
||||||
package os2
|
package os2
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:time"
|
import "core:time"
|
||||||
import "base:runtime"
|
import "core:sync"
|
||||||
import "core:sys/linux"
|
import "core:sys/linux"
|
||||||
|
|
||||||
File_Impl :: struct {
|
File_Impl :: struct {
|
||||||
@@ -11,13 +12,17 @@ File_Impl :: struct {
|
|||||||
name: string,
|
name: string,
|
||||||
fd: linux.Fd,
|
fd: linux.Fd,
|
||||||
allocator: runtime.Allocator,
|
allocator: runtime.Allocator,
|
||||||
|
|
||||||
|
buffer: []byte,
|
||||||
|
rw_mutex: sync.RW_Mutex, // read write calls
|
||||||
|
p_mutex: sync.Mutex, // pread pwrite calls
|
||||||
}
|
}
|
||||||
|
|
||||||
_stdin := File{
|
_stdin := File{
|
||||||
impl = &File_Impl{
|
impl = &File_Impl{
|
||||||
name = "/proc/self/fd/0",
|
name = "/proc/self/fd/0",
|
||||||
fd = 0,
|
fd = 0,
|
||||||
allocator = _file_allocator(),
|
allocator = file_allocator(),
|
||||||
},
|
},
|
||||||
stream = {
|
stream = {
|
||||||
procedure = _file_stream_proc,
|
procedure = _file_stream_proc,
|
||||||
@@ -28,7 +33,7 @@ _stdout := File{
|
|||||||
impl = &File_Impl{
|
impl = &File_Impl{
|
||||||
name = "/proc/self/fd/1",
|
name = "/proc/self/fd/1",
|
||||||
fd = 1,
|
fd = 1,
|
||||||
allocator = _file_allocator(),
|
allocator = file_allocator(),
|
||||||
},
|
},
|
||||||
stream = {
|
stream = {
|
||||||
procedure = _file_stream_proc,
|
procedure = _file_stream_proc,
|
||||||
@@ -39,7 +44,7 @@ _stderr := File{
|
|||||||
impl = &File_Impl{
|
impl = &File_Impl{
|
||||||
name = "/proc/self/fd/2",
|
name = "/proc/self/fd/2",
|
||||||
fd = 2,
|
fd = 2,
|
||||||
allocator = _file_allocator(),
|
allocator = file_allocator(),
|
||||||
},
|
},
|
||||||
stream = {
|
stream = {
|
||||||
procedure = _file_stream_proc,
|
procedure = _file_stream_proc,
|
||||||
@@ -59,10 +64,6 @@ _standard_stream_init :: proc() {
|
|||||||
stderr = &_stderr
|
stderr = &_stderr
|
||||||
}
|
}
|
||||||
|
|
||||||
_file_allocator :: proc() -> runtime.Allocator {
|
|
||||||
return heap_allocator()
|
|
||||||
}
|
|
||||||
|
|
||||||
_open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) {
|
_open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
name_cstr := temp_cstring(name) or_return
|
||||||
@@ -108,13 +109,30 @@ _new_file :: proc(fd: uintptr, _: string = "") -> (f: ^File, err: Error) {
|
|||||||
return &impl.file, nil
|
return &impl.file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
_open_buffered :: proc(name: string, buffer_size: uint, flags := File_Flags{.Read}, perm := 0o777) -> (f: ^File, err: Error) {
|
||||||
|
assert(buffer_size > 0)
|
||||||
|
f, err = _open(name, flags, perm)
|
||||||
|
if f != nil && err == nil {
|
||||||
|
impl := (^File_Impl)(f.impl)
|
||||||
|
impl.buffer = make([]byte, buffer_size, file_allocator())
|
||||||
|
f.stream.procedure = _file_stream_buffered_proc
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
_destroy :: proc(f: ^File_Impl) -> Error {
|
_destroy :: proc(f: ^File_Impl) -> Error {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
a := f.allocator
|
a := f.allocator
|
||||||
delete(f.name, a)
|
err0 := delete(f.name, a)
|
||||||
free(f, a)
|
err1 := delete(f.buffer, a)
|
||||||
|
err2 := free(f, a)
|
||||||
|
err0 or_return
|
||||||
|
err1 or_return
|
||||||
|
err2 or_return
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,3 +481,47 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte,
|
|||||||
return 0, .Empty
|
return 0, .Empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(private="package")
|
||||||
|
_file_stream_buffered_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
||||||
|
f := (^File_Impl)(stream_data)
|
||||||
|
ferr: Error
|
||||||
|
switch mode {
|
||||||
|
case .Read:
|
||||||
|
n, ferr = _read(f, p)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Read_At:
|
||||||
|
n, ferr = _read_at(f, p, offset)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Write:
|
||||||
|
n, ferr = _write(f, p)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Write_At:
|
||||||
|
n, ferr = _write_at(f, p, offset)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Seek:
|
||||||
|
n, ferr = _seek(f, offset, whence)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Size:
|
||||||
|
n, ferr = _file_size(f)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Flush:
|
||||||
|
ferr = _flush(f)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Close, .Destroy:
|
||||||
|
ferr = _close(f)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Query:
|
||||||
|
return io.query_utility({.Read, .Read_At, .Write, .Write_At, .Seek, .Size, .Flush, .Close, .Destroy, .Query})
|
||||||
|
}
|
||||||
|
return 0, .Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ File_Impl :: struct {
|
|||||||
|
|
||||||
allocator: runtime.Allocator,
|
allocator: runtime.Allocator,
|
||||||
|
|
||||||
|
buffer: []byte,
|
||||||
rw_mutex: sync.RW_Mutex, // read write calls
|
rw_mutex: sync.RW_Mutex, // read write calls
|
||||||
p_mutex: sync.Mutex, // pread pwrite calls
|
p_mutex: sync.Mutex, // pread pwrite calls
|
||||||
}
|
}
|
||||||
@@ -165,6 +166,26 @@ _new_file :: proc(handle: uintptr, name: string) -> (f: ^File, err: Error) {
|
|||||||
return &impl.file, nil
|
return &impl.file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
_open_buffered :: proc(name: string, buffer_size: uint, flags := File_Flags{.Read}, perm := 0o777) -> (f: ^File, err: Error) {
|
||||||
|
assert(buffer_size > 0)
|
||||||
|
flags := flags if flags != nil else {.Read}
|
||||||
|
handle := _open_internal(name, flags, perm) or_return
|
||||||
|
return _new_file_buffered(handle, name, buffer_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
_new_file_buffered :: proc(handle: uintptr, name: string, buffer_size: uint) -> (f: ^File, err: Error) {
|
||||||
|
f, err = _new_file(handle, name)
|
||||||
|
if f != nil && err == nil {
|
||||||
|
impl := (^File_Impl)(f.impl)
|
||||||
|
impl.buffer = make([]byte, buffer_size, file_allocator())
|
||||||
|
f.stream.procedure = _file_stream_buffered_proc
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
_fd :: proc(f: ^File) -> uintptr {
|
_fd :: proc(f: ^File) -> uintptr {
|
||||||
if f == nil || f.impl == nil {
|
if f == nil || f.impl == nil {
|
||||||
return INVALID_HANDLE
|
return INVALID_HANDLE
|
||||||
@@ -181,9 +202,11 @@ _destroy :: proc(f: ^File_Impl) -> Error {
|
|||||||
err0 := free(f.wname, a)
|
err0 := free(f.wname, a)
|
||||||
err1 := delete(f.name, a)
|
err1 := delete(f.name, a)
|
||||||
err2 := free(f, a)
|
err2 := free(f, a)
|
||||||
|
err3 := delete(f.buffer, a)
|
||||||
err0 or_return
|
err0 or_return
|
||||||
err1 or_return
|
err1 or_return
|
||||||
err2 or_return
|
err2 or_return
|
||||||
|
err3 or_return
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -780,6 +803,52 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(private="package")
|
||||||
|
_file_stream_buffered_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
||||||
|
f := (^File_Impl)(stream_data)
|
||||||
|
ferr: Error
|
||||||
|
switch mode {
|
||||||
|
case .Read:
|
||||||
|
n, ferr = _read(f, p)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Read_At:
|
||||||
|
n, ferr = _read_at(f, p, offset)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Write:
|
||||||
|
n, ferr = _write(f, p)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Write_At:
|
||||||
|
n, ferr = _write_at(f, p, offset)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Seek:
|
||||||
|
n, ferr = _seek(f, offset, whence)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Size:
|
||||||
|
n, ferr = _file_size(f)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Flush:
|
||||||
|
ferr = _flush(f)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Close, .Destroy:
|
||||||
|
ferr = _close(f)
|
||||||
|
err = error_to_io_error(ferr)
|
||||||
|
return
|
||||||
|
case .Query:
|
||||||
|
return io.query_utility({.Read, .Read_At, .Write, .Write_At, .Seek, .Size, .Flush, .Close, .Query})
|
||||||
|
}
|
||||||
|
return 0, .Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@(private="package", require_results)
|
@(private="package", require_results)
|
||||||
win32_utf8_to_wstring :: proc(s: string, allocator: runtime.Allocator) -> (ws: [^]u16, err: runtime.Allocator_Error) {
|
win32_utf8_to_wstring :: proc(s: string, allocator: runtime.Allocator) -> (ws: [^]u16, err: runtime.Allocator_Error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user