New version

This commit is contained in:
Pavol Marko 2004-07-28 18:31:30 +00:00
parent 7801cde7f0
commit 286a0d0d02
2 changed files with 182 additions and 17 deletions

View File

@ -126,12 +126,12 @@ const uint32_t CRCTable[256] = {
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
uint32_t CLangMngr::CLang::MakeHash(const char *src) uint32_t CLangMngr::CLang::MakeHash(const char *src, bool makeLower)
{ {
uint32_t crc = 0xFFFFFFFF; uint32_t crc = 0xFFFFFFFF;
while (*src) while (*src)
crc = ((crc>>8)&0xFFFFFFFF)^CRCTable[(crc^*src++)&0xFF]; crc = ((crc>>8)&0xFFFFFFFF)^CRCTable[(crc^ (makeLower ? tolower(*src++) : *src++) )&0xFF];
return ~crc; return ~crc;
} }
@ -248,7 +248,7 @@ void CLangMngr::CLang::LangEntry::SetKey(const char *pKey)
delete [] m_pKey; delete [] m_pKey;
m_pKey = new char[strlen(pKey)+1]; m_pKey = new char[strlen(pKey)+1];
strcpy(m_pKey, pKey); strcpy(m_pKey, pKey);
m_KeyHash = MakeHash(pKey); m_KeyHash = MakeHash(pKey, true);
} }
void CLangMngr::CLang::LangEntry::SetDef(const char *pDef) void CLangMngr::CLang::LangEntry::SetDef(const char *pDef)
@ -286,7 +286,7 @@ void CLangMngr::CLang::Clear()
CLangMngr::CLang::LangEntry & CLangMngr::CLang::GetEntry(const char *key) CLangMngr::CLang::LangEntry & CLangMngr::CLang::GetEntry(const char *key)
{ {
LookUpVecIter iter; LookUpVecIter iter;
uint32_t hash = MakeHash(key); uint32_t hash = MakeHash(key, true);
for (iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter) for (iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter)
if (*iter == hash) if (*iter == hash)
break; break;
@ -317,7 +317,7 @@ void CLangMngr::CLang::Dump()
const char * CLangMngr::CLang::GetDef(const char *key) const char * CLangMngr::CLang::GetDef(const char *key)
{ {
uint32_t hash = MakeHash(key); uint32_t hash = MakeHash(key, true);
for (LookUpVecIter iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter) for (LookUpVecIter iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter)
if (*iter == hash) if (*iter == hash)
return iter->GetDef(); return iter->GetDef();
@ -438,7 +438,7 @@ bool CLangMngr::CLang::Load(FILE *fp)
char keyBuf[257]; char keyBuf[257];
char defBuf[4096]; char defBuf[4096];
for (int i = 0; i < numOfEntries; ++i) for (unsigned int i = 0; i < numOfEntries; ++i)
{ {
uint32_t keyHash, defHash; uint32_t keyHash, defHash;
uint32_t tmp1, tmp2, tmp3; uint32_t tmp1, tmp2, tmp3;
@ -471,10 +471,10 @@ bool CLangMngr::CLang::Load(FILE *fp)
/******** CLangMngr *********/ /******** CLangMngr *********/
const char *CLangMngr::Format(const char *pKey, ...) const char *CLangMngr::Format(const char *src, ...)
{ {
va_list argptr; va_list argptr;
va_start(argptr, pKey); va_start(argptr, src);
static char outbuf[4096]; static char outbuf[4096];
char *outptr = outbuf; char *outptr = outbuf;
enum State enum State
@ -485,13 +485,13 @@ const char *CLangMngr::Format(const char *pKey, ...)
State curState = S_Normal; State curState = S_Normal;
while (*pKey) while (*src)
{ {
if (*pKey == '%' && curState == S_Normal) if (*src == '%' && curState == S_Normal)
curState = S_PercentSign; curState = S_PercentSign;
else if (curState == S_PercentSign) else if (curState == S_PercentSign)
{ {
switch (*pKey) switch (*src)
{ {
case 's': case 's':
{ {
@ -517,6 +517,10 @@ const char *CLangMngr::Format(const char *pKey, ...)
case 'L': case 'L':
{ {
char *langName = va_arg(argptr, char*); char *langName = va_arg(argptr, char*);
// Handle player ids (1-32)
if ((int)langName >= 1 && (int)langName <= 32)
langName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I((int)langName)->pEdict, "_language");
char *key = va_arg(argptr, char*); char *key = va_arg(argptr, char*);
const char *def = GetDef(langName, key); const char *def = GetDef(langName, key);
while (*def) while (*def)
@ -556,17 +560,136 @@ const char *CLangMngr::Format(const char *pKey, ...)
} }
default: default:
*outptr++= '%'; *outptr++= '%';
*outptr++ = *pKey; *outptr++ = *src;
} }
curState = S_Normal; curState = S_Normal;
} }
else else
*outptr++ = *pKey; *outptr++ = *src;
++pKey; ++src;
} }
*outptr++ = 0;
return outbuf; return outbuf;
} }
char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
{
cell *src = get_amxaddr(amx, params[parm++]);
static char outbuf[4096];
char *outptr = outbuf;
enum State
{
S_Normal,
S_PercentSign,
};
State curState = S_Normal;
while (*src)
{
if (*src == '%' && curState == S_Normal)
curState = S_PercentSign;
else if (curState == S_PercentSign)
{
switch (*src)
{
case 's':
{
cell *tmpArg = get_amxaddr(amx, params[parm++]);;
while (*tmpArg)
*outptr++ = *tmpArg++;
break;
}
case 'f':
case 'g':
{
char format[16];
format[0] = '%';
char *ptr = format+1;
while (!isalpha(*ptr++ = *src++))
/*nothing*/;
--src;
*ptr = 0;
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++]));
outptr += strlen(outptr);
break;
}
case 'L':
{
cell langName = params[parm];
cell *pLangName = get_amxaddr(amx, params[parm++]);
const char *cpLangName=NULL;
// Handle player ids (1-32) and server language
if (*pLangName == 0)
*pLangName = m_CurGlobId;
if (*pLangName == -1)
cpLangName = g_vault.get("server_language");
else if (*pLangName > 1 && *pLangName < 32)
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(*pLangName)->pEdict, "_language");
else
{
int len = 0;
cpLangName = get_amxstring(amx, langName, 2, len);
}
int len;
char *key = get_amxstring(amx, params[parm++], 1, len);
const char *def = GetDef(cpLangName, key);
while (*def)
{
switch (*def)
{
case INSERT_NUMBER:
{
itoa((float)*(REAL*)get_amxaddr(amx, params[parm++]), outptr, 10);
outptr += strlen(outptr);
break;
}
case INSERT_STRING:
{
cell *tmpArg = get_amxaddr(amx, params[parm++]);;
while (*tmpArg)
*outptr++ = *tmpArg++;
break;
}
case INSERT_FLOAT:
{
sprintf(outptr, "%f", *(REAL*)get_amxaddr(amx, params[parm++]));
outptr += strlen(outptr);
break;
}
case INSERT_NEWLINE:
*outptr++ = '\n';
break;
default:
*outptr++ = *def;
}
++def;
}
break;
}
default:
{
char format[16];
format[0] = '%';
char *ptr = format+1;
while (!isalpha(*ptr++ = *src++))
/*nothing*/;
--src;
*ptr = 0;
sprintf(outptr, format, *get_amxaddr(amx, params[parm++]));
outptr += strlen(outptr);
break;
}
}
curState = S_Normal;
}
else
*outptr++ = *src;
++src;
}
len = outptr - outbuf;
*outptr++ = 0;
return outbuf;
}
void CLangMngr::MergeDefinitions(const char *lang, CVector<sKeyDef> &tmpVec) void CLangMngr::MergeDefinitions(const char *lang, CVector<sKeyDef> &tmpVec)
{ {
@ -843,3 +966,34 @@ void CLangMngr::Clear()
{ {
m_Languages.clear(); m_Languages.clear();
} }
int CLangMngr::GetLangsNum()
{
return m_Languages.size();
}
const char *CLangMngr::GetLangName(int langId)
{
return m_Languages.at(langId).GetName();
}
bool CLangMngr::LangExists(const char *langName)
{
char buf[3] = { 0 };
int i = 0;
while (buf[i] = tolower(*langName++))
{
if (++i == 2)
break;
}
for (LangVecIter iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
if (*iter == buf)
return true;
return false;
}
void CLangMngr::SetDefLang(int id)
{
m_CurGlobId = id;
}

View File

@ -32,6 +32,8 @@
#ifndef _INCLUDE_CLANG_H #ifndef _INCLUDE_CLANG_H
#define _INCLUDE_CLANG_H #define _INCLUDE_CLANG_H
#define LANG_SERVER -1
class CLangMngr class CLangMngr
{ {
struct sKeyDef struct sKeyDef
@ -61,7 +63,7 @@ class CLangMngr
bool Load(FILE *fp); bool Load(FILE *fp);
private: private:
static uint32_t MakeHash(const char *src); static uint32_t MakeHash(const char *src, bool makeLower = false);
class LangEntry class LangEntry
{ {
@ -107,14 +109,23 @@ class CLangMngr
CLang & GetLang(const char *name); CLang & GetLang(const char *name);
void Clear(); int m_CurGlobId;
public: public:
int MergeDefinitionFile(const char *file); int MergeDefinitionFile(const char *file);
void Dump(); void Dump();
const char *GetDef(const char *langName, const char *key); const char *GetDef(const char *langName, const char *key);
const char *Format(const char *Key, ...); const char *Format(const char *src, ...);
char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
bool Save(const char *filename); bool Save(const char *filename);
bool Load(const char *filename); bool Load(const char *filename);
int GetLangsNum();
const char *GetLangName(int langId);
bool LangExists(const char *langName);
// When a language id in a format string in FormatAmxString is 0, the glob id decides which language to take.
void SetDefLang(int id);
void Clear();
}; };
#endif //_INCLUDE_CLANG_H #endif //_INCLUDE_CLANG_H