core/src/main/java/org/owasp/encoder/XMLEncoder.java
protected CoderResult encodeArrays(CharBuffer input, CharBuffer output, boolean endOfInput) {
        final char[] in = input.array();
        final char[] out = output.array();
        int i = input.arrayOffset() + input.position();
        final int n = input.arrayOffset() + input.limit();
        int j = output.arrayOffset() + output.position();
        final int m = output.arrayOffset() + output.limit();

        for (; i < n; ++i) {
            final char ch = in[i];
            if (ch < Unicode.DEL) {
                if (ch > '>' || ((_validMask & (1L << ch)) != 0)) {
                    // Common case ('>' .. '~') reached in two branches
                    if (j >= m) {
                        return overflow(input, i, output, j);
                    }
                    out[j++] = ch;
                } else {
                    switch (ch) {
                        case '&':
                            if (j + AMP_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = 'a';
                            out[j++] = 'm';
                            out[j++] = 'p';
                            out[j++] = ';';
                            break;
                        case '<':
                            if (j + LT_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = 'l';
                            out[j++] = 't';
                            out[j++] = ';';
                            break;
                        case '>':
                            if (j + GT_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = 'g';
                            out[j++] = 't';
                            out[j++] = ';';
                            break;
                        case '\'':
                            // &apos; is valid in XML, but not in HTML, and numeric code is shorter
                            if (j + APOS_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = '#';
                            out[j++] = '3';
                            out[j++] = '9';
                            out[j++] = ';';
                            break;
                        case '\"':
                            // &quot; is valid in XML and HTML, but numeric code is shorter
                            if (j + QUOT_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = '#';
                            out[j++] = '3';
                            out[j++] = '4';
                            out[j++] = ';';
                            break;
                        default:
                            // invalid character
                            if (j >= m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = INVALID_CHARACTER_REPLACEMENT;
                            break;
                    }
                }
            } else if (ch < Character.MIN_HIGH_SURROGATE) {
                if (j >= m) {
                    return overflow(input, i, output, j);
                }
                if (ch > Unicode.MAX_C1_CTRL_CHAR || ch == Unicode.NEL) {
                    out[j++] = ch;
                } else {
                    // C1 control code
                    out[j++] = INVALID_CHARACTER_REPLACEMENT;
                }
            } else if (ch <= Character.MAX_HIGH_SURROGATE) {
                if (i + 1 < n) {
                    if (Character.isLowSurrogate(in[i + 1])) {
                        int cp = Character.toCodePoint(ch, in[i + 1]);
                        if (Unicode.isNonCharacter(cp)) {
                            // noncharacter
                            if (j >= m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = INVALID_CHARACTER_REPLACEMENT;
                            ++i;
                        } else {
                            if (j + 1 >= m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = ch;
                            out[j++] = in[++i];
                        }
                    } else {
                        // high without low
                        if (j >= m) {
                            return overflow(input, i, output, j);
                        }
                        out[j++] = INVALID_CHARACTER_REPLACEMENT;
                    }
                } else if (endOfInput) {
                    // end of input, high without low = invalid
                    if (j >= m) {
                        return overflow(input, i, output, j);
                    }
                    out[j++] = INVALID_CHARACTER_REPLACEMENT;
                } else {
                    break;
                }
            } else if (// low surrogate without preceding high surrogate
                    ch <= Character.MAX_LOW_SURROGATE
                    // or non-characters
                    || ch > '\ufffd'
                    || ('\ufdd0' <= ch && ch <= '\ufdef'))
            {
                if (j >= m) {
                    return overflow(input, i, output, j);
                }
                out[j++] = INVALID_CHARACTER_REPLACEMENT;
            } else {
                if (j >= m) {
                    return overflow(input, i, output, j);
                }
                out[j++] = ch;
            }
        }

        return underflow(input, i, output, j);
    }
protected CoderResult encodeArrays(CharBuffer input, CharBuffer output, boolean endOfInput) {
        final char[] in = input.array();
        final char[] out = output.array();
        int i = input.arrayOffset() + input.position();
        final int n = input.arrayOffset() + input.limit();
        int j = output.arrayOffset() + output.position();
        final int m = output.arrayOffset() + output.limit();

        for (; i < n; ++i) {
            final char ch = in[i];
            if (ch < Unicode.DEL) {
                if (ch > '>' || ((_validMask & (1L << ch)) != 0)) {
                    // Common case ('>' .. '~') reached in two branches
                    if (j >= m) {
                        return overflow(input, i, output, j);
                    }
                    out[j++] = ch;
                } else {
                    switch (ch) {
                        case '&':
                            if (j + AMP_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = 'a';
                            out[j++] = 'm';
                            out[j++] = 'p';
                            out[j++] = ';';
                            break;
                        case '<':
                            if (j + LT_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = 'l';
                            out[j++] = 't';
                            out[j++] = ';';
                            break;
                        case '>':
                            if (j + GT_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = 'g';
                            out[j++] = 't';
                            out[j++] = ';';
                            break;
                        case '\'':
                            // &apos; is valid in XML, but not in HTML, and numeric code is shorter
                            if (j + APOS_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = '#';
                            out[j++] = '3';
                            out[j++] = '9';
                            out[j++] = ';';
                            break;
                        case '\"':
                            // &quot; is valid in XML and HTML, but numeric code is shorter
                            if (j + QUOT_LENGTH > m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = '&';
                            out[j++] = '#';
                            out[j++] = '3';
                            out[j++] = '4';
                            out[j++] = ';';
                            break;
                        default:
                            // invalid character
                            if (j >= m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = INVALID_CHARACTER_REPLACEMENT;
                            break;
                    }
                }
            } else if (ch < Character.MIN_HIGH_SURROGATE) {
                if (j >= m) {
                    return overflow(input, i, output, j);
                }
                if (ch > Unicode.MAX_C1_CTRL_CHAR || ch == Unicode.NEL) {
                    out[j++] = ch;
                } else {
                    // C1 control code
                    out[j++] = INVALID_CHARACTER_REPLACEMENT;
                }
            } else if (ch <= Character.MAX_HIGH_SURROGATE) {
                if (i + 1 < n) {
                    if (Character.isLowSurrogate(in[i + 1])) {
                        int cp = Character.toCodePoint(ch, in[i + 1]);
                        if (Unicode.isNonCharacter(cp)) {
                            // noncharacter
                            if (j >= m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = INVALID_CHARACTER_REPLACEMENT;
                            ++i;
                        } else {
                            if (j + 1 >= m) {
                                return overflow(input, i, output, j);
                            }
                            out[j++] = ch;
                            out[j++] = in[++i];
                        }
                    } else {
                        // high without low
                        if (j >= m) {
                            return overflow(input, i, output, j);
                        }
                        out[j++] = INVALID_CHARACTER_REPLACEMENT;
                    }
                } else if (endOfInput) {
                    // end of input, high without low = invalid
                    if (j >= m) {
                        return overflow(input, i, output, j);
                    }
                    out[j++] = INVALID_CHARACTER_REPLACEMENT;
                } else {
                    break;
                }
            } else if (// low surrogate without preceding high surrogate
                    ch <= Character.MAX_LOW_SURROGATE
                    // or non-characters
                    || ch > '\ufffd'
                    || ('\ufdd0' <= ch && ch <= '\ufdef'))
            {
                if (j >= m) {
                    return overflow(input, i, output, j);
                }
                out[j++] = INVALID_CHARACTER_REPLACEMENT;
            } else {
                if (j >= m) {
                    return overflow(input, i, output, j);
                }
                out[j++] = ch;
            }
        }

        return underflow(input, i, output, j);
    }
{@inheritDoc}