diff options
Diffstat (limited to 'src/io.c')
| -rw-r--r-- | src/io.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/io.c b/src/io.c new file mode 100644 index 0000000..b005307 --- /dev/null +++ b/src/io.c @@ -0,0 +1,224 @@ +#include <bh/io.h> +#include <malloc.h> + + +#define BUFFER_SIZE (sizeof(char *)) + + +struct bh_io_s +{ + bh_io_func_t func; +}; + + +bh_io_t *bh_io_new(bh_io_func_t func, + void *data) +{ + size_t requested; + bh_io_t *io; + + /* Get information about IO device size */ + if (func(NULL, BH_IO_INFO_CB, &requested, NULL)) + return NULL; + + /* Allocate space for the IO device */ + io = malloc(sizeof(*io) + requested); + if (!io) + return NULL; + + /* Initialize IO device */ + io->func = func; + if (func(io + 1, BH_IO_INIT_CB, data, NULL)) + { + free(io); + return NULL; + } + + return io; +} + + +void bh_io_free(bh_io_t *io) +{ + /* Prevent working with NULL io */ + if (!io) + return; + + /* Call the IO device destruction handler */ + io->func(io + 1, BH_IO_DESTROY_CB, NULL, NULL); +} + + +const char *bh_io_classname(bh_io_t *io) +{ + const char *name; + + if (!io) + goto error; + + if (io->func(io + 1, BH_IO_INFO_CB, NULL, &name) != BH_OK) + goto error; + + return name; + +error: + return NULL; +} + + +int bh_io_open(bh_io_t *io, + int mode) +{ + /* Prevent working with NULL io */ + if (!io) + return BH_ERROR; + + /* Call the IO device open handler with specified mode */ + return io->func(io + 1, BH_IO_OPEN_CB, &mode, NULL); +} + + +int bh_io_close(bh_io_t *io) +{ + /* Prevent working with NULL io */ + if (!io) + return BH_ERROR; + + /* Call the IO device close handler */ + return io->func(io + 1, BH_IO_CLOSE_CB, NULL, NULL); +} + + +int bh_io_read(bh_io_t *io, + char *buffer, + size_t size, + size_t *actual) +{ + int code; + + /* Prevent working with NULL io */ + if (!io) + return BH_ERROR; + + /* Call the IO device read handler */ + code = io->func(io + 1, BH_IO_READ_CB, buffer, &size); + + /* If caller wants to know actual read size - report it back */ + if (actual) + *actual = size; + + return code; +} + + +int bh_io_write(bh_io_t *io, + const char *buffer, + size_t size, + size_t *actual) +{ + int code; + + /* Prevent working with NULL io */ + if (!io) + return BH_ERROR; + + /* Call the IO device write handler */ + code = io->func(io + 1, BH_IO_WRITE_CB, (void *)buffer, &size); + + /* If caller wants to know actual written size - report it back */ + if (actual) + *actual = size; + + return code; +} + +int bh_io_peek(bh_io_t *io, + char *buffer, + size_t size, + size_t *actual) +{ + int code; + + /* Prevent working with NULL io */ + if (!io) + return BH_ERROR; + + /* Call the IO device peek handler */ + code = io->func(io + 1, BH_IO_PEEK_CB, (void *)buffer, &size); + + /* If caller wants to know actual written size - report it back */ + if (actual) + *actual = size; + + return code; +} + + +int bh_io_tell(bh_io_t *io, + int64_t *position) +{ + /* Prevent working with NULL io */ + if (!io) + return BH_ERROR; + + /* Call the IO device tell handler */ + return io->func(io + 1, BH_IO_TELL_CB, position, NULL); +} + + +int bh_io_seek(bh_io_t *io, + int64_t position, + int direction) +{ + /* Prevent working with NULL io */ + if (!io) + return BH_ERROR; + + /* Call the IO device seek handler */ + return io->func(io + 1, BH_IO_SEEK_CB, &position, &direction); +} + + +int bh_io_flush(bh_io_t *io) +{ + /* Prevent working with NULL io */ + if (!io) + return BH_ERROR; + + /* Call the IO device flush handler */ + return io->func(io + 1, BH_IO_FLUSH_CB, NULL, NULL); +} + + +int bh_io_size(bh_io_t *io, + int64_t *size) +{ + /* Prevent working with NULL io */ + if (!io) + return BH_ERROR; + + /* Call the IO device size handler */ + return io->func(io + 1, BH_IO_SIZE_CB, size, NULL); +} + + +int bh_io_flags(bh_io_t *io) +{ + /* Prevent working with NULL io */ + if (!io) + return BH_IO_FLAG_ERROR; + + /* Call the IO device flags handler */ + return io->func(io + 1, BH_IO_FLAGS_CB, NULL, NULL); +} + + +int bh_io_clear(bh_io_t *io) +{ + /* Prevent working with NULL io */ + if (!io) + return BH_OK; + + /* Call the IO device clear error handler */ + return io->func(io + 1, BH_IO_CLEAR_CB, NULL, NULL); +} |
