committed new language code

This commit is contained in:
David Anderson 2006-03-19 19:26:29 +00:00
parent 555ac1c7f3
commit ccaa4434ad
4 changed files with 3 additions and 458 deletions

View File

@ -47,41 +47,6 @@
#define INSERT_STRING 3
#define INSERT_NEWLINE 4
// dictionary format is Fast-Format-Hash-Lookup, v6
#define MAGIC_HDR 0x4646484C
#define FFHL_VERSION 6
#define FFHL_MIN_VERSION 6
/*version history:
* 1 (BAILOPAN) - Simplest form possible, no reverse
* 2 (BAILOPAN) - One language per file with full reverse
* 3 (PM OnoTo) - 2^32 languages per file with full reverse
* 4 (BAILOPAN) - Optimized by separating and relocating tables (normalization)
* 5 (BAILOPAN) - Removed hash storage
* 6 (BAILOPAN) - Arbitrary bump to force reparse.
FORMAT:
Magic 4bytes
Version 1byte
Number of Keys 4bytes
Number of Languages 4bytes
LANG INFO TABLE[]
Language Name 2bytes
Offset 4bytes
KEY TABLE[]
Key Lookup Offset 4bytes
LANGUAGES TABLE[]
Language[]
Definitions 4bytes
Key # 4bytes (0-index into key table)
Def Offset 4bytes
KEY LOOKUP TABLE[]
Key length 1byte
Key string variable
DEF LOOKUP TABLE[]
Def length 2bytes
Def string variable
*/
template<>
int Compare<String>(const String &k1, const String &k2)
{
@ -249,76 +214,11 @@ const char * CLangMngr::CLang::GetDef(int key, int &status)
return def.definition->c_str();
}
// Assumes fp is set to the right position
bool CLangMngr::CLang::SaveDefinitions(FILE *fp, uint32_t &curOffset)
{
unsigned short defLen = 0;
String *pdef;
THash<int, defentry>::iterator iter;
for (iter=m_LookUpTable.begin(); iter!=m_LookUpTable.end(); iter++)
{
pdef = iter->val.definition;
if (!pdef)
continue;
defLen = pdef->size();
fwrite((void *)&defLen, sizeof(unsigned short), 1, fp);
curOffset += sizeof(unsigned short);
fwrite(pdef->c_str(), sizeof(char), defLen, fp);
curOffset += defLen;
}
return true;
}
int CLangMngr::CLang::Entries()
{
return m_entries;
}
// Assumes fp is set to the right position
bool CLangMngr::CLang::Save(FILE *fp, int &defOffset, uint32_t &curOffset)
{
uint32_t keynum = 0;
uint32_t size = 0;
String *pdef;
//:TODO: remove this loop and assertion, use m_entries for size
THash<int, defentry>::iterator iter;
for (iter=m_LookUpTable.begin(); iter!=m_LookUpTable.end(); iter++)
{
if (iter->val.definition)
size++;
}
assert(size == m_entries);
fwrite((void*)&size, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
for (iter=m_LookUpTable.begin(); iter!=m_LookUpTable.end(); iter++)
{
keynum = iter->key;
pdef = iter->val.definition;
if (!pdef)
continue;
fwrite((void *)&keynum, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
fwrite((void *)&defOffset, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
defOffset += sizeof(short);
defOffset += pdef->size();
}
return true;
}
// assumes fp is set to the right position
bool CLangMngr::CLang::Load(FILE *fp)
{
return true;
}
/******** CLangMngr *********/
inline String &make_string(const char *str)
@ -381,35 +281,6 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
return outbuf;
}
const char *CLangMngr::Format(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
const char *retVal = FormatString(fmt, ap);
va_end(ap);
return retVal;
}
#undef CHECK_PTR
#undef CHECK_OUTPR
#undef ZEROTERM
#undef NEXT_PARAM
#define CHECK_PTR(ptr, start, bufsize) if ((ptr) - (start) >= (bufsize)) { \
AMXXLOG_Log("[AMXX] Buffer overflow in formatting"); \
outbuf[0] = 0; \
return outbuf; }
#define CHECK_OUTPTR(offset) CHECK_PTR(outptr+offset, outbuf, sizeof(outbuf))
#define ZEROTERM(buf) buf[(sizeof(buf)/sizeof(buf[0]))-1]=0;
#define NEXT_PARAM()
//this is not implemented....
char *CLangMngr::FormatString(const char *fmt, va_list &ap)
{
return "";
}
void CLangMngr::MergeDefinitions(const char *lang, CQueue<sKeyDef> &tmpVec)
{
CLang * language = GetLang(lang);
@ -638,294 +509,6 @@ void CLangMngr::InvalidateCache()
FileList.clear();
}
bool CLangMngr::Save(const char *filename)
{
FILE *fp = fopen(filename, "wb");
if (!fp)
return false;
uint32_t magic = MAGIC_HDR;
unsigned char version = FFHL_VERSION;
uint32_t langNum = m_Languages.size();
const char *langName = 0;
uint32_t curOffset = 0;
uint32_t keyNum = KeyList.size();
uint32_t ktbSize = KeyList.size() * sizeof(uint32_t);
uint32_t ltbSize = m_Languages.size() * ((sizeof(char)*2) + sizeof(uint32_t));
fwrite((void *)&magic, sizeof(uint32_t), 1, fp);
fwrite((void *)&version, sizeof(unsigned char), 1, fp);
fwrite((void *)&keyNum, sizeof(uint32_t), 1, fp);
fwrite((void *)&langNum, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
curOffset += sizeof(unsigned char);
curOffset += sizeof(uint32_t);
curOffset += sizeof(uint32_t);
uint32_t langOffset = curOffset + ktbSize + ltbSize;
for (unsigned int i = 0; i < m_Languages.size(); i++)
{
langName = m_Languages[i]->GetName();
fwrite(langName, sizeof(char), 2, fp);
curOffset += sizeof(char) * 2;
fwrite((void *)&langOffset, sizeof(uint32_t), 1, fp);
langOffset += sizeof(uint32_t) + (m_Languages[i]->Entries() * (sizeof(uint32_t) * 2));
curOffset += sizeof(uint32_t);
}
//Note - langOffset now points to the start of key lookup table
uint32_t keyHash = 0;
uint32_t keyOffset = langOffset;
for (unsigned int i = 0; i < KeyList.size(); i++)
{
fwrite((void*)&keyOffset, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
keyOffset += sizeof(char);
keyOffset += KeyList[i]->size();
}
//Note - now keyOffset points toward the start of the def table
int defOffset = keyOffset;
for (unsigned int i = 0; i < m_Languages.size(); i++)
{
m_Languages[i]->Save(fp, defOffset, curOffset);
}
//Now, defOffset points toward the END of the file
//curoffset should point toward the key table, so...
unsigned char keyLen = 0;
for (unsigned int i = 0; i < KeyList.size(); i++)
{
keyLen = KeyList[i]->size();
fwrite((void*)&keyLen, sizeof(unsigned char), 1, fp);
curOffset += sizeof(unsigned char);
fwrite(KeyList[i]->c_str(), sizeof(char), keyLen, fp);
curOffset += sizeof(char) * keyLen;
}
//Finally, write the def table
// It's assumed no orders changed...
for (unsigned int i = 0; i < m_Languages.size(); i++)
{
m_Languages[i]->SaveDefinitions(fp, curOffset);
}
fclose(fp);
//done!
return true;
}
bool CLangMngr::SaveCache(const char *filename)
{
FILE *fp = fopen(filename, "wb");
if (!fp)
{
return false;
}
CVector<md5Pair *>::iterator i;
short dictCount = FileList.size();
char len = 0;
fwrite((void *)&dictCount, sizeof(short), 1, fp);
for (i = FileList.begin(); i != FileList.end(); i++)
{
len = (*i)->file.size();
fwrite((void *)&len, sizeof(char), 1, fp);
fwrite((*i)->file.c_str(), sizeof(char), len, fp);
fwrite((*i)->val.c_str(), sizeof(char), 32, fp);
}
fclose(fp);
return true;
}
#define CACHEREAD(expr, type) \
if (! (expr==1) ) { \
FileList.clear(); \
fclose(fp); \
return false; \
}
#define CACHEREAD_S(expr, size) \
if (! (expr==size) ) { \
FileList.clear(); \
fclose(fp); \
return false; \
}
bool CLangMngr::LoadCache(const char *filename)
{
FILE *fp = fopen(filename, "rb");
if (!fp)
{
return false;
}
SetUnhandledExceptionFilter(NULL);
short dictCount = 0;
char len = 0;
char buf[255];
char md5[34];
CACHEREAD(fread((void*)&dictCount, sizeof(short), 1, fp), short);
md5Pair *p = 0;
for (int i = 1; i <= dictCount; i++)
{
CACHEREAD(fread((void*)&len, sizeof(char), 1, fp), char);
CACHEREAD_S(fread(buf, sizeof(char), len, fp), len);
buf[len] = 0;
CACHEREAD_S(fread(md5, sizeof(char), 32, fp), 32);
md5[32] = 0;
p = new md5Pair;
p->file.assign(buf);
p->val.assign(md5);
FileList.push_back(p);
p = 0;
}
fclose(fp);
return true;
}
#define DATREAD(expr, type) \
if (! (expr==1) ) { \
Clear(); \
fclose(fp); \
return false; \
}
#define DATREAD_S(expr, size) \
if (! (expr==size) ) { \
Clear(); \
fclose(fp); \
return false; \
}
bool CLangMngr::Load(const char *filename)
{
Clear();
FILE *fp = fopen(filename, "rb");
if (!fp)
return false;
uint32_t magic = 0;
uint32_t langCount = 0;
uint32_t keycount = 0;
char version = 0;
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
rewind(fp);
DATREAD(fread((void*)&magic, sizeof(uint32_t), 1, fp), uint32_t);
if (magic != MAGIC_HDR)
return false;
DATREAD(fread((void*)&version, sizeof(char), 1, fp), char);
if (version > FFHL_VERSION || version < FFHL_MIN_VERSION)
return false;
DATREAD(fread((void*)&keycount, sizeof(uint32_t), 1, fp), uint32_t);
DATREAD(fread((void*)&langCount, sizeof(uint32_t), 1, fp), uint32_t);
uint32_t *LangOffsets = new uint32_t[langCount];
char langname[3];
for (unsigned int i = 0; i < langCount; i++)
{
DATREAD_S(fread(langname, sizeof(char), 2, fp), 2);
langname[2] = 0;
GetLang(langname); //this will initialize for us
DATREAD(fread((void *)&(LangOffsets[i]), sizeof(uint32_t), 1, fp), uint32_t);
}
//we should now be at the key table
int ktbOffset = ftell(fp);
unsigned char keylen;
char keybuf[255];
uint32_t bogus;
uint32_t keyoffset, save;
String _tmpkey;
for (unsigned i = 0; i < keycount; i++)
{
if (version == 4)
fread((void*)&(bogus), sizeof(uint32_t), 1, fp);
DATREAD(fread((void*)&keyoffset, sizeof(uint32_t), 1, fp), uint32_t);
if (keyoffset > size-sizeof(uint32_t))
{
Clear();
fclose(fp);
return false;
}
save = ftell(fp);
fseek(fp, keyoffset, SEEK_SET);
DATREAD(fread((void*)&keylen, sizeof(char), 1, fp), char);
//technically this isn't possible since
// a char will never be more than 255
// but it's good practice.
if (keylen > sizeof(keybuf))
return false;
DATREAD_S(fread(keybuf, sizeof(char), keylen, fp), keylen);
keybuf[keylen] = 0;
_tmpkey.assign(keybuf);
AddKeyEntry(_tmpkey);
fseek(fp, save, SEEK_SET); //bring back to next key
}
//we should now be at the languages table
uint32_t numentries;
uint32_t keynum;
uint32_t defoffset;
unsigned short deflen;
char valbuf[4096];
for (unsigned int i = 0; i < langCount; i++)
{
DATREAD(fread((void*)&numentries, sizeof(uint32_t), 1, fp), uint32_t);
for (unsigned int j = 0; j < numentries; j++)
{
DATREAD(fread((void *)&keynum, sizeof(uint32_t), 1, fp), uint32_t);
if (version == 4)
{
DATREAD(fread((void *)&bogus, sizeof(uint32_t), 1, fp), uint32_t);
}
DATREAD(fread((void *)&defoffset, sizeof(uint32_t), 1, fp), uint32_t);
if (defoffset > size-sizeof(uint32_t))
{
Clear();
fclose(fp);
return false;
}
save = ftell(fp);
fseek(fp, defoffset, SEEK_SET);
DATREAD(fread((void *)&deflen, sizeof(unsigned short), 1, fp), short);
if (deflen > sizeof(valbuf))
return false;
DATREAD_S(fread(valbuf, sizeof(char), deflen, fp), deflen);
valbuf[deflen] = 0;
m_Languages[i]->AddEntry(keynum, valbuf);
fseek(fp, save, SEEK_SET); //bring back to next entry
}
}
fclose(fp);
delete [] LangOffsets;
//we're done!
return true;
}
CLangMngr::~CLangMngr()
{
Clear();

View File

@ -111,11 +111,6 @@ class CLangMngr
// Get language name
const char *GetName() { return m_LanguageName; }
// Save to file
bool Save(FILE *fp, int &defOffset, uint32_t &curOffset);
bool SaveDefinitions(FILE *fp, uint32_t &curOffset);
// Load
bool Load(FILE *fp);
void SetMngr(CLangMngr *l) { m_LMan = l; }
// Get number of entries
int Entries();
@ -159,18 +154,8 @@ public:
int MergeDefinitionFile(const char *file);
// Get a definition from a lang name and a key
const char *GetDef(const char *langName, const char *key, int &status);
// Format a string
const char *Format(const char *src, ...);
// Format a string for an AMX plugin
char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
char *FormatString(const char *fmt, va_list &ap);
// Save
bool Save(const char *filename);
// Load
bool Load(const char *filename);
// Cache
bool LoadCache(const char *filename);
bool SaveCache(const char *filename);
void InvalidateCache();
// Get index
int GetKeyEntry(String &key);

View File

@ -244,15 +244,6 @@ int C_Spawn(edict_t *pent)
// ###### Initialize task manager
g_tasksMngr.registerTimers(&gpGlobals->time, &mp_timelimit->value, &g_game_timeleft);
// ###### Load lang
char file[256];
if (!g_langMngr.Load(build_pathname_r(file, sizeof(file) - 1, "%s/languages.dat", get_localinfo("amxmodx_datadir", "addons/amxmodx/data"))))
{
g_langMngr.InvalidateCache();
} else {
g_langMngr.LoadCache(build_pathname_r(file, sizeof(file) - 1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
}
// ###### Initialize commands prefixes
g_commands.registerPrefix("amx");
g_commands.registerPrefix("amxx");
@ -279,6 +270,7 @@ int C_Spawn(edict_t *pent)
CVAR_SET_STRING(init_amxmodx_modules.name, buffer);
// ###### Load Vault
char file[255];
g_vault.setSource(build_pathname_r(file, sizeof(file) - 1, "%s", get_localinfo("amxx_vault", "addons/amxmodx/configs/vault.ini")));
g_vault.loadVault();
@ -449,11 +441,6 @@ void C_ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
executeForwards(FF_PluginInit);
executeForwards(FF_PluginCfg);
// ###### Save lang
char file[256];
g_langMngr.Save(build_pathname_r(file, sizeof(file) - 1, "%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.SaveCache(build_pathname_r(file, sizeof(file) - 1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
// Correct time in Counter-Strike and other mods (except DOD)
if (!g_bmod_dod)
g_game_timeleft = 0;
@ -524,12 +511,6 @@ void C_ServerDeactivate_Post()
g_plugins.clear();
ClearPluginLibraries();
char file[256];
g_langMngr.Save(build_pathname_r(file, sizeof(file) - 1, "%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.SaveCache(build_pathname_r(file, sizeof(file) - 1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.Clear();
for (unsigned int i=0; i<g_hudsync.size(); i++)
delete [] g_hudsync[i];
g_hudsync.clear();
@ -1316,6 +1297,7 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
g_xvars.clear();
g_plugins.clear();
g_cvars.clear();
g_langMngr.Clear();
detachModules();

View File

@ -1503,12 +1503,7 @@ edict_t* MNF_GetPlayerEdict(int id)
const char *MNF_Format(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
const char *retVal = g_langMngr.FormatString(fmt, ap);
va_end(ap);
return retVal;
return "";
}
const char *MNF_GetPlayerTeam(int id)