123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- /*
- * 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);
- std::string modName = VLC->modh->findResourceOrigin(resource);
- std::string language = VLC->modh->getModLanguage(modName);
- fileEncoding = Languages::getLanguageOptions(language).encoding;
- 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
|