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