--- jlscp/trunk/src/org/linuxsampler/lscp/Parser.java 2007/09/13 21:46:25 1345
+++ jlscp/trunk/src/org/linuxsampler/lscp/Parser.java 2007/09/13 22:02:03 1346
@@ -31,7 +31,7 @@
* This class contains only helper functions that are used from the other classes in this library.
* @author Grigor Iliev
*/
-final class Parser {
+public final class Parser {
/** Forbits the instantiatrion of this class */
private Parser() { }
@@ -170,6 +170,56 @@
}
/**
+ * Parses a comma separated string list, which elements contains escaped sequences.
+ * @param list The list to parse.
+ * @return A String
array containing all items in the list.
+ */
+ protected static String[]
+ parseEscapedStringList(String list) throws LscpException {
+ return parseEscapedStringList(list, ',');
+ }
+
+ /**
+ * Parses a string list, which elements contains escaped sequences.
+ * @param list The list to parse.
+ * @param separator Provides the character used as separator.
+ * @return A String
array containing all items in the list.
+ */
+ protected static String[]
+ parseEscapedStringList(String list, char separator) throws LscpException {
+ if(list == null || list.length() == 0) return new String[0];
+ int q1 = 0, q2 = 0;
+ Vector v = new Vector();
+
+ for(;;) {
+ if(list.charAt(q1) != '\'')
+ throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
+ q2 = findApostrophe(list, q1 + 1);
+ if(q2 == -1) throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
+ v.add(list.substring(q1 + 1, q2));
+
+ if(q2 + 1 >= list.length()) break;
+
+ if(list.charAt(q2 + 1) != separator)
+ throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
+ q1 = q2 + 2;
+ if(q1 >= list.length())
+ throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
+ }
+
+ return v.toArray(new String[v.size()]);
+ }
+
+ /**
+ * Returns the index of the first occurrence of a non-escaped apostrophe
+ * in the specified string, starting at index, or -1 if nothing is found.
+ */
+ private static int
+ findApostrophe(String s, int index) {
+ return findNonEscapedChar(s, index, '\'');
+ }
+
+ /**
* Parses a comma separated list whose items are encapsulated into apostrophes.
* @param list The comma separated list.
* @return A String
array containing all items in the list.
@@ -480,11 +530,37 @@
/**
* Returns the provided string with added escape sequences where necessary.
*/
- protected static String
- getEscapedString(String s) {
+ public static String
+ toEscapedString(Object obj) {
+ String s = obj.toString();
+ StringBuffer sb = new StringBuffer();
+ for(int i = 0; i < s.length(); i++) {
+ switch(s.charAt(i)) {
+ case '\n': sb.append("\\n"); break;
+ case '\r': sb.append("\\r"); break;
+ case '\f': sb.append("\\f"); break;
+ case '\t': sb.append("\\t"); break;
+ case 0x0B: sb.append("\\v"); break;
+ case '\'': sb.append("\\'"); break;
+ case '\"': sb.append("\\\""); break;
+ case '\\': sb.append("\\\\"); break;
+ default : sb.append(s.charAt(i));
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Returns the provided file name with added escape sequences where necessary.
+ */
+ public static String
+ toEscapedFileName(Object obj) {
+ String s = obj.toString();
StringBuffer sb = new StringBuffer();
for(int i = 0; i < s.length(); i++) {
switch(s.charAt(i)) {
+ case '/' : sb.append("\\/"); break;
case '\n': sb.append("\\n"); break;
case '\r': sb.append("\\r"); break;
case '\f': sb.append("\\f"); break;
@@ -499,4 +575,211 @@
return sb.toString();
}
+
+ /**
+ * Removes the escape sequences from the specified file name
+ * @return The provided file name with removed escape sequences.
+ */
+ public static String
+ toNonEscapedFileName(Object obj) {
+ String s = obj.toString();
+ StringBuffer sb = new StringBuffer();
+ for(int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if(c == '\\') {
+ if(i >= s.length()) {
+ Client.getLogger().info("Broken escape sequence");
+ break;
+ }
+ char c2 = s.charAt(++i);
+ if(c2 == '\'') sb.append('\'');
+ else if(c2 == '"') sb.append('"');
+ else if(c2 == '\\') sb.append('\\');
+ else if(c2 == 'r') sb.append('\r');
+ else if(c2 == 'n') sb.append('\n');
+ else if(c2 == '/') sb.append('/');
+ else Client.getLogger().info("Unknown escape sequence \\" + c2);
+ } else {
+ sb.append(c);
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Removes the escape sequences from the string obj.toString()
.
+ * @return The provided text with removed escape sequences.
+ */
+ public static String
+ toNonEscapedText(Object obj) {
+ String s = obj.toString();
+ StringBuffer sb = new StringBuffer();
+ for(int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if(c == '\\') {
+ if(i >= s.length()) {
+ Client.getLogger().info("Broken escape sequence");
+ break;
+ }
+ char c2 = s.charAt(++i);
+ if(c2 == '\'') sb.append('\'');
+ else if(c2 == '"') sb.append('"');
+ else if(c2 == '\\') sb.append('\\');
+ else if(c2 == 'r') sb.append('\r');
+ else if(c2 == 'n') sb.append('\n');
+ else Client.getLogger().info("Unknown escape sequence \\" + c2);
+ } else {
+ sb.append(c);
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Determines whether the character at the specified position
+ * is escaped with backslash.
+ */
+ public static boolean
+ isEscaped(String s, int index) {
+ if (index < 0 || index >= s.length()) return false;
+ int count = 0;
+ for (int i = index - 1; i >= 0; i--) {
+ if (s.charAt(i) != '\\') break;
+ count++;
+ }
+ return count % 2 != 0;
+ }
+
+ /**
+ * Returns the index of the first occurrence of the specified non-escaped character
+ * in the specified string, starting at index, or -1 if nothing is found.
+ */
+ private static int
+ findNonEscapedChar(String s, int index, char c) {
+ if(s == null) return -1;
+ int pos = index;
+ if (pos < 0 || pos >= s.length()) return -1;
+
+ for(;;) {
+ int i = s.indexOf(c, pos);
+ if (i == -1) break;
+ if (!isEscaped(s, i)) return i;
+ pos = i + 1;
+ if (pos >= s.length()) break;
+ }
+
+ return -1;
+ }
+
+ /**
+ * Returns the index of the first occurrence of a file separator
+ * in the specified escaped path, starting at index, or -1 if nothing is found.
+ */
+ private static int
+ findFileSeparator(String path, int index) {
+ return findNonEscapedChar(path, index, '/');
+ }
+
+ /**
+ * Gets the position of the last file separator in the specified
+ * escaped path, or -1 if failed.
+ */
+ private static int
+ getLastFileSeparator(String path) {
+ if(path == null || path.length() == 0) return -1;
+ int pos = path.length() - 1;
+
+ for(;;) {
+ pos = path.lastIndexOf('/', pos);
+ if(pos == -1) return -1;
+ if(!isEscaped(path, pos)) return pos;
+ pos--;
+ }
+ }
+
+ /**
+ * Determines whether the specified escaped path ends with a file separator.
+ */
+ protected static boolean
+ hasEndingFileSeparator(String path) {
+ if(path == null || path.length() < 2) return false;
+
+ int last = path.length() - 1;
+ if(path.charAt(last) == '/' && !isEscaped(path, last)) return true;
+
+ return false;
+ }
+
+ /**
+ * If the specified escaped path ends with a file separator,
+ * a new string is returned with the ending file separator removed.
+ */
+ protected static String
+ removeEndingFileSeparator(String path) {
+ if(path == null || path.length() < 2) return path;
+
+ int last = path.length() - 1;
+ if(path.charAt(last) == '/' && !isEscaped(path, last)) {
+ path = path.substring(0, path.length() - 1);
+ }
+
+ return path;
+ }
+
+ /**
+ * Gets the parent directory of the specified escaped path.
+ */
+ public static String
+ getParentDirectory(String path) {
+ if(path == null || path.length() == 0) return null;
+ if(path.charAt(0) != '/') return null;
+ if(path.length() == 1) return null;
+
+ path = removeEndingFileSeparator(path);
+
+ int i = getLastFileSeparator(path);
+ if(i == 0) return "/";
+ return path.substring(0, i);
+ }
+
+ /**
+ * Extracts the file name from the specified escaped path.
+ * If the path does not ends with a file name, null
is returned.
+ */
+ public static String
+ getFileName(String path) {
+ if(path == null || path.length() < 2) return null;
+ int i = getLastFileSeparator(path);
+ if(i == -1) return null;
+ if(i == path.length() - 1) return null;
+ return path.substring(i + 1);
+ }
+
+ /**
+ * Returns an array containing all directories in the specified escaped path.
+ */
+ public static String[]
+ getDirectoryList(String path) {
+ if(path == null || path.length() == 0) return null;
+ if(path.charAt(0) != '/') return null;
+ Vector v = new Vector();
+ v.add("/");
+ if(path.length() == 1) return v.toArray(new String[v.size()]);
+
+ if(!hasEndingFileSeparator(path)) path += "/";
+ int i = 1;
+ int j = findFileSeparator(path, i);
+
+ while(j != -1) {
+ v.add(path.substring(i, j));
+
+ i = j + 1;
+ if(i >= path.length()) return v.toArray(new String[v.size()]);
+ j = findFileSeparator(path, i);
+ }
+
+ return null;
+ }
}