Index: trunk/src/stl/string_table.cc
===================================================================
--- trunk/src/stl/string_table.cc	(revision 428)
+++ trunk/src/stl/string_table.cc	(revision 428)
@@ -0,0 +1,74 @@
+// 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/stl/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<uint32>( m_data.size() );
+	// TODO : resize without init!
+	m_data.resize( dsize + 2 + length + 1 );
+	*reinterpret_cast<uint16*>( m_data.data() + dsize ) = length;
+	if ( length > 0 )
+		raw_copy( str, str + length, m_data.data() + dsize + 2 );
+	m_data[dsize + 2 + length] = 0;
+	m_map[h] = dsize;
+	return dsize;
+}
+
