in components/core-streams/src/main/java/org/apache/axiom/core/stream/serializer/Serializer.java [314:468]
public void characters(char chars[], int start, int length) throws StreamException {
// It does not make sense to continue with rest of the method if the number of
// characters to read from array is 0.
// Section 7.6.1 of XSLT 1.0 (http://www.w3.org/TR/xslt#value-of) suggest no text node
// is created if string is empty.
if (length == 0) return;
final XmlWriter writer = this.writer;
final int context = this.context;
final String illegalCharacterSequence = illegalCharacterSequences[context];
try {
int i;
final int end = start + length;
// last non-clean character that was processed that was processed
int lastDirtyCharProcessed = start - 1;
int matchedIllegalCharacters = this.matchedIllegalCharacters;
int squareBrackets = this.squareBrackets;
for (i = start; i < end; i++) {
char ch = chars[i];
if (illegalCharacterSequence != null) {
while (true) {
if (ch == illegalCharacterSequence.charAt(matchedIllegalCharacters)) {
if (++matchedIllegalCharacters == illegalCharacterSequence.length()) {
throw new IllegalCharacterSequenceException(
"Illegal character sequence \""
+ illegalCharacterSequence
+ "\"");
}
break;
} else if (matchedIllegalCharacters > 0) {
int offset = 1;
loop:
while (offset < matchedIllegalCharacters) {
for (int j = 0; j < matchedIllegalCharacters - offset; j++) {
if (illegalCharacterSequence.charAt(j)
!= illegalCharacterSequence.charAt(j + offset)) {
offset++;
continue loop;
}
}
break;
}
matchedIllegalCharacters -= offset;
} else {
break;
}
}
}
String replacement = null;
boolean generateCharacterReference = false;
if (context == MIXED_CONTENT || context == ATTRIBUTE_VALUE) {
if (ch <= 0x1F) {
// Range 0x00 through 0x1F inclusive
//
// This covers the non-whitespace control characters
// in the range 0x1 to 0x1F inclusive.
// It also covers the whitespace control characters in the same way:
// 0x9 TAB
// 0xA NEW LINE
// 0xD CARRIAGE RETURN
//
// We also cover 0x0 ... It isn't valid
// but we will output "�"
// The default will handle this just fine, but this
// is a little performance boost to handle the more
// common TAB, NEW-LINE, CARRIAGE-RETURN
switch (ch) {
case 0x09:
if (context == ATTRIBUTE_VALUE) {
replacement = "	";
}
break;
case 0x0A:
if (context == ATTRIBUTE_VALUE) {
replacement = "
";
}
break;
case 0x0D:
replacement = "
";
// Leave whitespace carriage return as a real character
break;
default:
generateCharacterReference = true;
break;
}
} else if (ch < 0x7F) {
switch (ch) {
case '<':
replacement = "<";
break;
case '>':
if (context == MIXED_CONTENT && squareBrackets >= 2) {
replacement = ">";
}
break;
case '&':
replacement = "&";
break;
case '"':
if (context == ATTRIBUTE_VALUE) {
replacement = """;
}
}
} else if (ch <= 0x9F) {
// Range 0x7F through 0x9F inclusive
// More control characters, including NEL (0x85)
generateCharacterReference = true;
} else if (ch == 0x2028) {
// LINE SEPARATOR
replacement = "
";
}
if (ch == ']') {
squareBrackets++;
} else {
squareBrackets = 0;
}
}
int startClean = lastDirtyCharProcessed + 1;
int lengthClean = i - startClean;
if (replacement != null
|| generateCharacterReference
|| lengthClean == CHUNK_SIZE) {
if (startClean < i) {
writer.write(chars, startClean, lengthClean);
}
if (replacement != null) {
writer.write(replacement);
} else if (generateCharacterReference) {
writer.writeCharacterReference(ch);
}
lastDirtyCharProcessed = i;
}
}
// we've reached the end. Any clean characters at the
// end of the array than need to be written out?
int startClean = lastDirtyCharProcessed + 1;
if (i > startClean) {
int lengthClean = i - startClean;
writer.write(chars, startClean, lengthClean);
}
this.matchedIllegalCharacters = matchedIllegalCharacters;
this.squareBrackets = squareBrackets;
} catch (IOException ex) {
throw new StreamException(ex);
}
}