package com.fasterxml.jackson.dataformat.javaprop.io;

import java.util.Arrays;

Container class for definitions of characters to escape.
/** * Container class for definitions of characters to escape. */
public class JPropEscapes { private final static char[] HEX = "0123456789ABCDEF".toCharArray(); private final static int UNICODE_ESCAPE = -1; private final static int[] sValueEscapes; static { final int[] table = new int[256]; // For values, fewer escapes needed, but most control chars need them for (int i = 0; i < 32; ++i) { table[i] = UNICODE_ESCAPE; // also high-bit ones table[128+i] = UNICODE_ESCAPE; } // also, that one weird character needs escaping: table[0x7F] = UNICODE_ESCAPE; // except for "well-known" ones table['\t'] = 't'; table['\r'] = 'r'; table['\n'] = 'n'; // Beyond that, just backslash table['\\'] = '\\'; sValueEscapes = table; } private final static int[] sKeyEscapes; static { // with keys, start with value escapes, and add the rest final int[] table = Arrays.copyOf(sValueEscapes, 256); // comment line starters (could get by with just start char but whatever) table['#'] = '#'; table['!'] = '!'; // and then equals (and equivalents) that mark end of key table['='] = '='; table[':'] = ':'; // plus space chars are escapes too table[' '] = ' '; sKeyEscapes = table; } public static void appendKey(StringBuilder sb, String key) { final int end = key.length(); if (end == 0) { return; } final int[] esc = sKeyEscapes; // first quick loop for common case of no escapes int i = 0; while (true) { char c = key.charAt(i); if ((c > 0xFF) || esc[c] != 0) { break; } sb.append(c); if (++i == end) { return; } } _appendWithEscapes(sb, key, esc, i); } public static StringBuilder appendValue(String value) { final int end = value.length(); if (end == 0) { return null; // nothing to write, but "write as is" } final int[] esc = sValueEscapes; int i = 0; // little bit different here; we scan to ensure nothing to escape while (true) { char c = value.charAt(i); if ((c > 0xFF) || esc[c] != 0) { break; } if (++i == end) { return null; // write as-is } } // if not real work StringBuilder sb = new StringBuilder(end + 5 + (end>>3)); for (int j = 0; j < i; ++j) { sb.append(value.charAt(j)); } _appendWithEscapes(sb, value, esc, i); return sb; } private static void _appendWithEscapes(StringBuilder sb, String key, int[] esc, int i) { final int end = key.length(); do { char c = key.charAt(i); int type = (c > 0xFF) ? UNICODE_ESCAPE : esc[c]; if (type == 0) { sb.append(c); continue; } if (type == UNICODE_ESCAPE) { sb.append('\\'); sb.append('u'); sb.append(HEX[c >>> 12]); sb.append(HEX[(c >> 8) & 0xF]); sb.append(HEX[(c >> 4) & 0xF]); sb.append(HEX[c & 0xF]); } else { sb.append('\\'); sb.append((char) type); } } while (++i < end); } }