[395] | 1 | // Copyright (C) 2014-2015 ChaosForge Ltd
|
---|
[280] | 2 | // http://chaosforge.org/
|
---|
| 3 | //
|
---|
[395] | 4 | // This file is part of Nova libraries.
|
---|
| 5 | // For conditions of distribution and use, see copying.txt file in root folder.
|
---|
[280] | 6 |
|
---|
| 7 | #include "nv/io/string_table.hh"
|
---|
| 8 |
|
---|
[422] | 9 | nv::string_table::string_table( stream& in )
|
---|
[280] | 10 | {
|
---|
[422] | 11 | uint32 entry_count = 0;
|
---|
| 12 | in.read( &entry_count, sizeof( entry_count ), 1 );
|
---|
| 13 | m_map.reserve( entry_count );
|
---|
| 14 | indexer_type::value_type entry;
|
---|
[425] | 15 | for ( uint32 i = 0; i < entry_count; i++ )
|
---|
[280] | 16 | {
|
---|
[422] | 17 | in.read( &entry, sizeof( entry ), 1 );
|
---|
| 18 | // TODO: this performs a existence check -
|
---|
| 19 | // using a per-container stream implementation would avoid this!
|
---|
| 20 | m_map.insert( entry );
|
---|
[280] | 21 | }
|
---|
| 22 |
|
---|
[422] | 23 | uint32 data_size = 0;
|
---|
| 24 | in.read( &data_size, sizeof( data_size ), 1 );
|
---|
| 25 | // TODO: either no-init resize, or per-container implementation?
|
---|
| 26 | m_data.resize( data_size );
|
---|
| 27 | in.read( m_data.data(), data_size, 1 );
|
---|
[280] | 28 | }
|
---|
| 29 |
|
---|
[422] | 30 | void nv::string_table::insert( string_table* in )
|
---|
[280] | 31 | {
|
---|
[422] | 32 | m_data.reserve( m_data.size() + in->m_data.size() );
|
---|
| 33 | m_map.reserve( m_map.size() + in->m_map.size() );
|
---|
| 34 | for ( const auto& hash_index : in->m_map )
|
---|
| 35 | {
|
---|
| 36 | insert( hash_index.first, in->extract_raw( hash_index.second ) );
|
---|
| 37 | }
|
---|
[280] | 38 | }
|
---|
| 39 |
|
---|
[422] | 40 | nv::uint32 nv::string_table::dump_size() const
|
---|
[280] | 41 | {
|
---|
[422] | 42 | return sizeof( uint32 ) + sizeof( indexer_type::value_type ) * m_map.size() +
|
---|
| 43 | sizeof( uint32 ) + m_data.size();
|
---|
[280] | 44 | }
|
---|
| 45 |
|
---|
[422] | 46 | void nv::string_table::dump( nv::stream& out ) const
|
---|
[280] | 47 | {
|
---|
[422] | 48 | // TODO these should be generic stream operations
|
---|
| 49 | uint32 entry_count = m_map.size();
|
---|
| 50 | out.write( &entry_count, sizeof( entry_count ), 1 );
|
---|
| 51 | for ( const auto& entry : m_map )
|
---|
[280] | 52 | {
|
---|
[422] | 53 | out.write( &entry, sizeof( entry ), 1 );
|
---|
[280] | 54 | }
|
---|
| 55 |
|
---|
[422] | 56 | uint32 data_size = m_data.size();
|
---|
| 57 | out.write( &data_size, sizeof( data_size ), 1 );
|
---|
| 58 | // TODO: either no-init resize, or per-container implementation?
|
---|
| 59 | out.write( m_data.data(), data_size, 1 );
|
---|
[280] | 60 | }
|
---|
| 61 |
|
---|
[422] | 62 | nv::string_table::size_type nv::string_table::insert_raw( hash_type h, const char* str, length_type length )
|
---|
[281] | 63 | {
|
---|
[422] | 64 | size_type dsize = static_cast<uint32>( m_data.size() );
|
---|
| 65 | // TODO : resize without init!
|
---|
| 66 | m_data.resize( dsize + 2 + length + 1 );
|
---|
| 67 | *reinterpret_cast<uint16*>( m_data.data() + dsize ) = length;
|
---|
[427] | 68 | if ( length > 0 )
|
---|
| 69 | raw_copy( str, str + length, m_data.data() + dsize + 2 );
|
---|
| 70 | m_data[dsize + 2 + length] = 0;
|
---|
[422] | 71 | m_map[h] = dsize;
|
---|
| 72 | return dsize;
|
---|
[281] | 73 | }
|
---|
| 74 |
|
---|