Subversion Repositories spk

Rev

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