Update nvault module project files and use AMTL.

This commit is contained in:
Arkshine 2014-08-10 16:57:53 +02:00
parent 3ba84fb283
commit ab16be08f5
24 changed files with 545 additions and 7662 deletions

View File

@ -113,7 +113,6 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="..\mysql2_header.h" /> <ClInclude Include="..\mysql2_header.h" />
<ClInclude Include="..\sqlheaders.h" /> <ClInclude Include="..\sqlheaders.h" />
<ClInclude Include="..\svn_version.h" />
<ClInclude Include="..\threading.h" /> <ClInclude Include="..\threading.h" />
<ClInclude Include="..\thread\IThreader.h" /> <ClInclude Include="..\thread\IThreader.h" />
<ClInclude Include="..\thread\BaseWorker.h" /> <ClInclude Include="..\thread\BaseWorker.h" />

View File

@ -85,9 +85,6 @@
<ClInclude Include="..\sqlheaders.h"> <ClInclude Include="..\sqlheaders.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\svn_version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\threading.h"> <ClInclude Include="..\threading.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@ -3,8 +3,12 @@ import os.path
binary = AMXX.Module(builder, 'nvault') binary = AMXX.Module(builder, 'nvault')
binary.compiler.defines += [
'HAVE_STDINT_H',
]
binary.sources = [ binary.sources = [
'sdk/amxxmodule.cpp', '../../public/sdk/amxxmodule.cpp',
'amxxapi.cpp', 'amxxapi.cpp',
'Binary.cpp', 'Binary.cpp',
'Journal.cpp', 'Journal.cpp',

View File

@ -20,17 +20,17 @@
Journal::Journal(const char *file) Journal::Journal(const char *file)
{ {
m_File.assign(file); m_File = file;
} }
bool Journal::Erase() bool Journal::Erase()
{ {
return (unlink(m_File.c_str()) == 0); return (unlink(m_File.chars()) == 0);
} }
int Journal::Replay(VaultMap *pMap) int Journal::Replay(VaultMap *pMap)
{ {
m_fp = fopen(m_File.c_str(), "rb"); m_fp = fopen(m_File.chars(), "rb");
if (!m_fp) if (!m_fp)
{ {
return -1; return -1;
@ -42,8 +42,8 @@ int Journal::Replay(VaultMap *pMap)
uint16_t len16; uint16_t len16;
char *key = NULL; char *key = NULL;
char *val = NULL; char *val = NULL;
String sKey; ke::AString sKey;
String sVal; ke::AString sVal;
time_t stamp; time_t stamp;
JOp op; JOp op;
int ops = 0; int ops = 0;
@ -59,8 +59,10 @@ int Journal::Replay(VaultMap *pMap)
op = static_cast<JOp>(temp8); op = static_cast<JOp>(temp8);
if (op == Journal_Clear) if (op == Journal_Clear)
{ {
pMap->Clear(); pMap->clear();
} else if (op == Journal_Prune) { }
else if (op == Journal_Prune)
{
time_t start; time_t start;
time_t end; time_t end;
@ -70,11 +72,31 @@ int Journal::Replay(VaultMap *pMap)
if (!br.ReadUInt32(itemp)) goto fail; if (!br.ReadUInt32(itemp)) goto fail;
end = static_cast<time_t>(itemp); end = static_cast<time_t>(itemp);
pMap->Prune(start, end); for (StringHashMap<ArrayInfo>::iterator iter = pMap->iter(); !iter.empty(); iter.next())
{
} else if (op == Journal_Insert) { time_t stamp = iter->value.stamp;
bool remove = false;
if (stamp != 0)
{
if (start == 0 && end == 0)
remove = true;
else if (start == 0 && stamp < end)
remove = true;
else if (end == 0 && stamp > start)
remove = true;
else if (stamp > start && stamp < end)
remove = true;
if (remove)
{
iter.erase();
}
}
}
}
else if (op == Journal_Insert)
{
if (!br.ReadUInt32(itemp)) goto fail; if (!br.ReadUInt32(itemp)) goto fail;
stamp = static_cast<time_t>(itemp); stamp = static_cast<time_t>(itemp);
@ -90,9 +112,10 @@ int Journal::Replay(VaultMap *pMap)
key[len8] = '\0'; key[len8] = '\0';
val[len16] = '\0'; val[len16] = '\0';
sKey.assign(key);
sVal.assign(val); ArrayInfo info; info.value = val; info.stamp = stamp;
pMap->Insert(sKey, sVal, stamp); pMap->replace(key, info);
//clean up //clean up
delete [] key; delete [] key;
key = NULL; key = NULL;
@ -105,8 +128,8 @@ int Journal::Replay(VaultMap *pMap)
key = new char[len8+1]; key = new char[len8+1];
if (!br.ReadChars(key, len8)) goto fail; if (!br.ReadChars(key, len8)) goto fail;
key[len8] = '\0'; key[len8] = '\0';
sKey.assign(key);
pMap->Remove(sKey); pMap->remove(key);
} }
ops++; ops++;
} while (op < Journal_TotalOps && op); } while (op < Journal_TotalOps && op);
@ -135,7 +158,7 @@ success:
bool Journal::Begin() bool Journal::Begin()
{ {
m_fp = fopen(m_File.c_str(), "wb"); m_fp = fopen(m_File.chars(), "wb");
m_Bw.SetFilePtr(m_fp); m_Bw.SetFilePtr(m_fp);
return (m_fp != NULL); return (m_fp != NULL);
} }

View File

@ -15,9 +15,11 @@
#define _INCLUDE_JOURNAL_H #define _INCLUDE_JOURNAL_H
#include "Binary.h" #include "Binary.h"
#include "sh_list.h" #include <am-linkedlist.h>
#include "sh_tinyhash.h" #include <sm_stringhashmap.h>
#include "CString.h" #include <am-string.h>
using namespace SourceMod;
enum JOp enum JOp
{ {
@ -35,7 +37,13 @@ enum Encode
Encode_Medium, Encode_Medium,
}; };
typedef THash<String,String> VaultMap; struct ArrayInfo
{
ke::AString value;
time_t stamp;
};
typedef StringHashMap<ArrayInfo> VaultMap;
class Journal class Journal
{ {
@ -56,7 +64,7 @@ private:
bool WriteInt32(int num); bool WriteInt32(int num);
bool WriteString(const char *str, Encode enc); bool WriteString(const char *str, Encode enc);
private: private:
String m_File; ke::AString m_File;
FILE *m_fp; FILE *m_fp;
BinaryWriter m_Bw; BinaryWriter m_Bw;
}; };

View File

@ -7,6 +7,7 @@
HLSDK = ../../../hlsdk HLSDK = ../../../hlsdk
MM_ROOT = ../../../metamod/metamod MM_ROOT = ../../../metamod/metamod
PUBLIC_ROOT = ../../public
##################################### #####################################
### EDIT BELOW FOR OTHER PROJECTS ### ### EDIT BELOW FOR OTHER PROJECTS ###
@ -14,7 +15,7 @@ MM_ROOT = ../../../metamod/metamod
PROJECT = nvault PROJECT = nvault
OBJECTS = sdk/amxxmodule.cpp amxxapi.cpp Binary.cpp Journal.cpp NVault.cpp OBJECTS = amxxmodule.cpp amxxapi.cpp Binary.cpp Journal.cpp NVault.cpp
############################################## ##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ### ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
@ -29,8 +30,9 @@ CPP_OSX = clang
LINK = LINK =
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/common -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared \ INCLUDE = -I. -I$(PUBLIC_ROOT) -I$(PUBLIC_ROOT)/sdk -I$(PUBLIC_ROOT)/amtl \
-I$(HLSDK)/public -I$(MM_ROOT) -Isdk -I$(HLSDK) -I$(HLSDK)/public -I$(HLSDK)/common -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/pm_shared\
-I$(MM_ROOT)
################################################ ################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ### ### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
@ -105,7 +107,7 @@ $(BIN_DIR)/%.o: %.cpp
all: all:
mkdir -p $(BIN_DIR) mkdir -p $(BIN_DIR)
mkdir -p $(BIN_DIR)/sdk ln -sf $(PUBLIC_ROOT)/sdk/amxxmodule.cpp
$(MAKE) -f $(MAKEFILE_NAME) $(PROJECT) $(MAKE) -f $(MAKEFILE_NAME) $(PROJECT)
$(PROJECT): $(OBJ_BIN) $(PROJECT): $(OBJ_BIN)
@ -118,6 +120,5 @@ default: all
clean: clean:
rm -rf $(BIN_DIR)/*.o rm -rf $(BIN_DIR)/*.o
rm -rf $(BIN_DIR)/sdk/*.o
rm -f $(BIN_DIR)/$(BINARY) rm -f $(BIN_DIR)/$(BINARY)

View File

@ -15,7 +15,7 @@
#include "amxxmodule.h" #include "amxxmodule.h"
#include "NVault.h" #include "NVault.h"
#include "Binary.h" #include "Binary.h"
#include "CString.h" #include <am-string.h>
/** /**
* :TODO: This beast calls strcpy()/new() way too much by creating new strings on the stack. * :TODO: This beast calls strcpy()/new() way too much by creating new strings on the stack.
@ -23,35 +23,16 @@
* ---bail * ---bail
*/ */
template <>
int HashFunction<String>(const String & k)
{
unsigned long hash = 5381;
const char *str = k.c_str();
char c;
while ((c = *str++))
{
hash = ((hash << 5) + hash) + c; // hash*33 + c
}
return hash;
}
template <>
int Compare<String>(const String & k1, const String & k2)
{
return strcmp(k1.c_str(),k2.c_str());
}
NVault::NVault(const char *file) NVault::NVault(const char *file)
{ {
m_File.assign(file); m_File = file;
m_Journal = NULL; m_Journal = NULL;
m_Open = false; m_Open = false;
FILE *fp = fopen(m_File.c_str(), "rb"); FILE *fp = fopen(m_File.chars(), "rb");
if (!fp) if (!fp)
{ {
fp = fopen(m_File.c_str(), "wb"); fp = fopen(m_File.chars(), "wb");
if (!fp) if (!fp)
{ {
this->m_Valid = false; this->m_Valid = false;
@ -70,7 +51,7 @@ NVault::~NVault()
VaultError NVault::_ReadFromFile() VaultError NVault::_ReadFromFile()
{ {
FILE *fp = fopen(m_File.c_str(), "rb"); FILE *fp = fopen(m_File.chars(), "rb");
if (!fp) if (!fp)
{ {
@ -90,8 +71,6 @@ VaultError NVault::_ReadFromFile()
time_t stamp; time_t stamp;
char *key = NULL; char *key = NULL;
char *val = NULL; char *val = NULL;
String sKey;
String sVal;
// try // try
// { // {
@ -143,9 +122,9 @@ VaultError NVault::_ReadFromFile()
key[keylen] = '\0'; key[keylen] = '\0';
val[vallen] = '\0'; val[vallen] = '\0';
sKey.assign(key);
sVal.assign(val); ArrayInfo info; info.value = val; info.stamp = stamp;
m_Hash.Insert(sKey, sVal, stamp); m_Hash.replace(key, info);
} }
// } catch (...) { // } catch (...) {
@ -174,7 +153,7 @@ success:
bool NVault::_SaveToFile() bool NVault::_SaveToFile()
{ {
FILE *fp = fopen(m_File.c_str(), "wb"); FILE *fp = fopen(m_File.chars(), "wb");
if (!fp) if (!fp)
{ {
@ -189,28 +168,29 @@ bool NVault::_SaveToFile()
uint16_t version = VAULT_VERSION; uint16_t version = VAULT_VERSION;
time_t stamp; time_t stamp;
String key; ke::AString key;
String val; ke::AString val;
THash<String,String>::iterator iter = m_Hash.begin(); StringHashMap<ArrayInfo>::iterator iter = m_Hash.iter();
if (!bw.WriteUInt32(magic)) goto fail; if (!bw.WriteUInt32(magic)) goto fail;
if (!bw.WriteUInt16(version)) goto fail; if (!bw.WriteUInt16(version)) goto fail;
if (!bw.WriteUInt32( m_Hash.Size() )) goto fail; if (!bw.WriteUInt32( m_Hash.elements() )) goto fail;
while (iter != m_Hash.end()) while (!iter.empty())
{ {
key = (*iter).key; key = (*iter).key;
val = (*iter).val; val = (*iter).value.value;
stamp = (*iter).stamp; stamp = (*iter).value.stamp;
if (!bw.WriteInt32(static_cast<int32_t>(stamp))) goto fail;; if (!bw.WriteInt32(static_cast<int32_t>(stamp))) goto fail;;
if (!bw.WriteUInt8( key.size() )) goto fail; if (!bw.WriteUInt8( key.length() )) goto fail;
if (!bw.WriteUInt16( val.size() )) goto fail; if (!bw.WriteUInt16( val.length() )) goto fail;
if (!bw.WriteChars( key.c_str(), key.size() )) goto fail; if (!bw.WriteChars( key.chars(), key.length() )) goto fail;
if (!bw.WriteChars( val.c_str(), val.size() )) goto fail; if (!bw.WriteChars( val.chars(), val.length() )) goto fail;
iter++;
iter.next();
} }
goto success; goto success;
@ -229,21 +209,21 @@ success:
const char *NVault::GetValue(const char *key) const char *NVault::GetValue(const char *key)
{ {
String sKey(key); ArrayInfo result;
if (!m_Hash.Exists(sKey)) if (!m_Hash.retrieve(key, &result))
{ {
return ""; result.value.setVoid();
} else {
return m_Hash.Retrieve(sKey).c_str();
} }
return result.value.chars();
} }
bool NVault::Open() bool NVault::Open()
{ {
_ReadFromFile(); _ReadFromFile();
char *journal_name = new char[m_File.size() + 10]; char *journal_name = new char[m_File.length() + 10];
strcpy(journal_name, m_File.c_str()); strcpy(journal_name, m_File.chars());
char *pos = strstr(journal_name, ".vault"); char *pos = strstr(journal_name, ".vault");
if (pos) if (pos)
@ -291,78 +271,106 @@ void NVault::SetValue(const char *key, const char *val)
{ {
if (m_Journal) if (m_Journal)
m_Journal->Write_Insert(key, val, time(NULL)); m_Journal->Write_Insert(key, val, time(NULL));
String sKey;
String sVal; ArrayInfo info; info.value = val; info.stamp = time(NULL);
sKey.assign(key); m_Hash.replace(key, info);
sVal.assign(val);
m_Hash.Insert(sKey, sVal);
} }
void NVault::SetValue(const char *key, const char *val, time_t stamp) void NVault::SetValue(const char *key, const char *val, time_t stamp)
{ {
if (m_Journal) if (m_Journal)
m_Journal->Write_Insert(key, val, stamp); m_Journal->Write_Insert(key, val, stamp);
String sKey;
String sVal; ArrayInfo info; info.value = val; info.stamp = stamp;
sKey.assign(key); m_Hash.replace(key, info);
sVal.assign(val);
m_Hash.Insert(sKey, sVal, stamp);
} }
void NVault::Remove(const char *key) void NVault::Remove(const char *key)
{ {
if (m_Journal) if (m_Journal)
m_Journal->Write_Remove(key); m_Journal->Write_Remove(key);
String sKey(key);
m_Hash.Remove(sKey); m_Hash.remove(ke::AString(key).chars());
} }
void NVault::Clear() void NVault::Clear()
{ {
if (m_Journal) if (m_Journal)
m_Journal->Write_Clear(); m_Journal->Write_Clear();
m_Hash.Clear();
m_Hash.clear();
} }
size_t NVault::Items() size_t NVault::Items()
{ {
return m_Hash.Size(); return m_Hash.elements();
} }
size_t NVault::Prune(time_t start, time_t end) size_t NVault::Prune(time_t start, time_t end)
{ {
if (m_Journal) if (m_Journal)
m_Journal->Write_Prune(start, end); m_Journal->Write_Prune(start, end);
return m_Hash.Prune(start, end);
size_t removed = 0;
for (StringHashMap<ArrayInfo>::iterator iter = m_Hash.iter(); !iter.empty(); iter.next())
{
time_t stamp = iter->value.stamp;
bool remove = false;
if (stamp != 0)
{
if (start == 0 && end == 0)
remove = true;
else if (start == 0 && stamp < end)
remove = true;
else if (end == 0 && stamp > start)
remove = true;
else if (stamp > start && stamp < end)
remove = true;
if (remove)
{
iter.erase();
removed++;
}
}
}
return removed;
} }
void NVault::Touch(const char *key, time_t stamp) void NVault::Touch(const char *key, time_t stamp)
{ {
String sKey(key); StringHashMap<ArrayInfo>::Insert i = m_Hash.findForAdd(key);
if (!i.found())
if (!m_Hash.Exists(sKey))
{ {
SetValue(key, "", time(NULL)); if (!m_Hash.add(i, key))
{
return;
}
ArrayInfo info; info.value = ""; info.stamp = time(NULL);
i->key = key;
i->value = info;
} }
m_Hash.Touch(key, stamp); i->value.stamp = stamp;
} }
bool NVault::GetValue(const char *key, time_t &stamp, char buffer[], size_t len) bool NVault::GetValue(const char *key, time_t &stamp, char buffer[], size_t len)
{ {
String sKey(key); ArrayInfo result;
if (!m_Hash.Exists(sKey))
if (!m_Hash.retrieve(key, &result))
{ {
buffer[0] = '\0'; buffer[0] = '\0';
return false; return false;
} }
time_t st; stamp = result.stamp;
String sVal; UTIL_Format(buffer, len, "%s", result.value.chars());
sVal = m_Hash.Retrieve(sKey, st);
stamp = st;
UTIL_Format(buffer, len, "%s", sVal.c_str());
return true; return true;
} }

View File

@ -14,12 +14,13 @@
#ifndef _INCLUDE_NVAULT_H #ifndef _INCLUDE_NVAULT_H
#define _INCLUDE_NVAULT_H #define _INCLUDE_NVAULT_H
#include "sh_list.h" #include <am-linkedlist.h>
#include "sh_tinyhash.h" #include <sm_stringhashmap.h>
#include "IVault.h" #include "IVault.h"
#include "CString.h"
#include "Journal.h" #include "Journal.h"
using namespace SourceMod;
#define VAULT_MAGIC 0x6E564C54 //nVLT #define VAULT_MAGIC 0x6E564C54 //nVLT
#define VAULT_VERSION 0x0200 //second version #define VAULT_VERSION 0x0200 //second version
@ -61,13 +62,13 @@ public:
bool Open(); bool Open();
bool Close(); bool Close();
size_t Items(); size_t Items();
const char *GetFilename() { return m_File.c_str(); } const char *GetFilename() { return m_File.chars(); }
private: private:
VaultError _ReadFromFile(); VaultError _ReadFromFile();
bool _SaveToFile(); bool _SaveToFile();
private: private:
String m_File; ke::AString m_File;
THash<String, String> m_Hash; StringHashMap<ArrayInfo> m_Hash;
Journal *m_Journal; Journal *m_Journal;
bool m_Open; bool m_Open;

View File

@ -14,7 +14,9 @@
#include <stdlib.h> #include <stdlib.h>
#include "amxxapi.h" #include "amxxapi.h"
#include "NVault.h" #include "NVault.h"
#include "CQueue.h" #include <sm_queue.h>
using namespace SourceMod;
#ifdef WIN32 #ifdef WIN32
#define MKDIR(p) mkdir(p) #define MKDIR(p) mkdir(p)
@ -30,8 +32,8 @@
#include <direct.h> #include <direct.h>
#endif #endif
CVector<NVault *> g_Vaults; ke::Vector<NVault *> g_Vaults;
CQueue<int> g_OldVaults; Queue<int> g_OldVaults;
VaultMngr g_VaultMngr; VaultMngr g_VaultMngr;
@ -48,7 +50,7 @@ static cell nvault_open(AMX *amx, cell *params)
char path[255], file[255]; char path[255], file[255];
MF_BuildPathnameR(path, sizeof(path)-1, "%s/vault", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data")); MF_BuildPathnameR(path, sizeof(path)-1, "%s/vault", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data"));
sprintf(file, "%s/%s.vault", path, name); sprintf(file, "%s/%s.vault", path, name);
for (size_t i=0; i<g_Vaults.size(); i++) for (size_t i=0; i<g_Vaults.length(); i++)
{ {
if (!g_Vaults[i]) if (!g_Vaults[i])
continue; continue;
@ -63,15 +65,15 @@ static cell nvault_open(AMX *amx, cell *params)
} }
if (!g_OldVaults.empty()) if (!g_OldVaults.empty())
{ {
id = g_OldVaults.front(); id = g_OldVaults.first();
g_OldVaults.pop(); g_OldVaults.pop();
} }
if (id != -1) if (id != -1)
{ {
g_Vaults[id] = v; g_Vaults[id] = v;
} else { } else {
g_Vaults.push_back(v); g_Vaults.append(v);
id = (int)g_Vaults.size()-1; id = (int)g_Vaults.length()-1;
} }
return id; return id;
@ -80,7 +82,7 @@ static cell nvault_open(AMX *amx, cell *params)
static cell nvault_touch(AMX *amx, cell *params) static cell nvault_touch(AMX *amx, cell *params)
{ {
unsigned int id = params[1]; unsigned int id = params[1];
if (id >= g_Vaults.size() || !g_Vaults.at(id)) if (id >= g_Vaults.length() || !g_Vaults.at(id))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id);
return 0; return 0;
@ -102,7 +104,7 @@ static cell nvault_touch(AMX *amx, cell *params)
static cell nvault_get(AMX *amx, cell *params) static cell nvault_get(AMX *amx, cell *params)
{ {
unsigned int id = params[1]; unsigned int id = params[1];
if (id >= g_Vaults.size() || !g_Vaults.at(id)) if (id >= g_Vaults.length() || !g_Vaults.at(id))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id);
return 0; return 0;
@ -140,7 +142,7 @@ static cell nvault_get(AMX *amx, cell *params)
static cell nvault_lookup(AMX *amx, cell *params) static cell nvault_lookup(AMX *amx, cell *params)
{ {
unsigned int id = params[1]; unsigned int id = params[1];
if (id >= g_Vaults.size() || !g_Vaults.at(id)) if (id >= g_Vaults.length() || !g_Vaults.at(id))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id);
return 0; return 0;
@ -165,7 +167,7 @@ static cell nvault_lookup(AMX *amx, cell *params)
static cell nvault_set(AMX *amx, cell *params) static cell nvault_set(AMX *amx, cell *params)
{ {
unsigned int id = params[1]; unsigned int id = params[1];
if (id >= g_Vaults.size() || !g_Vaults.at(id)) if (id >= g_Vaults.length() || !g_Vaults.at(id))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id);
return 0; return 0;
@ -183,7 +185,7 @@ static cell nvault_set(AMX *amx, cell *params)
static cell nvault_pset(AMX *amx, cell *params) static cell nvault_pset(AMX *amx, cell *params)
{ {
unsigned int id = params[1]; unsigned int id = params[1];
if (id >= g_Vaults.size() || !g_Vaults.at(id)) if (id >= g_Vaults.length() || !g_Vaults.at(id))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id);
return 0; return 0;
@ -201,7 +203,7 @@ static cell nvault_pset(AMX *amx, cell *params)
static cell nvault_close(AMX *amx, cell *params) static cell nvault_close(AMX *amx, cell *params)
{ {
unsigned int id = params[1]; unsigned int id = params[1];
if (id >= g_Vaults.size() || !g_Vaults.at(id)) if (id >= g_Vaults.length() || !g_Vaults.at(id))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id);
return 0; return 0;
@ -218,7 +220,7 @@ static cell nvault_close(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL nvault_prune(AMX *amx, cell *params) static cell AMX_NATIVE_CALL nvault_prune(AMX *amx, cell *params)
{ {
unsigned int id = params[1]; unsigned int id = params[1];
if (id >= g_Vaults.size() || !g_Vaults.at(id)) if (id >= g_Vaults.length() || !g_Vaults.at(id))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id);
return 0; return 0;
@ -233,7 +235,7 @@ static cell AMX_NATIVE_CALL nvault_prune(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL nvault_remove(AMX *amx, cell *params) static cell AMX_NATIVE_CALL nvault_remove(AMX *amx, cell *params)
{ {
unsigned int id = params[1]; unsigned int id = params[1];
if (id >= g_Vaults.size() || !g_Vaults.at(id)) if (id >= g_Vaults.length() || !g_Vaults.at(id))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid vault id: %d\n", id);
return 0; return 0;
@ -261,7 +263,7 @@ void OnAmxxAttach()
void OnPluginsUnloaded() void OnPluginsUnloaded()
{ {
for (size_t i=0; i<g_Vaults.size(); i++) for (size_t i=0; i<g_Vaults.length(); i++)
{ {
if (g_Vaults[i]) if (g_Vaults[i])
delete g_Vaults[i]; delete g_Vaults[i];

View File

@ -15,9 +15,9 @@
#define _INCLUDE_AMXXAPI_H #define _INCLUDE_AMXXAPI_H
#include "amxxmodule.h" #include "amxxmodule.h"
#include "CVector.h" #include <am-vector.h>
#include "CQueue.h" #include <am-string.h>
#include "CString.h" #include <sm_queue.h>
extern AMX_NATIVE_INFO nVault_natives[]; extern AMX_NATIVE_INFO nVault_natives[];

View File

@ -15,15 +15,23 @@
#define _INCLUDE_COMPAT_H #define _INCLUDE_COMPAT_H
#ifdef WIN32 #ifdef WIN32
typedef __int16 int16_t; #if (_MSC_VER < 1300)
typedef unsigned __int16 uint16_t; typedef signed char int8_t;
typedef __int8 int8_t; typedef signed short int16_t;
typedef unsigned __int8 uint8_t; typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
#else #else
#include <stdint.h>
#include <stdint.h>
#endif #endif
#endif //_INCLUDE_COMPAT_H #endif //_INCLUDE_COMPAT_H

View File

View File

@ -52,8 +52,8 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\;..\sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;NVAULT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;NVAULT_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild> <MinimalRebuild>true</MinimalRebuild>
<ExceptionHandling>Sync</ExceptionHandling> <ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -75,8 +75,8 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\;..\sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;NVAULT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;NVAULT_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StructMemberAlignment>4Bytes</StructMemberAlignment> <StructMemberAlignment>4Bytes</StructMemberAlignment>
<RuntimeTypeInfo>false</RuntimeTypeInfo> <RuntimeTypeInfo>false</RuntimeTypeInfo>
@ -99,7 +99,7 @@
<ClCompile Include="..\Binary.cpp" /> <ClCompile Include="..\Binary.cpp" />
<ClCompile Include="..\Journal.cpp" /> <ClCompile Include="..\Journal.cpp" />
<ClCompile Include="..\NVault.cpp" /> <ClCompile Include="..\NVault.cpp" />
<ClCompile Include="..\sdk\amxxmodule.cpp" /> <ClCompile Include="..\..\..\public\sdk\amxxmodule.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\amxxapi.h" /> <ClInclude Include="..\amxxapi.h" />
@ -108,14 +108,8 @@
<ClInclude Include="..\IVault.h" /> <ClInclude Include="..\IVault.h" />
<ClInclude Include="..\Journal.h" /> <ClInclude Include="..\Journal.h" />
<ClInclude Include="..\NVault.h" /> <ClInclude Include="..\NVault.h" />
<ClInclude Include="..\svn_version.h" /> <ClInclude Include="..\moduleconfig.h" />
<ClInclude Include="..\sdk\moduleconfig.h" /> <ClInclude Include="..\..\..\public\sdk\amxxmodule.h" />
<ClInclude Include="..\sdk\CQueue.h" />
<ClInclude Include="..\sdk\CString.h" />
<ClInclude Include="..\sdk\CVector.h" />
<ClInclude Include="..\sdk\sh_list.h" />
<ClInclude Include="..\sdk\sh_tinyhash.h" />
<ClInclude Include="..\sdk\amxxmodule.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\..\plugins\include\nvault.inc" /> <None Include="..\..\..\plugins\include\nvault.inc" />

View File

@ -12,9 +12,6 @@
<Filter Include="Module SDK"> <Filter Include="Module SDK">
<UniqueIdentifier>{3ba100b1-c511-4a2b-bd4f-d4793e871082}</UniqueIdentifier> <UniqueIdentifier>{3ba100b1-c511-4a2b-bd4f-d4793e871082}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Module SDK\AMXX STL">
<UniqueIdentifier>{aa2aa172-b8f1-4e12-a51b-c3892e2d1f9c}</UniqueIdentifier>
</Filter>
<Filter Include="Module SDK\SDK Base"> <Filter Include="Module SDK\SDK Base">
<UniqueIdentifier>{300ce24d-2a06-4b65-8c00-8b0f757656ec}</UniqueIdentifier> <UniqueIdentifier>{300ce24d-2a06-4b65-8c00-8b0f757656ec}</UniqueIdentifier>
</Filter> </Filter>
@ -35,7 +32,7 @@
<ClCompile Include="..\NVault.cpp"> <ClCompile Include="..\NVault.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\sdk\amxxmodule.cpp"> <ClCompile Include="..\..\..\public\sdk\amxxmodule.cpp">
<Filter>Module SDK\SDK Base</Filter> <Filter>Module SDK\SDK Base</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
@ -58,30 +55,12 @@
<ClInclude Include="..\NVault.h"> <ClInclude Include="..\NVault.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\svn_version.h"> <ClInclude Include="..\..\..\public\sdk\amxxmodule.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sdk\moduleconfig.h">
<Filter>Module SDK</Filter>
</ClInclude>
<ClInclude Include="..\sdk\CQueue.h">
<Filter>Module SDK\AMXX STL</Filter>
</ClInclude>
<ClInclude Include="..\sdk\CString.h">
<Filter>Module SDK\AMXX STL</Filter>
</ClInclude>
<ClInclude Include="..\sdk\CVector.h">
<Filter>Module SDK\AMXX STL</Filter>
</ClInclude>
<ClInclude Include="..\sdk\sh_list.h">
<Filter>Module SDK\AMXX STL</Filter>
</ClInclude>
<ClInclude Include="..\sdk\sh_tinyhash.h">
<Filter>Module SDK\AMXX STL</Filter>
</ClInclude>
<ClInclude Include="..\sdk\amxxmodule.h">
<Filter>Module SDK\SDK Base</Filter> <Filter>Module SDK\SDK Base</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\moduleconfig.h">
<Filter>Module SDK</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\..\plugins\include\nvault.inc"> <None Include="..\..\..\plugins\include\nvault.inc">

View File

@ -1,104 +0,0 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//by David "BAILOPAN" Anderson
#ifndef _INCLUDE_CQUEUE_H
#define _INCLUDE_CQUEUE_H
template <class T>
class CQueue
{
public:
class CQueueItem
{
public:
CQueueItem(const T &i, CQueueItem *n)
{
item = i;
next = n;
}
CQueueItem *GetNext()
{
return next;
}
T & GetItem()
{
return item;
}
void SetNext(CQueueItem *n)
{
next = n;
}
private:
T item;
CQueueItem *next;
};
public:
CQueue()
{
mSize = 0;
mFirst = NULL;
mLast = NULL;
}
bool empty()
{
return ((mSize==0)?true:false);
}
void push(const T &v)
{
CQueueItem *p = new CQueueItem(v, NULL);
if (empty())
{
mFirst = p;
} else {
mLast->SetNext(p);
}
mLast = p;
mSize++;
}
void pop()
{
if (mFirst == mLast)
{
delete mFirst;
mFirst = NULL;
mLast = NULL;
} else {
CQueueItem *p = mFirst->GetNext();
delete mFirst;
mFirst = p;
}
mSize--;
}
T & front()
{
return mFirst->GetItem();
}
T & back()
{
return mLast->GetItem();
}
unsigned int size()
{
return mSize;
}
private:
CQueueItem *mFirst;
CQueueItem *mLast;
unsigned int mSize;
};
#endif //_INCLUDE_CQUEUE_H

View File

@ -1,367 +0,0 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#ifndef _INCLUDE_CSTRING_H
#define _INCLUDE_CSTRING_H
#include <string.h>
#include <stdio.h>
//by David "BAILOPAN" Anderson
class String
{
public:
String()
{
v = NULL;
a_size = 0;
//assign("");
}
~String()
{
if (v)
delete [] v;
}
String(const char *src)
{
v = NULL;
a_size = 0;
assign(src);
}
const char * _fread(FILE *fp)
{
Grow(512, false);
char *ret = fgets(v, 511, fp);
return ret;
}
String(const String &src)
{
v = NULL;
a_size = 0;
assign(src.c_str());
}
const char *c_str() { return v?v:""; }
const char *c_str() const { return v?v:""; }
void append(const char *t)
{
Grow(size() + strlen(t) + 1);
strcat(v, t);
}
void append(const char c)
{
size_t len = size();
Grow(len + 2);
v[len] = c;
v[len + 1] = '\0';
}
void append(String &d)
{
append(d.c_str());
}
void assign(const String &src)
{
assign(src.c_str());
}
void assign(const char *d)
{
if (!d)
{
clear();
} else {
size_t len = strlen(d);
Grow(len + 1, false);
memcpy(v, d, len);
v[len] = '\0';
}
}
void clear()
{
if (v)
v[0] = '\0';
}
int compare (const char *d) const
{
if (!v)
return strcmp("", d);
else
return strcmp(v, d);
}
//Added this for amxx inclusion
bool empty()
{
if (!v)
return true;
if (v[0] == '\0')
return true;
return false;
}
size_t size()
{
if (v)
return strlen(v);
else
return 0;
}
int find(const char c, int index = 0)
{
int len = static_cast<int>(size());
if (len < 1)
return npos;
if (index >= len || index < 0)
return npos;
int i = 0;
for (i=index; i<len; i++)
{
if (v[i] == c)
{
return i;
}
}
return npos;
}
bool is_space(int c)
{
if (c == '\f' || c == '\n' ||
c == '\t' || c == '\r' ||
c == '\v' || c == ' ')
{
return true;
}
return false;
}
void trim()
{
if (!v)
return;
unsigned int i = 0;
unsigned int j = 0;
size_t len = strlen(v);
if (len == 1)
{
if (is_space(v[i]))
{
clear();
return;
}
}
unsigned char c0 = v[0];
if (is_space(c0))
{
for (i=0; i<len; i++)
{
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
{
erase(0, i);
break;
}
}
}
len = strlen(v);
if (len < 1)
{
return;
}
if (is_space(v[len-1]))
{
for (i=len-1; i<len; i--)
{
if (!is_space(v[i])
|| (is_space(v[i]) && i==0))
{
erase(i+1, j);
break;
}
j++;
}
}
if (len == 1)
{
if (is_space(v[0]))
{
clear();
return;
}
}
}
void erase(unsigned int start, int num = npos)
{
if (!v)
return;
unsigned int i = 0;
size_t len = size();
//check for bounds
if (num == npos || start+num > len-start)
num = len - start;
//do the erasing
bool copyflag = false;
for (i=0; i<len; i++)
{
if (i>=start && i<start+num)
{
if (i+num < len)
{
v[i] = v[i+num];
} else {
v[i] = 0;
}
copyflag = true;
} else if (copyflag) {
if (i+num < len)
{
v[i] = v[i+num];
} else {
v[i] = 0;
}
}
}
len -= num;
v[len] = 0;
}
String substr(unsigned int index, int num = npos)
{
if (!v)
{
String b("");
return b;
}
String ns;
size_t len = size();
if (index >= len || !v)
return ns;
if (num == npos)
{
num = len - index;
} else if (index+num >= len) {
num = len - index;
}
unsigned int i = 0;
unsigned int nslen = num + 2;
ns.Grow(nslen);
for (i=index; i<index+num; i++)
ns.append(v[i]);
return ns;
}
void toLower()
{
if (!v)
return;
unsigned int i = 0;
size_t len = strlen(v);
for (i=0; i<len; i++)
{
if (v[i] >= 65 && v[i] <= 90)
v[i] &= ~(1<<5);
}
}
String & operator = (const String &src)
{
assign(src);
return *this;
}
String & operator = (const char *src)
{
assign(src);
return *this;
}
char operator [] (unsigned int index)
{
if (index > size() || !v)
{
return -1;
} else {
return v[index];
}
}
int at(int a)
{
if (a < 0 || a >= (int)size() || !v)
return -1;
return v[a];
}
bool at(int at, char c)
{
if (at < 0 || at >= (int)size() || !v)
return false;
v[at] = c;
return true;
}
private:
void Grow(unsigned int d, bool copy=true)
{
if (d <= a_size)
return;
char *n = new char[d + 1];
if (copy && v)
strcpy(n, v);
if (v)
delete [] v;
else
strcpy(n, "");
v = n;
a_size = d + 1;
}
char *v;
unsigned int a_size;
public:
static const int npos = -1;
};
#endif //_INCLUDE_CSTRING_H

View File

@ -1,480 +0,0 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#ifndef __CVECTOR_H__
#define __CVECTOR_H__
#include <assert.h>
// Vector
template <class T> class CVector
{
bool Grow(size_t amount)
{
// automatic grow
size_t newSize = m_Size * 2;
if (newSize == 0)
{
newSize = 8;
}
while (m_CurrentUsedSize + amount > newSize)
{
newSize *= 2;
}
T *newData = new T[newSize];
if (!newData)
return false;
if (m_Data)
{
for (size_t i=0; i<m_CurrentUsedSize; i++)
newData[i] = m_Data[i];
delete [] m_Data;
}
m_Data = newData;
m_Size = newSize;
return true;
}
bool GrowIfNeeded(size_t amount)
{
if (m_CurrentUsedSize + amount >= m_Size)
{
return Grow(amount);
}
else
{
return true;
}
}
bool ChangeSize(size_t size)
{
// change size
if (size == m_Size)
return true;
if (!size)
{
if (m_Data)
{
delete [] m_Data;
m_Data = NULL;
m_Size = 0;
}
return true;
}
T *newData = new T[size];
if (!newData)
return false;
if (m_Data)
{
size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size;
for (size_t i=0; i<end; i++)
newData[i] = m_Data[i];
delete [] m_Data;
}
m_Data = newData;
m_Size = size;
if (m_CurrentUsedSize > m_Size)
m_CurrentUsedSize = m_Size;
return true;
}
void FreeMemIfPossible()
{
if (!m_Data)
return;
if (!m_CurrentUsedSize)
{
ChangeSize(0);
return;
}
size_t newSize = m_Size;
while (m_CurrentUsedSize <= newSize / 2)
newSize /= 2;
if (newSize != m_Size)
ChangeSize(newSize);
}
protected:
T *m_Data;
size_t m_Size;
size_t m_CurrentUsedSize;
public:
class iterator
{
protected:
T *m_Ptr;
public:
// constructors / destructors
iterator()
{
m_Ptr = NULL;
}
iterator(T * ptr)
{
m_Ptr = ptr;
}
// member functions
T * base()
{
return m_Ptr;
}
const T * base() const
{
return m_Ptr;
}
// operators
T & operator*()
{
return *m_Ptr;
}
T * operator->()
{
return m_Ptr;
}
iterator & operator++() // preincrement
{
++m_Ptr;
return (*this);
}
iterator operator++(int) // postincrement
{
iterator tmp = *this;
++m_Ptr;
return tmp;
}
iterator & operator--() // predecrement
{
--m_Ptr;
return (*this);
}
iterator operator--(int) // postdecrememnt
{
iterator tmp = *this;
--m_Ptr;
return tmp;
}
bool operator==(T * right) const
{
return (m_Ptr == right);
}
bool operator==(const iterator & right) const
{
return (m_Ptr == right.m_Ptr);
}
bool operator!=(T * right) const
{
return (m_Ptr != right);
}
bool operator!=(const iterator & right) const
{
return (m_Ptr != right.m_Ptr);
}
iterator & operator+=(size_t offset)
{
m_Ptr += offset;
return (*this);
}
iterator & operator-=(size_t offset)
{
m_Ptr -= offset;
return (*this);
}
iterator operator+(size_t offset) const
{
iterator tmp(*this);
tmp.m_Ptr += offset;
return tmp;
}
iterator operator-(size_t offset) const
{
iterator tmp(*this);
tmp.m_Ptr -= offset;
return tmp;
}
T & operator[](size_t offset)
{
return (*(*this + offset));
}
const T & operator[](size_t offset) const
{
return (*(*this + offset));
}
bool operator<(const iterator & right) const
{
return m_Ptr < right.m_Ptr;
}
bool operator>(const iterator & right) const
{
return m_Ptr > right.m_Ptr;
}
bool operator<=(const iterator & right) const
{
return m_Ptr <= right.m_Ptr;
}
bool operator>=(const iterator & right) const
{
return m_Ptr >= right.m_Ptr;
}
size_t operator-(const iterator & right) const
{
return m_Ptr - right.m_Ptr;
}
};
// constructors / destructors
CVector<T>()
{
m_Size = 0;
m_CurrentUsedSize = 0;
m_Data = NULL;
}
CVector<T>(const CVector<T> & other)
{
// copy data
m_Data = new T [other.m_CurrentUsedSize];
m_Size = other.m_CurrentUsedSize;
m_CurrentUsedSize = other.m_CurrentUsedSize;
for (size_t i=0; i<other.m_CurrentUsedSize; i++)
m_Data[i] = other.m_Data[i];
}
~CVector<T>()
{
clear();
}
// interface
size_t size() const
{
return m_CurrentUsedSize;
}
size_t capacity() const
{
return m_Size;
}
iterator begin() const
{
return iterator(m_Data);
}
iterator end() const
{
return iterator(m_Data + m_CurrentUsedSize);
}
iterator iterAt(size_t pos)
{
if (pos > m_CurrentUsedSize)
assert(0);
return iterator(m_Data + pos);
}
bool reserve(size_t newSize)
{
if (newSize > m_Size)
return ChangeSize(newSize);
return true;
}
bool push_back(const T & elem)
{
if (!GrowIfNeeded(1))
{
return false;
}
m_Data[m_CurrentUsedSize++] = elem;
return true;
}
void pop_back()
{
--m_CurrentUsedSize;
if (m_CurrentUsedSize < 0)
m_CurrentUsedSize = 0;
FreeMemIfPossible();
}
bool resize(size_t newSize)
{
if (!ChangeSize(newSize))
return false;
m_CurrentUsedSize = newSize;
return true;
}
bool empty() const
{
return (m_CurrentUsedSize == 0);
}
T & at(size_t pos)
{
if (pos > m_CurrentUsedSize)
{
assert(0);
}
return m_Data[pos];
}
const T & at(size_t pos) const
{
if (pos > m_CurrentUsedSize)
{
assert(0);
}
return m_Data[pos];
}
T & operator[](size_t pos)
{
return at(pos);
}
const T & operator[](size_t pos) const
{
return at(pos);
}
T & front()
{
if (m_CurrentUsedSize < 1)
{
assert(0);
}
return m_Data[0];
}
const T & front() const
{
if (m_CurrentUsedSize < 1)
{
assert(0);
}
return m_Data[0];
}
T & back()
{
if (m_CurrentUsedSize < 1)
{
assert(0);
}
return m_Data[m_CurrentUsedSize - 1];
}
const T & back() const
{
if (m_CurrentUsedSize < 1)
{
assert(0);
}
return m_Data[m_CurrentUsedSize - 1];
}
iterator insert(iterator where, const T & value)
{
// validate iter
if (where < m_Data || where > (m_Data + m_CurrentUsedSize))
return iterator(0);
size_t ofs = where - begin();
if (!GrowIfNeeded(1))
{
return false;
}
++m_CurrentUsedSize;
where = begin() + ofs;
// Move subsequent entries
for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr)
*(ptr + 1) = *ptr;
*where.base() = value;
return where;
}
iterator erase(iterator where)
{
// validate iter
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
return iterator(0);
size_t ofs = where - begin();
if (m_CurrentUsedSize > 1)
{
// move
T *theend = m_Data + m_CurrentUsedSize;
for (T *ptr = where.base() + 1; ptr < theend; ++ptr)
*(ptr - 1) = *ptr;
}
--m_CurrentUsedSize;
FreeMemIfPossible();
return begin() + ofs;
}
void clear()
{
m_Size = 0;
m_CurrentUsedSize = 0;
if (m_Data)
{
delete [] m_Data;
m_Data = NULL;
}
}
};
#endif // __CVECTOR_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,297 +0,0 @@
/* ======== SourceMM ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): David "BAILOPAN" Anderson
* ============================
*/
#ifndef _INCLUDE_SMM_LIST_H
#define _INCLUDE_SMM_LIST_H
// MSVC8 fix for offsetof macro redefition warnings
#ifdef _MSC_VER
#if _MSC_VER >= 1400
#undef offsetof
#endif
#endif
#include <new>
#include <stdlib.h>
//namespace SourceHook
//{
//This class is from CSDM for AMX Mod X
/*
A circular, doubly-linked list with one sentinel node
Empty:
m_Head = sentinel
m_Head->next = m_Head;
m_Head->prev = m_Head;
One element:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node1
node1->next = m_Head
node1->prev = m_Head
Two elements:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node2
node1->next = node2
node1->prev = m_Head
node2->next = m_Head
node2->prev = node1
*/
template <class T>
class List
{
public:
class iterator;
friend class iterator;
class ListNode
{
public:
ListNode(const T & o) : obj(o) { };
ListNode() { };
T obj;
ListNode *next;
ListNode *prev;
};
private:
// Initializes the sentinel node.
// BAIL used malloc instead of new in order to bypass the need for a constructor.
ListNode *_Initialize()
{
ListNode *n = (ListNode *)malloc(sizeof(ListNode));
n->next = n;
n->prev = n;
return n;
}
public:
List() : m_Head(_Initialize()), m_Size(0)
{
}
List(const List &src) : m_Head(_Initialize()), m_Size(0)
{
iterator iter;
for (iter=src.begin(); iter!=src.end(); iter++)
push_back( (*iter) );
}
~List()
{
clear();
// Don't forget to free the sentinel
if (m_Head)
{
free(m_Head);
m_Head = NULL;
}
}
void push_back(const T &obj)
{
ListNode *node = new ListNode(obj);
node->prev = m_Head->prev;
node->next = m_Head;
m_Head->prev->next = node;
m_Head->prev = node;
m_Size++;
}
size_t size()
{
return m_Size;
}
void clear()
{
ListNode *node = m_Head->next;
ListNode *temp;
m_Head->next = m_Head;
m_Head->prev = m_Head;
// Iterate through the nodes until we find g_Head (the sentinel) again
while (node != m_Head)
{
temp = node->next;
delete node;
node = temp;
}
m_Size = 0;
}
bool empty()
{
return (m_Size == 0);
}
T & back()
{
return m_Head->prev->obj;
}
private:
ListNode *m_Head;
size_t m_Size;
public:
class iterator
{
friend class List;
public:
iterator()
{
m_This = NULL;
}
iterator(const List &src)
{
m_This = src.m_Head;
}
iterator(ListNode *n) : m_This(n)
{
}
iterator(const iterator &where)
{
m_This = where.m_This;
}
//pre decrement
iterator & operator--()
{
if (m_This)
m_This = m_This->prev;
return *this;
}
//post decrement
iterator operator--(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->prev;
return old;
}
//pre increment
iterator & operator++()
{
if (m_This)
m_This = m_This->next;
return *this;
}
//post increment
iterator operator++(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->next;
return old;
}
const T & operator * () const
{
return m_This->obj;
}
T & operator * ()
{
return m_This->obj;
}
T * operator -> ()
{
return &(m_This->obj);
}
const T * operator -> () const
{
return &(m_This->obj);
}
bool operator != (const iterator &where) const
{
return (m_This != where.m_This);
}
bool operator ==(const iterator &where) const
{
return (m_This == where.m_This);
}
private:
ListNode *m_This;
};
public:
iterator begin() const
{
return iterator(m_Head->next);
}
iterator end() const
{
return iterator(m_Head);
}
iterator erase(iterator &where)
{
ListNode *pNode = where.m_This;
iterator iter(where);
iter++;
// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
pNode->prev->next = pNode->next;
pNode->next->prev = pNode->prev;
delete pNode;
m_Size--;
return iter;
}
iterator insert(iterator where, const T &obj)
{
// Insert obj right before where
ListNode *node = new ListNode(obj);
ListNode *pWhereNode = where.m_This;
pWhereNode->prev->next = node;
node->prev = pWhereNode->prev;
pWhereNode->prev = node;
node->next = pWhereNode;
m_Size++;
return iterator(node);
}
public:
void remove(const T & obj)
{
iterator b;
for (b=begin(); b!=end(); b++)
{
if ( (*b) == obj )
{
erase( b );
break;
}
}
}
template <typename U>
iterator find(const U & equ)
{
iterator iter;
for (iter=begin(); iter!=end(); iter++)
{
if ( (*iter) == equ )
return iter;
}
return end();
}
List & operator =(const List &src)
{
clear();
iterator iter;
for (iter=src.begin(); iter!=src.end(); iter++)
push_back( (*iter) );
return *this;
}
};
//}; //NAMESPACE
#endif //_INCLUDE_CSDM_LIST_H

View File

@ -1,582 +0,0 @@
/* ======== SourceMM ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): David "BAILOPAN" Anderson
* ============================
*/
#ifndef _INCLUDE_SH_TINYHASH_H_
#define _INCLUDE_SH_TINYHASH_H_
#include <time.h>
#include "sh_list.h"
#define _T_INIT_HASH_SIZE 32
//namespace SourceHook
//{
template <class K>
int HashFunction(const K & k);
template <class K>
int Compare(const K & k1, const K & k2);
/**
* This is a tiny, growable hash class.
* Meant for quick and dirty dictionaries only!
*/
template <class K, class V>
class THash
{
public:
struct THashNode
{
THashNode(const K & k, const V & v) :
key(k), val(v)
{
};
THashNode & operator =(const THashNode &other)
{
key = other.key;
val = other.val;
}
K key;
V val;
time_t stamp;
};
typedef List<THashNode *> * NodePtr;
public:
class const_iterator;
THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f), m_Items(0)
{
_Refactor();
}
THash(const THash &other) : m_Buckets(new NodePtr[other.numBuckets]),
m_numBuckets(other.m_numBuckets),
m_percentUsed(other.m_percentUsed)
{
for (size_t i=0; i<m_numBuckets; i++)
m_Buckets[i] = NULL;
for (const_iterator iter=other.begin(); iter != other.end(); ++iter)
_FindOrInsert(iter->key)->val = iter->val;
}
void operator=(const THash &other)
{
Clear();
for (const_iterator iter=other.begin(); iter!=other.end(); ++iter)
_FindOrInsert(iter->key)->val = iter->val;
}
~THash()
{
_Clear();
}
void Clear()
{
_Clear();
_Refactor();
}
void Insert(const K & key, const V & val)
{
Insert(key, val, time(NULL));
}
void Insert(const K & key, const V & val, time_t stamp)
{
THashNode *pNode = _FindOrInsert(key);
pNode->val = val;
pNode->stamp = stamp;
}
bool Exists(const K & key)
{
size_t place = HashFunction(key) % m_numBuckets;
if (!m_Buckets[place])
return false;
typename List<THashNode *>::iterator iter;
for (iter = m_Buckets[place]->begin(); iter != m_Buckets[place]->end(); iter++)
{
if (Compare(key, (*iter)->key) == 0)
return true;
}
return false;
}
V & Retrieve(const K & k, time_t & stamp)
{
THashNode *pNode = _FindOrInsert(k);
stamp = pNode->stamp;
return pNode->val;
}
void Touch(const K & k, time_t stamp)
{
THashNode *pNode = _FindOrInsert(k);
pNode->stamp = stamp;
}
V & Retrieve(const K & k)
{
time_t stamp;
return Retrieve(k, stamp);
}
void Remove(const K & key)
{
size_t place = HashFunction(key) % m_numBuckets;
if (!m_Buckets[place])
return;
typename List<THashNode *>::iterator iter;
for (iter = m_Buckets[place]->begin(); iter != m_Buckets[place]->end(); iter++)
{
if (Compare(key, (*iter)->key) == 0)
{
iter = m_Buckets[place]->erase(iter);
m_Items--;
return;
}
}
}
size_t Prune(time_t start=0, time_t end=0)
{
typename List<THashNode *>::iterator iter;
time_t stamp;
size_t removed = 0;
for (size_t i=0; i<m_numBuckets; i++)
{
if (!m_Buckets[i])
continue;
iter = m_Buckets[i]->begin();
bool remove;
while (iter != m_Buckets[i]->end())
{
stamp = (*iter)->stamp;
remove = false;
if (stamp != 0)
{
if (start == 0 && end == 0)
remove = true;
else if (start == 0 && stamp < end)
remove = true;
else if (end == 0 && stamp > start)
remove = true;
else if (stamp > start && stamp < end)
remove = true;
if (remove)
{
iter = m_Buckets[i]->erase(iter);
removed++;
} else {
iter++;
}
} else {
iter++;
}
}
}
m_Items -= removed;
return removed;
}
size_t Size()
{
return m_Items;
}
size_t GetBuckets()
{
return m_numBuckets;
}
float PercentUsed()
{
return m_percentUsed;
}
V & operator [](const K & key)
{
THashNode *pNode = _FindOrInsert(key);
return pNode->val;
}
private:
void _Clear()
{
typename List<THashNode *>::iterator iter, end;
for (size_t i=0; i<m_numBuckets; i++)
{
if (m_Buckets[i])
{
end = m_Buckets[i]->end();
iter = m_Buckets[i]->begin();
while (iter != end)
{
delete (*iter);
iter++;
}
m_Buckets[i]->clear();
delete m_Buckets[i];
}
}
if (m_Buckets)
delete [] m_Buckets;
m_numBuckets = 0;
m_Items = 0;
m_Buckets = NULL;
}
THashNode *_FindOrInsert(const K & key)
{
size_t place = HashFunction(key) % m_numBuckets;
THashNode *pNode = NULL;
if (!m_Buckets[place])
{
m_Buckets[place] = new List<THashNode *>;
pNode = new THashNode(key, V());
m_Buckets[place]->push_back(pNode);
m_percentUsed += (1.0f / (float)m_numBuckets);
m_Items++;
} else {
typename List<THashNode *>::iterator iter;
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
{
if (Compare((*iter)->key, key) == 0)
return (*iter);
}
//node does not exist
pNode = new THashNode(key, V());
m_Buckets[place]->push_back(pNode);
m_Items++;
}
if (PercentUsed() > 0.75f)
_Refactor();
return pNode;
}
void _Refactor()
{
m_percentUsed = 0.0f;
if (!m_numBuckets)
{
m_numBuckets = _T_INIT_HASH_SIZE;
m_Buckets = new NodePtr[m_numBuckets];
for (size_t i=0; i<m_numBuckets; i++)
m_Buckets[i] = NULL;
} else {
size_t oldSize = m_numBuckets;
m_numBuckets *= 2;
typename List<THashNode *>::iterator iter;
size_t place;
THashNode *pHashNode;
NodePtr *temp = new NodePtr[m_numBuckets];
for (size_t i=0; i<m_numBuckets; i++)
temp[i] = NULL;
//look in old hash table
for (size_t i=0; i<oldSize; i++)
{
//does a bucket have anything?
if (m_Buckets[i])
{
//go through the list of items
for (iter = m_Buckets[i]->begin(); iter != m_Buckets[i]->end(); iter++)
{
pHashNode = (*iter);
//rehash it with the new bucket filter
place = HashFunction(pHashNode->key) % m_numBuckets;
//add it to the new hash table
if (!temp[place])
{
temp[place] = new List<THashNode *>;
m_percentUsed += (1.0f / (float)m_numBuckets);
}
temp[place]->push_back(pHashNode);
}
//delete that bucket!
delete m_Buckets[i];
m_Buckets[i] = NULL;
}
}
//reassign bucket table
delete [] m_Buckets;
m_Buckets = temp;
}
}
public:
friend class iterator;
friend class const_iterator;
class iterator
{
friend class THash;
public:
iterator() : curbucket(-1), hash(NULL), end(true)
{
};
iterator(THash *h) : curbucket(-1), hash(h), end(false)
{
if (!h->m_Buckets)
end = true;
else
_Inc();
};
//pre increment
iterator & operator++()
{
_Inc();
return *this;
}
//post increment
iterator operator++(int)
{
iterator old(*this);
_Inc();
return old;
}
const THashNode & operator * () const
{
return *(*iter);
}
THashNode & operator * ()
{
return *(*iter);
}
const THashNode * operator ->() const
{
return (*iter);
}
THashNode * operator ->()
{
return (*iter);
}
bool operator ==(const iterator &where) const
{
if (where.hash == this->hash
&& where.end == this->end
&&
(this->end ||
((where.curbucket == this->curbucket)
&& (where.iter == iter))
))
return true;
return false;
}
bool operator !=(const iterator &where) const
{
return !( (*this) == where );
}
private:
void _Inc()
{
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
return;
if (curbucket < 0)
{
for (int i=0; i<(int)hash->m_numBuckets; i++)
{
if (hash->m_Buckets[i])
{
iter = hash->m_Buckets[i]->begin();
if (iter == hash->m_Buckets[i]->end())
continue;
curbucket = i;
break;
}
}
if (curbucket < 0)
end = true;
} else {
if (iter != hash->m_Buckets[curbucket]->end())
iter++;
if (iter == hash->m_Buckets[curbucket]->end())
{
int oldbucket = curbucket;
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
{
if (hash->m_Buckets[i])
{
iter = hash->m_Buckets[i]->begin();
if (iter == hash->m_Buckets[i]->end())
continue;
curbucket = i;
break;
}
}
if (curbucket == oldbucket)
end = true;
}
}
}
private:
int curbucket;
typename List<THashNode *>::iterator iter;
THash *hash;
bool end;
};
class const_iterator
{
friend class THash;
public:
const_iterator() : curbucket(-1), hash(NULL), end(true)
{
};
const_iterator(const THash *h) : curbucket(-1), hash(h), end(true)
{
if (!h->m_Buckets)
end = true;
else
_Inc();
};
const_iterator & operator++()
{
_Inc();
return *this;
}
const_iterator operator++(int)
{
iterator old(*this);
_Inc();
return old;
}
void erase()
{
if (end || !hash || curbucket < 0 || curbucket >= static_cast<int>(hash->m_numBuckets))
return;
iterator tmp = *this;
++tmp;
delete (*iter);
hash->m_Items--;
hash->m_Buckets[curbucket]->erase(iter);
*this = tmp;
}
const THashNode & operator *() const
{
return *(*iter);
}
const THashNode * operator ->() const
{
return (*iter);
}
bool operator ==(const const_iterator &where) const
{
if (where.hash == this->hash
&& where.end == this->end
&&
(this->end ||
((where.curbucket == this->curbucket)
&& (where.iter == iter))
))
return true;
return false;
}
bool operator !=(const const_iterator &where) const
{
return !((*this)==where);
}
private:
void _Inc()
{
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
return;
if (curbucket < 0)
{
for (int i=0; i<(int)hash->m_numBuckets; i++)
{
if (hash->m_Buckets[i])
{
iter = hash->m_Buckets[i]->begin();
if (iter == hash->m_Buckets[i]->end())
continue;
curbucket = i;
break;
}
}
if (curbucket < 0)
end = true;
} else {
if (iter != hash->m_Buckets[curbucket]->end())
iter++;
if (iter == hash->m_Buckets[curbucket]->end())
{
int oldbucket = curbucket;
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
{
if (hash->m_Buckets[i])
{
iter = hash->m_Buckets[i]->begin();
if (iter == hash->m_Buckets[i]->end())
continue;
curbucket = i;
break;
}
}
if (curbucket == oldbucket)
end = true;
}
}
}
private:
int curbucket;
typename List<THashNode *>::iterator iter;
const THash *hash;
bool end;
};
public:
iterator begin()
{
return iterator(this);
}
iterator end()
{
iterator iter;
iter.hash = this;
return iter;
}
const_iterator begin() const
{
return const_iterator(this);
}
const_iterator end() const
{
const_iterator iter;
iter.hash = this;
return iter;
}
iterator erase(iterator where)
{
where.erase();
return where;
}
template <typename U>
void erase(const U & u)
{
iterator iter = find(u);
if (iter == end())
return;
iter.erase();
}
template <typename U>
iterator find(const U & u) const
{
iterator b = begin();
iterator e = end();
for (iterator iter = b; iter != e; iter++)
{
if ( (*iter).key == u )
return iter;
}
return end();
}
template <typename U>
iterator find(const U & u)
{
iterator b = begin();
iterator e = end();
for (iterator iter = b; iter != e; iter++)
{
if ( (*iter).key == u )
return iter;
}
return end();
}
private:
NodePtr *m_Buckets;
size_t m_numBuckets;
float m_percentUsed;
size_t m_Items;
};
//};
#endif //_INCLUDE_SH_TINYHASH_H_

View File

@ -21,8 +21,8 @@
#include <new> #include <new>
#include <stdlib.h> #include <stdlib.h>
namespace SourceHook //namespace SourceHook
{ //{
//This class is from CSDM for AMX Mod X //This class is from CSDM for AMX Mod X
/* /*
@ -293,6 +293,6 @@ namespace SourceHook
return *this; return *this;
} }
}; };
}; //NAMESPACE //}; //NAMESPACE
#endif //_INCLUDE_CSDM_LIST_H #endif //_INCLUDE_CSDM_LIST_H

View File

@ -19,8 +19,8 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
namespace SourceHook //namespace SourceHook
{ //{
class String class String
{ {
public: public:
@ -362,6 +362,6 @@ public:
static const int npos = -1; static const int npos = -1;
}; };
}; //NAMESPACE //}; //NAMESPACE
#endif //_INCLUDE_CSTRING_H #endif //_INCLUDE_CSTRING_H

333
public/sm_queue.h Normal file
View File

@ -0,0 +1,333 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SM_QUEUE_H
#define _INCLUDE_SM_QUEUE_H
#include <new>
#include <stdlib.h>
#include <sh_stack.h>
//using namespace SourceHook;
/*
A circular, doubly-linked List with one sentinel node
Empty:
m_Head = sentinel
m_Head->next = m_Head;
m_Head->prev = m_Head;
One element:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node1
node1->next = m_Head
node1->prev = m_Head
Two elements:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node2
node1->next = node2
node1->prev = m_Head
node2->next = m_Head
node2->prev = node1
*/
template <class T>
class Queue
{
public:
class iterator;
friend class iterator;
class QueueNode
{
public:
T obj;
QueueNode *next;
QueueNode *prev;
};
private:
// Initializes the sentinel node.
QueueNode *_Initialize()
{
QueueNode *n = (QueueNode *)malloc(sizeof(QueueNode));
n->next = n;
n->prev = n;
return n;
}
public:
Queue() : m_Head(_Initialize()), m_Size(0)
{
}
Queue(const Queue &src) : m_Head(_Initialize()), m_Size(0)
{
iterator iter;
for (iter=src.begin(); iter!=src.end(); iter++)
{
push_back( (*iter) );
}
}
~Queue()
{
clear();
// Don't forget to free the sentinel
if (m_Head)
{
free(m_Head);
m_Head = NULL;
}
while (!m_FreeNodes.empty())
{
free(m_FreeNodes.front());
m_FreeNodes.pop();
}
}
void push(const T &obj)
{
QueueNode *node;
if (m_FreeNodes.empty())
{
node = (QueueNode *)malloc(sizeof(QueueNode));
} else {
node = m_FreeNodes.front();
m_FreeNodes.pop();
}
/* Copy the object */
new (&node->obj) T(obj);
/* Install into the Queue */
node->prev = m_Head->prev;
node->next = m_Head;
m_Head->prev->next = node;
m_Head->prev = node;
m_Size++;
}
size_t size() const
{
return m_Size;
}
void clear()
{
QueueNode *node = m_Head->next;
QueueNode *temp;
m_Head->next = m_Head;
m_Head->prev = m_Head;
// Iterate through the nodes until we find g_Head (the sentinel) again
while (node != m_Head)
{
temp = node->next;
node->obj.~T();
m_FreeNodes.push(node);
node = temp;
}
m_Size = 0;
}
bool empty() const
{
return (m_Size == 0);
}
private:
QueueNode *m_Head;
size_t m_Size;
CStack<QueueNode *> m_FreeNodes;
public:
class iterator
{
friend class Queue;
public:
iterator()
{
m_This = NULL;
}
iterator(const Queue &src)
{
m_This = src.m_Head;
}
iterator(QueueNode *n) : m_This(n)
{
}
iterator(const iterator &where)
{
m_This = where.m_This;
}
//pre decrement
iterator & operator--()
{
if (m_This)
m_This = m_This->prev;
return *this;
}
//post decrement
iterator operator--(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->prev;
return old;
}
//pre increment
iterator & operator++()
{
if (m_This)
m_This = m_This->next;
return *this;
}
//post increment
iterator operator++(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->next;
return old;
}
const T & operator * () const
{
return m_This->obj;
}
T & operator * ()
{
return m_This->obj;
}
T * operator -> ()
{
return &(m_This->obj);
}
const T * operator -> () const
{
return &(m_This->obj);
}
bool operator != (const iterator &where) const
{
return (m_This != where.m_This);
}
bool operator ==(const iterator &where) const
{
return (m_This == where.m_This);
}
private:
QueueNode *m_This;
};
public:
iterator begin() const
{
return iterator(m_Head->next);
}
iterator end() const
{
return iterator(m_Head);
}
iterator erase(iterator &where)
{
QueueNode *pNode = where.m_This;
iterator iter(where);
iter++;
// Works for all cases: empty Queue, erasing first element, erasing tail, erasing in the middle...
pNode->prev->next = pNode->next;
pNode->next->prev = pNode->prev;
pNode->obj.~T();
m_FreeNodes.push(pNode);
m_Size--;
return iter;
}
public:
void remove(const T & obj)
{
iterator b;
for (b=begin(); b!=end(); b++)
{
if ( (*b) == obj )
{
erase( b );
break;
}
}
}
template <typename U>
iterator find(const U & equ) const
{
iterator iter;
for (iter=begin(); iter!=end(); iter++)
{
if ( (*iter) == equ )
{
return iter;
}
}
return end();
}
Queue & operator =(const Queue &src)
{
clear();
iterator iter;
for (iter=src.begin(); iter!=src.end(); iter++)
{
push_back( (*iter) );
}
return *this;
}
public:
T & first() const
{
iterator i = begin();
return (*i);
}
void pop()
{
iterator iter = begin();
erase(iter);
}
};
#endif //_INCLUDE_SM_QUEUE_H