You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@logging.apache.org by cakofony <gi...@git.apache.org> on 2018/07/11 21:26:14 UTC

[GitHub] logging-log4j2 pull request #190: [LOG4J2-2373] Reduce unnecessary char move...

Github user cakofony commented on a diff in the pull request:

    https://github.com/apache/logging-log4j2/pull/190#discussion_r201844357
  
    --- Diff: log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java ---
    @@ -169,53 +169,85 @@ public static void trimToMaxSize(final StringBuilder stringBuilder, final int ma
         }
     
         public static void escapeJson(final StringBuilder toAppendTo, final int start) {
    -        for (int i = toAppendTo.length() - 1; i >= start; i--) { // backwards: length may change
    +        int escapeCount = 0;
    +        for (int i = start; i < toAppendTo.length(); i++) {
                 final char c = toAppendTo.charAt(i);
                 switch (c) {
                     case '\b':
    -                    toAppendTo.setCharAt(i, '\\');
    -                    toAppendTo.insert(i + 1, 'b');
    +                case '\t':
    +                case '\f':
    +                case '\n':
    +                case '\r':
    +                case '"':
    +                case '\\':
    +                    escapeCount++;
    +                    break;
    +                default:
    +                    if (Character.isISOControl(c)) {
    +                        escapeCount += 5;
    +                    }
    +            }
    +        }
    +
    +        int lastChar = toAppendTo.length() - 1;
    +        toAppendTo.setLength(toAppendTo.length() + escapeCount);
    +        int lastPos = toAppendTo.length() - 1;
    +
    +        for (int i = lastChar; i >= start; i--) {
    +            final char c = toAppendTo.charAt(i);
    +            switch (c) {
    +                case '\b':
    +                    lastPos = escapeAndDecrement(toAppendTo, lastPos, 'b');
                         break;
     
                     case '\t':
    -                    toAppendTo.setCharAt(i, '\\');
    -                    toAppendTo.insert(i + 1, 't');
    +                    lastPos = escapeAndDecrement(toAppendTo, lastPos, 't');
                         break;
     
                     case '\f':
    -                    toAppendTo.setCharAt(i, '\\');
    -                    toAppendTo.insert(i + 1, 'f');
    +                    lastPos = escapeAndDecrement(toAppendTo, lastPos, 'f');
                         break;
     
                     case '\n':
    -                    // Json string newline character must be encoded as literal "\n"
    -                    toAppendTo.setCharAt(i, '\\');
    -                    toAppendTo.insert(i + 1, 'n');
    +                    lastPos = escapeAndDecrement(toAppendTo, lastPos, 'n');
                         break;
     
                     case '\r':
    -                    toAppendTo.setCharAt(i, '\\');
    -                    toAppendTo.insert(i + 1, 'r');
    +                    lastPos = escapeAndDecrement(toAppendTo, lastPos, 'r');
                         break;
     
                     case '"':
    +                    lastPos = escapeAndDecrement(toAppendTo, lastPos, '"');
    +                    break;
                     case '\\':
    -                    // only " and \ need to be escaped; other escapes are optional
    -                    toAppendTo.insert(i, '\\');
    +                    lastPos = escapeAndDecrement(toAppendTo, lastPos, '\\');
    --- End diff --
    
    Might as well combine `\` and `"`, in both cases the char `c` is the escaped character


---