Beispiel #1
0
void membuf::resize(int new_size)
{
	assert(!m_read_only);

	if (new_size == m_size)
	{
		return;
	}

	int new_capacity = capacity(new_size);

	if (m_data == NULL)
	{
		m_data = tu_malloc(new_capacity);
	}
	else
	{
		if (new_capacity != m_capacity) 
		{
			m_data = tu_realloc(m_data, new_capacity, m_capacity);
		}
	}

	assert(m_data);

	m_capacity = new_capacity;
	assert(m_capacity >= new_size);
	m_size = new_size;
}
void	tu_string::resize(int new_size)
{
	assert(new_size >= 0);

	if (new_size == size()) {
		return;
	}

	int old_size = size();

	if (using_heap() == false)
	{
		if (new_size <= sizeof(m_union.m_local.m_buffer))
		{
			// Stay with internal storage.
			m_union.m_local.m_bufsize_minus_length = (char) (sizeof(m_union.m_local.m_buffer) - new_size);
			m_union.m_local.m_buffer[new_size] = 0;	// terminate
		}
		else
		{
			// need to allocate heap buffer.
			int	capacity = new_size + 1;
			// round up.
			// TODO: test to see if this rounding-up is actually a performance win.
			capacity = (capacity + 15) & ~15;
			char*	buf = (char*) tu_malloc(capacity);
			memset(buf, 0, capacity);

			// Copy existing data.
			memcpy(buf, m_union.m_local.m_buffer, old_size);

			// Set the heap state.
			m_union.m_local.m_bufsize_minus_length = char(~0);
			m_union.m_heap.m_buffer = buf;
			m_union.m_heap.m_size = new_size;
			m_union.m_heap.m_capacity = capacity;
		}
	}
	else
	{
		// Currently using heap storage.
		if (new_size <= sizeof(m_union.m_local.m_buffer))
		{
			// Switch to local storage.

			// Be sure to get stack copies of m_heap info, before we overwrite it.
			char*	old_buffer = m_union.m_heap.m_buffer;
			int	old_capacity = m_union.m_heap.m_capacity;
			UNUSED(old_capacity);

			// Copy existing string info.
			m_union.m_local.m_bufsize_minus_length = (char) (sizeof(m_union.m_local.m_buffer) - new_size);
			assert(old_size >= new_size);
			memcpy(m_union.m_local.m_buffer, old_buffer, new_size);
			m_union.m_local.m_buffer[new_size] = 0;	// ensure termination.

			tu_free(old_buffer, old_capacity);
		}
		else
		{
			// Changing size of heap buffer.
			int	capacity = new_size + 1;
			// Round up.
			capacity = (capacity + 15) & ~15;
			if (capacity != m_union.m_heap.m_capacity)	// @@ TODO should use hysteresis when resizing
			{
				m_union.m_heap.m_buffer = (char*) tu_realloc(m_union.m_heap.m_buffer, capacity, m_heap.m_capacity);
				m_union.m_heap.m_capacity = capacity;
			}
			// else we're OK with existing buffer.

			m_union.m_heap.m_size = new_size;

			// Ensure termination.
			m_union.m_heap.m_buffer[new_size] = 0;

			assert(m_union.m_local.m_bufsize_minus_length == (char) ~0);
		}
	}
}
Beispiel #3
0
void	tu_string::resize(int new_size)
{
	assert(new_size >= 0);

	if (new_size == size()) {
		return;
	}

	if (using_heap() == false)
	{
		if (new_size < 15)
		{
			// Stay with internal storage.
			m_local.m_size = (char) (new_size + 1);
			m_local.m_buffer[new_size] = 0;	// terminate
		}
		else
		{
			// need to allocate heap buffer.
			int	capacity = new_size + 1;
			// round up.
			capacity = (capacity + 15) & ~15;
			char*	buf = (char*) tu_malloc(capacity);
                        memset(buf, 0, capacity);

			// Copy existing data.
			strcpy(buf, m_local.m_buffer);

			// Set the heap state.
			m_heap.m_buffer = buf;
			m_heap.m_all_ones = char(~0);
			m_heap.m_size = new_size + 1;
			m_heap.m_capacity = capacity;
		}
	}
	else
	{
		// Currently using heap storage.
		if (new_size < 15)
		{
			// Switch to local storage.

			// Be sure to get stack copies of m_heap info, before we overwrite it.
			char*	old_buffer = m_heap.m_buffer;
			int	old_capacity = m_heap.m_capacity;
			UNUSED(old_capacity);

			// Copy existing string info.
			m_local.m_size = (char) (new_size + 1);
			strncpy(m_local.m_buffer, old_buffer, 15);
			m_local.m_buffer[new_size] = 0;	// ensure termination.

			tu_free(old_buffer, old_capacity);
		}
		else
		{
			// Changing size of heap buffer.
			int	capacity = new_size + 1;
			// Round up.
			capacity = (capacity + 15) & ~15;
			if (capacity != m_heap.m_capacity)	// @@ TODO should use hysteresis when resizing
			{
				m_heap.m_buffer = (char*) tu_realloc(m_heap.m_buffer, capacity, m_heap.m_capacity);
				m_heap.m_capacity = capacity;
			}
			// else we're OK with existing buffer.

			m_heap.m_size = new_size + 1;

			// Ensure termination.
			m_heap.m_buffer[new_size] = 0;
		}
	}
}