| summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src/sequence/sequence_to_string.c')
| -rw-r--r-- | src/sequence/sequence_to_string.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/src/sequence/sequence_to_string.c b/src/sequence/sequence_to_string.c new file mode 100644 index 0000000..6794fcb --- /dev/null +++ b/src/sequence/sequence_to_string.c @@ -0,0 +1,196 @@ +#define _POSIX_C_SOURCE 200809L +#include <stdlib.h> +#include <string.h> +#include <stdint.h> /* defines SIZE_MAX */ + +#include "../core/char.h" +#include "../core/index.h" + +#include "../error/error.h" + +#include "../knowledge/knowledge.h" + +#include "sequence.h" + +/******************************************************************************/ +/** MEMORY ALLOCATION *********************************************************/ +/******************************************************************************/ +static int ensure_string_capacity +( + JH_char * string [const restrict static 1], + size_t string_capacity [const restrict static 1], + const size_t string_required_capacity, + FILE io [const restrict static 1] +) +{ + JH_char * new_string; + + if (string_required_capacity <= *string_capacity) + { + return 0; + } + + new_string = + (JH_char *) realloc + ( + (void *) *string, + ((size_t) string_required_capacity) * sizeof(JH_char) + ); + + if (new_string== (JH_char *) NULL) + { + JH_S_ERROR + ( + io, + "Unable to reallocate memory to match string's required size." + ); + + return -1; + } + + *string_capacity = string_required_capacity; + *string = new_string; + + return 1; +} + +/******************************************************************************/ +/** ADD WORD ******************************************************************/ +/******************************************************************************/ +static int increment_required_capacity +( + size_t current_capacity [const restrict static 1], + const size_t increase_factor, + FILE io [const restrict static 1] +) +{ + if ((JH_INDEX_MAX - increase_factor) < *current_capacity) + { + JH_S_ERROR + ( + io, + "String capacity increment aborted, as the new capacity would not " + "fit in a JH_index variable." + ); + + return -1; + } + + *current_capacity += increase_factor; + + if ((SIZE_MAX / sizeof(JH_char)) < *current_capacity) + { + *current_capacity -= increase_factor; + + JH_S_ERROR + ( + io, + "String capacity increment aborted, as the new size would not fit " + "in a size_t variable." + ); + + return -2; + } + + return 0; +} + +static int add_word +( + const JH_index word_id, + struct JH_knowledge k [const restrict static 1], + JH_char * destination [const restrict static 1], + size_t destination_capacity [const restrict static 1], + size_t destination_length [const restrict static 1], + FILE io [const restrict static 1] +) +{ + const JH_char * word; + JH_index word_size; + size_t insertion_point; + + if (word_id < JH_RESERVED_IDS_COUNT) + { + return 0; + } + + (void) JH_knowledge_lock_access(k, io); + JH_knowledge_get_word(k, word_id, &word, &word_size); + (void) JH_knowledge_unlock_access(k, io); + + insertion_point = *destination_length; + + /* word_size includes '\n', which will be replaced by a space. */ + /* (word_size == JH_INDEX_MAX) ==> could not have learned word. */ + if (increment_required_capacity(destination_length, (word_size + 1), io) < 0) + { + return -1; + } + + if + ( + ensure_string_capacity + ( + destination, + destination_capacity, + *destination_length, + io + ) < 0 + ) + { + return -2; + } + + memcpy + ( + (*destination + insertion_point), + (const void *) word, + word_size + ); + + (*destination)[*destination_length - 1] = ' '; + + return 0; +} + +/******************************************************************************/ +/** EXPORTED ******************************************************************/ +/******************************************************************************/ +int JH_sequence_to_undercase_string +( + const JH_index sequence [const restrict static 1], + const size_t sequence_length, + struct JH_knowledge k [const restrict static 1], + JH_char * destination [const restrict static 1], + size_t destination_capacity [const restrict static 1], + size_t destination_length [const restrict static 1], + FILE io [const restrict static 1] +) +{ + size_t i; + + *destination_length = 0; + + for (i = 0; i < sequence_length; ++i) + { + if + ( + add_word + ( + sequence[i], + k, + destination, + destination_capacity, + destination_length, + io + ) < 0 + ) + { + *destination_length = 0; + + return -1; + } + } + + return 0; +} |


