/* * DataImageF150221.cpp * * Created on: * Author: titov */ #include "DataImageF150221.hh" bool driver::bf::DataImageF150221::insert_new_setting( Id id, Size size ) { if( get_image_size() + sizeof( SettingInfo ) + aligned_size( size ) > max_size ) return false; move_buff( data_buff, data_buff + head->buff_size, aligned_size( sizeof( SettingInfo ) ) ); unsigned int next_index = head->setting_count; info[next_index].id = id; info[next_index].size = size; info[next_index].crc = 0; head->setting_count = next_index + 1; data_buff = data_buff + aligned_size( sizeof( SettingInfo ) ); head->buff_size = head->buff_size + aligned_size( size ); return true; } bool driver::bf::DataImageF150221::build_from_buff( char * buff, std::size_t buff_size, std::size_t buff_align ) { max_size = buff_size; data_align = buff_align; head = reinterpret_cast( buff ); info = reinterpret_cast( buff + sizeof(Head) ); data_buff = buff + aligned_size( sizeof(Head) + aligned_size( sizeof(SettingInfo) ) * head->setting_count ); return get_image_size() < buff_size; } bool driver::bf::DataImageF150221::change_size( Size new_size, Setting setting ) { int delta = aligned_size( new_size ) - aligned_size( setting.info->size ); if( delta + get_image_size() > max_size ) return false; move_buff( setting.buffer, data_buff + head->buff_size, delta ); setting.info->size = new_size; setting.info->crc = 0; head->buff_size = head->buff_size + delta; return true; } bool driver::bf::DataImageF150221::change_setting_info( Id id, Size size ) { Setting setting = extract_setting( id ); if( setting.info == &default_info ) return insert_new_setting( id, size ); else return change_size( size, setting ); } std::size_t driver::bf::DataImageF150221::get_image_size() const { return sizeof(Head) + sizeof(SettingInfo) * head->setting_count + head->buff_size; } std::size_t driver::bf::DataImageF150221::show_setting_size( Id id ) const { return extract_setting( id ).info->size; } char * driver::bf::DataImageF150221::show_setting_data_buff( Id id ) const { return extract_setting( id ).buffer; } void driver::bf::DataImageF150221::move_buff( char * from, char * to, int delta ) { if( delta > 0 ) do { *( to + delta ) = *to; } while( to-- != from ); else if( delta < 0 ) do { *( from + delta ) = *from; } while( from++ != to ); } driver::bf::DataImageF150221::SettingInfo driver::bf::DataImageF150221::default_info = {static_cast(ULLONG_MAX), 0, 0}; driver::bf::DataImageF150221::Setting driver::bf::DataImageF150221::extract_setting( Id id ) const { char * current_ptr = data_buff; for( unsigned int i = 0; i < head->setting_count; i++ ) { if( info[i].id == id ) { if( current_ptr > data_buff + max_size ) return { &default_info, nullptr }; return { &info[i], current_ptr }; } current_ptr = current_ptr + aligned_size( info[i].size ); } return { &default_info, nullptr }; } std::pair driver::bf::DataImageF150221::show_setting( Id id ) const { Setting setting = extract_setting( id ); return { setting.buffer, setting.info->size }; } std::pair driver::bf::DataImageF150221::show_setting_crc( Id id ) const { Setting setting = extract_setting( id ); return { reinterpret_cast( &setting.info->crc ), sizeof(setting.info->crc) }; } std::size_t driver::bf::DataImageF150221::aligned_size( std::size_t size ) const { return ( size + data_align - 1 ) & ~( data_align - 1 ); } void driver::bf::DataImageF150221::reset() { if(head) { head->buff_size = 0; head->setting_count = 0; head->info_crc = 0; data_buff = reinterpret_cast( head ) + aligned_size( sizeof(Head) + sizeof(SettingInfo) * head->setting_count ); } }