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

View File

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

View File

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

View File

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

View File

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

View File

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