Rev 254 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include <algorithm>
#include "TextDB.h"
#include "File_IO.h"
namespace SPK {
CTextDB::CTextDB(void) : _iInGame(0),
m_iInPage(0),
m_iLang(44),
_bSortedGames(false)
{
m_pTexts = new TextList;
m_pTextComment = new TextList;
}
CTextDB::~CTextDB(void)
{
if ( m_pTexts ) delete m_pTexts;
if ( m_pTextComment ) delete m_pTextComment;
}
void CTextDB::parseTextFile(int iFromPage, int iToPage, const Utils::WString &sFile, int iLang)
{
// open and read the text file
CFileIO File(sFile);
if ( File.startRead() ) {
while ( !File.atEnd() ) {
this->_parseFileLine(iFromPage, iToPage, iLang, File.readEndOfLineStr());
}
File.close();
}
if (_bSortedGames)
_sortGames();
m_iInPage = 0;
}
void CTextDB::setLanguage(int iLang)
{
m_iLang = iLang;
}
bool CTextDB::exists(int iPage, int iID) const
{
return this->exists(m_iLang, iPage, iID);
}
bool CTextDB::exists(int iLang, int iPage, int iID) const
{
TextListItr itr = m_pTexts->find(_mapID(iLang, iPage, iID));
if ( itr != m_pTexts->end() ) return true;
return false;
}
Utils::WString CTextDB::get(int iPage, int iID) const
{
return this->get(m_iLang, iPage, iID);
}
Utils::WString CTextDB::get(int iLang, int iPage, int iID) const
{
TextListItr itr = m_pTexts->find(_mapID(iLang, iPage, iID));
if ( itr != m_pTexts->end() ) return _parseText(iLang, itr->second);
return L"";
}
bool CTextDB::anyTextLoaded() const
{
return !m_pTexts->empty();
}
Utils::WString CTextDB::_parseText(int iLang, const Utils::WString &sText, const Utils::WString &sReplace) const
{
std::wstring::size_type pos = sReplace.toStdWString().find_first_of(L",", 0);
if ( pos != std::wstring::npos ) {
int iPage = Utils::WString(sReplace.substr(1, pos));
int iID = Utils::WString(sReplace.substr(pos + 1, sReplace.length() - pos - 2));
return sText.findReplace(sReplace, this->get(iLang, iPage, iID));
}
return sText;
}
Utils::WString CTextDB::_parseText(int iLang, const Utils::WString &sText) const
{
Utils::WString sNewText = sText;
std::wstring::size_type pos = sNewText.toStdWString().find_first_of(L"{", 0);
while ( pos != std::wstring::npos ) {
std::wstring::size_type endPos = sNewText.toStdWString().find_first_of(L"}", pos);
if ( endPos != std::wstring::npos ) {
sNewText = this->_parseText(iLang, sNewText, sNewText.substr(pos, (endPos - pos) + 1));
pos = sNewText.toStdWString().find_first_of(L"{", 0);
}
else
pos = sNewText.toStdWString().find_first_of(L"{", pos);
}
return sNewText;
}
void CTextDB::_parseFileLine(int iFromPage, int iToPage, int iLang, const Utils::WString &sLine)
{
if ( m_iInPage ) {
// check for end of page
size_t pos = sLine.toStdWString().find(L"</page>");
if ( pos != std::wstring::npos ) {
m_iInPage = 0;
}
else {
this->_parsePage(iLang, sLine);
}
}
else {
size_t pos = sLine.toStdWString().find(L"<page id=\"");
if ( pos != std::wstring::npos ) {
pos += 10; // move to the end of the search string (after ")
size_t endPos = sLine.toStdWString().find(L"\"", pos);
int iPageID = Utils::WString(sLine.substr(pos, endPos - pos));
int iGameID = iPageID / 10000;
iPageID %= 10000; // make sure we remove the game id
if ( iFromPage > 0 && iPageID < iFromPage ) return; // out of range
if ( iToPage > 0 && iPageID > iToPage) return; // out of range
_iInGame = iGameID;
m_iInPage = iPageID;
}
}
}
void CTextDB::_parsePage(int iLang, const Utils::WString &sLine)
{
// move to the id number
size_t pos = sLine.toStdWString().find(L"<t id=\"");
if ( pos == std::wstring::npos ) return;
pos += 7; // move past to the "
size_t endPos = sLine.toStdWString().find(L"\"", pos);
if ( endPos == std::wstring::npos ) return;
// get the number to add
int iID = Utils::WString(sLine.substr(pos, endPos - pos));
// now find the text
pos = sLine.toStdWString().find(L">", endPos);
if ( pos == std::wstring::npos ) return;
++pos;
endPos = sLine.toStdWString().find(L"</t>", pos);
if ( endPos == std::wstring::npos ) return;
this->_addText(iLang, iID, sLine.substr(pos, endPos - pos));
}
void CTextDB::_addText(int iLang, int iID, const Utils::WString &sText)
{
// split the comment out
Utils::WString fullComment;
Utils::WString text = sText;
while ( text.contains(L"(") && text.contains(L")") ) {
int iStart = text.findPos(L"(");
if ( iStart != -1 ) {
int iEnd = text.findPos(L")", iStart);
if ( iEnd != -1 ) {
Utils::WString comment = text.mid(iStart, ++iEnd);
text.erase(iStart, iEnd - iStart);
if ( !fullComment.empty() ) fullComment += L", ";
fullComment += comment;
}
}
}
text.removeEndSpace();
_lGames.insert(_iInGame);
_bSortedGames = false;
(*m_pTexts)[_mapID(iLang, m_iInPage, iID)] = text;
if ( !fullComment.empty() )
(*m_pTextComment)[_mapID(iLang, m_iInPage, iID)] = fullComment;
}
Utils::WString CTextDB::_mapID(int iLang, int iPage, int iID) const
{
Utils::WString sID;
sID += (long)iLang;
sID += L":";
sID += (long)iPage;
sID += L":";
sID += (long)iID;
return sID;
}
void CTextDB::_sortGames()
{
_lGameOrder.clear();
_lGameOrder.reserve(_lGames.size());
std::copy(_lGames.begin(), _lGames.end(), _lGameOrder.begin());
std::sort(_lGameOrder.begin(), _lGameOrder.end());
_bSortedGames = true;
}
}//NAMESPACE