version 1.42.4.1, 2008/09/17 18:31:54
|
version 1.43, 2008/02/20 13:55:50
|
|
|
} | } |
} | } |
| |
|
#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) |
static inline int _getCharRef(char*& p, bool hex) |
{ | { |
char* end; | char* end; |
unsigned long ch; | unsigned long ch; |
Boolean hex = false; |
|
| |
if (*p == 'x') |
if (hex) |
{ | { |
hex = true; |
ch = strtoul(p, &end, 16); |
ch = strtoul(++p, &end, 16); |
|
} | } |
else | else |
{ | { |
|
|
return ch; | return ch; |
} | } |
| |
// Parse an entity reference or a character reference |
static void _normalize(Uint32& line, char*& p, char end_char, char*& start) |
static inline int _getRef(Uint32 line, char*& p) |
|
{ |
|
int ch; |
|
|
|
if (*p == '#') |
|
{ |
|
ch = _getCharRef(++p); |
|
} |
|
else |
|
{ | { |
ch = _getEntityRef(p); |
// Skip over leading whitespace: |
} |
|
|
|
if (ch == -1) |
|
{ |
|
throw XmlException(XmlException::MALFORMED_REFERENCE, line); |
|
} |
|
| |
return ch; |
_skipWhitespace(line, p); |
} |
start = p; |
| |
static inline void _normalizeElementValue( |
|
Uint32& line, |
|
char*& p) |
|
{ |
|
// Process one character at a time: | // Process one character at a time: |
| |
char* q = p; | char* q = p; |
| |
while (*p && (*p != '<')) |
while (*p && (*p != end_char)) |
{ | { |
if (_isspace(*p)) | if (_isspace(*p)) |
{ | { |
// Trim whitespace from the end of the value, but do not compress |
// Compress sequences of whitespace characters to a single space |
// whitespace within the value. |
// character. Update line number when newlines encountered. |
|
|
const char* start = p; |
|
| |
if (*p++ == '\n') | if (*p++ == '\n') |
{ | { |
line++; | line++; |
} | } |
| |
_skipWhitespace(line, p); |
*q++ = ' '; |
| |
if (*p && (*p != '<')) |
_skipWhitespace(line, p); |
{ |
|
// Transfer internal whitespace to q without compressing it. |
|
const char* i = start; |
|
while (i < p) |
|
{ |
|
*q++ = *i++; |
|
} |
|
} |
|
else |
|
{ |
|
// Do not transfer trailing whitespace to q. |
|
break; |
|
} |
|
} | } |
else if (*p == '&') | else if (*p == '&') |
{ | { |
// Process an entity reference or a character reference. |
// Process entity characters and entity references: |
|
|
|
p++; |
|
int ch; |
| |
*q++ = _getRef(line, ++p); |
if (*p == '#') |
|
{ |
|
*p++; |
|
|
|
if (*p == 'x') |
|
{ |
|
p++; |
|
ch = _getCharRef(p, true); |
} | } |
else | else |
{ | { |
*q++ = *p++; |
ch = _getCharRef(p, false); |
} | } |
} | } |
|
else |
// If q got behind p, it is safe and necessary to null-terminate q |
|
|
|
if (q != p) |
|
{ | { |
*q = '\0'; |
ch = _getEntityRef(p); |
} |
|
} | } |
| |
static inline void _normalizeAttributeValue( |
if (ch == -1) |
Uint32& line, |
|
char*& p, |
|
char end_char, |
|
char*& start) |
|
{ |
|
// Skip over leading whitespace: |
|
|
|
_skipWhitespace(line, p); |
|
start = p; |
|
|
|
// Process one character at a time: |
|
|
|
char* q = p; |
|
|
|
while (*p && (*p != end_char)) |
|
{ |
|
if (_isspace(*p)) |
|
{ |
|
// Compress sequences of whitespace characters to a single space |
|
// character. Update line number when newlines encountered. |
|
|
|
if (*p++ == '\n') |
|
{ | { |
line++; |
throw XmlException(XmlException::MALFORMED_REFERENCE, line); |
} |
|
|
|
*q++ = ' '; |
|
|
|
_skipWhitespace(line, p); |
|
} | } |
else if (*p == '&') |
|
{ |
|
// Process an entity reference or a character reference. |
|
| |
*q++ = _getRef(line, ++p); |
*q++ = ch; |
} | } |
else | else |
{ | { |
|
|
} | } |
} | } |
| |
|
// We encountered a the end_char or a zero-terminator. |
|
|
|
*q = *p; |
|
|
// Remove single trailing whitespace (consecutive whitespaces already | // Remove single trailing whitespace (consecutive whitespaces already |
// compressed above). Since p >= q, we can tell if we need to strip a | // compressed above). Since p >= q, we can tell if we need to strip a |
// trailing space from q by looking at the end of p. We must not look at | // trailing space from q by looking at the end of p. We must not look at |
// the last character of p, though, if p is an empty string. | // the last character of p, though, if p is an empty string. |
Boolean adjust_q = (p != start) && _isspace(p[-1]); |
|
| |
// We encountered a the end_char or a zero-terminator. |
if ((p != start) && _isspace(p[-1])) |
|
|
*q = *p; |
|
|
|
if (adjust_q) |
|
{ | { |
q--; | q--; |
} | } |
|
|
{ | { |
// Normalize the content: | // Normalize the content: |
| |
char* start = _current; |
char* start; |
_normalizeElementValue(_line, _current); |
_normalize(_line, _current, '<', start); |
| |
// Get the content: | // Get the content: |
| |
|
|
char quote = *p++; | char quote = *p++; |
| |
char* start; | char* start; |
_normalizeAttributeValue(_line, p, quote, start); |
_normalize(_line, p, quote, start); |
attr.value = start; | attr.value = start; |
| |
if (*p != quote) | if (*p != quote) |