summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/cstrpool.c
blob: 36c5ff694bb641de7633b7df43c1187df52842a9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    cstrpool.c

    Constant string pool helper class.

***************************************************************************/

#include <assert.h>

#include "cstrpool.h"


//**************************************************************************
//  CONST STRING POOL
//**************************************************************************

//-------------------------------------------------
//  const_string_pool - constructor
//-------------------------------------------------

const_string_pool::const_string_pool()
{
}


//-------------------------------------------------
//  add - add a string to the string pool
//-------------------------------------------------

const char *const_string_pool::add(const char *string)
{
	// if NULL or a small number (for some hash strings), just return as-is
	if (FPTR(string) < 0x100)
		return string;

	// scan to find space
	for (pool_chunk *chunk = m_chunklist.first(); chunk != NULL; chunk = chunk->next())
	{
		const char *result = chunk->add(string);
		if (result != NULL)
			return result;
	}

	// no space anywhere, create a new pool and prepend it (so it gets used first)
	const char *result = m_chunklist.prepend(*global_alloc(pool_chunk)).add(string);
	assert(result != NULL);
	return result;
}


//-------------------------------------------------
//  contains - determine if the given string
//  pointer lives in the pool
//-------------------------------------------------

bool const_string_pool::contains(const char *string)
{
	// if NULL or a small number (for some hash strings), then yes, effectively
	if (FPTR(string) < 0x100)
		return true;

	// scan to find it
	for (pool_chunk *chunk = m_chunklist.first(); chunk != NULL; chunk = chunk->next())
		if (chunk->contains(string))
			return true;

	return false;
}

/**
 * @fn	const_string_pool::pool_chunk::pool_chunk()
 *
 * @brief	-------------------------------------------------
 * 			  pool_chunk - constructor
 * 			-------------------------------------------------.
 */

const_string_pool::pool_chunk::pool_chunk()
	: m_next(NULL),
		m_used(0)
{
}

/**
 * @fn	const char *const_string_pool::pool_chunk::add(const char *string)
 *
 * @brief	-------------------------------------------------
 * 			  add - add a string to this pool
 * 			-------------------------------------------------.
 *
 * @param	string	The string to add.
 *
 * @return	null if it fails, else a char*.
 */

const char *const_string_pool::pool_chunk::add(const char *string)
{
	// get the length of the string (no string can be longer than a full pool)
	int bytes = strlen(string) + 1;
	assert(bytes < POOL_SIZE);

	// if too big, return NULL
	if (m_used + bytes > POOL_SIZE)
		return NULL;

	// allocate, copy, and return the memory
	char *dest = &m_buffer[m_used];
	m_used += bytes;
	memcpy(dest, string, bytes);
	return dest;
}