Example #1
0
int tsm_symbol_table_new(struct tsm_symbol_table **out)
{
	struct tsm_symbol_table *tbl;
	int ret;
	static const uint32_t *val = NULL; /* we need a valid lvalue */

	if (!out)
		return -EINVAL;

	tbl = malloc(sizeof(*tbl));
	if (!tbl)
		return -ENOMEM;
	memset(tbl, 0, sizeof(*tbl));
	tbl->ref = 1;
	tbl->next_id = TSM_UCS4_MAX + 2;
	shl_htable_init(&tbl->symbols, cmp_ucs4, hash_ucs4, NULL);

	ret = shl_array_new(&tbl->index, sizeof(uint32_t*), 4);
	if (ret)
		goto err_free;

	/* first entry is not used so add dummy */
	shl_array_push(tbl->index, &val);

	*out = tbl;
	return 0;

err_free:
	free(tbl);
	return ret;
}
Example #2
0
tsm_symbol_t tsm_symbol_append(struct tsm_symbol_table *tbl,
			       tsm_symbol_t sym, uint32_t ucs4)
{
	uint32_t buf[TSM_UCS4_MAXLEN + 1], nsym, *nval;
	const uint32_t *ptr;
	size_t s;
	bool res;
	int ret;

	if (!tbl)
		return sym;

	if (ucs4 > TSM_UCS4_MAX)
		return sym;

	ptr = tsm_symbol_get(tbl, &sym, &s);
	if (s >= TSM_UCS4_MAXLEN)
		return sym;

	memcpy(buf, ptr, s * sizeof(uint32_t));
	buf[s++] = ucs4;
	buf[s++] = TSM_UCS4_MAX + 1;

	res = shl_htable_lookup(&tbl->symbols, buf, hash_ucs4(buf, NULL),
				(void**)&nval);
	if (res) {
		/* key is prefixed with actual value */
		return *--nval;
	}

	/* We save the key in nval and prefix it with the new ID. Note that
	 * the prefix is hidden, we actually store "++nval" in the htable. */
	nval = malloc(sizeof(uint32_t) * (s + 1));
	if (!nval)
		return sym;

	++nval;
	memcpy(nval, buf, s * sizeof(uint32_t));

	nsym = tbl->next_id + 1;
	/* Out of IDs; we actually have 2 Billion IDs so this seems
	 * very unlikely but lets be safe here */
	if (nsym <= tbl->next_id++)
		goto err_id;

	/* store ID hidden before the key */
	*(nval - 1) = nsym;

	ret = shl_htable_insert(&tbl->symbols, nval, hash_ucs4(nval, NULL));
	if (ret)
		goto err_id;

	ret = shl_array_push(tbl->index, &nval);
	if (ret)
		goto err_symbol;

	return nsym;

err_symbol:
	shl_htable_remove(&tbl->symbols, nval, hash_ucs4(nval, NULL), NULL);
err_id:
	--tbl->next_id;
	free(nval);
	return sym;
}
Example #3
0
SHL_EXPORT
tsm_symbol_t tsm_symbol_append(struct tsm_symbol_table *tbl,
			       tsm_symbol_t sym, uint32_t ucs4)
{
	uint32_t buf[TSM_UCS4_MAXLEN + 1], nsym, *nval;
	const uint32_t *ptr;
	size_t s;
	void *tmp;
	bool res;
	int ret;

	if (!tbl)
		tbl = tsm_symbol_table_default;

	if (!tbl) {
		ret = tsm_symbol_table_new(&tbl);
		if (ret)
			return sym;
		tsm_symbol_table_default = tbl;
	}

	if (ucs4 > TSM_UCS4_MAX)
		return sym;

	ptr = tsm_symbol_get(tbl, &sym, &s);
	if (s >= TSM_UCS4_MAXLEN)
		return sym;

	memcpy(buf, ptr, s * sizeof(uint32_t));
	buf[s++] = ucs4;
	buf[s++] = TSM_UCS4_MAX + 1;

	res = shl_hashtable_find(tbl->symbols, &tmp, buf);
	if (res)
		return (uint32_t)(long)tmp;

	nval = malloc(sizeof(uint32_t) * s);
	if (!nval)
		return sym;

	memcpy(nval, buf, s * sizeof(uint32_t));
	nsym = tbl->next_id + 1;
	/* Out of IDs; we actually have 2 Billion IDs so this seems
	 * very unlikely but lets be safe here */
	if (nsym <= tbl->next_id++)
		goto err_id;

	ret = shl_hashtable_insert(tbl->symbols, nval, (void*)(long)nsym);
	if (ret)
		goto err_id;

	ret = shl_array_push(tbl->index, &nval);
	if (ret)
		goto err_symbol;

	return nsym;

err_symbol:
	shl_hashtable_remove(tbl->symbols, nval);
err_id:
	--tbl->next_id;
	free(nval);
	return sym;
}