aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-11-27 14:57:49 +0000
committergingerBill <bill@gingerbill.org>2021-11-27 14:57:49 +0000
commitc9c197ba08d5c4d9697eaead3d3ec545e8e7e195 (patch)
treeaaad1286adba4107561e51f032c6aee19984937c
parent7876660d8c78143c71d7ba2b42d52ea67219a628 (diff)
Add `os.read_at_least` and `os_read_full` utility procedures.
-rw-r--r--core/os/os.odin61
1 files changed, 40 insertions, 21 deletions
diff --git a/core/os/os.odin b/core/os/os.odin
index be1f5ad4e..83158be80 100644
--- a/core/os/os.odin
+++ b/core/os/os.odin
@@ -55,6 +55,25 @@ write_encoded_rune :: proc(fd: Handle, r: rune) {
write_byte(fd, '\'')
}
+read_at_least :: proc(fd: Handle, buf: []byte, min: int) -> (n: int, err: Errno) {
+ if len(buf) < min {
+ return 0, -1
+ }
+ for n < min && err == 0 {
+ nn: int
+ nn, err = read(fd, buf[n:])
+ n += nn
+ }
+ if n >= min {
+ err = 0
+ }
+ return
+}
+
+read_full :: proc(fd: Handle, buf: []byte) -> (n: int, err: Errno) {
+ return read_at_least(fd, buf, len(buf))
+}
+
file_size_from_path :: proc(path: string) -> i64 {
fd, err := open(path, O_RDONLY, 0)
@@ -85,27 +104,27 @@ read_entire_file_from_filename :: proc(name: string, allocator := context.alloca
read_entire_file_from_handle :: proc(fd: Handle, allocator := context.allocator) -> (data: []byte, success: bool) {
context.allocator = allocator
- length: i64
- err: Errno
- if length, err = file_size(fd); err != 0 {
- return nil, false
- }
-
- if length <= 0 {
- return nil, true
- }
-
- data = make([]byte, int(length), allocator)
- if data == nil {
- return nil, false
- }
-
- bytes_read, read_err := read(fd, data)
- if read_err != ERROR_NONE {
- delete(data)
- return nil, false
- }
- return data[:bytes_read], true
+ length: i64
+ err: Errno
+ if length, err = file_size(fd); err != 0 {
+ return nil, false
+ }
+
+ if length <= 0 {
+ return nil, true
+ }
+
+ data = make([]byte, int(length), allocator)
+ if data == nil {
+ return nil, false
+ }
+
+ bytes_read, read_err := read_full(fd, data)
+ if read_err != ERROR_NONE {
+ delete(data)
+ return nil, false
+ }
+ return data[:bytes_read], true
}
read_entire_file :: proc {