version 1.132.4.1, 2006/01/18 17:37:56
|
version 1.133, 2006/01/10 19:41:15
|
|
|
void XmlWriter::appendSpecial(Buffer& out, const String& str) | void XmlWriter::appendSpecial(Buffer& out, const String& str) |
{ | { |
const Uint16* p = (const Uint16*)str.getChar16Data(); | const Uint16* p = (const Uint16*)str.getChar16Data(); |
// prevCharIsSpace is true when the last character written to the Buffer |
size_t n = str.size(); |
// is a space character (not a character reference). |
|
Boolean prevCharIsSpace = false; |
|
|
|
// If the first character is a space, use a character reference to avoid |
|
// space compression. |
|
if (*p == ' ') |
|
{ |
|
out.append(STRLIT_ARGS(" ")); |
|
p++; |
|
} |
|
| |
Uint16 c; |
// Handle leading ASCII 7 characers in these next two loops (use unrolling). |
while ((c = *p++) != 0) |
|
{ |
while (n >= 8) |
if (c < 128) |
|
{ |
|
if (_isSpecialChar7[c]) |
|
{ | { |
// Write the character reference for the special character |
// The following condition is equivalent to this: |
out.append( |
// (p[0] < 128 && p[1] < 128 && p[2] < 128 && p[3] < 128 && |
_specialChars[int(c)].str, _specialChars[int(c)].size); |
// p[4] < 128 && p[5] < 128 && p[6] < 128 && p[7] < 128) |
prevCharIsSpace = false; |
|
} |
if (((p[0]|p[1]|p[2]|p[3]|p[4]|p[5]|p[6]|p[7]) & 0xFF80) == 0) |
else if (prevCharIsSpace && (c == ' ')) |
{ |
{ |
// Note: "|" is faster than "||" and achieves the same effect |
// Write the character reference for the space character, to |
// since p[i] is either 0 or 1. |
// avoid compression |
|
out.append(STRLIT_ARGS(" ")); |
if (_isSpecialChar7[p[0]] | _isSpecialChar7[p[1]] | |
prevCharIsSpace = false; |
_isSpecialChar7[p[2]] | _isSpecialChar7[p[3]] | |
|
_isSpecialChar7[p[4]] | _isSpecialChar7[p[5]] | |
|
_isSpecialChar7[p[6]] | _isSpecialChar7[p[7]]) |
|
{ |
|
// Rare case. |
|
_appendSpecialChar7(out, p[0]); |
|
_appendSpecialChar7(out, p[1]); |
|
_appendSpecialChar7(out, p[2]); |
|
_appendSpecialChar7(out, p[3]); |
|
_appendSpecialChar7(out, p[4]); |
|
_appendSpecialChar7(out, p[5]); |
|
_appendSpecialChar7(out, p[6]); |
|
_appendSpecialChar7(out, p[7]); |
} | } |
else | else |
{ | { |
out.append(c); |
// Common case. |
prevCharIsSpace = (c == ' '); |
out.append(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); |
} | } |
|
p += 8; |
|
n -= 8; |
} | } |
else | else |
|
break; |
|
} |
|
|
|
while (n >= 4) |
{ | { |
// Handle UTF8 case |
// The following condition is equivalent to this: |
|
// (p[0] < 128 && p[1] < 128 && p[2] < 128 && p[3] < 128) |
| |
if ((((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) || |
if (((p[0]|p[1]|p[2]|p[3]) & 0xFF80) == 0) |
((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) && |
|
*p) |
|
{ | { |
_xmlWritter_appendSurrogatePair(out, c, *p++); |
if (_isSpecialChar7[p[0]] | _isSpecialChar7[p[1]] | |
|
_isSpecialChar7[p[2]] | _isSpecialChar7[p[3]]) |
|
{ |
|
// Rare case: |
|
_appendSpecialChar7(out, p[0]); |
|
_appendSpecialChar7(out, p[1]); |
|
_appendSpecialChar7(out, p[2]); |
|
_appendSpecialChar7(out, p[3]); |
} | } |
else | else |
{ | { |
_xmlWritter_appendChar(out, c); |
// Common case: |
|
out.append(p[0], p[1], p[2], p[3]); |
} | } |
| |
prevCharIsSpace = false; |
p += 4; |
|
n -= 4; |
} | } |
|
else |
|
break; |
|
} |
|
|
|
// Process remaining characters. A UTF8 character must have been |
|
// encountered or this would have never been reached. |
|
|
|
while (n--) |
|
{ |
|
Uint16 c = *p++; |
|
|
|
// Special processing for UTF8 case: |
|
|
|
if (c < 128) |
|
{ |
|
_appendSpecialChar7(out, c); |
|
continue; |
} | } |
| |
// If the last character is a space, use a character reference to avoid |
// Hanlde UTF8 case (if reached). |
// space compression. |
|
if (prevCharIsSpace) |
if(((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) || |
|
((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) |
{ | { |
out.remove(out.size() - 1); |
Char16 highSurrogate = p[-1]; |
out.append(STRLIT_ARGS(" ")); |
Char16 lowSurrogate = p[0]; |
|
p++; |
|
n--; |
|
|
|
_xmlWritter_appendSurrogatePair( |
|
out, Uint16(highSurrogate),Uint16(lowSurrogate)); |
|
} |
|
else |
|
{ |
|
_xmlWritter_appendSpecialChar(out, c); |
|
} |
} | } |
} | } |
| |
|
|
case XmlEntry::CDATA: | case XmlEntry::CDATA: |
{ | { |
_xmlWritter_indent(os, stack.size(), indentChars); | _xmlWritter_indent(os, stack.size(), indentChars); |
os << "<![CDATA[" << entry.text << "]]>"; |
os << "<![CDATA[...]]>"; |
break; | break; |
} | } |
| |