This commit is contained in:
halx99 2023-01-17 10:06:09 +08:00
parent 2698663f90
commit 9f94bd461e
6 changed files with 78 additions and 41 deletions

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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)

View File

@ -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

View File

@ -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;
} }

View File

@ -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