StringUtil { public static CharSequence unescapeCsv(CharSequence value) { int length = checkNotNull(value, "value").length(); if (length == 0) { return value; } int last = length - 1; boolean quoted = isDoubleQuote(value.charAt(0)) && isDoubleQuote(value.charAt(last)) && length != 1; if (!quoted) { validateCsvFormat(value); return value; } StringBuilder unescaped = InternalThreadLocalMap.get().stringBuilder(); for (int i = 1; i < last; i++) { char current = value.charAt(i); if (current == DOUBLE_QUOTE) { if (isDoubleQuote(value.charAt(i + 1)) && (i + 1) != last) { i++; } else { throw newInvalidEscapedCsvFieldException(value, i); } } unescaped.append(current); } return unescaped.toString(); } private  StringUtil(); static String substringAfter(String value, char delim); static boolean commonSuffixOfLength(String s, String p, int len); static String byteToHexStringPadded(int value); static T byteToHexStringPadded(T buf, int value); static String toHexStringPadded(byte[] src); static String toHexStringPadded(byte[] src, int offset, int length); static T toHexStringPadded(T dst, byte[] src); static T toHexStringPadded(T dst, byte[] src, int offset, int length); static String byteToHexString(int value); static T byteToHexString(T buf, int value); static String toHexString(byte[] src); static String toHexString(byte[] src, int offset, int length); static T toHexString(T dst, byte[] src); static T toHexString(T dst, byte[] src, int offset, int length); static int decodeHexNibble(final char c); static byte decodeHexByte(CharSequence s, int pos); static byte[] decodeHexDump(CharSequence hexDump, int fromIndex, int length); static byte[] decodeHexDump(CharSequence hexDump); static String simpleClassName(Object o); static String simpleClassName(Class<?> clazz); static CharSequence escapeCsv(CharSequence value); static CharSequence escapeCsv(CharSequence value, boolean trimWhiteSpace); static CharSequence unescapeCsv(CharSequence value); static List<CharSequence> unescapeCsvFields(CharSequence value); static int length(String s); static boolean isNullOrEmpty(String s); static int indexOfNonWhiteSpace(CharSequence seq, int offset); static boolean isSurrogate(char c); static boolean endsWith(CharSequence s, char c); static CharSequence trimOws(CharSequence value); static final String EMPTY_STRING; static final String NEWLINE; static final char DOUBLE_QUOTE; static final char COMMA; static final char LINE_FEED; static final char CARRIAGE_RETURN; static final char TAB; static final char SPACE; }
@Test public void testUnescapeCsv() { assertEquals("", unescapeCsv("")); assertEquals("\"", unescapeCsv("\"\"\"\"")); assertEquals("\"\"", unescapeCsv("\"\"\"\"\"\"")); assertEquals("\"\"\"", unescapeCsv("\"\"\"\"\"\"\"\"")); assertEquals("\"netty\"", unescapeCsv("\"\"\"netty\"\"\"")); assertEquals("netty", unescapeCsv("netty")); assertEquals("netty", unescapeCsv("\"netty\"")); assertEquals("\r", unescapeCsv("\"\r\"")); assertEquals("\n", unescapeCsv("\"\n\"")); assertEquals("hello,netty", unescapeCsv("\"hello,netty\"")); }
@Test(expected = IllegalArgumentException.class) public void unescapeCsvWithSingleQuote() { unescapeCsv("\""); }
@Test(expected = IllegalArgumentException.class) public void unescapeCsvWithOddQuote() { unescapeCsv("\"\"\""); }
@Test(expected = IllegalArgumentException.class) public void unescapeCsvWithCRAndWithoutQuote() { unescapeCsv("\r"); }
@Test(expected = IllegalArgumentException.class) public void unescapeCsvWithLFAndWithoutQuote() { unescapeCsv("\n"); }
@Test(expected = IllegalArgumentException.class) public void unescapeCsvWithCommaAndWithoutQuote() { unescapeCsv(","); }