From 25eed0fcaca4c72bfddb71ded3930912c8e672fb Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Sun, 27 Aug 2023 13:15:02 +0200 Subject: Einfacheres Speichermanagement implementiert --- csv-tutorial.c | 36 ++++++++---------------- csv.c | 89 ++++++++++++++++++++++++---------------------------------- 2 files changed, 48 insertions(+), 77 deletions(-) diff --git a/csv-tutorial.c b/csv-tutorial.c index 17b95c8..9bdb7e6 100644 --- a/csv-tutorial.c +++ b/csv-tutorial.c @@ -8,9 +8,9 @@ bool processFile(const char *filename) { - FILE *in; + FILE *in = fopen(filename, "r"); - if ( (in = fopen(filename, "r")) == NULL ) { + if ( in == NULL ) { return false; } @@ -18,22 +18,21 @@ processFile(const char *filename) csv_init(&csv); while ( csv_read(&csv, in) ) { - const size_t nf = csv_nfields(&csv); - (void) nf; + const size_t nfields = csv_nfields(&csv); // ... } csv_cleanup(&csv); - fclose(in); + (void) fclose(in); return true; } bool processFile_options(const char *filename) { - FILE *in; + FILE *in = fopen(filename, "r"); - if ( (in = fopen(filename, "r")) == NULL ) { + if ( in == NULL ) { return false; } @@ -45,13 +44,12 @@ processFile_options(const char *filename) csv_init_opt(&csv, &csv_options); while ( csv_read(&csv, in) ) { - const size_t nf = csv_nfields(&csv); - (void) nf; + const size_t nfields = csv_nfields(&csv); // ... } csv_cleanup(&csv); - fclose(in); + (void) fclose(in); return true; } @@ -64,9 +62,9 @@ csvErrorHandler(csv_err_t err, void *cb_arg) bool processFile_error(const char *filename) { - FILE *in; + FILE *in = fopen(filename, "r"); - if ( (in = fopen(filename, "r")) == NULL ) { + if ( in == NULL ) { return false; } @@ -84,30 +82,20 @@ processFile_error(const char *filename) switch ( setjmp(env) ) { case CSV_ERR_OK: while ( csv_read(&csv, in) ) { - const size_t nf = csv_nfields(&csv); - (void) nf; + const size_t nfields = csv_nfields(&csv); // ... } break; case CSV_ERR_OUT_OF_MEMORY: - csv_cleanup(&csv); - break; - case CSV_ERR_OUT_OF_RANGE: - csv_cleanup(&csv); - break; - case CSV_ERR_IO_READ: - csv_cleanup(&csv); - break; - case CSV_ERR_IO_WRITE: csv_cleanup(&csv); break; } - fclose(in); + (void) fclose(in); return true; } diff --git a/csv.c b/csv.c index 4f3cd14..b68189b 100644 --- a/csv.c +++ b/csv.c @@ -43,18 +43,6 @@ mul_overflow(size_t a, size_t b, size_t *out) } #endif -static void * -csv_mem_allocate(size_t number, size_t size, void *cb_arg) -{ - UNUSED(cb_arg); - - size_t len = 0; - if ( number == 0 || size == 0 || mul_overflow(number, size, &len) ) { - return NULL; - } - return malloc(len); -} - static void * csv_mem_reallocate(void *ptr, size_t number, size_t size, void *cb_arg) { @@ -83,7 +71,6 @@ const csv_options_t csv_default_options = { .field_delimiter = CSV_DEFAULT_DELIMITER, .field_separator = CSV_DEFAULT_SEPARATOR, .cb_error = NULL, - .cb_allocate = csv_mem_allocate, .cb_reallocate = csv_mem_reallocate, .cb_free = csv_mem_free }; @@ -129,34 +116,32 @@ csv_string_isempty(csv_string_t *csv_string) } static inline void -csv_string_append(csv_string_t *csv_string, int ch, const csv_options_t *const csv_options) +csv_string_grow_if_needed(csv_string_t *csv_string, const csv_options_t *const csv_options) { assert(csv_string != NULL); assert(csv_options != NULL); static const size_t INITIAL_CAP = 16; - if ( csv_string->pos == csv_string->cap ) { // grow if needed - if ( csv_string->str == NULL ) { // first call? - char *str = csv_options->cb_allocate(INITIAL_CAP, 1, csv_options->cb_memory_arg); - if ( str == NULL ) { - csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); - return; - } - csv_string->str = str; - csv_string->cap = INITIAL_CAP; - } - else { // subsequent call - size_t cap = (csv_string->cap * 3) / 2; // *= 1.5 - char *str = csv_options->cb_reallocate(csv_string->str, cap, 1, csv_options->cb_memory_arg); - if ( str == NULL ) { - csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); - return; - } - csv_string->str = str; - csv_string->cap = cap; + if ( csv_string->pos == csv_string->cap ) { + size_t cap = (csv_string->str == NULL) ? INITIAL_CAP : (csv_string->cap * 3) / 2; + char *str = csv_options->cb_reallocate(csv_string->str, cap, 1, csv_options->cb_memory_arg); + if ( str == NULL ) { + csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); + return; } + csv_string->str = str; + csv_string->cap = cap; } +} + +static inline void +csv_string_append(csv_string_t *csv_string, int ch, const csv_options_t *const csv_options) +{ + assert(csv_string != NULL); + assert(csv_options != NULL); + + csv_string_grow_if_needed(csv_string, csv_options); csv_string->str[csv_string->pos++] = (char) ch; // append char } @@ -194,34 +179,32 @@ csv_field_reset(csv_field_t *csv_field) } static inline void -csv_field_append(csv_field_t *csv_field, size_t idx, const csv_options_t *const csv_options) +csv_field_grow_if_needed(csv_field_t *csv_field, const csv_options_t *const csv_options) { assert(csv_field != NULL); assert(csv_options != NULL); static const size_t INITIAL_CAP = 16; - if ( csv_field->pos == csv_field->cap ) { // grow if needed - if ( csv_field->fields == NULL ) { // first call - size_t *fields = csv_options->cb_allocate(INITIAL_CAP, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg); - if ( fields == NULL ) { - csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); - return; - } - csv_field->fields = fields; - csv_field->cap = INITIAL_CAP; - } - else { // subsequent call - size_t cap = (csv_field->cap * 3) / 2; // *= 1.5 - size_t *fields = csv_options->cb_reallocate(csv_field->fields, cap, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg); - if ( fields == NULL ) { - csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); - return; - } - csv_field->fields = fields; - csv_field->cap = cap; + if ( csv_field->pos == csv_field->cap ) { + size_t cap = (csv_field->fields == NULL) ? INITIAL_CAP : (csv_field->cap * 3) / 2; + size_t *fields = csv_options->cb_reallocate(csv_field->fields, cap, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg); + if ( fields == NULL ) { + csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); + return; } + csv_field->fields = fields; + csv_field->cap = cap; } +} + +static inline void +csv_field_append(csv_field_t *csv_field, size_t idx, const csv_options_t *const csv_options) +{ + assert(csv_field != NULL); + assert(csv_options != NULL); + + csv_field_grow_if_needed(csv_field, csv_options); csv_field->fields[csv_field->pos++] = idx; // append index } -- cgit v1.3