mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
22f517686d
Now VCMI will use either preferred language or install language to load maps and campaigns that are part of "core" mod, or, in other words - placed in Maps directory of H3 data (like most of manually downloaded maps and campaigns are) If game data is in English, then game can safely use encoding of player- selected language (such as Chinese) to load maps. After all, both GBK and all Win-125X encoding are superset of ASCII, so English map will always load up correctly. Maps that are part of a mod still use mod language as before - it is up to mod maker to correctly set up mod language.
159 lines
3.4 KiB
C++
159 lines
3.4 KiB
C++
/*
|
|
* CLegacyConfigParser.cpp, part of VCMI engine
|
|
*
|
|
* Authors: listed in file AUTHORS in main folder
|
|
*
|
|
* License: GNU General Public License v2.0 or later
|
|
* Full text of license available in license.txt file, in main folder
|
|
*
|
|
*/
|
|
#include "StdInc.h"
|
|
#include "CLegacyConfigParser.h"
|
|
|
|
#include "TextOperations.h"
|
|
#include "Languages.h"
|
|
|
|
#include "../VCMI_Lib.h"
|
|
#include "filesystem/Filesystem.h"
|
|
#include "../modding/CModHandler.h"
|
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
//Helper for string -> float conversion
|
|
class LocaleWithComma: public std::numpunct<char>
|
|
{
|
|
protected:
|
|
char do_decimal_point() const override
|
|
{
|
|
return ',';
|
|
}
|
|
};
|
|
|
|
CLegacyConfigParser::CLegacyConfigParser(const TextPath & resource)
|
|
{
|
|
auto input = CResourceHandler::get()->load(resource);
|
|
fileEncoding = VLC->modh->findResourceEncoding(resource);
|
|
|
|
data.reset(new char[input->getSize()]);
|
|
input->read(reinterpret_cast<uint8_t*>(data.get()), input->getSize());
|
|
|
|
curr = data.get();
|
|
end = curr + input->getSize();
|
|
}
|
|
|
|
std::string CLegacyConfigParser::extractQuotedPart()
|
|
{
|
|
assert(*curr == '\"');
|
|
|
|
curr++; // skip quote
|
|
const char * begin = curr;
|
|
|
|
while (curr != end && *curr != '\"' && *curr != '\t')
|
|
curr++;
|
|
|
|
return std::string(begin, curr++); //increment curr to close quote
|
|
}
|
|
|
|
std::string CLegacyConfigParser::extractQuotedString()
|
|
{
|
|
assert(*curr == '\"');
|
|
|
|
std::string ret;
|
|
while (true)
|
|
{
|
|
ret += extractQuotedPart();
|
|
|
|
// double quote - add it to string and continue quoted part
|
|
if (curr < end && *curr == '\"')
|
|
{
|
|
ret += '\"';
|
|
}
|
|
//extract normal part
|
|
else if(curr < end && *curr != '\t' && *curr != '\r')
|
|
{
|
|
const char * begin = curr;
|
|
|
|
while (curr < end && *curr != '\t' && *curr != '\r' && *curr != '\"')//find end of string or next quoted part start
|
|
curr++;
|
|
|
|
ret += std::string(begin, curr);
|
|
|
|
if(curr>=end || *curr != '\"')
|
|
return ret;
|
|
}
|
|
else // end of string
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
std::string CLegacyConfigParser::extractNormalString()
|
|
{
|
|
const char * begin = curr;
|
|
|
|
while (curr < end && *curr != '\t' && *curr != '\r')//find end of string
|
|
curr++;
|
|
|
|
return std::string(begin, curr);
|
|
}
|
|
|
|
std::string CLegacyConfigParser::readRawString()
|
|
{
|
|
if (curr >= end || *curr == '\n')
|
|
return "";
|
|
|
|
std::string ret;
|
|
|
|
if (*curr == '\"')
|
|
ret = extractQuotedString();// quoted text - find closing quote
|
|
else
|
|
ret = extractNormalString();//string without quotes - copy till \t or \r
|
|
|
|
curr++;
|
|
return ret;
|
|
}
|
|
|
|
std::string CLegacyConfigParser::readString()
|
|
{
|
|
// do not convert strings that are already in ASCII - this will only slow down loading process
|
|
std::string str = readRawString();
|
|
if (TextOperations::isValidASCII(str))
|
|
return str;
|
|
return TextOperations::toUnicode(str, fileEncoding);
|
|
}
|
|
|
|
float CLegacyConfigParser::readNumber()
|
|
{
|
|
std::string input = readRawString();
|
|
|
|
std::istringstream stream(input);
|
|
|
|
if(input.find(',') != std::string::npos) // code to handle conversion with comma as decimal separator
|
|
stream.imbue(std::locale(std::locale(), new LocaleWithComma()));
|
|
|
|
float result;
|
|
if ( !(stream >> result) )
|
|
return 0;
|
|
return result;
|
|
}
|
|
|
|
bool CLegacyConfigParser::isNextEntryEmpty() const
|
|
{
|
|
const char * nextSymbol = curr;
|
|
while (nextSymbol < end && *nextSymbol == ' ')
|
|
nextSymbol++; //find next meaningful symbol
|
|
|
|
return nextSymbol >= end || *nextSymbol == '\n' || *nextSymbol == '\r' || *nextSymbol == '\t';
|
|
}
|
|
|
|
bool CLegacyConfigParser::endLine()
|
|
{
|
|
while (curr < end && *curr != '\n')
|
|
readString();
|
|
|
|
curr++;
|
|
|
|
return curr < end;
|
|
}
|
|
|
|
VCMI_LIB_NAMESPACE_END
|