/** * Transforms this literal (which must be of type character) into a new one in which 4-digit * Unicode escape sequences have been replaced with the corresponding Unicode characters. * * @param unicodeEscapeChar escape character (e.g. backslash) for Unicode numeric sequences; 0 * implies no transformation * @return transformed literal */ public SqlLiteral unescapeUnicode(char unicodeEscapeChar) { if (unicodeEscapeChar == 0) { return this; } assert SqlTypeUtil.inCharFamily(getTypeName()); NlsString ns = (NlsString) value; String s = ns.getValue(); StringBuilder sb = new StringBuilder(); int n = s.length(); for (int i = 0; i < n; ++i) { char c = s.charAt(i); if (c == unicodeEscapeChar) { if (n > (i + 1)) { if (s.charAt(i + 1) == unicodeEscapeChar) { sb.append(unicodeEscapeChar); ++i; continue; } } if ((i + 5) > n) { throw SqlUtil.newContextException( getParserPosition(), RESOURCE.unicodeEscapeMalformed(i)); } final String u = s.substring(i + 1, i + 5); final int v; try { v = Integer.parseInt(u, 16); } catch (NumberFormatException ex) { throw SqlUtil.newContextException( getParserPosition(), RESOURCE.unicodeEscapeMalformed(i)); } sb.append((char) (v & 0xFFFF)); // skip hexits i += 4; } else { sb.append(c); } } ns = new NlsString(sb.toString(), ns.getCharsetName(), ns.getCollation()); return new SqlCharStringLiteral(ns, getParserPosition()); }