From 0fea309c5b8dee1ff044f6bbc853cb2450d1d5de Mon Sep 17 00:00:00 2001 From: John Kerl Date: Fri, 4 Sep 2015 09:19:33 -0400 Subject: [PATCH] [read performance iterate] byte-reader iterate --- c/input/byte_readers.h | 4 ++ c/input/stdio_byte_reader.c | 62 +++++++++++++++++++++++++ c/input/string_byte_reader.c | 3 ++ c/input/test_stdio_byte_reader.c | 77 ++++++++++++++++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 c/input/stdio_byte_reader.c create mode 100644 c/input/test_stdio_byte_reader.c diff --git a/c/input/byte_readers.h b/c/input/byte_readers.h index ea02ec516..1a0fd7cf9 100644 --- a/c/input/byte_readers.h +++ b/c/input/byte_readers.h @@ -3,7 +3,11 @@ #include "input/byte_reader.h" byte_reader_t* string_byte_reader_alloc(); +byte_reader_t* stdio_byte_reader_alloc(); +byte_reader_t* mmap_byte_reader_alloc(); void string_byte_reader_free(byte_reader_t* pbr); +void stdio_byte_reader_free(byte_reader_t* pbr); +void mmap_byte_reader_free(byte_reader_t* pbr); #endif // BYTE_READERS_H diff --git a/c/input/stdio_byte_reader.c b/c/input/stdio_byte_reader.c new file mode 100644 index 000000000..b444715b7 --- /dev/null +++ b/c/input/stdio_byte_reader.c @@ -0,0 +1,62 @@ +#include +#include +#include "input/byte_readers.h" +#include "lib/mlr_globals.h" +#include "lib/mlrutil.h" + +typedef struct _stdio_byte_reader_state_t { + char* filename; + FILE* fp; +} stdio_byte_reader_state_t; + +// ---------------------------------------------------------------- +static int stdio_byte_reader_open_func(struct _byte_reader_t* pbr, char* filename) { + stdio_byte_reader_state_t* pstate = mlr_malloc_or_die(sizeof(stdio_byte_reader_state_t)); + pstate->filename = strdup(filename); + pstate->fp = fopen(filename, "r"); + if (pstate->fp == NULL) { + perror("fopen"); + fprintf(stderr, "%s: Couldn't open \"%s\" for read.\n", MLR_GLOBALS.argv0, filename); + exit(1); + } + pbr->pvstate = pstate; + return TRUE; +} + +static int stdio_byte_reader_read_func(struct _byte_reader_t* pbr) { + stdio_byte_reader_state_t* pstate = pbr->pvstate; + int c = getc_unlocked(pstate->fp); + if (c == EOF && ferror(pstate->fp)) { + perror("fread"); + fprintf(stderr, "%s: Read error on file \"%s\".\n", MLR_GLOBALS.argv0, pstate->filename); + exit(1); + } + return c; +} + +static void stdio_byte_reader_close_func(struct _byte_reader_t* pbr) { + stdio_byte_reader_state_t* pstate = pbr->pvstate; + fclose(pstate->fp); + free(pstate); + pbr->pvstate = NULL; +} + +// ---------------------------------------------------------------- +byte_reader_t* stdio_byte_reader_alloc() { + byte_reader_t* pbr = mlr_malloc_or_die(sizeof(byte_reader_t)); + + pbr->pvstate = NULL; + pbr->popen_func = stdio_byte_reader_open_func; + pbr->pread_func = stdio_byte_reader_read_func; + pbr->pclose_func = stdio_byte_reader_close_func; + + return pbr; +} + +void stdio_byte_reader_free(byte_reader_t* pbr) { + stdio_byte_reader_state_t* pstate = pbr->pvstate; + if (pstate != NULL) { + free(pstate->filename); // null-ok semantics + } + free(pbr); +} diff --git a/c/input/string_byte_reader.c b/c/input/string_byte_reader.c index ce4d9067b..2dee23656 100644 --- a/c/input/string_byte_reader.c +++ b/c/input/string_byte_reader.c @@ -8,6 +8,7 @@ typedef struct _string_byte_reader_state_t { char* pend; } string_byte_reader_state_t; +// ---------------------------------------------------------------- static int string_byte_reader_open_func(struct _byte_reader_t* pbr, char* backing) { string_byte_reader_state_t* pstate = mlr_malloc_or_die(sizeof(string_byte_reader_state_t)); pstate->backing = backing; @@ -27,8 +28,10 @@ static int string_byte_reader_read_func(struct _byte_reader_t* pbr) { } static void string_byte_reader_close_func(struct _byte_reader_t* pbr) { + pbr->pvstate = NULL; } +// ---------------------------------------------------------------- byte_reader_t* string_byte_reader_alloc() { byte_reader_t* pbr = mlr_malloc_or_die(sizeof(byte_reader_t)); diff --git a/c/input/test_stdio_byte_reader.c b/c/input/test_stdio_byte_reader.c new file mode 100644 index 000000000..04264dfbd --- /dev/null +++ b/c/input/test_stdio_byte_reader.c @@ -0,0 +1,77 @@ +#include +#include +#include "lib/mlrutil.h" +#include "lib/minunit.h" +#include "input/byte_readers.h" + +#ifdef __TEST_STDIO_BYTE_READER_MAIN__ +int tests_run = 0; +int tests_failed = 0; +int assertions_run = 0; +int assertions_failed = 0; + +// xxx mkstemp +// xxx tmpfile +// xxx pop from buf +// xxx take dirname from argv[1]? + +// ---------------------------------------------------------------- +static FILE* make_temp_file(char* contents) { + xxx + + int fd = mkstemp("/tmp/mlr-ut-XXXXXXXX"); + +} + +// ---------------------------------------------------------------- +static char* test_it() { + byte_reader_t* pbr = stdio_byte_reader_alloc(); + + char* filename = xxx; + int ok = pbr->popen_func(pbr, filename); + mu_assert_lf(ok == TRUE); + mu_assert_lf(pbr->pread_func(pbr) == EOF); + mu_assert_lf(pbr->pread_func(pbr) == EOF); + mu_assert_lf(pbr->pread_func(pbr) == EOF); + pbr->pclose_func(pbr); + + ok = pbr->popen_func(pbr, "a"); + mu_assert_lf(ok == TRUE); + mu_assert_lf(pbr->pread_func(pbr) == 'a'); + mu_assert_lf(pbr->pread_func(pbr) == EOF); + mu_assert_lf(pbr->pread_func(pbr) == EOF); + pbr->pclose_func(pbr); + + ok = pbr->popen_func(pbr, "abc"); + mu_assert_lf(ok == TRUE); + mu_assert_lf(pbr->pread_func(pbr) == 'a'); + mu_assert_lf(pbr->pread_func(pbr) == 'b'); + mu_assert_lf(pbr->pread_func(pbr) == 'c'); + mu_assert_lf(pbr->pread_func(pbr) == EOF); + mu_assert_lf(pbr->pread_func(pbr) == EOF); + pbr->pclose_func(pbr); + + return NULL; +} + +// ================================================================ +static char * run_all_tests() { + mu_run_test(test_it); + return 0; +} + +int main(int argc, char **argv) { + char *result = run_all_tests(); + printf("\n"); + if (result != 0) { + printf("Not all unit tests passed\n"); + } + else { + printf("TEST_STDIO_BYTE_READER: ALL UNIT TESTS PASSED\n"); + } + printf("Tests passed: %d of %d\n", tests_run - tests_failed, tests_run); + printf("Assertions passed: %d of %d\n", assertions_run - assertions_failed, assertions_run); + + return result != 0; +} +#endif // __TEST_STDIO_BYTE_READER_MAIN__