dvander@370: /** dvander@4096: * vim: set ts=4 sw=4 tw=99 noet : ds@1330: * ============================================================================= dvander@1231: * SourceMod ds@1947: * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. ds@1330: * ============================================================================= dvander@370: * ds@1330: * This program is free software; you can redistribute it and/or modify it under ds@1330: * the terms of the GNU General Public License, version 3.0, as published by the ds@1330: * Free Software Foundation. dvander@1231: * ds@1330: * This program is distributed in the hope that it will be useful, but WITHOUT ds@1330: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ds@1330: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ds@1330: * details. dvander@1231: * ds@1330: * You should have received a copy of the GNU General Public License along with ds@1330: * this program. If not, see . dvander@1231: * ds@1330: * As a special exception, AlliedModders LLC gives you permission to link the ds@1330: * code of this program (as well as its derivative works) to "Half-Life 2," the ds@1330: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software ds@1330: * by the Valve Corporation. You must obey the GNU General Public License in ds@1330: * all respects for all other code used. Additionally, AlliedModders LLC grants ds@1330: * this exception to all derivative works. AlliedModders LLC defines further ds@1330: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), ds@1330: * or . dvander@370: * dvander@370: * Version: $Id$ dvander@370: */ dvander@370: dvander@203: #ifndef _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_ dvander@203: #define _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_ dvander@203: dvander@3003: #include dvander@3003: #include dvander@3003: dvander@203: class BaseMemTable dvander@203: { dvander@203: public: dvander@3003: BaseMemTable(unsigned int init_size) dvander@3003: { dvander@3003: membase = (unsigned char *)malloc(init_size); dvander@3003: size = init_size; dvander@3003: tail = 0; dvander@3003: } dvander@3003: ~BaseMemTable() dvander@3003: { dvander@3003: free(membase); dvander@3003: membase = NULL; dvander@3003: } dvander@203: public: dvander@203: /** dvander@203: * Allocates 'size' bytes of memory. dvander@203: * Optionally outputs the address through 'addr'. dvander@203: * Returns an index >= 0 on success, < 0 on failure. dvander@203: */ dvander@3003: int CreateMem(unsigned int addsize, void **addr) dvander@3003: { dvander@3003: int idx = (int)tail; dvander@3003: dvander@3003: while (tail + addsize >= size) { dvander@3003: size *= 2; dvander@3003: membase = (unsigned char *)realloc(membase, size); dvander@3003: } dvander@3003: dvander@3003: tail += addsize; dvander@3003: if (addr) dvander@3003: *addr = (void *)&membase[idx]; dvander@3003: dvander@3003: return idx; dvander@3003: } dvander@203: dvander@203: /** dvander@203: * Given an index into the memory table, returns its address. dvander@203: * Returns NULL if invalid. dvander@203: */ dvander@3003: void *GetAddress(int index) dvander@3003: { dvander@3003: if (index < 0 || (unsigned int)index >= tail) dvander@3003: return NULL; dvander@3003: return &membase[index]; dvander@3003: } dvander@203: dvander@203: /** dvander@203: * Scraps the memory table. For caching purposes, the memory dvander@203: * is not freed, however subsequent calls to CreateMem() will dvander@203: * begin at the first index again. dvander@203: */ dvander@3003: void Reset() dvander@3003: { dvander@3003: tail = 0; dvander@3003: } dvander@404: dvander@1766: inline unsigned int GetMemUsage() dvander@1766: { dvander@1766: return size; dvander@1766: } dvander@404: pred@2142: inline unsigned int GetActualMemUsed() pred@2142: { pred@2142: return tail; pred@2142: } pred@2142: dvander@203: private: dvander@203: unsigned char *membase; dvander@203: unsigned int size; dvander@203: unsigned int tail; dvander@203: }; dvander@203: dvander@203: class BaseStringTable dvander@203: { dvander@203: public: dvander@3003: BaseStringTable(unsigned int init_size) : m_table(init_size) dvander@3003: { dvander@3003: } dvander@203: public: dvander@203: /** dvander@203: * Adds a string to the string table and returns its index. dvander@203: */ dvander@3003: int AddString(const char *string) dvander@3003: { dvander@4096: return AddString(string, strlen(string)); dvander@4096: } dvander@4096: dvander@4096: /** dvander@4096: * Adds a string to the string table and returns its index. dvander@4096: */ dvander@4096: int AddString(const char *string, size_t length) dvander@4096: { dvander@4096: size_t len = length + 1; dvander@3003: int idx; dvander@3003: char *addr; dvander@3003: dvander@3003: idx = m_table.CreateMem(len, (void **)&addr); dvander@4096: memcpy(addr, string, length + 1); dvander@3003: return idx; dvander@3003: } dvander@203: dvander@203: /** dvander@203: * Given an index into the string table, returns the associated string. dvander@203: */ dvander@293: inline const char *GetString(int str) dvander@293: { dvander@293: return (const char *)m_table.GetAddress(str); dvander@293: } dvander@203: dvander@203: /** dvander@4096: * Scraps the string table. For caching purposes, the memory dvander@203: * is not freed, however subsequent calls to AddString() will dvander@203: * begin at the first index again. dvander@203: */ dvander@3003: void Reset() dvander@3003: { dvander@3003: m_table.Reset(); dvander@3003: } dvander@203: dvander@203: /** dvander@203: * Returns the parent BaseMemTable that this string table uses. dvander@203: */ dvander@203: inline BaseMemTable *GetMemTable() dvander@203: { dvander@203: return &m_table; dvander@203: } dvander@203: private: dvander@203: BaseMemTable m_table; dvander@203: }; dvander@203: dvander@203: #endif //_INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_ dvander@3003: