summaryrefslogtreecommitdiff
path: root/kit/input_stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'kit/input_stream.c')
-rw-r--r--kit/input_stream.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/kit/input_stream.c b/kit/input_stream.c
new file mode 100644
index 0000000..369cf64
--- /dev/null
+++ b/kit/input_stream.c
@@ -0,0 +1,103 @@
+#include "input_stream.h"
+
+#include <string.h>
+
+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);
+}