// Copyright (C) 2014-2015 ChaosForge Ltd // http://chaosforge.org/ // // This file is part of Nova libraries. // For conditions of distribution and use, see copying.txt file in root folder. #include "nv/io/string_table.hh" nv::string_table::string_table( stream& in ) { uint32 entry_count = 0; in.read( &entry_count, sizeof( entry_count ), 1 ); m_map.reserve( entry_count ); indexer_type::value_type entry; for ( uint32 i = 0; i < entry_count; i++ ) { in.read( &entry, sizeof( entry ), 1 ); // TODO: this performs a existence check - // using a per-container stream implementation would avoid this! m_map.insert( entry ); } uint32 data_size = 0; in.read( &data_size, sizeof( data_size ), 1 ); // TODO: either no-init resize, or per-container implementation? m_data.resize( data_size ); in.read( m_data.data(), data_size, 1 ); } void nv::string_table::insert( string_table* in ) { m_data.reserve( m_data.size() + in->m_data.size() ); m_map.reserve( m_map.size() + in->m_map.size() ); for ( const auto& hash_index : in->m_map ) { insert( hash_index.first, in->extract_raw( hash_index.second ) ); } } nv::uint32 nv::string_table::dump_size() const { return sizeof( uint32 ) + sizeof( indexer_type::value_type ) * m_map.size() + sizeof( uint32 ) + m_data.size(); } void nv::string_table::dump( nv::stream& out ) const { // TODO these should be generic stream operations uint32 entry_count = m_map.size(); out.write( &entry_count, sizeof( entry_count ), 1 ); for ( const auto& entry : m_map ) { out.write( &entry, sizeof( entry ), 1 ); } uint32 data_size = m_data.size(); out.write( &data_size, sizeof( data_size ), 1 ); // TODO: either no-init resize, or per-container implementation? out.write( m_data.data(), data_size, 1 ); } nv::string_table::size_type nv::string_table::insert_raw( hash_type h, const char* str, length_type length ) { size_type dsize = static_cast( m_data.size() ); // TODO : resize without init! m_data.resize( dsize + 2 + length + 1 ); *reinterpret_cast( m_data.data() + dsize ) = length; raw_copy( str, str + length + 1, m_data.data() + dsize + 2 ); m_map[h] = dsize; return dsize; }