/*
* PtokaX - hub server for Direct Connect peer to peer network.
* Copyright (C) 2004-2022 Petr Kozelka, PPK at PtokaX dot org
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3
* 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/>.
*/
//---------------------------------------------------------------------------
#include "stdinc.h"
//---------------------------------------------------------------------------
#include "LanguageXml.h"
#include "LanguageStrings.h"
#include "LanguageManager.h"
//---------------------------------------------------------------------------
#include "SettingManager.h"
#include "ServerManager.h"
#include "utility.h"
#include "tinyxml.h"
//---------------------------------------------------------------------------
#ifdef _WIN32
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
LanguageManager * LanguageManager::m_Ptr = nullptr;
//---------------------------------------------------------------------------
LanguageManager::LanguageManager(void)
{
for (size_t szi = 0; szi < LANG_IDS_END; szi++)
{
size_t szTextLen = strlen(LangStr[szi]);
m_sTexts[szi] = (char *)malloc(szTextLen + 1);
if (m_sTexts[szi] == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes in LanguageManager::LanguageManager\n", szTextLen+1);
exit(EXIT_FAILURE);
}
memcpy(m_sTexts[szi], LangStr[szi], szTextLen);
m_ui16TextsLens[szi] = (uint16_t)szTextLen;
m_sTexts[szi][m_ui16TextsLens[szi]] = '\0';
}
}
//---------------------------------------------------------------------------
LanguageManager::~LanguageManager(void)
{
for (size_t szi = 0; szi < LANG_IDS_END; szi++)
{
free(m_sTexts[szi]);
}
}
//---------------------------------------------------------------------------
void LanguageManager::Load()
{
if (SettingManager::m_Ptr->m_sTexts[SETTXT_LANGUAGE] == NULL)
{
for (size_t szi = 0; szi < LANG_IDS_END; szi++)
{
char * sOldText = m_sTexts[szi];
size_t szTextLen = strlen(LangStr[szi]);
m_sTexts[szi] = (char *)realloc(sOldText, szTextLen + 1);
if (m_sTexts[szi] == NULL)
{
m_sTexts[szi] = sOldText;
AppendDebugLogFormat("[MEM] Cannot reallocate %zu bytes in LanguageManager::Load\n", szTextLen+1);
continue;
}
memcpy(m_sTexts[szi], LangStr[szi], szTextLen);
m_ui16TextsLens[szi] = (uint16_t)szTextLen;
m_sTexts[szi][m_ui16TextsLens[szi]] = '\0';
}
}
else
{
#ifdef _WIN32
string sLanguageFile = ServerManager::m_sPath + "\\language\\" + string(SettingManager::m_Ptr->m_sTexts[SETTXT_LANGUAGE],
#else
string sLanguageFile = ServerManager::m_sPath + "/language/" + string(SettingManager::m_Ptr->m_sTexts[SETTXT_LANGUAGE],
#endif
(size_t)SettingManager::m_Ptr->m_ui16TextsLens[SETTXT_LANGUAGE]) + ".xml";
TiXmlDocument doc(sLanguageFile.c_str());
if (doc.LoadFile() == false)
{
if (doc.ErrorId() != TiXmlBase::TIXML_ERROR_OPENING_FILE && doc.ErrorId() != TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY)
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "Error loading file %s.xml. %s (Col: %d, Row: %d)", SettingManager::m_Ptr->m_sTexts[SETTXT_LANGUAGE], doc.ErrorDesc(), doc.Column(), doc.Row());
if (iMsgLen > 0)
{
#ifdef _BUILD_GUI
::MessageBox(NULL, ServerManager::m_pGlobalBuffer, g_sPtokaXTitle, MB_OK | MB_ICONERROR);
#else
AppendLog(ServerManager::m_pGlobalBuffer);
#endif
}
}
}
else
{
TiXmlHandle cfg(&doc);
TiXmlNode *language = cfg.FirstChild("Language").Node();
if (language != NULL)
{
TiXmlNode *text = nullptr;
while ((text = language->IterateChildren(text)) != NULL)
{
if (text->ToElement() == NULL)
{
continue;
}
const char * sName = text->ToElement()->Attribute("Name");
const char * sText = text->ToElement()->GetText();
size_t szLen = (sText != NULL ? strlen(sText) : 0);
if (szLen != 0 && szLen < 129)
{
for (size_t szi = 0; szi < LANG_IDS_END; szi++)
{
if (strcmp(LangXmlStr[szi], sName) == 0)
{
char * sOldText = m_sTexts[szi];
m_sTexts[szi] = (char *)realloc(sOldText, szLen + 1);
if (m_sTexts[szi] == NULL)
{
m_sTexts[szi] = sOldText;
AppendDebugLogFormat("[MEM] Cannot reallocate %zu bytes in LanguageManager::Load1\n", szLen+1);
break;
}
memcpy(m_sTexts[szi], sText, szLen);
m_ui16TextsLens[szi] = (uint16_t)szLen;
m_sTexts[szi][m_ui16TextsLens[szi]] = '\0';
break;
}
}
}
}
}
}
}
}
//---------------------------------------------------------------------------
void LanguageManager::GenerateXmlExample()
{
TiXmlDocument xmldoc;
xmldoc.InsertEndChild(TiXmlDeclaration("1.0", "windows-1252", "yes"));
TiXmlElement xmllanguage("Language");
xmllanguage.SetAttribute("Name", "Example English Language");
xmllanguage.SetAttribute("Author", "PtokaX");
xmllanguage.SetAttribute("Version", PtokaXVersionString " build " BUILD_NUMBER);
for (int i = 0; i < LANG_IDS_END; i++)
{
TiXmlElement xmlstring("String");
xmlstring.SetAttribute("Name", LangXmlStr[i]);
xmlstring.InsertEndChild(TiXmlText(LangStr[i]));
xmllanguage.InsertEndChild(xmlstring);
}
xmldoc.InsertEndChild(xmllanguage);
xmldoc.SaveFile("English.xml.example");
}
//---------------------------------------------------------------------------
↑ V1042 This file is marked with copyleft license, which requires you to open the derived source code.