Line data Source code
1 : #include "passgen/pattern/special.h" 2 : #include "passgen/assert.h" 3 : #include "passgen/util/utf8.h" 4 : #include <assert.h> 5 : #include <stdbool.h> 6 : #include <stdlib.h> 7 : 8 : #define PARAMETERS_INITIAL_SIZE 16 9 : #define PARAMETERS_MULTIPLIER 2 10 : 11 129 : void passgen_pattern_special_init( 12 : passgen_pattern_special *special, 13 : uint32_t kind) { 14 129 : special->parameters_len = 0; 15 129 : special->parameters_cap = 0; 16 129 : special->parameters = NULL; 17 : 18 129 : switch(kind) { 19 42 : case 'm': 20 42 : special->kind = PASSGEN_PATTERN_SPECIAL_MARKOV; 21 42 : break; 22 41 : case 'w': 23 41 : special->kind = PASSGEN_PATTERN_SPECIAL_WORDLIST; 24 41 : break; 25 46 : case 'p': 26 46 : special->kind = PASSGEN_PATTERN_SPECIAL_PRESET; 27 46 : break; 28 0 : default: 29 0 : passgen_assert(false); 30 0 : break; 31 : } 32 129 : } 33 : 34 129 : void passgen_pattern_special_free(passgen_pattern_special *special) { 35 129 : free(special->parameters); 36 129 : } 37 : 38 207 : void passgen_pattern_special_push( 39 : passgen_pattern_special *special, 40 : int32_t codepoint) { 41 207 : if(special->parameters_cap == 0) { 42 11 : special->parameters_cap = PARAMETERS_INITIAL_SIZE; 43 11 : special->parameters = malloc(special->parameters_cap); 44 : } 45 : 46 : // always leave enough space for a full UTF8 character (4 bytes) plus a 47 : // NULL. 48 207 : if((special->parameters_len + 5) >= special->parameters_cap) { 49 9 : special->parameters_cap *= PARAMETERS_MULTIPLIER; 50 9 : special->parameters = 51 9 : realloc(special->parameters, special->parameters_cap); 52 : } 53 : 54 207 : int bytes = passgen_utf8_encode_codepoint( 55 207 : (uint8_t *) &special->parameters[special->parameters_len], 56 : codepoint); 57 : 58 207 : passgen_assert(bytes > 0); 59 207 : special->parameters_len += bytes; 60 : 61 207 : assert(special->parameters_len < special->parameters_cap); 62 : 63 : // always NULL-terminate the string. 64 207 : special->parameters[special->parameters_len] = 0; 65 207 : }