diff options
| author | kr.angelov <kr.angelov@gmail.com> | 2012-01-20 13:41:10 +0000 |
|---|---|---|
| committer | kr.angelov <kr.angelov@gmail.com> | 2012-01-20 13:41:10 +0000 |
| commit | 2eee382a62a909d5a3f2f5eda94f30fe68fd5335 (patch) | |
| tree | b0b0d513535895f244214aebf6358e172b8dce6d /src/runtime/c/gu/file.c | |
| parent | b9728357126f8b9a6311cca17d9f0dcc2a7bfb9b (diff) | |
initial import of the C runtime
Diffstat (limited to 'src/runtime/c/gu/file.c')
| -rw-r--r-- | src/runtime/c/gu/file.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/runtime/c/gu/file.c b/src/runtime/c/gu/file.c new file mode 100644 index 000000000..ed1956537 --- /dev/null +++ b/src/runtime/c/gu/file.c @@ -0,0 +1,73 @@ +#include <gu/file.h> + +typedef struct GuFileOutStream GuFileOutStream; + +struct GuFileOutStream { + GuOutStream stream; + FILE* file; +}; + +static size_t +gu_file_output(GuOutStream* stream, const uint8_t* buf, size_t len, GuExn* err) +{ + GuFileOutStream* fos = gu_container(stream, GuFileOutStream, stream); + errno = 0; + size_t wrote = fwrite(buf, 1, len, fos->file); + if (wrote < len) { + if (ferror(fos->file)) { + gu_raise_errno(err); + } + } + return wrote; +} + +static void +gu_file_flush(GuOutStream* stream, GuExn* err) +{ + GuFileOutStream* fos = gu_container(stream, GuFileOutStream, stream); + errno = 0; + if (fflush(fos->file) != 0) { + gu_raise_errno(err); + } +} + +GuOut* +gu_file_out(FILE* file, GuPool* pool) +{ + GuFileOutStream* fos = gu_new_i(pool, GuFileOutStream, + .stream.output = gu_file_output, + .stream.flush = gu_file_flush, + .file = file); + return gu_new_out(&fos->stream, pool); +} + + +typedef struct GuFileInStream GuFileInStream; + +struct GuFileInStream { + GuInStream stream; + FILE* file; +}; + +static size_t +gu_file_input(GuInStream* stream, uint8_t* buf, size_t sz, GuExn* err) +{ + GuFileInStream* fis = gu_container(stream, GuFileInStream, stream); + errno = 0; + size_t got = fread(buf, 1, sz, fis->file); + if (got == 0) { + if (ferror(fis->file)) { + gu_raise_errno(err); + } + } + return got; +} + +GuIn* +gu_file_in(FILE* file, GuPool* pool) +{ + GuFileInStream* fis = gu_new_s(pool, GuFileInStream, + .stream.input = gu_file_input, + .file = file); + return gu_new_in(&fis->stream, pool); +} |
