1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
package os
import "base:intrinsics"
import "base:runtime"
import "core:io"
// A subset of the io.Stream_Mode with added File specific modes
File_Stream_Mode :: enum {
Close,
Flush,
Read,
Read_At,
Write,
Write_At,
Seek,
Size,
Destroy,
Query, // query what modes are available on `io.Stream`
Fstat, // File specific (not available on io.Stream)
}
#assert(intrinsics.type_is_superset_of(File_Stream_Mode, io.Stream_Mode))
// Superset interface of io.Stream_Proc with the added `runtime.Allocator` parameter needed for the Fstat mode
File_Stream_Proc :: #type proc(
stream_data: rawptr,
mode: File_Stream_Mode,
p: []byte,
offset: i64,
whence: io.Seek_From,
allocator: runtime.Allocator,
) -> (n: i64, err: Error)
File_Stream :: struct {
procedure: File_Stream_Proc,
data: rawptr,
}
// Converts a file `f` into an `io.Stream`
to_stream :: proc(f: ^File) -> (s: io.Stream) {
if f != nil {
assert(f.stream.procedure != nil)
s = {
file_io_stream_proc,
f,
}
}
return
}
/*
This is an alias of `to_stream` which converts a file `f` to an `io.Stream`.
It can be useful to indicate what the stream is meant to be used for as a writer,
even if it has no logical difference.
*/
to_writer :: to_stream
/*
This is an alias of `to_stream` which converts a file `f` to an `io.Stream`.
It can be useful to indicate what the stream is meant to be used for as a reader,
even if it has no logical difference.
*/
to_reader :: to_stream
@(private="package")
file_io_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
f := (^File)(stream_data)
file_stream_mode := transmute(File_Stream_Mode)mode
ferr: Error
n, ferr = f.stream.procedure(f, file_stream_mode, p, offset, whence, runtime.nil_allocator())
err = error_to_io_error(ferr)
return
}
@(private="package")
file_stream_fstat_utility :: proc(f: ^File_Impl, p: []byte, allocator: runtime.Allocator) -> (err: Error) {
fi: File_Info
if len(p) >= size_of(fi) {
fi, err = _fstat(&f.file, allocator)
runtime.mem_copy_non_overlapping(raw_data(p), &fi, size_of(fi))
} else {
err = .Short_Buffer
}
return
}
|