1993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira/** 2993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * Copyright (c) 2006, Google Inc. 3993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 4993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License"); 5993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * you may not use this file except in compliance with the License. 6993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * You may obtain a copy of the License at 7993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 8993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * http://www.apache.org/licenses/LICENSE-2.0 9993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 10993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * Unless required by applicable law or agreed to in writing, software 11993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS, 12993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * See the License for the specific language governing permissions and 14993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * limitations under the License. 15993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira */ 16993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 171bdbfefe4b144c7b031a1d9242a0fa061a0ae6b5Scott Kennedypackage com.google.android.mail.common.base; 18993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 191bdbfefe4b144c7b031a1d9242a0fa061a0ae6b5Scott Kennedyimport static com.google.android.mail.common.base.Preconditions.checkNotNull; 20993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 21993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereiraimport java.io.IOException; 22993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 23993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira/** 24993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * An object that converts literal text into a format safe for inclusion in a particular context 25993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * (such as an XML document). Typically (but not always), the inverse process of "unescaping" the 26993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * text is performed automatically by the relevant parser. 27993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 28993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * <p>For example, an XML escaper would convert the literal string {@code "Foo<Bar>"} into {@code 29993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * "Foo<Bar>"} to prevent {@code "<Bar>"} from being confused with an XML tag. When the 30993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * resulting XML document is parsed, the parser API will return this text as the original literal 31993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * string {@code "Foo<Bar>"}. 32993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 33993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * <p>A {@code CharEscaper} instance is required to be stateless, and safe when used concurrently by 34993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * multiple threads. 35993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 36993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * <p>Several popular escapers are defined as constants in the class {@link CharEscapers}. To create 37993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * your own escapers, use {@link CharEscaperBuilder}, or extend this class and implement the {@link 38993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * #escape(char)} method. 39993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 40993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @author sven@google.com (Sven Mawson) 41993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira */ 42993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereirapublic abstract class CharEscaper extends Escaper { 43993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira /** 44993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * Returns the escaped form of a given literal string. 45993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 46993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @param string the literal string to be escaped 47993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @return the escaped form of {@code string} 48993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @throws NullPointerException if {@code string} is null 49993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira */ 50993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira @Override public String escape(String string) { 51993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira checkNotNull(string); 52993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // Inlineable fast-path loop which hands off to escapeSlow() only if needed 53993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int length = string.length(); 54993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira for (int index = 0; index < length; index++) { 55993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira if (escape(string.charAt(index)) != null) { 56993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira return escapeSlow(string, index); 57993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 58993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 59993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira return string; 60993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 61993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 62993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira /** 63993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * Returns an {@code Appendable} instance which automatically escapes all text appended to it 64993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * before passing the resulting text to an underlying {@code Appendable}. 65993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 66993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * <p>The methods of the returned object will propagate any exceptions thrown by the underlying 67993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * {@code Appendable}, and will throw {@link NullPointerException} if asked to append {@code 68993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * null}, but do not otherwise throw any exceptions. 69993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 70993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * <p>The escaping behavior is identical to that of {@link #escape(String)}, so the following code 71993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * is always equivalent to {@code escaper.escape(string)}: <pre> {@code 72993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 73993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * StringBuilder sb = new StringBuilder(); 74993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * escaper.escape(sb).append(string); 75993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * return sb.toString();}</pre> 76993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 77993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @param out the underlying {@code Appendable} to append escaped output to 78993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @return an {@code Appendable} which passes text to {@code out} after escaping it 79993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @throws NullPointerException if {@code out} is null. 80993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira */ 81993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira @Override public Appendable escape(final Appendable out) { 82993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira checkNotNull(out); 83993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 84993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira return new Appendable() { 85993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira @Override public Appendable append(CharSequence csq) throws IOException { 86993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira out.append(escape(csq.toString())); 87993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira return this; 88993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 89993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 90993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira @Override public Appendable append(CharSequence csq, int start, int end) throws IOException { 91993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira out.append(escape(csq.subSequence(start, end).toString())); 92993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira return this; 93993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 94993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 95993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira @Override public Appendable append(char c) throws IOException { 96993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira char[] escaped = escape(c); 97993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira if (escaped == null) { 98993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira out.append(c); 99993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } else { 100993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira for (char e : escaped) { 101993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira out.append(e); 102993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 103993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 104993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira return this; 105993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 106993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira }; 107993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 108993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 109993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira /** 110993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * Returns the escaped form of a given literal string, starting at the given index. This method is 111993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * called by the {@link #escape(String)} method when it discovers that escaping is required. It is 112993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * protected to allow subclasses to override the fastpath escaping function to inline their 113993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * escaping test. See {@link CharEscaperBuilder} for an example usage. 114993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 115993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @param s the literal string to be escaped 116993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @param index the index to start escaping from 117993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @return the escaped form of {@code string} 118993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @throws NullPointerException if {@code string} is null 119993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira */ 120993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira protected String escapeSlow(String s, int index) { 121993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int slen = s.length(); 122993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 123993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // Get a destination buffer and setup some loop variables. 124993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira char[] dest = Platform.charBufferFromThreadLocal(); 125993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int destSize = dest.length; 126993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int destIndex = 0; 127993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int lastEscape = 0; 128993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 129993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // Loop through the rest of the string, replacing when needed into the 130993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // destination buffer, which gets grown as needed as well. 131993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira for (; index < slen; index++) { 132993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 133993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // Get a replacement for the current character. 134993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira char[] r = escape(s.charAt(index)); 135993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 136993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // If no replacement is needed, just continue. 137993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira if (r == null) continue; 138993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 139993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int rlen = r.length; 140993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int charsSkipped = index - lastEscape; 141993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 142993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // This is the size needed to add the replacement, not the full size needed by the string. We 143993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // only regrow when we absolutely must. 144993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int sizeNeeded = destIndex + charsSkipped + rlen; 145993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira if (destSize < sizeNeeded) { 146993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira destSize = sizeNeeded + (slen - index) + DEST_PAD; 147993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira dest = growBuffer(dest, destIndex, destSize); 148993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 149993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 150993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // If we have skipped any characters, we need to copy them now. 151993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira if (charsSkipped > 0) { 152993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira s.getChars(lastEscape, index, dest, destIndex); 153993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira destIndex += charsSkipped; 154993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 155993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 156993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // Copy the replacement string into the dest buffer as needed. 157993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira if (rlen > 0) { 158993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira System.arraycopy(r, 0, dest, destIndex, rlen); 159993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira destIndex += rlen; 160993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 161993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira lastEscape = index + 1; 162993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 163993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 164993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // Copy leftover characters if there are any. 165993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int charsLeft = slen - lastEscape; 166993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira if (charsLeft > 0) { 167993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira int sizeNeeded = destIndex + charsLeft; 168993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira if (destSize < sizeNeeded) { 169993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 170993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira // Regrow and copy, expensive! No padding as this is the final copy. 171993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira dest = growBuffer(dest, destIndex, sizeNeeded); 172993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 173993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira s.getChars(lastEscape, slen, dest, destIndex); 174993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira destIndex = sizeNeeded; 175993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 176993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira return new String(dest, 0, destIndex); 177993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 178993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 179993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira /** 180993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * Returns the escaped form of the given character, or {@code null} if this character does not 181993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * need to be escaped. If an empty array is returned, this effectively strips the input character 182993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * from the resulting text. 183993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 184993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * <p>If the character does not need to be escaped, this method should return {@code null}, rather 185993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * than a one-character array containing the character itself. This enables the escaping algorithm 186993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * to perform more efficiently. 187993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 188993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * <p>An escaper is expected to be able to deal with any {@code char} value, so this method should 189993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * not throw any exceptions. 190993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * 191993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @param c the character to escape if necessary 192993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * @return the replacement characters, or {@code null} if no escaping was needed 193993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira */ 194993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira protected abstract char[] escape(char c); 195993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 196993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira /** 197993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * Helper method to grow the character buffer as needed, this only happens once in a while so it's 198993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * ok if it's in a method call. If the index passed in is 0 then no copying will be done. 199993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira */ 200993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira private static char[] growBuffer(char[] dest, int index, int size) { 201993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira char[] copy = new char[size]; 202993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira if (index > 0) { 203993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira System.arraycopy(dest, 0, copy, 0, index); 204993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 205993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira return copy; 206993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira } 207993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira 208993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira /** 209993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira * The amount of padding to use when growing the escape buffer. 210993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira */ 211993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira private static final int DEST_PAD = 32; 212993ef2674bf860a84c5c17e51a7a9e13e5d56504Mindy Pereira}