001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 2007.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.query.parser.serql;
007:
008: import info.aduna.text.StringUtil;
009:
010: /**
011: * SeRQL-related utility methods.
012: *
013: * @author Arjohn Kampman
014: */
015: public class SeRQLUtil {
016:
017: /**
018: * Encodes the supplied string for inclusion as a 'normal' string in a SeRQL
019: * query.
020: */
021: public static String encodeString(String s) {
022: s = StringUtil.gsub("\\", "\\\\", s);
023: s = StringUtil.gsub("\t", "\\t", s);
024: s = StringUtil.gsub("\n", "\\n", s);
025: s = StringUtil.gsub("\r", "\\r", s);
026: s = StringUtil.gsub("\b", "\\b", s);
027: s = StringUtil.gsub("\f", "\\f", s);
028: s = StringUtil.gsub("\"", "\\\"", s);
029: return s;
030: }
031:
032: /**
033: * Decodes an encoded SeRQL string. Any \-escape sequences are substituted
034: * with their decoded value.
035: *
036: * @param s
037: * An encoded SeRQL string.
038: * @return The unencoded string.
039: * @exception IllegalArgumentException
040: * If the supplied string is not a correctly encoded SeRQL
041: * string.
042: */
043: public static String decodeString(String s) {
044: int backSlashIdx = s.indexOf('\\');
045:
046: if (backSlashIdx == -1) {
047: // No escaped characters found
048: return s;
049: }
050:
051: int startIdx = 0;
052: int sLength = s.length();
053: StringBuilder sb = new StringBuilder(sLength);
054:
055: while (backSlashIdx != -1) {
056: sb.append(s.substring(startIdx, backSlashIdx));
057:
058: if (backSlashIdx + 1 >= sLength) {
059: throw new IllegalArgumentException(
060: "Unescaped backslash in: " + s);
061: }
062:
063: char c = s.charAt(backSlashIdx + 1);
064:
065: if (c == 't') {
066: sb.append('\t');
067: startIdx = backSlashIdx + 2;
068: } else if (c == 'n') {
069: sb.append('\n');
070: startIdx = backSlashIdx + 2;
071: } else if (c == 'r') {
072: sb.append('\r');
073: startIdx = backSlashIdx + 2;
074: } else if (c == 'b') {
075: sb.append('\b');
076: startIdx = backSlashIdx + 2;
077: } else if (c == 'f') {
078: sb.append('\f');
079: startIdx = backSlashIdx + 2;
080: } else if (c == '"') {
081: sb.append('"');
082: startIdx = backSlashIdx + 2;
083: } else if (c == '\\') {
084: sb.append('\\');
085: startIdx = backSlashIdx + 2;
086: } else if (c == 'u') {
087: // \\uxxxx
088:if (backSlashIdx + 5 >= sLength) {
089: throw new IllegalArgumentException(
090: "Incomplete Unicode escape sequence in: "
091: + s);
092: }
093: String xx = s.substring(backSlashIdx + 2,
094: backSlashIdx + 6);
095:
096: try {
097: c = (char) Integer.parseInt(xx, 16);
098: sb.append(c);
099:
100: startIdx = backSlashIdx + 6;
101: } catch (NumberFormatException e) {
102: throw new IllegalArgumentException(
103: "Illegal Unicode escape sequence '\\u" + xx
104: + "' in: " + s);
105: }
106: } else if (c == 'U') {
107: // \\Uxxxxxxxx
108: if (backSlashIdx + 9 >= sLength) {
109: throw new IllegalArgumentException(
110: "Incomplete Unicode escape sequence in: "
111: + s);
112: }
113: String xx = s.substring(backSlashIdx + 2,
114: backSlashIdx + 10);
115:
116: try {
117: c = (char) Integer.parseInt(xx, 16);
118: sb.append(c);
119:
120: startIdx = backSlashIdx + 10;
121: } catch (NumberFormatException e) {
122: throw new IllegalArgumentException(
123: "Illegal Unicode escape sequence '\\U" + xx
124: + "' in: " + s);
125: }
126: } else {
127: throw new IllegalArgumentException(
128: "Unescaped backslash in: " + s);
129: }
130:
131: backSlashIdx = s.indexOf('\\', startIdx);
132: }
133:
134: sb.append(s.substring(startIdx));
135:
136: return sb.toString();
137: }
138: }
|