private static String XMLOrHTMLEnc()

in freemarker-core/src/main/java/freemarker/template/utility/StringUtil.java [110:200]


    private static String XMLOrHTMLEnc(String s, boolean escGT, boolean escQuot, char[] apos) {
        final int ln = s.length();
        
        // First we find out if we need to escape, and if so, what the length of the output will be:
        int firstEscIdx = -1;
        int lastEscIdx = 0;
        int plusOutLn = 0;
        for (int i = 0; i < ln; i++) {
            escape: do {
                final char c = s.charAt(i);
                switch (c) {
                case '<':
                    plusOutLn += LT.length - 1;
                    break;
                case '>':
                    if (!(escGT || maybeCDataEndGT(s, i))) {
                        break escape;
                    }
                    plusOutLn += GT.length - 1;
                    break;
                case '&':
                    plusOutLn += AMP.length - 1;
                    break;
                case '"':
                    if (!escQuot) {
                        break escape;
                    }
                    plusOutLn += QUOT.length - 1;
                    break;
                case '\'': // apos
                    if (apos == null) {
                        break escape;
                    }
                    plusOutLn += apos.length - 1;
                    break;
                default:
                    break escape;
                }
                
                if (firstEscIdx == -1) {
                    firstEscIdx = i;
                }
                lastEscIdx = i;
            } while (false);
        }
        
        if (firstEscIdx == -1) {
            return s; // Nothing to escape
        } else {
            final char[] esced = new char[ln + plusOutLn];
            if (firstEscIdx != 0) {
                s.getChars(0, firstEscIdx, esced, 0);
            }
            int dst = firstEscIdx;
            scan: for (int i = firstEscIdx; i <= lastEscIdx; i++) {
                final char c = s.charAt(i);
                switch (c) {
                case '<':
                    dst = shortArrayCopy(LT, esced, dst);
                    continue scan;
                case '>':
                    if (!(escGT || maybeCDataEndGT(s, i))) {
                        break;
                    }
                    dst = shortArrayCopy(GT, esced, dst);
                    continue scan;
                case '&':
                    dst = shortArrayCopy(AMP, esced, dst);
                    continue scan;
                case '"':
                    if (!escQuot) {
                        break;
                    }
                    dst = shortArrayCopy(QUOT, esced, dst);
                    continue scan;
                case '\'': // apos
                    if (apos == null) {
                        break;
                    }
                    dst = shortArrayCopy(apos, esced, dst);
                    continue scan;
                }
                esced[dst++] = c;
            }
            if (lastEscIdx != ln - 1) {
                s.getChars(lastEscIdx + 1, ln, esced, dst);
            }
            
            return String.valueOf(esced);
        }
    }