version 1.42.8.1, 2008/02/07 18:46:11
|
version 1.43.2.4, 2008/03/12 23:40:26
|
|
|
"One or more tags are still open", | "One or more tags are still open", |
"More than one root element was encountered", | "More than one root element was encountered", |
"Validation error", | "Validation error", |
"Semantic error" |
"Semantic error", |
|
"Malformed namespace declaration", |
|
"Namespace not supported", |
|
"Namespace not declared" |
}; | }; |
| |
static const char* _xmlKeys[] = | static const char* _xmlKeys[] = |
|
|
"Common.XmlParser.UNCLOSED_TAGS", | "Common.XmlParser.UNCLOSED_TAGS", |
"Common.XmlParser.MULTIPLE_ROOTS", | "Common.XmlParser.MULTIPLE_ROOTS", |
"Common.XmlParser.VALIDATION_ERROR", | "Common.XmlParser.VALIDATION_ERROR", |
"Common.XmlParser.SEMANTIC_ERROR" |
"Common.XmlParser.SEMANTIC_ERROR", |
|
"Common.XmlParser.MALFORMED_NAMESPACE_DECL", |
|
"Common.XmlParser.UNSUPPORTED_NAMESPACE", |
|
"Common.XmlParser.UNDECLARED_NAMESPACE" |
}; | }; |
| |
// l10n replace _formMessage (comment out the old one) |
|
/* |
|
static String _formMessage(Uint32 code, Uint32 line, const String& message) |
|
{ |
|
String result = _xmlMessages[Uint32(code) - 1]; |
|
|
|
char buffer[32]; |
|
sprintf(buffer, "%d", line); |
|
result.append(": on line "); |
|
result.append(buffer); |
|
|
|
if (message.size()) |
|
{ |
|
result.append(": "); |
|
result.append(message); |
|
} |
|
|
|
return result; |
|
} |
|
*/ |
|
| |
static MessageLoaderParms _formMessage( | static MessageLoaderParms _formMessage( |
Uint32 code, | Uint32 code, |
|
|
// | // |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
| |
XmlParser::XmlParser(char* text) |
XmlParser::XmlParser(char* text, XmlNamespace* ns) |
: _line(1), | : _line(1), |
_current(text), | _current(text), |
_restoreChar('\0'), | _restoreChar('\0'), |
_foundRoot(false) |
_foundRoot(false), |
|
_scopeLevel(0), |
|
_supportedNamespaces(ns) |
{ | { |
} | } |
| |
|
|
} | } |
} | } |
| |
|
#if defined(PEGASUS_PLATFORM_WIN64_IA64_MSVC) || \ |
|
defined(PEGASUS_PLATFORM_WIN64_X86_64_MSVC) |
|
#pragma optimize( "", off ) |
|
#endif |
static int _getEntityRef(char*& p) | static int _getEntityRef(char*& p) |
{ | { |
if ((p[0] == 'g') && (p[1] == 't') && (p[2] == ';')) | if ((p[0] == 'g') && (p[1] == 't') && (p[2] == ';')) |
|
|
| |
return -1; | return -1; |
} | } |
|
#if defined(PEGASUS_PLATFORM_WIN64_IA64_MSVC) || \ |
|
defined(PEGASUS_PLATFORM_WIN64_X86_64_MSVC) |
|
#pragma optimize( "", on ) |
|
#endif |
| |
static inline int _getCharRef(char*& p, bool hex) | static inline int _getCharRef(char*& p, bool hex) |
{ | { |
|
|
} | } |
} | } |
| |
Boolean XmlParser::next(XmlEntry& entry, Boolean includeComment, |
Boolean XmlParser::next( |
Boolean* firstTime) |
XmlEntry& entry, |
|
Boolean includeComment) |
{ | { |
entry.attributes.clear(); | entry.attributes.clear(); |
| |
|
|
{ | { |
entry = _putBackStack.top(); | entry = _putBackStack.top(); |
_putBackStack.pop(); | _putBackStack.pop(); |
if (firstTime) |
|
{ |
|
*firstTime = false; |
|
} |
|
return true; | return true; |
} | } |
| |
if (firstTime) |
|
{ |
|
*firstTime = true; |
|
} |
|
|
|
// If a character was overwritten with a null-terminator the last | // If a character was overwritten with a null-terminator the last |
// time this routine was called, then put back that character. Before | // time this routine was called, then put back that character. Before |
// exiting of course, restore the null-terminator. | // exiting of course, restore the null-terminator. |
|
|
} | } |
}while (!includeComment && entry.type == XmlEntry::COMMENT); | }while (!includeComment && entry.type == XmlEntry::COMMENT); |
| |
|
if (_supportedNamespaces && |
|
(entry.type == XmlEntry::START_TAG || |
|
entry.type == XmlEntry::EMPTY_TAG || |
|
entry.type == XmlEntry::END_TAG)) |
|
{ |
|
// Process attributes and enter namespaces into the table |
|
if (entry.type == XmlEntry::START_TAG || |
|
entry.type == XmlEntry::EMPTY_TAG) |
|
{ |
|
_scopeLevel++; |
|
for (unsigned int i = 0; i < entry.attributes.size(); i++) |
|
{ |
|
XmlAttribute& attr = entry.attributes[i]; |
|
if (strncmp(attr.name, "xmlns", 5) == 0) |
|
{ |
|
XmlNamespace ns; |
|
if (attr.name[5] == ':') |
|
{ |
|
ns.localName = attr.name + 6; |
|
|
|
// Check if we have malformed XML of the form: |
|
// "xmlns:=URI". In this case attr.name will be set |
|
// to "xmlns:" and ns.localName will point to '\0' |
|
if (ns.localName[0] == '\0') |
|
{ |
|
throw XmlException( |
|
XmlException::MALFORMED_NAMESPACE_DECL, |
|
_line); |
|
} |
|
} |
|
else |
|
{ |
|
// Default name space has no local name |
|
ns.localName = 0; |
|
} |
|
ns.extendedName = attr.value; |
|
ns.scopeLevel = _scopeLevel; |
|
ns.type = getSupportedNamespaceType(ns.extendedName); |
|
|
|
// Even unsupported namespaces get pushed onto the stack. |
|
// We will throw an exception of there is an attempt to |
|
// reference an unsupported namespace later. |
|
_nameSpaces.push(ns); |
|
} |
|
else |
|
{ |
|
// Attribute names may also be namespace qualified. |
|
attr.nsType = _getNamespaceType(attr.name); |
|
} |
|
} |
|
} |
|
|
|
// Get the namespace type for this tag. |
|
entry.nsType = _getNamespaceType(entry.text); |
|
|
|
if (entry.type == XmlEntry::END_TAG || |
|
entry.type == XmlEntry::EMPTY_TAG) |
|
{ |
|
// Remove any namespaces of the current scope level from |
|
// the scope stack. |
|
while (!_nameSpaces.isEmpty() && |
|
_scopeLevel <= _nameSpaces.top().scopeLevel) |
|
{ |
|
_nameSpaces.pop(); |
|
} |
|
|
|
PEGASUS_ASSERT(_scopeLevel > 0); |
|
_scopeLevel--; |
|
} |
|
} |
|
else |
|
{ |
|
entry.nsType = -1; |
|
} |
|
|
return true; | return true; |
} | } |
| |
|
// Get the namespace type of the given tag |
|
int XmlParser::_getNamespaceType(const char* tag) |
|
{ |
|
const char* pos = strchr(tag, ':'); |
|
|
|
// If ":" is not found, the tag is not namespace qualified and we |
|
// need to look for the default name space. |
|
|
|
// Search the namespace stack from the top |
|
for (int i = _nameSpaces.size() - 1; i >=0; i--) |
|
{ |
|
// If ":" is found, look for the name space with the matching |
|
// local name... |
|
if ((pos && _nameSpaces[i].localName && |
|
!strncmp(_nameSpaces[i].localName, tag, pos - tag)) || |
|
// ... otherwise look for the default name space. It's the |
|
// one with localName set to NULL |
|
(!pos && !_nameSpaces[i].localName)) |
|
{ |
|
// If it's a reference to an unsupported namespace, |
|
// throw an exception |
|
if (_nameSpaces[i].type == -1) |
|
{ |
|
throw XmlException(XmlException::UNSUPPORTED_NAMESPACE, _line); |
|
} |
|
return _nameSpaces[i].type; |
|
} |
|
} |
|
|
|
// If the tag is namespace qualified, but the name space has not been |
|
// declared, it's malformed XML and we must throw an exception |
|
if (pos) |
|
{ |
|
throw XmlException(XmlException::UNDECLARED_NAMESPACE, _line); |
|
} |
|
|
|
// Otherwise it's OK not to have a name space. |
|
return -1; |
|
} |
|
|
|
// Gived the extended namespace name, find it in the table of supported |
|
// namespaces and return its type. |
|
int XmlParser::getSupportedNamespaceType(const char* extendedName) |
|
{ |
|
for (int i = 0; |
|
_supportedNamespaces[i].localName != 0; |
|
i++) |
|
{ |
|
PEGASUS_ASSERT(_supportedNamespaces[i].type == i); |
|
if (!strcmp(_supportedNamespaces[i].extendedName, extendedName)) |
|
{ |
|
return _supportedNamespaces[i].type; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
XmlNamespace* XmlParser::getNamespace(int nsType) |
|
{ |
|
for (int i = _nameSpaces.size() - 1; i >=0; i--) |
|
{ |
|
if (_nameSpaces[i].type == nsType) |
|
{ |
|
return &_nameSpaces[i]; |
|
} |
|
} |
|
return 0; |
|
} |
|
|
void XmlParser::putBack(XmlEntry& entry) | void XmlParser::putBack(XmlEntry& entry) |
{ | { |
_putBackStack.push(entry); | _putBackStack.push(entry); |
|
|
} | } |
| |
XmlAttribute attr; | XmlAttribute attr; |
|
attr.nsType = -1; |
attr.name = p; | attr.name = p; |
_getAttributeNameAndEqual(p); | _getAttributeNameAndEqual(p); |
| |