static NOINLINE config_key_t* config_key( hash_t section, hash_t key, bool create ) { config_key_t new_key = {0}; config_section_t* csection; config_key_t* bucket; int ib, bsize; csection = config_section( section, create ); if( !csection ) { FOUNDATION_ASSERT( !create ); return 0; } bucket = csection->key[ key % CONFIG_KEY_BUCKETS ]; for( ib = 0, bsize = array_size( bucket ); ib < bsize; ++ib ) { /*lint --e{613} array_size( bucket ) in loop condition does the null pointer guard */ if( bucket[ib].name == key ) return bucket + ib; } if( !create ) return 0; new_key.name = key; //TODO: Thread safeness array_push_memcpy( bucket, &new_key ); csection->key[ key % CONFIG_KEY_BUCKETS ] = bucket; return bucket + bsize; }
static NOINLINE config_section_t* config_section( hash_t section, bool create ) { config_section_t* bucket; int ib, bsize; bucket = _config_section[ section % CONFIG_SECTION_BUCKETS ]; for( ib = 0, bsize = array_size( bucket ); ib < bsize; ++ib ) { /*lint --e{613} array_size( bucket ) in loop condition does the null pointer guard */ if( bucket[ib].name == section ) return bucket + ib; } if( !create ) return 0; //TODO: Thread safeness { config_section_t new_section = {0}; new_section.name = section; array_push_memcpy( bucket, &new_section ); _config_section[ section % CONFIG_SECTION_BUCKETS ] = bucket; } return bucket + bsize; }
font_t font_create(const char* name) { //todo: make this a task FOUNDATION_ASSERT(fs_is_file(name)); stream_t* ttf_stream = fs_open_file(name, STREAM_IN|STREAM_BINARY); FOUNDATION_ASSERT(ttf_stream); const uint64_t ttf_stream_size = stream_size(ttf_stream); unsigned char* ttf_buffer = (unsigned char*) memory_allocate(ttf_stream_size, 4, MEMORY_TEMPORARY); unsigned char* ttf_bitmap = (unsigned char*) memory_allocate(MINT_FONT_BITMAPSIZE*MINT_FONT_BITMAPSIZE, 4, MEMORY_PERSISTENT); const uint64_t read = stream_read(ttf_stream, ttf_buffer, ttf_stream_size); FOUNDATION_ASSERT(read == ttf_stream_size); font_data_t data; stbtt_BakeFontBitmap( ttf_buffer,0, 32.0, ttf_bitmap, MINT_FONT_BITMAPSIZE, MINT_FONT_BITMAPSIZE, 32,96, data.cdata ); TextureCreationInfo info; info.type = Texture2D; info.format = FormatR8; info.width = MINT_FONT_BITMAPSIZE; info.height = MINT_FONT_BITMAPSIZE; data.texture = texture_create(ttf_bitmap, info); array_push_memcpy(s_fontCtx.fonts, &data); memory_deallocate(ttf_bitmap); memory_deallocate(ttf_buffer); stream_deallocate(ttf_stream); return array_size(s_fontCtx.fonts)-1; }
int hashify_read_hashes(stream_t* file, hashify_string_t** hashes) { //Read in hashes in file char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; string_const_t tokens[32]; memset(line_buffer, 0, sizeof(line_buffer)); do { string_t line = stream_read_line_buffer(file, line_buffer, sizeof(line_buffer), '\n'); string_const_t stripped_line = string_strip(STRING_ARGS(line), STRING_CONST("\n\r")); if ((string_find_string(STRING_ARGS(stripped_line), STRING_CONST("define"), 0) != STRING_NPOS) && (string_find_string(STRING_ARGS(stripped_line), STRING_CONST("static_hash"), 0) != STRING_NPOS)) { //Format is: #define HASH_<hashstring> static_hash_string( "<string>", 0x<hashvalue>ULL ) size_t num_tokens = string_explode(STRING_ARGS(stripped_line), STRING_CONST(" \t"), tokens, 32, false); if (num_tokens >= 6) { hashify_string_t hash_string; string_const_t stripped = string_strip(STRING_ARGS(tokens[3]), STRING_CONST(",")); stripped = string_strip(STRING_ARGS(stripped), STRING_CONST("\"")); hash_string.string = string_copy(hash_string.buffer, HASHIFY_STRING_LENGTH, STRING_ARGS(stripped)); hash_string.hash = string_to_uint64(STRING_ARGS(tokens[4]), true); if (hash(STRING_ARGS(hash_string.string)) != hash_string.hash) { log_errorf(0, ERROR_INVALID_VALUE, STRING_CONST(" hash output file is out of date, %.*s is set to 0x%" PRIx64 " but should be 0x%" PRIx64), STRING_FORMAT(hash_string.string), hash_string.hash, hash(STRING_ARGS(hash_string.string))); return HASHIFY_RESULT_OUTPUT_FILE_OUT_OF_DATE; } array_push_memcpy(*hashes, &hash_string); } } } while (!stream_eos(file)); return 0; }
int hashify_read_hashes( stream_t* file, hashify_string_t** hashes ) { //Read in hashes in file char* line; char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; do { stream_read_line_buffer( file, line_buffer, HASHIFY_LINEBUFFER_LENGTH-1, '\n' ); line = string_strip( line_buffer, "\n\r" ); if( ( string_find_string( line, "define", 0 ) != STRING_NPOS ) && ( string_find_string( line, "static_hash", 0 ) != STRING_NPOS ) ) { //Format is: #define HASH_<hashstring> static_hash_string( "<string>", 0x<hashvalue>ULL ) char** tokens = string_explode( line, " \t", false ); if( array_size( tokens ) >= 6 ) { hashify_string_t hash_string; string_copy( hash_string.string, string_strip( string_strip( tokens[3], "," ), "\"" ), HASHIFY_STRING_LENGTH ); hash_string.hash = string_to_uint64( tokens[4], true ); if( hash( hash_string.string, string_length( hash_string.string ) ) != hash_string.hash ) { log_errorf( ERROR_INVALID_VALUE, " hash output file is out of date, %s is set to 0x%llx but should be 0x%llx ", hash_string.string, hash_string.hash, hash( hash_string.string, string_length( hash_string.string ) ) ); string_array_deallocate( tokens ); return HASHIFY_RESULT_OUTPUT_FILE_OUT_OF_DATE; } array_push_memcpy( *hashes, &hash_string ); } string_array_deallocate( tokens ); } } while( !stream_eos( file ) ); return 0; }
int hashify_process_file(stream_t* input_file, stream_t* output_file, string_t output_filename, bool check_only, hashify_string_t** history) { int result = HASHIFY_RESULT_OK; char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; hashify_string_t* local_hashes = 0; hashify_string_t* local_generated = 0; if (check_only) result = hashify_read_hashes(output_file, &local_hashes); else result = hashify_generate_preamble(output_file, output_filename); memset(line_buffer, 0, sizeof(line_buffer)); while (!stream_eos(input_file) && (result == HASHIFY_RESULT_OK)) { string_t line_string; string_const_t def_string; string_const_t value_string; line_string = stream_read_line_buffer(input_file, line_buffer, sizeof(line_buffer), '\n'); string_split(STRING_ARGS(line_string), STRING_CONST(" \t"), &def_string, &value_string, false); def_string = string_strip(STRING_ARGS(def_string), STRING_CONST(STRING_WHITESPACE)); value_string = string_strip(STRING_ARGS(value_string), STRING_CONST(STRING_WHITESPACE)); if (value_string.length && (value_string.str[0] == '"') && (value_string.str[ value_string.length - 1 ] == '"')) { ++value_string.str; value_string.length -= 2; } if (def_string.length) { hash_t hash_value = hash(STRING_ARGS(value_string)); log_infof(0, STRING_CONST(" %.*s: %.*s -> 0x%" PRIx64), STRING_FORMAT(def_string), STRING_FORMAT(value_string), hash_value); if (check_only) { //Check local consistency result = hashify_check_local_consistency(value_string, hash_value, local_hashes); } else { stream_write_format(output_file, STRING_CONST("#define %.*s static_hash_string(\"%.*s\", %" PRIsize ", 0x%" PRIx64 "ULL)\n"), STRING_FORMAT(def_string), STRING_FORMAT(value_string), value_string.length, hash_value); } if (result == HASHIFY_RESULT_OK) { hashify_string_t hash_string; //Check history result = hashify_check_collisions(value_string, hash_value, *history); //Add to history hash_string.string = string_copy(hash_string.buffer, HASHIFY_STRING_LENGTH, STRING_ARGS(value_string)); hash_string.hash = hash_value; array_push_memcpy(*history, &hash_string); array_push_memcpy(local_generated, &hash_string); } } } if (check_only) { //Check local consistency result = hashify_check_match(local_hashes, local_generated); } array_deallocate(local_hashes); array_deallocate(local_generated); return result; }
int hashify_process_file( stream_t* input_file, stream_t* output_file, bool check_only, hashify_string_t** history ) { int result = HASHIFY_RESULT_OK; char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; hashify_string_t* local_hashes = 0; hashify_string_t* local_generated = 0; if( check_only ) result = hashify_read_hashes( output_file, &local_hashes ); else result = hashify_generate_preamble( output_file ); while( !stream_eos( input_file ) && ( result == HASHIFY_RESULT_OK ) ) { char* def_string = 0; char* value_string = 0; stream_read_line_buffer( input_file, line_buffer, HASHIFY_LINEBUFFER_LENGTH, '\n' ); string_split( line_buffer, " \t", &def_string, &value_string, false ); string_strip( def_string, STRING_WHITESPACE ); string_strip( value_string, STRING_WHITESPACE ); if( string_length( value_string ) && ( value_string[0] == '"' ) && ( value_string[ string_length( value_string ) - 1 ] == '"' ) ) { unsigned int len = string_length( value_string ); memmove( value_string, value_string + 1, len - 2 ); value_string[len-2] = 0; } if( string_length( def_string ) ) { hash_t hash_value = hash( value_string, string_length( value_string ) ); log_infof( " %s: %s -> 0x%llx", def_string, value_string, hash_value ); if( check_only ) { //Check local consistency result = hashify_check_local_consistency( value_string, hash_value, local_hashes ); } else { stream_write_format( output_file, "#define %s static_hash_string( \"%s\", 0x%llxULL )\n", def_string, value_string, hash_value ); } if( result == HASHIFY_RESULT_OK ) { hashify_string_t hash_string; //Check history result = hashify_check_collisions( value_string, hash_value, *history ); //Add to history string_copy( hash_string.string, value_string, HASHIFY_STRING_LENGTH ); hash_string.hash = hash_value; array_push_memcpy( *history, &hash_string ); array_push_memcpy( local_generated, &hash_string ); } } string_deallocate( def_string ); string_deallocate( value_string ); } if( check_only ) { //Check local consistency result = hashify_check_match( local_hashes, local_generated ); } array_deallocate( local_hashes ); array_deallocate( local_generated ); return result; }