2010-11-20 10:37:14 +00:00
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
2009-06-13 16:54:04 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "localization.h"
|
|
|
|
#include <base/tl/algorithm.h>
|
2009-06-13 16:54:04 +00:00
|
|
|
|
2012-12-18 23:30:01 +00:00
|
|
|
#include <engine/external/json-parser/json.h>
|
2010-08-17 22:06:00 +00:00
|
|
|
#include <engine/console.h>
|
2010-10-06 21:07:35 +00:00
|
|
|
#include <engine/storage.h>
|
2009-06-13 17:18:06 +00:00
|
|
|
|
2013-06-04 16:41:32 +00:00
|
|
|
const char *Localize(const char *pStr, const char *pContext)
|
2009-06-13 16:54:04 +00:00
|
|
|
{
|
2013-06-04 16:41:32 +00:00
|
|
|
const char *pNewStr = g_Localization.FindString(str_quickhash(pStr), str_quickhash(pContext));
|
2010-05-29 07:25:38 +00:00
|
|
|
return pNewStr ? pNewStr : pStr;
|
2009-06-13 16:54:04 +00:00
|
|
|
}
|
|
|
|
|
2013-06-04 16:41:32 +00:00
|
|
|
CLocConstString::CLocConstString(const char *pStr, const char *pContext)
|
2009-06-13 16:54:04 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pDefaultStr = pStr;
|
|
|
|
m_Hash = str_quickhash(m_pDefaultStr);
|
2013-06-04 16:54:15 +00:00
|
|
|
m_ContextHash = str_quickhash(pContext);
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Version = -1;
|
2009-06-13 16:54:04 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CLocConstString::Reload()
|
2009-06-13 16:54:04 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Version = g_Localization.Version();
|
2013-06-04 16:41:32 +00:00
|
|
|
const char *pNewStr = g_Localization.FindString(m_Hash, m_ContextHash);
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pCurrentStr = pNewStr;
|
|
|
|
if(!m_pCurrentStr)
|
|
|
|
m_pCurrentStr = m_pDefaultStr;
|
2009-06-13 16:54:04 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CLocalizationDatabase::CLocalizationDatabase()
|
2009-06-13 16:54:04 +00:00
|
|
|
{
|
2010-11-03 01:15:39 +00:00
|
|
|
m_VersionCounter = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
m_CurrentVersion = 0;
|
2009-06-13 16:54:04 +00:00
|
|
|
}
|
|
|
|
|
2013-06-04 16:41:32 +00:00
|
|
|
void CLocalizationDatabase::AddString(const char *pOrgStr, const char *pNewStr, const char *pContext)
|
2009-06-13 16:54:04 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CString s;
|
|
|
|
s.m_Hash = str_quickhash(pOrgStr);
|
2013-06-04 16:54:15 +00:00
|
|
|
s.m_ContextHash = str_quickhash(pContext);
|
2010-11-20 23:27:38 +00:00
|
|
|
s.m_Replacement = *pNewStr ? pNewStr : pOrgStr;
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Strings.add(s);
|
2009-06-13 17:18:06 +00:00
|
|
|
}
|
|
|
|
|
2010-10-06 21:07:35 +00:00
|
|
|
bool CLocalizationDatabase::Load(const char *pFilename, IStorage *pStorage, IConsole *pConsole)
|
2009-06-13 17:18:06 +00:00
|
|
|
{
|
2009-06-15 08:15:53 +00:00
|
|
|
// empty string means unload
|
2010-05-29 07:25:38 +00:00
|
|
|
if(pFilename[0] == 0)
|
2009-06-15 08:15:53 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Strings.clear();
|
|
|
|
m_CurrentVersion = 0;
|
2009-06-15 08:15:53 +00:00
|
|
|
return true;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2012-12-18 23:30:01 +00:00
|
|
|
// read file data into buffer
|
|
|
|
IOHANDLE File = pStorage->OpenFile(pFilename, IOFLAG_READ, IStorage::TYPE_ALL);
|
|
|
|
if(!File)
|
2009-06-13 17:18:06 +00:00
|
|
|
return false;
|
2012-12-18 23:30:01 +00:00
|
|
|
int FileSize = (int)io_length(File);
|
|
|
|
char *pFileData = (char *)mem_alloc(FileSize+1, 1);
|
|
|
|
io_read(File, pFileData, FileSize);
|
|
|
|
pFileData[FileSize] = 0;
|
|
|
|
io_close(File);
|
|
|
|
|
|
|
|
// init
|
|
|
|
char aBuf[64];
|
2010-08-17 22:06:00 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "loaded '%s'", pFilename);
|
|
|
|
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf);
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Strings.clear();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2012-12-18 23:30:01 +00:00
|
|
|
// parse json data
|
|
|
|
json_settings JsonSettings;
|
|
|
|
mem_zero(&JsonSettings, sizeof(JsonSettings));
|
|
|
|
char aError[256];
|
|
|
|
json_value *pJsonData = json_parse_ex(&JsonSettings, pFileData, aError);
|
|
|
|
if(pJsonData == 0)
|
2009-06-13 17:18:06 +00:00
|
|
|
{
|
2012-12-21 23:34:49 +00:00
|
|
|
pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, pFilename, aError);
|
|
|
|
mem_free(pFileData);
|
2012-12-18 23:30:01 +00:00
|
|
|
return false;
|
|
|
|
}
|
2009-06-13 17:18:06 +00:00
|
|
|
|
2012-12-18 23:30:01 +00:00
|
|
|
// extract data
|
|
|
|
const json_value &rStart = (*pJsonData)["translated strings"];
|
|
|
|
if(rStart.type == json_array)
|
|
|
|
{
|
2012-12-20 15:30:16 +00:00
|
|
|
for(unsigned i = 0; i < rStart.u.array.length; ++i)
|
2013-06-04 16:41:32 +00:00
|
|
|
AddString((const char *)rStart[i]["or"], (const char *)rStart[i]["tr"], (const char *)rStart[i]["context"]);
|
2009-06-13 17:18:06 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2012-12-18 23:30:01 +00:00
|
|
|
// clean up
|
|
|
|
json_value_free(pJsonData);
|
2012-12-20 15:30:16 +00:00
|
|
|
mem_free(pFileData);
|
2010-11-03 01:15:39 +00:00
|
|
|
m_CurrentVersion = ++m_VersionCounter;
|
2009-06-13 17:18:06 +00:00
|
|
|
return true;
|
2009-06-13 16:54:04 +00:00
|
|
|
}
|
|
|
|
|
2013-06-04 16:41:32 +00:00
|
|
|
const char *CLocalizationDatabase::FindString(unsigned Hash, unsigned ContextHash)
|
2009-06-13 16:54:04 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CString String;
|
|
|
|
String.m_Hash = Hash;
|
|
|
|
sorted_array<CString>::range r = ::find_binary(m_Strings.all(), String);
|
2009-06-13 16:54:04 +00:00
|
|
|
if(r.empty())
|
|
|
|
return 0;
|
2013-06-04 16:54:15 +00:00
|
|
|
|
|
|
|
unsigned DefaultHash = str_quickhash("");
|
|
|
|
unsigned DefaultIndex = 0;
|
2014-02-24 21:50:33 +00:00
|
|
|
for(unsigned i = 0; i < r.size() && r.index(i).m_Hash == Hash; ++i)
|
2013-06-04 16:54:15 +00:00
|
|
|
{
|
|
|
|
const CString &rStr = r.index(i);
|
|
|
|
if(rStr.m_ContextHash == ContextHash)
|
|
|
|
return rStr.m_Replacement;
|
|
|
|
else if(rStr.m_ContextHash == DefaultHash)
|
|
|
|
DefaultIndex = i;
|
|
|
|
}
|
2013-06-04 16:41:32 +00:00
|
|
|
|
|
|
|
return r.index(DefaultIndex).m_Replacement;
|
2009-06-13 16:54:04 +00:00
|
|
|
}
|
2009-06-15 06:45:44 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CLocalizationDatabase g_Localization;
|