mirror of https://github.com/axmolengine/axmol.git
Fix #1032
This commit is contained in:
parent
2698663f90
commit
9f94bd461e
|
@ -33,9 +33,10 @@ THE SOFTWARE.
|
|||
// #include "2d/CCTMXTiledMap.h"
|
||||
#include "base/ZipUtils.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/ccUtils.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
|
||||
using namespace std;
|
||||
// using namespace std;
|
||||
|
||||
NS_AX_BEGIN
|
||||
|
||||
|
@ -185,7 +186,7 @@ bool TMXMapInfo::parseXMLString(std::string_view xmlString)
|
|||
|
||||
parser.setDelegator(this);
|
||||
|
||||
return parser.parse(xmlString.data(), len);
|
||||
return parser.parse(xmlString.data(), len, SAXParser::ParseOption::TRIM_WHITESPACE);
|
||||
}
|
||||
|
||||
bool TMXMapInfo::parseXMLFile(std::string_view xmlFilename)
|
||||
|
@ -199,7 +200,7 @@ bool TMXMapInfo::parseXMLFile(std::string_view xmlFilename)
|
|||
|
||||
parser.setDelegator(this);
|
||||
|
||||
return parser.parse(FileUtils::getInstance()->fullPathForFilename(xmlFilename));
|
||||
return parser.parse(xmlFilename, SAXParser::ParseOption::TRIM_WHITESPACE);
|
||||
}
|
||||
|
||||
// the XML parser calls here with all the elements
|
||||
|
@ -288,9 +289,9 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts
|
|||
_externalTilesetFilename = externalTilesetFilename;
|
||||
|
||||
// Tileset file will be relative to the map file. So we need to convert it to an absolute path
|
||||
if (_TMXFileName.find_last_of('/') != string::npos)
|
||||
if (_TMXFileName.find_last_of('/') != std::string::npos)
|
||||
{
|
||||
string dir = _TMXFileName.substr(0, _TMXFileName.find_last_of('/') + 1);
|
||||
std::string dir = _TMXFileName.substr(0, _TMXFileName.find_last_of('/') + 1);
|
||||
externalTilesetFilename = dir + externalTilesetFilename;
|
||||
}
|
||||
else
|
||||
|
@ -421,9 +422,9 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts
|
|||
std::string imagename = attributeDict["source"].asString();
|
||||
tileset->_originSourceImage = imagename;
|
||||
|
||||
if (_TMXFileName.find_last_of('/') != string::npos)
|
||||
if (_TMXFileName.find_last_of('/') != std::string::npos)
|
||||
{
|
||||
string dir = _TMXFileName.substr(0, _TMXFileName.find_last_of('/') + 1);
|
||||
std::string dir = _TMXFileName.substr(0, _TMXFileName.find_last_of('/') + 1);
|
||||
tileset->_sourceImage = dir + imagename;
|
||||
}
|
||||
else
|
||||
|
@ -582,13 +583,13 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts
|
|||
pointsArray.reserve(10);
|
||||
|
||||
// parse points string into a space-separated set of points
|
||||
stringstream pointsStream(value);
|
||||
string pointPair;
|
||||
std::stringstream pointsStream(value);
|
||||
std::string pointPair;
|
||||
while (std::getline(pointsStream, pointPair, ' '))
|
||||
{
|
||||
// parse each point combo into a comma-separated x,y point
|
||||
stringstream pointStream(pointPair);
|
||||
string xStr, yStr;
|
||||
std::stringstream pointStream(pointPair);
|
||||
std::string xStr, yStr;
|
||||
|
||||
ValueMap pointDict;
|
||||
|
||||
|
@ -627,13 +628,13 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts
|
|||
pointsArray.reserve(10);
|
||||
|
||||
// parse points string into a space-separated set of points
|
||||
stringstream pointsStream(value);
|
||||
string pointPair;
|
||||
std::stringstream pointsStream(value);
|
||||
std::string pointPair;
|
||||
while (std::getline(pointsStream, pointPair, ' '))
|
||||
{
|
||||
// parse each point combo into a comma-separated x,y point
|
||||
stringstream pointStream(pointPair);
|
||||
string xStr, yStr;
|
||||
std::stringstream pointStream(pointPair);
|
||||
std::string xStr, yStr;
|
||||
|
||||
ValueMap pointDict;
|
||||
|
||||
|
@ -689,8 +690,8 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name)
|
|||
|
||||
auto currentString = tmxMapInfo->getCurrentString();
|
||||
unsigned char* buffer;
|
||||
auto len =
|
||||
utils::base64Decode((unsigned char*)currentString.data(), (unsigned int)currentString.length(), &buffer);
|
||||
auto len = utils::base64Decode((unsigned char*)currentString.data(), (unsigned int)currentString.length(),
|
||||
&buffer);
|
||||
if (!buffer)
|
||||
{
|
||||
AXLOG("axmol: TiledMap: decode data error");
|
||||
|
@ -734,15 +735,15 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name)
|
|||
tmxMapInfo->setStoringCharacters(false);
|
||||
auto currentString = tmxMapInfo->getCurrentString();
|
||||
|
||||
vector<string> gidTokens;
|
||||
std::vector<std::string> gidTokens;
|
||||
std::stringstream filestr;
|
||||
filestr << currentString;
|
||||
string sRow;
|
||||
while (getline(filestr, sRow, '\n'))
|
||||
std::string sRow;
|
||||
while (std::getline(filestr, sRow, '\n'))
|
||||
{
|
||||
string sGID;
|
||||
istringstream rowstr(sRow);
|
||||
while (getline(rowstr, sGID, ','))
|
||||
std::string sGID;
|
||||
std::istringstream rowstr(sRow);
|
||||
while (std::getline(rowstr, sGID, ','))
|
||||
{
|
||||
gidTokens.emplace_back(sGID);
|
||||
}
|
||||
|
|
|
@ -844,22 +844,35 @@ int base64Encode(const unsigned char* in, unsigned int inLength, char** out)
|
|||
{
|
||||
auto n = ax::base64::encoded_size(inLength);
|
||||
// should be enough to store 8-bit buffers in 6-bit buffers
|
||||
*out = (char*)malloc(n + 1);
|
||||
if (*out)
|
||||
char* tmp = nullptr;
|
||||
if (n > 0 && (tmp = (char*)malloc(n + 1)))
|
||||
{
|
||||
auto ret = ax::base64::encode(*out, in, inLength);
|
||||
*out[ret] = '\0';
|
||||
auto ret = ax::base64::encode(tmp, in, inLength);
|
||||
tmp[ret] = '\0';
|
||||
*out = tmp;
|
||||
return ret;
|
||||
}
|
||||
*out = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AX_DLL int base64Decode(const unsigned char* in, unsigned int inLength, unsigned char** out)
|
||||
{
|
||||
size_t n = ax::base64::decoded_size(inLength);
|
||||
*out = (unsigned char*)malloc(n);
|
||||
if (*out)
|
||||
return static_cast<int>(ax::base64::decode(*out, (char*)in, inLength));
|
||||
unsigned char* tmp = nullptr;
|
||||
if (n > 0 && (tmp = (unsigned char*)malloc(n)))
|
||||
{
|
||||
n = static_cast<int>(ax::base64::decode(tmp, reinterpret_cast<const char*>(in), inLength));
|
||||
if (n > 0)
|
||||
*out = tmp;
|
||||
else
|
||||
{
|
||||
*out = nullptr;
|
||||
free(tmp);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
*out = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,36 +98,51 @@ bool SAXParser::init(const char* /*encoding*/)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SAXParser::parse(const char* xmlData, size_t dataLength)
|
||||
bool SAXParser::parse(const char* xmlData, size_t dataLength, ParseOption opt)
|
||||
{
|
||||
if (xmlData != nullptr && dataLength > 0)
|
||||
{
|
||||
std::string mutableData(xmlData, dataLength);
|
||||
return this->parseIntrusive(&mutableData.front(), dataLength);
|
||||
return this->parseIntrusive(&mutableData.front(), dataLength, opt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SAXParser::parse(std::string_view filename)
|
||||
bool SAXParser::parse(std::string_view filename, ParseOption opt)
|
||||
{
|
||||
bool ret = false;
|
||||
Data data = FileUtils::getInstance()->getDataFromFile(filename);
|
||||
if (!data.isNull())
|
||||
{
|
||||
ret = parseIntrusive((char*)data.getBytes(), data.getSize());
|
||||
ret = parseIntrusive((char*)data.getBytes(), data.getSize(), opt);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool SAXParser::parseIntrusive(char* xmlData, size_t dataLength)
|
||||
bool SAXParser::parseIntrusive(char* xmlData, size_t dataLength, ParseOption opt)
|
||||
{
|
||||
SAX2Hander handler;
|
||||
handler.setSAXParserImp(this);
|
||||
|
||||
try
|
||||
{
|
||||
xsxml::xml_sax3_parser::parse(xmlData, static_cast<int>(dataLength), handler);
|
||||
switch (opt)
|
||||
{
|
||||
case ParseOption::NORMAL:
|
||||
xsxml::xml_sax3_parser::parse<xsxml::parse_normal>(xmlData, static_cast<int>(dataLength), handler);
|
||||
break;
|
||||
case ParseOption::HTML:
|
||||
xsxml::xml_sax3_parser::parse<xsxml::parse_normal | xsxml::parse_html_entity_translation |
|
||||
xsxml::parse_normalize_whitespace>(xmlData, static_cast<int>(dataLength),
|
||||
handler);
|
||||
break;
|
||||
case ParseOption::TRIM_WHITESPACE:
|
||||
xsxml::xml_sax3_parser::parse<xsxml::parse_normal | xsxml::parse_trim_whitespace>(
|
||||
xmlData, static_cast<int>(dataLength), handler);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (xsxml::parse_error& e)
|
||||
|
|
|
@ -66,6 +66,14 @@ class AX_DLL SAXParser
|
|||
SAXDelegator* _delegator;
|
||||
|
||||
public:
|
||||
|
||||
enum class ParseOption
|
||||
{
|
||||
NORMAL, // parse_normal
|
||||
HTML, // parse_normal|parse_html_entity_translation|parse_normalize_whitespace
|
||||
TRIM_WHITESPACE, // parse_normal|parse_trim_whitespace
|
||||
};
|
||||
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
|
@ -85,17 +93,17 @@ public:
|
|||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
bool parse(const char* xmlData, size_t dataLength);
|
||||
bool parse(const char* xmlData, size_t dataLength, ParseOption opt = ParseOption::NORMAL);
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
bool parse(std::string_view filename);
|
||||
bool parse(std::string_view filename, ParseOption opt = ParseOption::NORMAL);
|
||||
|
||||
/**
|
||||
* New API for performance.
|
||||
*/
|
||||
bool parseIntrusive(char* xmlData, size_t dataLength);
|
||||
bool parseIntrusive(char* xmlData, size_t dataLength, ParseOption opt = ParseOption::NORMAL);
|
||||
|
||||
/**
|
||||
* @js NA
|
||||
|
|
|
@ -1102,7 +1102,7 @@ bool RichText::initWithXML(std::string_view origxml, const ValueMap& defaults, c
|
|||
MyXMLVisitor visitor(this);
|
||||
SAXParser parser;
|
||||
parser.setDelegator(&visitor);
|
||||
return parser.parseIntrusive(&xml.front(), xml.length());
|
||||
return parser.parseIntrusive(&xml.front(), xml.length(), SAXParser::ParseOption::HTML);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ void HtmlParser::parse(const std::string& source, const TextFormat& format, std:
|
|||
string xmlText = "<dummy>" + source + "</dummy>";
|
||||
SAXParser parser;
|
||||
parser.setDelegator(this);
|
||||
parser.parseIntrusive(&xmlText.front(), xmlText.length());
|
||||
parser.parseIntrusive(&xmlText.front(), xmlText.length(), SAXParser::ParseOption::HTML);
|
||||
}
|
||||
|
||||
NS_FGUI_END
|
||||
|
|
Loading…
Reference in New Issue