summaryrefslogtreecommitdiff
path: root/src/utils/translation/poparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/translation/poparser.cpp')
-rw-r--r--src/utils/translation/poparser.cpp221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/utils/translation/poparser.cpp b/src/utils/translation/poparser.cpp
new file mode 100644
index 000000000..24d2ee4d4
--- /dev/null
+++ b/src/utils/translation/poparser.cpp
@@ -0,0 +1,221 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "utils/translation/poparser.h"
+
+#include "resources/resourcemanager.h"
+
+#include "utils/stringutils.h"
+
+#include "localconsts.h"
+#include "logger.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "debug.h"
+
+PoParser::PoParser() :
+ mDict(nullptr),
+ mReadingId(false),
+ mReadingStr(false)
+{
+}
+
+void PoParser::openFile()
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ int size;
+ char *buf = static_cast<char*>(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 dont 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);
+}