/* * Copyright Aduna (http://www.aduna-software.com/) (c) 2007. * * Licensed under the Aduna BSD-style license. */ package org.openrdf.query.parser.serql; import info.aduna.text.StringUtil; /** * SeRQL-related utility methods. * * @author Arjohn Kampman */ public class SeRQLUtil { /** * Encodes the supplied string for inclusion as a 'normal' string in a SeRQL * query. */ public static String encodeString(String s) { s = StringUtil.gsub("\\", "\\\\", s); s = StringUtil.gsub("\t", "\\t", s); s = StringUtil.gsub("\n", "\\n", s); s = StringUtil.gsub("\r", "\\r", s); s = StringUtil.gsub("\b", "\\b", s); s = StringUtil.gsub("\f", "\\f", s); s = StringUtil.gsub("\"", "\\\"", s); return s; } /** * Decodes an encoded SeRQL string. Any \-escape sequences are substituted * with their decoded value. * * @param s * An encoded SeRQL string. * @return The unencoded string. * @exception IllegalArgumentException * If the supplied string is not a correctly encoded SeRQL * string. */ public static String decodeString(String s) { int backSlashIdx = s.indexOf('\\'); if (backSlashIdx == -1) { // No escaped characters found return s; } int startIdx = 0; int sLength = s.length(); StringBuilder sb = new StringBuilder(sLength); while (backSlashIdx != -1) { sb.append(s.substring(startIdx, backSlashIdx)); if (backSlashIdx + 1 >= sLength) { throw new IllegalArgumentException("Unescaped backslash in: " + s); } char c = s.charAt(backSlashIdx + 1); if (c == 't') { sb.append('\t'); startIdx = backSlashIdx + 2; } else if (c == 'n') { sb.append('\n'); startIdx = backSlashIdx + 2; } else if (c == 'r') { sb.append('\r'); startIdx = backSlashIdx + 2; } else if (c == 'b') { sb.append('\b'); startIdx = backSlashIdx + 2; } else if (c == 'f') { sb.append('\f'); startIdx = backSlashIdx + 2; } else if (c == '"') { sb.append('"'); startIdx = backSlashIdx + 2; } else if (c == '\\') { sb.append('\\'); startIdx = backSlashIdx + 2; } else if (c == 'u') { // \\uxxxx if (backSlashIdx + 5 >= sLength) { throw new IllegalArgumentException( "Incomplete Unicode escape sequence in: " + s); } String xx = s.substring(backSlashIdx + 2, backSlashIdx + 6); try { c = (char)Integer.parseInt(xx, 16); sb.append( c ); startIdx = backSlashIdx + 6; } catch (NumberFormatException e) { throw new IllegalArgumentException( "Illegal Unicode escape sequence '\\u" + xx + "' in: " + s); } } else if (c == 'U') { // \\Uxxxxxxxx if (backSlashIdx + 9 >= sLength) { throw new IllegalArgumentException( "Incomplete Unicode escape sequence in: " + s); } String xx = s.substring(backSlashIdx + 2, backSlashIdx + 10); try { c = (char)Integer.parseInt(xx, 16); sb.append( c ); startIdx = backSlashIdx + 10; } catch (NumberFormatException e) { throw new IllegalArgumentException( "Illegal Unicode escape sequence '\\U" + xx + "' in: " + s); } } else { throw new IllegalArgumentException("Unescaped backslash in: " + s); } backSlashIdx = s.indexOf('\\', startIdx); } sb.append(s.substring(startIdx)); return sb.toString(); } }