public void characters()

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 "&#0;"

                        // 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 = "&#x9;";
                                }
                                break;
                            case 0x0A:
                                if (context == ATTRIBUTE_VALUE) {
                                    replacement = "&#xa;";
                                }
                                break;
                            case 0x0D:
                                replacement = "&#xd;";
                                // Leave whitespace carriage return as a real character
                                break;
                            default:
                                generateCharacterReference = true;
                                break;
                        }
                    } else if (ch < 0x7F) {
                        switch (ch) {
                            case '<':
                                replacement = "&lt;";
                                break;
                            case '>':
                                if (context == MIXED_CONTENT && squareBrackets >= 2) {
                                    replacement = "&gt;";
                                }
                                break;
                            case '&':
                                replacement = "&amp;";
                                break;
                            case '"':
                                if (context == ATTRIBUTE_VALUE) {
                                    replacement = "&quot;";
                                }
                        }
                    } else if (ch <= 0x9F) {
                        // Range 0x7F through 0x9F inclusive
                        // More control characters, including NEL (0x85)
                        generateCharacterReference = true;
                    } else if (ch == 0x2028) {
                        // LINE SEPARATOR
                        replacement = "&#x2028;";
                    }

                    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);
        }
    }