Index: trunk/src/io/string_table.cc
===================================================================
--- trunk/src/io/string_table.cc	(revision 421)
+++ trunk/src/io/string_table.cc	(revision 422)
@@ -7,76 +7,66 @@
 #include "nv/io/string_table.hh"
 
-nv::string_table_creator::string_table_creator()
+nv::string_table::string_table( stream& in )
 {
-	insert(""); // 0 always is empty string
+	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; )
+	{
+		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 );
 }
 
-nv::string_table_creator::index nv::string_table_creator::insert( const string_view& s )
+void nv::string_table::insert( string_table* in )
 {
-	uint64 hash_value = hash_string< uint64 >( s.data() );
-	auto i = m_map.find( hash_value );
-	if ( i != m_map.end() )
+	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 )
 	{
-		return i->second;
+		insert( hash_index.first, in->extract_raw( hash_index.second ) );
 	}
-	const char* cs = s.data();
-	uint32 cs_size = s.size() + 1;
-	NV_ASSERT( m_offsets.size() < index(-1), "Too many strings!" );
-	index  result = index( m_offsets.size() );
-	size_t dsize = m_data.size();
-	m_offsets.push_back( dsize );
-	m_data.resize( dsize + cs_size );
-	raw_copy( cs, cs + cs_size, m_data.data() + dsize );
-	m_map[ hash_value ] = result;
-	return result;
 }
 
-nv::string_table* nv::string_table_creator::create_table() const
+nv::uint32 nv::string_table::dump_size() const
 {
-	offset* offsets = new offset[m_offsets.size()];
-	char*   data    = new char [m_data.size()];
-	raw_copy( m_offsets.begin(), m_offsets.end(), offsets );
-	raw_copy( m_data.begin(),    m_data.end(),    data );
-	return new string_table( data, m_data.size(), offsets, index( m_offsets.size() ) );
+	return sizeof( uint32 ) + sizeof( indexer_type::value_type ) * m_map.size() +
+		sizeof( uint32 ) + m_data.size();
 }
 
-void nv::string_table_creator::dump( nv::stream* out ) const
+void nv::string_table::dump( nv::stream& out ) const
 {
-	index  count = index( m_offsets.size() );
-	uint32 size  = m_data.size();
-	out->write( &count,  sizeof( count ), 1 );
-	out->write( &size,   sizeof( size ), 1 );
-	out->write( m_offsets.data(), sizeof( offset ), count );
-	out->write( m_data.data(),    sizeof( char ),  size );
+	// 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 );
 }
 
-const char* nv::string_table_creator::get( index i ) const
+nv::string_table::size_type  nv::string_table::insert_raw( hash_type h, const char* str, length_type length )
 {
-	return i < m_offsets.size() ? m_data.data() + m_offsets[i] : nullptr;
+	size_type dsize  = static_cast<uint32>( m_data.size() );
+	// TODO : resize without init!
+	m_data.resize( dsize + 2 + length + 1 );
+	*reinterpret_cast<uint16*>( m_data.data() + dsize ) = length;
+	raw_copy( str, str + length + 1, m_data.data() + dsize + 2 );
+	m_map[h] = dsize;
+	return dsize;
 }
 
-nv::string_table_creator::index nv::string_table_creator::get( const string_view& s ) const
-{
-	uint64 hash_value = hash_string< uint64 >( s.data() );
-	auto i = m_map.find( hash_value );
-	if ( i != m_map.end() )
-	{
-		return i->second;
-	}
-	return 0;
-}
-
-void nv::string_table_creator::clear()
-{
-	m_map.clear();
-	m_offsets.clear();
-	m_data.clear();
-}
-
-nv::uint32 nv::string_table_creator::dump_size() const
-{
-	return sizeof( index ) + sizeof( uint32 ) +
-		sizeof( offset ) * m_offsets.size() +
-		sizeof( char ) * m_data.size();
-}
-
