|
@@ -1,5 +1,7 @@
|
|
package libc
|
|
package libc
|
|
|
|
|
|
|
|
+import "core:io"
|
|
|
|
+
|
|
when ODIN_OS == .Windows {
|
|
when ODIN_OS == .Windows {
|
|
foreign import libc {
|
|
foreign import libc {
|
|
"system:libucrt.lib",
|
|
"system:libucrt.lib",
|
|
@@ -218,3 +220,102 @@ foreign libc {
|
|
ferror :: proc(stream: ^FILE) -> int ---
|
|
ferror :: proc(stream: ^FILE) -> int ---
|
|
perror :: proc(s: cstring) ---
|
|
perror :: proc(s: cstring) ---
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+to_stream :: proc(file: ^FILE) -> io.Stream {
|
|
|
|
+ stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
|
|
|
+ unknown_or_eof :: proc(f: ^FILE) -> io.Error {
|
|
|
|
+ switch {
|
|
|
|
+ case ferror(f) != 0:
|
|
|
|
+ return .Unknown
|
|
|
|
+ case feof(f) != 0:
|
|
|
|
+ return .EOF
|
|
|
|
+ case:
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ file := (^FILE)(stream_data)
|
|
|
|
+ switch mode {
|
|
|
|
+ case .Close:
|
|
|
|
+ if fclose(file) != 0 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ case .Flush:
|
|
|
|
+ if fflush(file) != 0 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ case .Read:
|
|
|
|
+ n = i64(fread(raw_data(p), size_of(byte), len(p), file))
|
|
|
|
+ if n == 0 { err = unknown_or_eof(file) }
|
|
|
|
+
|
|
|
|
+ case .Read_At:
|
|
|
|
+ curr := ftell(file)
|
|
|
|
+ if curr == -1 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if fseek(file, long(offset), SEEK_SET) != 0 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ defer fseek(file, long(curr), SEEK_SET)
|
|
|
|
+
|
|
|
|
+ n = i64(fread(raw_data(p), size_of(byte), len(p), file))
|
|
|
|
+ if n == 0 { err = unknown_or_eof(file) }
|
|
|
|
+
|
|
|
|
+ case .Write:
|
|
|
|
+ n = i64(fwrite(raw_data(p), size_of(byte), len(p), file))
|
|
|
|
+ if n == 0 { err = unknown_or_eof(file) }
|
|
|
|
+
|
|
|
|
+ case .Write_At:
|
|
|
|
+ curr := ftell(file)
|
|
|
|
+ if curr == -1 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if fseek(file, long(offset), SEEK_SET) != 0 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ defer fseek(file, long(curr), SEEK_SET)
|
|
|
|
+
|
|
|
|
+ n = i64(fwrite(raw_data(p), size_of(byte), len(p), file))
|
|
|
|
+ if n == 0 { err = unknown_or_eof(file) }
|
|
|
|
+
|
|
|
|
+ case .Seek:
|
|
|
|
+ if fseek(file, long(offset), int(whence)) != 0 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ case .Size:
|
|
|
|
+ curr := ftell(file)
|
|
|
|
+ if curr == -1 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+ defer fseek(file, curr, SEEK_SET)
|
|
|
|
+
|
|
|
|
+ if fseek(file, 0, SEEK_END) != 0 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ n = i64(ftell(file))
|
|
|
|
+ if n == -1 {
|
|
|
|
+ return 0, unknown_or_eof(file)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ case .Destroy:
|
|
|
|
+ return 0, .Empty
|
|
|
|
+
|
|
|
|
+ case .Query:
|
|
|
|
+ return io.query_utility({ .Close, .Flush, .Read, .Read_At, .Write, .Write_At, .Seek, .Size })
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ data = file,
|
|
|
|
+ procedure = stream_proc,
|
|
|
|
+ }
|
|
|
|
+}
|