/* * The ManaPlus Client * Copyright (C) 2012 The ManaPlus Developers * * This file is part of The ManaPlus Client. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * 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 . */ #include "utils/translation/poparser.h" #include "resources/resourcemanager.h" #include "utils/stringutils.h" #include "localconsts.h" #include "logger.h" #include #include #include "debug.h" PoParser::PoParser() : mDict(nullptr), mReadingId(false), mReadingStr(false) { } void PoParser::openFile() { ResourceManager *resman = ResourceManager::getInstance(); int size; char *buf = static_cast(resman->loadFile(getFileName(mLang), size)); mFile.str(std::string(buf, size)); free(buf); } PoDict *PoParser::load(std::string lang) { setLang(lang); mDict = getDict(); openFile(); mMsgId = ""; mMsgStr = ""; // cycle by msgid+msgstr while (readLine()) { // reading msgid while (readMsgId()) { if (!readLine()) break; } if (!mMsgId.empty()) { // if we got msgid then reading msgstr while (readMsgStr()) { if (!readLine()) break; } } if (!mMsgId.empty() && !mMsgStr.empty()) { // logger->log("add key: " + mMsgId); // logger->log("add value: " + mMsgStr); // store key and value mDict->set(mMsgId, mMsgStr); } mMsgId = ""; mMsgStr = ""; } return mDict; } bool PoParser::readLine() { char line[1001]; if (!mFile.getline(line, 1000)) return false; mLine = line; return true; } bool PoParser::readMsgId() { // if we reading msgstr then stop here if (mReadingStr) return false; const std::string msgId1 = "msgid \""; // check if in reading process if (mReadingId) { // if we get empty line in file then stop reading if (mLine.empty()) { mReadingId = false; return false; } else if (checkLine()) { // reading text from: "text" mMsgId += mLine.substr(1, mLine.size() - 2); mLine = ""; return true; } // stop reading in other case mReadingId = false; return false; } else { // check line start from msgid " if (strStartWith(mLine, msgId1)) { mReadingId = true; // reading text from: msgid "text" mMsgId += mLine.substr(msgId1.size(), mLine.size() - 1 - msgId1.size()); mLine = ""; return true; } // stop reading if we don't read msgid before return mMsgId.empty(); } } bool PoParser::readMsgStr() { const std::string msgStr1 = "msgstr \""; // check if in reading process if (mReadingStr) { // if we get empty line in file then stop reading if (mLine.empty()) { mReadingStr = false; return false; } if (checkLine()) { // reading text from: "text" mMsgStr += mLine.substr(1, mLine.size() - 2); mLine = ""; return true; } // stop reading in other case mReadingStr = false; } else { // check line start from msgstr " if (strStartWith(mLine, msgStr1)) { mReadingStr = true; // reading text from: msgid "text" mMsgStr += mLine.substr(msgStr1.size(), mLine.size() - 1 - msgStr1.size()); mLine = ""; return true; } } // stop reading in other case return false; } bool PoParser::checkLine() { // check is line in format: "text" return mLine.size() > 2 && mLine[0] == '\"' && mLine[mLine.size() - 1] == '\"'; } PoDict *PoParser::getEmptyDict() { return new PoDict(""); } bool PoParser::checkLang(std::string lang) const { // check is po file exists ResourceManager *resman = ResourceManager::getInstance(); return resman->exists(getFileName(lang)); } std::string PoParser::getFileName(std::string lang) const { // get po file name from lang name return strprintf("translations/%s.po", lang.c_str()); } PoDict *PoParser::getDict() { return new PoDict(mLang); }