#include "input_stream.h" #include enum { KIT_INPUT_STREAM_STR, KIT_INPUT_STREAM_FILE }; typedef struct { i64 type; kit_allocator_t *alloc; } kit_is_state_basic_t; typedef struct { i64 type; kit_allocator_t *alloc; kit_str_t string; } kit_is_state_str_t; typedef struct { i64 type; kit_allocator_t *alloc; FILE *file; } kit_is_state_file_t; static int kit_is_check_type_(void *state, i64 type) { kit_is_state_basic_t *basic = (kit_is_state_basic_t *) state; return basic != NULL && basic->type == type; } static i64 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; i64 size = destination.size < str->string.size ? destination.size : str->string.size; memcpy(destination.values, str->string.values, size); str->string.values += size; str->string.size -= size; return size; } static i64 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; i64 size = (i64) 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 = KIT_INPUT_STREAM_STR; state->string = string; state->alloc = alloc; in.state = state; 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; } void kit_is_destroy(kit_is_handle_t in) { kit_is_state_basic_t *basic = (kit_is_state_basic_t *) in.state; if (basic != NULL) kit_alloc_dispatch(basic->alloc, KIT_DEALLOCATE, 0, 0, in.state); }