diff options
-rw-r--r-- | include/kit.inl.h | 50 | ||||
-rw-r--r-- | source/kit/input_stream.c | 58 | ||||
-rw-r--r-- | source/kit/input_stream.h | 8 | ||||
-rw-r--r-- | source/tests/input_stream.test.c | 23 |
4 files changed, 126 insertions, 13 deletions
diff --git a/include/kit.inl.h b/include/kit.inl.h index c50dd61..968d973 100644 --- a/include/kit.inl.h +++ b/include/kit.inl.h @@ -1259,6 +1259,7 @@ static kit_bigint_t kit_bi_from_base58(kit_str_t base58) { *********************************************************************/ #ifndef KIT_INPUT_STREAM_H #define KIT_INPUT_STREAM_H +#include <stdio.h> #ifdef __cplusplus extern "C" { #endif @@ -1270,17 +1271,21 @@ typedef struct { } kit_is_handle_t; kit_is_handle_t kit_is_wrap_string(kit_str_t string, kit_allocator_t alloc); +kit_is_handle_t kit_is_wrap_file(FILE *f, kit_allocator_t alloc); void kit_is_destroy(kit_is_handle_t in); #define KIT_IS_WRAP_STRING(string) \ kit_is_wrap_string((string), kit_alloc_default()) +#define KIT_IS_WRAP_FILE(f) kit_is_wrap_file((f), kit_alloc_default()) #define KIT_IS_READ(in, destination) \ (in).read((in).state, (destination)) #ifndef KIT_DISABLE_SHORT_NAMES # define is_read_fn kit_is_read_fn # define is_handle_t kit_is_handle_t # define is_wrap_string kit_is_wrap_string +# define is_wrap_file kit_is_wrap_file # define is_destroy kit_is_destroy # define IS_WRAP_STRING KIT_IS_WRAP_STRING +# define IS_WRAP_FILE KIT_IS_WRAP_FILE # define IS_READ KIT_IS_READ #endif #ifdef __cplusplus @@ -2644,7 +2649,7 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, * * *********************************************************************/ #include <string.h> -enum { input_stream_str }; +enum { KIT_INPUT_STREAM_STR, KIT_INPUT_STREAM_FILE }; typedef struct { ptrdiff_t type; kit_allocator_t alloc; @@ -2654,12 +2659,17 @@ typedef struct { kit_allocator_t alloc; kit_str_t string; } kit_is_state_str_t; -static int check_type(void *state, ptrdiff_t type) { +typedef struct { + ptrdiff_t type; + kit_allocator_t alloc; + FILE *file; +} kit_is_state_file_t; +static int kit_is_check_type_(void *state, ptrdiff_t type) { kit_is_state_basic_t *basic = (kit_is_state_basic_t *) state; return basic != NULL && basic->type == type; } -static ptrdiff_t read_str(void *state, kit_str_t destination) { - if (!check_type(state, input_stream_str)) +static ptrdiff_t kit_read_str_(void *state, kit_str_t destination) { + if (!kit_is_check_type_(state, KIT_INPUT_STREAM_STR)) return 0; kit_is_state_str_t *str = (kit_is_state_str_t *) state; ptrdiff_t size = destination.size < str->string.size @@ -2670,6 +2680,18 @@ static ptrdiff_t read_str(void *state, kit_str_t destination) { str->string.size -= size; return size; } +static ptrdiff_t kit_read_file_(void *state, kit_str_t destination) { + if (!kit_is_check_type_(state, KIT_INPUT_STREAM_FILE)) + return 0; + kit_is_state_file_t *f = (kit_is_state_file_t *) state; + if (f->file == NULL || feof(f->file)) + return 0; + ptrdiff_t size = (ptrdiff_t) fread(destination.values, 1, + destination.size, f->file); + if (size <= 0) + return 0; + return size; +} kit_is_handle_t kit_is_wrap_string(kit_str_t string, kit_allocator_t alloc) { kit_is_handle_t in; @@ -2679,11 +2701,27 @@ kit_is_handle_t kit_is_wrap_string(kit_str_t string, sizeof(kit_is_state_str_t), 0, NULL); if (state != NULL) { memset(state, 0, sizeof *state); - state->type = input_stream_str; + state->type = KIT_INPUT_STREAM_STR; state->string = string; state->alloc = alloc; in.state = state; - in.read = read_str; + in.read = kit_read_str_; + } + return in; +} +kit_is_handle_t kit_is_wrap_file(FILE *f, kit_allocator_t alloc) { + kit_is_handle_t in; + memset(&in, 0, sizeof in); + kit_is_state_file_t *state = (kit_is_state_file_t *) + kit_alloc_dispatch(alloc, KIT_ALLOCATE, + sizeof(kit_is_state_file_t), 0, NULL); + if (state != NULL) { + memset(state, 0, sizeof *state); + state->type = KIT_INPUT_STREAM_FILE; + state->file = f; + state->alloc = alloc; + in.state = state; + in.read = kit_read_file_; } return in; } diff --git a/source/kit/input_stream.c b/source/kit/input_stream.c index 0ca2ee0..f7b17fa 100644 --- a/source/kit/input_stream.c +++ b/source/kit/input_stream.c @@ -2,7 +2,7 @@ #include <string.h> -enum { input_stream_str }; +enum { KIT_INPUT_STREAM_STR, KIT_INPUT_STREAM_FILE }; typedef struct { ptrdiff_t type; @@ -15,14 +15,21 @@ typedef struct { kit_str_t string; } kit_is_state_str_t; -static int check_type(void *state, ptrdiff_t type) { +typedef struct { + ptrdiff_t type; + kit_allocator_t alloc; + FILE *file; +} kit_is_state_file_t; + +static int kit_is_check_type_(void *state, ptrdiff_t type) { kit_is_state_basic_t *basic = (kit_is_state_basic_t *) state; return basic != NULL && basic->type == type; } -static ptrdiff_t read_str(void *state, kit_str_t destination) { - if (!check_type(state, input_stream_str)) +static ptrdiff_t kit_read_str_(void *state, kit_str_t destination) { + if (!kit_is_check_type_(state, KIT_INPUT_STREAM_STR)) return 0; + kit_is_state_str_t *str = (kit_is_state_str_t *) state; ptrdiff_t size = destination.size < str->string.size ? destination.size @@ -33,21 +40,60 @@ static ptrdiff_t read_str(void *state, kit_str_t destination) { return size; } +static ptrdiff_t kit_read_file_(void *state, kit_str_t destination) { + if (!kit_is_check_type_(state, KIT_INPUT_STREAM_FILE)) + return 0; + + kit_is_state_file_t *f = (kit_is_state_file_t *) state; + + if (f->file == NULL || feof(f->file)) + return 0; + + ptrdiff_t size = (ptrdiff_t) fread(destination.values, 1, + destination.size, f->file); + + if (size <= 0) + return 0; + + return size; +} + kit_is_handle_t kit_is_wrap_string(kit_str_t string, kit_allocator_t alloc) { kit_is_handle_t in; memset(&in, 0, sizeof in); + kit_is_state_str_t *state = (kit_is_state_str_t *) kit_alloc_dispatch(alloc, KIT_ALLOCATE, sizeof(kit_is_state_str_t), 0, NULL); if (state != NULL) { memset(state, 0, sizeof *state); - state->type = input_stream_str; + state->type = KIT_INPUT_STREAM_STR; state->string = string; state->alloc = alloc; in.state = state; - in.read = read_str; + in.read = kit_read_str_; + } + return in; +} + +kit_is_handle_t kit_is_wrap_file(FILE *f, kit_allocator_t alloc) { + kit_is_handle_t in; + memset(&in, 0, sizeof in); + + kit_is_state_file_t *state = (kit_is_state_file_t *) + kit_alloc_dispatch(alloc, KIT_ALLOCATE, + sizeof(kit_is_state_file_t), 0, NULL); + + if (state != NULL) { + memset(state, 0, sizeof *state); + state->type = KIT_INPUT_STREAM_FILE; + state->file = f; + state->alloc = alloc; + in.state = state; + in.read = kit_read_file_; } + return in; } diff --git a/source/kit/input_stream.h b/source/kit/input_stream.h index b3c3ae6..d60e37e 100644 --- a/source/kit/input_stream.h +++ b/source/kit/input_stream.h @@ -4,6 +4,8 @@ #include "allocator.h" #include "string_ref.h" +#include <stdio.h> + #ifdef __cplusplus extern "C" { #endif @@ -19,11 +21,15 @@ typedef struct { kit_is_handle_t kit_is_wrap_string(kit_str_t string, kit_allocator_t alloc); +kit_is_handle_t kit_is_wrap_file(FILE *f, kit_allocator_t alloc); + void kit_is_destroy(kit_is_handle_t in); #define KIT_IS_WRAP_STRING(string) \ kit_is_wrap_string((string), kit_alloc_default()) +#define KIT_IS_WRAP_FILE(f) kit_is_wrap_file((f), kit_alloc_default()) + #define KIT_IS_READ(in, destination) \ (in).read((in).state, (destination)) @@ -31,9 +37,11 @@ void kit_is_destroy(kit_is_handle_t in); # define is_read_fn kit_is_read_fn # define is_handle_t kit_is_handle_t # define is_wrap_string kit_is_wrap_string +# define is_wrap_file kit_is_wrap_file # define is_destroy kit_is_destroy # define IS_WRAP_STRING KIT_IS_WRAP_STRING +# define IS_WRAP_FILE KIT_IS_WRAP_FILE # define IS_READ KIT_IS_READ #endif diff --git a/source/tests/input_stream.test.c b/source/tests/input_stream.test.c index 46ee0dd..467c227 100644 --- a/source/tests/input_stream.test.c +++ b/source/tests/input_stream.test.c @@ -1,4 +1,5 @@ #include "../kit/input_stream.h" +#include "../kit/file.h" #define KIT_TEST_FILE input_stream #include "../kit_test/test.h" @@ -15,9 +16,29 @@ TEST("input stream wrap string") { char buf[4]; str_t buf_ref = { .size = sizeof(buf), .values = buf }; - REQUIRE(IS_READ(in, buf_ref) == buf_ref.size); + REQUIRE_EQ(IS_READ(in, buf_ref), buf_ref.size); REQUIRE(AR_EQUAL(foo_ref, bar_ref)); REQUIRE(AR_EQUAL(buf_ref, bar_ref)); is_destroy(in); } + +TEST("input stream wrap file") { + char foo[] = "test"; + char bar[] = "test"; + + FILE *f = fopen("_kit_temp", "wb"); + fwrite(foo, 1, 4, f); + fclose(f); + + f = fopen("_kit_temp", "rb"); + + is_handle_t in = IS_WRAP_FILE(f); + + REQUIRE_EQ(IS_READ(in, SZ(bar)), SZ(bar).size); + REQUIRE(AR_EQUAL(SZ(foo), SZ(bar))); + + is_destroy(in); + fclose(f); + file_remove(SZ("_kit_temp")); +} |