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 }