Add code to resolve all numeric XML entities
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9389 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
9d80812421
commit
c19572dcfb
@ -55,21 +55,30 @@ Addon::Addon(const XMLNode &xml)
|
||||
xml.get("arena", &is_arena );
|
||||
if(is_arena) m_type="arena";
|
||||
}
|
||||
xml.get("name", &m_name );
|
||||
m_id = StringUtils::toLowerCase(m_name);
|
||||
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string designer;
|
||||
|
||||
xml.get("name", &name );
|
||||
xml.get("id", &m_id );
|
||||
xml.get("designer", &m_designer );
|
||||
xml.get("designer", &designer );
|
||||
xml.get("status", &m_status );
|
||||
xml.get("date", &m_date );
|
||||
xml.get("installed", &m_installed );
|
||||
xml.get("installed-revision", &m_installed_revision);
|
||||
xml.get("revision", &m_revision );
|
||||
xml.get("file", &m_zip_file );
|
||||
xml.get("description", &m_description );
|
||||
xml.get("description", &description );
|
||||
|
||||
m_id = StringUtils::toLowerCase(name);
|
||||
m_name = StringUtils::removeHtmlEntities(name);
|
||||
m_description = StringUtils::removeHtmlEntities(description);
|
||||
m_designer = StringUtils::removeHtmlEntities(designer);
|
||||
|
||||
// resolve XML entities
|
||||
m_description = StringUtils::replace(m_description, " ", "\n");
|
||||
m_description = StringUtils::replace(m_description, " ", ""); // ignore \r
|
||||
//m_description = StringUtils::replace(m_description, " ", "\n");
|
||||
//m_description = StringUtils::replace(m_description, " ", ""); // ignore \r
|
||||
|
||||
xml.get("image", &m_icon_url );
|
||||
xml.get("icon-revision", &m_icon_revision );
|
||||
@ -105,9 +114,9 @@ void Addon::copyInstallData(const Addon &addon)
|
||||
void Addon::writeXML(std::ofstream *out_stream)
|
||||
{
|
||||
(*out_stream) << " <" << m_type
|
||||
<< " name=\"" << m_name
|
||||
<< " name=\"" << core::stringc(m_name).c_str()
|
||||
<< "\" id=\"" << m_id
|
||||
<< "\" designer=\"" << m_designer
|
||||
<< "\" designer=\"" << core::stringc(m_designer).c_str()
|
||||
<< "\" status=\"" << m_status
|
||||
<< "\" date=\"" << m_date
|
||||
<< "\" installed=\""
|
||||
|
@ -52,12 +52,12 @@ public:
|
||||
|
||||
private:
|
||||
/** The name to be displayed. */
|
||||
std::string m_name;
|
||||
core::stringw m_name;
|
||||
/** Internal id for this addon, which is the name in lower case.
|
||||
* This is used to create a subdirectory for this addon. */
|
||||
std::string m_id;
|
||||
/** The name of the designer of the addon. */
|
||||
std::string m_designer;
|
||||
core::stringw m_designer;
|
||||
/** The (highest) revision number available online. */
|
||||
int m_revision;
|
||||
/** The currently installed revision. */
|
||||
@ -69,7 +69,7 @@ private:
|
||||
/** Date when the addon was added. */
|
||||
Time::TimeType m_date;
|
||||
/** A description of this addon. */
|
||||
std::string m_description;
|
||||
core::stringw m_description;
|
||||
/** The URL of the icon (relative to the server) */
|
||||
std::string m_icon_url;
|
||||
/** Name of the icon to use. */
|
||||
@ -102,7 +102,7 @@ public:
|
||||
void copyInstallData(const Addon &addon);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of the addon. */
|
||||
const std::string& getName() const { return m_name; }
|
||||
const core::stringw& getName() const { return m_name; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the type of the addon. */
|
||||
const std::string& getType() const { return m_type; }
|
||||
@ -117,7 +117,7 @@ public:
|
||||
const std::string getIconBasename() const { return m_icon_basename; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of the addon. */
|
||||
const std::string& getDescription() const { return m_description; }
|
||||
const core::stringw& getDescription() const { return m_description; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the date (in seconds since epoch) when the addon was
|
||||
* uploaded. */
|
||||
@ -141,7 +141,7 @@ public:
|
||||
const std::string& getId() const { return m_id; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the designer of the addon. */
|
||||
const std::string &getDesigner() const { return m_designer; }
|
||||
const core::stringw& getDesigner() const { return m_designer; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** True if this addon needs to be updated. */
|
||||
bool needsUpdate() const
|
||||
|
@ -301,7 +301,7 @@ bool AddonsManager::install(const Addon &addon)
|
||||
bool AddonsManager::uninstall(const Addon &addon)
|
||||
{
|
||||
std::cout << "[Addons] Uninstalling <"
|
||||
<< addon.getName() << ">\n";
|
||||
<< core::stringc(addon.getName()).c_str() << ">\n";
|
||||
|
||||
// addon is a const reference, and to avoid removing the const, we
|
||||
// find the proper index again to modify the installed state
|
||||
|
@ -159,7 +159,7 @@ void AddonsScreen::loadList()
|
||||
|
||||
core::stringw s;
|
||||
if(addon->getDesigner().size()==0)
|
||||
s = (addon->getName()+"\t"+addon->getDateAsString()).c_str();
|
||||
s = (addon->getName()+L"\t"+core::stringc(addon->getDateAsString().c_str())).c_str();
|
||||
else
|
||||
//I18N: as in: The Old Island by Johannes Sjolund\t27.04.2011
|
||||
s = _("%s by %s\t%s", addon->getName().c_str(),
|
||||
|
@ -474,6 +474,84 @@ namespace StringUtils
|
||||
*/
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
irr::core::stringw removeHtmlEntities(const std::string& input)
|
||||
{
|
||||
irr::core::stringw output;
|
||||
std::string entity;
|
||||
bool isHex = false;
|
||||
|
||||
enum
|
||||
{
|
||||
NORMAL,
|
||||
ENTITY_PREAMBLE,
|
||||
ENTITY_BODY
|
||||
} state = NORMAL;
|
||||
|
||||
for (unsigned int n=0; n<input.size(); n++)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case NORMAL:
|
||||
if (input[n] == '&')
|
||||
{
|
||||
state = ENTITY_PREAMBLE;
|
||||
entity = "";
|
||||
isHex = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
output += wchar_t(input[n]);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENTITY_PREAMBLE:
|
||||
if (input[n] != '#')
|
||||
{
|
||||
output += L"&";
|
||||
output += wchar_t(input[n]);
|
||||
fprintf(stderr, "[StringUtils] WARNING: Invalid HTML entity in '%s' (we only support &#...; type HTML entities)\n", input.c_str());
|
||||
state = NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = ENTITY_BODY;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENTITY_BODY:
|
||||
if (input[n] == 'x' && entity.size() == 0)
|
||||
{
|
||||
isHex = true;
|
||||
}
|
||||
else if (input[n] == ';')
|
||||
{
|
||||
int c;
|
||||
|
||||
const char* format = (isHex ? "%x" : "%i");
|
||||
if (sscanf(entity.c_str(), format, &c) == 1)
|
||||
{
|
||||
output += wchar_t(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "[StringUtils] WARNING: non-numeric HTML entity not supported in '%s'\n", input.c_str());
|
||||
}
|
||||
state = NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
entity += wchar_t(input[n]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace StringUtils
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
@ -351,6 +351,11 @@ namespace StringUtils
|
||||
*/
|
||||
std::string replace(const std::string& other, const std::string& from, const std::string& to);
|
||||
|
||||
/**
|
||||
* Converts ASCII text with HTML entities (e.g. &xE9;) to unicode string
|
||||
*/
|
||||
irr::core::stringw removeHtmlEntities(const std::string& input);
|
||||
|
||||
} // namespace StringUtils
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user