diff --git a/nbio/nbio_stdio.c b/nbio/nbio_stdio.c index 57472a72f1..f0aaba8312 100644 --- a/nbio/nbio_stdio.c +++ b/nbio/nbio_stdio.c @@ -7,16 +7,23 @@ struct nbio_t { void* data; size_t progress; size_t len; - char op; + /* + * possible values: + * NBIO_READ, NBIO_WRITE - obvious + * -1 - currently doing nothing + * -2 - the pointer was reallocated since the last operation + */ + signed char op; }; static const char * modes[]={ "rb", "wb", "r+b" }; struct nbio_t* nbio_open(const char * filename, enum nbio_mode_t mode) { + struct nbio_t* handle; FILE* f=fopen(filename, modes[mode]); if (!f) return NULL; - struct nbio_t* handle=(struct nbio_t*)malloc(sizeof(struct nbio_t)); + handle=(struct nbio_t*)malloc(sizeof(struct nbio_t)); handle->f = f; if (mode != NBIO_WRITE) { @@ -26,17 +33,31 @@ struct nbio_t* nbio_open(const char * filename, enum nbio_mode_t mode) else handle->len = 0; handle->data = malloc(handle->len); handle->progress = handle->len; - handle->op = -1; + handle->op = -2; + + return handle; } void nbio_begin_read(struct nbio_t* handle) { + if (handle->op >= 0) + { + puts("ERROR - attempted file read operation while busy"); + abort(); + } + fseek(handle->f, 0, SEEK_SET); handle->op = NBIO_READ; handle->progress = 0; } void nbio_begin_write(struct nbio_t* handle) { + if (handle->op >= 0) + { + puts("ERROR - attempted file write operation while busy"); + abort(); + } + fseek(handle->f, 0, SEEK_SET); handle->op = NBIO_WRITE; handle->progress = 0; } @@ -50,27 +71,34 @@ bool nbio_iterate(struct nbio_t* handle, size_t* progress, size_t* len) } if (handle->op == NBIO_READ) { - fread((char*)handle->ptr + handle->progress, 1,amount, handle->f); + fread((char*)handle->data + handle->progress, 1,amount, handle->f); } if (handle->op == NBIO_WRITE) { - fwrite((char*)handle->ptr + handle->progress, 1,amount, handle->f); + fwrite((char*)handle->data + handle->progress, 1,amount, handle->f); } handle->progress += amount; if (progress) *progress = handle->progress; if (len) *len = handle->len; if (handle->progress == handle->len) handle->op = -1; - return (handle->op == -1); + return (handle->op < 0); } void nbio_resize(struct nbio_t* handle, size_t len) { + if (handle->op >= 0) + { + puts("ERROR - attempted file resize operation while busy"); + abort(); + } if (len < handle->len) { puts("ERROR - attempted file shrink operation, not implemented"); abort(); } handle->len = len; + handle->data = realloc(handle->data, handle->len); + handle->op = -1; } void* nbio_get_ptr(struct nbio_t* handle, size_t* len) diff --git a/nbio/nbio_test.c b/nbio/nbio_test.c new file mode 100644 index 0000000000..30d2e5726f --- /dev/null +++ b/nbio/nbio_test.c @@ -0,0 +1,49 @@ +#include "nbio.h" +#include +#include + +int main() +{ + struct nbio_t* write = nbio_open("test.bin", NBIO_WRITE); + nbio_resize(write, 1024*1024); + + size_t size; + void* ptr = nbio_get_ptr(write, &size); + if (size != 1024*1024) puts("ERROR: wrong size (1)"); + + memset(ptr, 0x42, 1024*1024); + nbio_begin_write(write); + + size_t prog; + bool looped=false; + while (!nbio_iterate(write, &prog, &size)) + { + printf("%u/%u\n", (unsigned)prog, (unsigned)size); + looped=true; + } + if (!looped) puts("Write finished immediately?"); + nbio_free(write); + + + struct nbio_t* read = nbio_open("test.bin", NBIO_READ); + + ptr = nbio_get_ptr(read, &size); + if (size != 1024*1024) puts("ERROR: wrong size (2)"); + if (ptr) puts("Read pointer is available before iterating?"); + + nbio_begin_read(read); + + looped=false; + while (!nbio_iterate(read, &prog, &size)) + { + printf("%u/%u\n", (unsigned)prog, (unsigned)size); + looped=true; + } + if (!looped) puts("Read finished immediately?"); + + ptr = nbio_get_ptr(read, &size); + if (size != 1024*1024) puts("ERROR: wrong size (3)"); + if (*(char*)ptr != 0x42 || memcmp(ptr, (char*)ptr+1, 1024*1024-1)) puts("ERROR: wrong data"); + + nbio_free(read); +}