mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Made the XML parser cope with some errors that it missed before. Also found a couple of performance optimisations for it.
This commit is contained in:
parent
023b9ac6cc
commit
cbb4a6e86f
2 changed files with 33 additions and 38 deletions
|
|
@ -101,6 +101,14 @@ namespace XmlIdentifierChars
|
|||
|
||||
DBG (s);
|
||||
}*/
|
||||
|
||||
static String::CharPointerType findEndOfToken (String::CharPointerType p)
|
||||
{
|
||||
while (isIdentifierChar (*p))
|
||||
++p;
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentElement)
|
||||
|
|
@ -189,17 +197,6 @@ juce_wchar XmlDocument::readNextChar() noexcept
|
|||
return c;
|
||||
}
|
||||
|
||||
int XmlDocument::findNextTokenLength() noexcept
|
||||
{
|
||||
int len = 0;
|
||||
juce_wchar c = *input;
|
||||
|
||||
while (XmlIdentifierChars::isIdentifierChar (c))
|
||||
c = input [++len];
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void XmlDocument::skipHeader()
|
||||
{
|
||||
const int headerStart = input.indexOf (CharPointer_UTF8 ("<?xml"));
|
||||
|
|
@ -373,23 +370,23 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
|
|||
if (openBracket >= 0)
|
||||
{
|
||||
input += openBracket + 1;
|
||||
int tagLen = findNextTokenLength();
|
||||
String::CharPointerType endOfToken (XmlIdentifierChars::findEndOfToken (input));
|
||||
|
||||
if (tagLen == 0)
|
||||
if (endOfToken == input)
|
||||
{
|
||||
// no tag name - but allow for a gap after the '<' before giving an error
|
||||
skipNextWhiteSpace();
|
||||
tagLen = findNextTokenLength();
|
||||
endOfToken = XmlIdentifierChars::findEndOfToken (input);
|
||||
|
||||
if (tagLen == 0)
|
||||
if (endOfToken == input)
|
||||
{
|
||||
setLastError ("tag name missing", false);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
node = new XmlElement (String (input, (size_t) tagLen));
|
||||
input += tagLen;
|
||||
node = new XmlElement (String (input, endOfToken));
|
||||
input = endOfToken;
|
||||
LinkedListPointer<XmlElement::XmlAttributeNode>::Appender attributeAppender (node->attributes);
|
||||
|
||||
// look for attributes
|
||||
|
|
@ -420,12 +417,12 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
|
|||
// get an attribute..
|
||||
if (XmlIdentifierChars::isIdentifierChar (c))
|
||||
{
|
||||
const int attNameLen = findNextTokenLength();
|
||||
String::CharPointerType attNameEnd (XmlIdentifierChars::findEndOfToken (input));
|
||||
|
||||
if (attNameLen > 0)
|
||||
if (attNameEnd != input)
|
||||
{
|
||||
const String::CharPointerType attNameStart (input);
|
||||
input += attNameLen;
|
||||
input = attNameEnd;
|
||||
|
||||
skipNextWhiteSpace();
|
||||
|
||||
|
|
@ -438,7 +435,7 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
|
|||
if (nextChar == '"' || nextChar == '\'')
|
||||
{
|
||||
XmlElement::XmlAttributeNode* const newAtt
|
||||
= new XmlElement::XmlAttributeNode (String (attNameStart, (size_t) attNameLen),
|
||||
= new XmlElement::XmlAttributeNode (String (attNameStart, attNameEnd),
|
||||
String::empty);
|
||||
|
||||
readQuotedString (newAtt->value);
|
||||
|
|
@ -446,6 +443,12 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setLastError ("expected '=' after attribute '"
|
||||
+ String (attNameStart, attNameEnd) + "'", false);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -478,7 +481,9 @@ void XmlDocument::readChildElements (XmlElement* parent)
|
|||
|
||||
if (*input == '<')
|
||||
{
|
||||
if (input[1] == '/')
|
||||
const juce_wchar c1 = input[1];
|
||||
|
||||
if (c1 == '/')
|
||||
{
|
||||
// our close tag..
|
||||
const int closeTag = input.indexOf ((juce_wchar) '>');
|
||||
|
|
@ -488,41 +493,32 @@ void XmlDocument::readChildElements (XmlElement* parent)
|
|||
|
||||
break;
|
||||
}
|
||||
else if (input[1] == '!'
|
||||
&& input[2] == '['
|
||||
&& input[3] == 'C'
|
||||
&& input[4] == 'D'
|
||||
&& input[5] == 'A'
|
||||
&& input[6] == 'T'
|
||||
&& input[7] == 'A'
|
||||
&& input[8] == '[')
|
||||
else if (c1 == '!' && CharacterFunctions::compare (input + 1, CharPointer_ASCII ("[CDATA[")) == 0)
|
||||
{
|
||||
input += 9;
|
||||
const String::CharPointerType inputStart (input);
|
||||
|
||||
size_t len = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*input == 0)
|
||||
const juce_wchar c0 = *input;
|
||||
|
||||
if (c0 == 0)
|
||||
{
|
||||
setLastError ("unterminated CDATA section", false);
|
||||
outOfData = true;
|
||||
break;
|
||||
}
|
||||
else if (input[0] == ']'
|
||||
else if (c0 == ']'
|
||||
&& input[1] == ']'
|
||||
&& input[2] == '>')
|
||||
{
|
||||
childAppender.append (XmlElement::createTextElement (String (inputStart, input)));
|
||||
input += 3;
|
||||
break;
|
||||
}
|
||||
|
||||
++input;
|
||||
++len;
|
||||
}
|
||||
|
||||
childAppender.append (XmlElement::createTextElement (String (inputStart, len)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -164,7 +164,6 @@ private:
|
|||
juce_wchar readNextChar() noexcept;
|
||||
XmlElement* readNextElement (bool alsoParseSubElements);
|
||||
void readChildElements (XmlElement* parent);
|
||||
int findNextTokenLength() noexcept;
|
||||
void readQuotedString (String& result);
|
||||
void readEntity (String& result);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue