diff options
Diffstat (limited to 'euler/source/std/cstdio.cpp')
-rw-r--r-- | euler/source/std/cstdio.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/euler/source/std/cstdio.cpp b/euler/source/std/cstdio.cpp new file mode 100644 index 0000000..8c12a7c --- /dev/null +++ b/euler/source/std/cstdio.cpp @@ -0,0 +1,59 @@ +#include <cstdio> + +extern "C" FILE *fopen(const char *filename, const char *mode) { + + bool r = false, w = false, a = false, p = false, x = false; + for (size_t i = 0; mode[i] != '\0'; ++i) + if (mode[i] == 'r') r = true; + else if (mode[i] == 'w') w = true; + else if (mode[i] == 'a') a = true; + else if (mode[i] == 'p') p = true; + else if (mode[i] == 'x') x = true; + + euler::syscall::stream_handle handle; + if (euler::syscall::open_file(filename, !r, x, handle) != + euler::syscall::stream_result::success) + return 0; + + if (w && euler::syscall::set_stream_length(handle, 0) != + euler::syscall::stream_result::success) + return 0; + + if (a && euler::syscall::seek_stream( + handle, euler::syscall::seek_from::end, 0) != + euler::syscall::stream_result::success) { + euler::syscall::close_stream(handle); + return 0; + } + + uint64_t length; + if (euler::syscall::get_stream_length(handle, length) != + euler::syscall::stream_result::success) { + euler::syscall::close_stream(handle); + return 0; + } + + return new euler::file_stream(handle, r || p, length, a ? length : 0); + +} + +extern "C" void fclose(FILE *stream) { + stream->close(); + delete stream; +} + +extern "C" int fseek(FILE *stream, long offset, int origin) { + + if (origin < 0 || origin > 2) + return -1; + + return (int)stream->seek((euler::syscall::seek_from)origin, offset); + +} + +extern "C" size_t fread( + void *buffer, size_t size, size_t count, FILE *stream) { + + return (stream->read(size * count, buffer).first - 1) / size + 1; + +} |