// $Id: BRbStringTable.cpp,v 1.4 2003/02/21 02:07:23 yuya Exp $

#include "BRbStringTable.h"

////////////////////////////////////////////////////////////////////////////////

BRbStringTable::BRbStringTable(BRbDebug& debug)
	: m_debug(debug)
{
}


BRbStringTable::~BRbStringTable()
{
	clear();
}

////////////////////////////////////////////////////////////////////////////////

inline word
BRbStringTable::set(const char* str)
{
	return set(str, ::strlen(str));
}

inline word
BRbStringTable::set(const char* str, word len)
{
	const int size = m_table.size();

	if ( size >= 0xFFFF ) {
		m_debug.raise("string table is too big.");
	}

	for ( int idx = 0; idx < size; idx++ ) {
		if ( m_table[idx]->len == len ) {
			if ( ::memcmp(m_table[idx]->str, str, len) == 0 ) {
				return idx;
			}
		}
	}

	STRITEM *pstritem = new STRITEM;
	pstritem->len = len;
	pstritem->str = new char[len + 1];
	pstritem->str[len] = '\0';

	::memcpy(pstritem->str, str, len);

	m_table.push_back(pstritem);

	return size;
}

inline const char*
BRbStringTable::get(word idx)
{
	return m_table[idx]->str;
}

inline const char*
BRbStringTable::get(word idx, word* len)
{
	*len = m_table[idx]->len;
	return m_table[idx]->str;
}

void
BRbStringTable::clear()
{
	for ( int idx = 0; idx < m_table.size(); idx++ ) {
		delete[] m_table[idx]->str;
		delete m_table[idx];
	}

	m_table.clear();
}

void
BRbStringTable::dump(BRbOutputBuffer& buffer)
{
	word size = m_table.size();

	buffer.write_word(size);

	for ( word idx = 0; idx < size; idx++ ) {
		buffer.write_word(m_table[idx]->len);
		buffer.write_bytes(m_table[idx]->str, m_table[idx]->len);
	}
}

void
BRbStringTable::load(BRbInputBuffer& buffer)
{
	word size = buffer.read_word();

	for ( word idx = 0; idx < size; idx++ ) {
		word len = buffer.read_word();

		STRITEM *pstritem = new STRITEM;
		pstritem->len = len;
		pstritem->str = new char[len + 1];
		pstritem->str[len] = '\0';

		buffer.read_bytes(pstritem->str, len);

		m_table.push_back(pstritem);
	}
}

////////////////////////////////////////////////////////////////////////////////
