summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/kit.inl.h50
-rw-r--r--source/kit/input_stream.c58
-rw-r--r--source/kit/input_stream.h8
-rw-r--r--source/tests/input_stream.test.c23
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"));
+}