/[svn]/jlscp/trunk/src/org/linuxsampler/lscp/Parser.java
ViewVC logotype

Diff of /jlscp/trunk/src/org/linuxsampler/lscp/Parser.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 784 by iliev, Mon Oct 10 14:55:44 2005 UTC revision 1393 by iliev, Sun Oct 7 20:29:41 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *   jlscp - a java LinuxSampler control protocol API   *   jlscp - a java LinuxSampler control protocol API
3   *   *
4   *   Copyright (C) 2005 Grigor Kirilov Iliev   *   Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of jlscp.   *   This file is part of jlscp.
7   *   *
# Line 31  import java.util.Vector; Line 31  import java.util.Vector;
31   * This class contains only helper functions that are used from the other classes in this library.   * This class contains only helper functions that are used from the other classes in this library.
32   * @author  Grigor Iliev   * @author  Grigor Iliev
33   */   */
34  final class Parser {  public final class Parser {
35            /** Forbits the instantiatrion of this class */
36            private Parser() { }
37            
38          /**          /**
39           * Parses an integer value.           * Parses an integer value.
40           * @param s The integer value to be parsed.           * @param s The integer value to be parsed.
# Line 65  final class Parser { Line 68  final class Parser {
68           * @return A <code>String</code> array containing all items in the list.           * @return A <code>String</code> array containing all items in the list.
69           */           */
70          protected static String[]          protected static String[]
71          parseList(String list) {          parseList(String list) { return parseList(list, ','); }
72            
73            /**
74             * Parses a list.
75             * @param list The list to parse.
76             * @param separator Provides the character used as separator.
77             * @return A <code>String</code> array containing all items in the list.
78             */
79            protected static String[]
80            parseList(String list, char separator) {
81                  if(list == null || list.length() == 0) return new String[0];                  if(list == null || list.length() == 0) return new String[0];
82                  int pos = 0;                  int pos = 0;
83                  int idx;                  int idx;
84                  Vector<String> v = new Vector<String>();                  Vector<String> v = new Vector<String>();
85                  while((idx = list.indexOf(',', pos)) > 0) {                  while((idx = list.indexOf(separator, pos)) > 0) {
86                          v.add(list.substring(pos, idx));                          v.add(list.substring(pos, idx));
87                          pos = idx + 1;                          pos = idx + 1;
88                  }                  }
# Line 106  final class Parser { Line 118  final class Parser {
118           * @throws LscpException if the list contains value(s) from different type.           * @throws LscpException if the list contains value(s) from different type.
119           */           */
120          protected static Integer[]          protected static Integer[]
121          parseIntList(String list) throws LscpException {          parseIntList(String list) throws LscpException { return parseIntList(list, ','); }
122                  String[] ar = parseList(list);          
123            /**
124             * Parses a list of integer values.
125             *
126             * @param list The list of integer values.
127             * @param separator Provides the character used as separator.
128             * @return A <code>Integer</code> array containing all items in the list.
129             *
130             * @throws LscpException if the list contains value(s) from different type.
131             */
132            protected static Integer[]
133            parseIntList(String list, char separator) throws LscpException {
134            String[] ar = parseList(list, separator);
135                                    
136                  Integer[] iar = new Integer[ar.length];                  Integer[] iar = new Integer[ar.length];
137                  for(int i = 0; i < ar.length; i++) iar[i] = parseInt(ar[i]);                  for(int i = 0; i < ar.length; i++) iar[i] = parseInt(ar[i]);
# Line 134  final class Parser { Line 158  final class Parser {
158          }          }
159                    
160          /**          /**
161             * Parses a comma separated string list, which elements contains escaped sequences.
162             * @param list The list to parse.
163             * @return A <code>String</code> array containing all items in the list.
164             */
165            protected static String[]
166            parseEscapedStringList(String list) throws LscpException {
167                    return parseEscapedStringList(list, ',');
168            }
169            
170            /**
171             * Parses a string list, which elements contains escaped sequences.
172             * @param list The list to parse.
173             * @param separator Provides the character used as separator.
174             * @return A <code>String</code> array containing all items in the list.
175             */
176            protected static String[]
177            parseEscapedStringList(String list, char separator) throws LscpException {
178                    if(list == null || list.length() == 0) return new String[0];
179                    int q1 = 0, q2 = 0;
180                    Vector<String> v = new Vector<String>();
181                    
182                    for(;;) {
183                            if(list.charAt(q1) != '\'')
184                                    throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
185                            q2 = findApostrophe(list, q1 + 1);
186                            if(q2 == -1) throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
187                            v.add(list.substring(q1 + 1, q2));
188                            
189                            if(q2 + 1 >= list.length()) break;
190                            
191                            if(list.charAt(q2 + 1) != separator)
192                                    throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
193                            q1 = q2 + 2;
194                            if(q1 >= list.length())
195                                    throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
196                    }
197                    
198                    return v.toArray(new String[v.size()]);
199            }
200            
201            /**
202             * Returns the index of the first occurrence of a non-escaped apostrophe
203             * in the specified string, starting at <b>index</b>, or -1 if nothing is found.
204             */
205            private static int
206            findApostrophe(String s, int index) {
207                    return findNonEscapedChar(s, index, '\'');
208            }
209            
210            /**
211           * Parses a comma separated list whose items are encapsulated into apostrophes.           * Parses a comma separated list whose items are encapsulated into apostrophes.
          *  
212           * @param list The comma separated list.           * @param list The comma separated list.
213           * @return A <code>String</code> array containing all items in the list.           * @return A <code>String</code> array containing all items in the list.
          *  
214           * @throws LscpException if the list is broken.           * @throws LscpException if the list is broken.
215           */           */
216          protected static String[]          protected static String[]
217          parseStringList(String list) throws LscpException {          parseStringList(String list) throws LscpException {
218                    return parseStringList(list, ',');
219            }
220            
221            /**
222             * Parses a list whose items are encapsulated into apostrophes.
223             * @param list The list of strings.
224             * @param separator Provides the character used as separator.
225             * @return A <code>String</code> array containing all items in the list.
226             * @throws LscpException if the list is broken.
227             */
228            protected static String[]
229            parseStringList(String list, char separator) throws LscpException {
230                  if(list == null || list.length() == 0) return new String[0];                  if(list == null || list.length() == 0) return new String[0];
231                  int q1 = 0, q2 = 0;                  int q1 = 0, q2 = 0;
232                  Vector<String> v = new Vector<String>();                  Vector<String> v = new Vector<String>();
# Line 156  final class Parser { Line 240  final class Parser {
240                                                    
241                          if(q2 + 1 >= list.length()) break;                          if(q2 + 1 >= list.length()) break;
242                                                    
243                          if(list.charAt(q2 + 1) != ',')                          if(list.charAt(q2 + 1) != separator)
244                                  throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));                                  throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
245                          q1 = q2 + 2;                          q1 = q2 + 2;
246                          if(q1 >= list.length())                          if(q1 >= list.length())
# Line 190  final class Parser { Line 274  final class Parser {
274                  }                  }
275                                    
276                  s2S = new String[v.size()][];                  s2S = new String[v.size()][];
277                  for(i = 0; i < v.size(); i++) s2S[i] = Parser.parseStringList(v.get(i));                  for(i = 0; i < v.size(); i++) s2S[i] = parseStringList(v.get(i));
278                                    
279                  return s2S;                  return s2S;
280          }          }
281                    
282            /**
283             * Parses a comma separated list whose items are encapsulated into curly braces.
284             *
285             * @param list The comma separated list.
286             * @return A <code>String</code> array containing all items in the list.
287             *
288             * @throws LscpException if the list is broken.
289             */
290            protected static String[]
291            parseArray(String list) throws LscpException {
292                    if(list == null || list.length() == 0) return new String[0];
293                    int q1 = 0, q2 = 0;
294                    Vector<String> v = new Vector<String>();
295                    
296                    for(;;) {
297                            if(list.charAt(q1) != '{')
298                                    throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
299                            q2 = list.indexOf('}', q1 + 1);
300                            if(q2 == -1) throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
301                            v.add(list.substring(q1 + 1, q2));
302                            
303                            if(q2 + 1 >= list.length()) break;
304                            
305                            if(list.charAt(q2 + 1) != ',')
306                                    throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
307                            q1 = q2 + 2;
308                            if(q1 >= list.length())
309                                    throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
310                    }
311                    
312                    return v.toArray(new String[v.size()]);
313            }
314            
315          /** Helper function used by <code>parseListOfStringLists</code>. */          /** Helper function used by <code>parseListOfStringLists</code>. */
316          private static int          private static int
317          getEndListIndex(int start, String list) throws LscpException {          getEndListIndex(int start, String list) throws LscpException {
# Line 397  final class Parser { Line 514  final class Parser {
514                                    
515                  return s;                  return s;
516          }          }
517            
518            /**
519             * Returns the provided string with added escape sequences where necessary.
520             */
521            public static String
522            toEscapedString(Object obj) {
523                    String s = obj.toString();
524                    StringBuffer sb = new StringBuffer();
525                    for(int i = 0; i < s.length(); i++) {
526                            switch(s.charAt(i)) {
527                                    case '\n': sb.append("\\n");  break;
528                                    case '\r': sb.append("\\r");  break;
529                                    case '\f': sb.append("\\f");  break;
530                                    case '\t': sb.append("\\t");  break;
531                                    case 0x0B: sb.append("\\v");  break;
532                                    case '\'': sb.append("\\'");  break;
533                                    case '\"': sb.append("\\\""); break;
534                                    case '\\': sb.append("\\\\"); break;
535                                    default  : sb.append(s.charAt(i));
536                            }
537                    }
538                    
539                    return sb.toString();
540            }
541            
542            /**
543             * Returns the provided file name with added escape sequences where necessary.
544             */
545            public static String
546            toEscapedFileName(Object obj) {
547                    String s = obj.toString();
548                    StringBuffer sb = new StringBuffer();
549                    for(int i = 0; i < s.length(); i++) {
550                            switch(s.charAt(i)) {
551                                    case '/' : sb.append("\\x2f"); break;
552                                    case '\n': sb.append("\\n");   break;
553                                    case '\r': sb.append("\\r");   break;
554                                    case '\f': sb.append("\\f");   break;
555                                    case '\t': sb.append("\\t");   break;
556                                    case 0x0B: sb.append("\\v");   break;
557                                    case '\'': sb.append("\\'");   break;
558                                    case '\"': sb.append("\\\"");  break;
559                                    case '\\': sb.append("\\\\");  break;
560                                    default  : sb.append(s.charAt(i));
561                            }
562                    }
563                    
564                    return sb.toString();
565            }
566            
567            /**
568             * Removes the escape sequences from the specified file name
569             * @return The provided file name with removed escape sequences.
570             */
571            public static String
572            toNonEscapedFileName(Object obj) {
573                    return toNonEscapedString(obj);
574            }
575            
576            /**
577             * Removes the escape sequences from the string <code>obj.toString()</code>.
578             * @return The provided text with removed escape sequences.
579             */
580            public static String
581            toNonEscapedString(Object obj) {
582                    String s = obj.toString();
583                    StringBuffer sb = new StringBuffer();
584                    for(int i = 0; i < s.length(); i++) {
585                            char c = s.charAt(i);
586                            if(c == '\\') {
587                                    if(i >= s.length()) {
588                                            Client.getLogger().info("Broken escape sequence!");
589                                            break;
590                                    }
591                                    char c2 = s.charAt(++i);
592                                    if(c2 == '\'')      sb.append('\'');
593                                    else if(c2 == '"')  sb.append('"');
594                                    else if(c2 == '\\') sb.append('\\');
595                                    else if(c2 == 'r')  sb.append('\r');
596                                    else if(c2 == 'n')  sb.append('\n');
597                                    else if(c2 == 'f')  sb.append('\f');
598                                    else if(c2 == 't')  sb.append('\t');
599                                    else if(c2 == 'v')  sb.append((char)0x0B);
600                                    else if(c2 == 'x') {
601                                            Character ch = getHexEscapeSequence(s, i + 1);
602                                            if(ch != null) sb.append(ch.charValue());
603                                            i += 2;
604                                    } else if(c2 >= '0' && c2 <= '9') {
605                                            Character ch = getOctEscapeSequence(s, i);
606                                            if(ch != null) sb.append(ch.charValue());
607                                            i += 2;
608                                    } else Client.getLogger().info("Unknown escape sequence \\" + c2);
609                            } else {
610                                    sb.append(c);
611                            }
612                    }
613                    
614                    return sb.toString();
615            }
616            
617            private static Character
618            getHexEscapeSequence(String s, int index) {
619                    Character c = null;
620                    
621                    if(index + 1 >= s.length()) {
622                            Client.getLogger().info("Broken escape sequence");
623                            return c;
624                    }
625                    
626                    try { c = (char)Integer.parseInt(s.substring(index, index + 2), 16); }
627                    catch(Exception x) { Client.getLogger().info("Broken escape sequence!"); }
628                    
629                    return c;
630            }
631            
632            private static Character
633            getOctEscapeSequence(String s, int index) {
634                    Character c = null;
635                    
636                    if(index + 2 >= s.length()) {
637                            Client.getLogger().info("Broken escape sequence");
638                            return c;
639                    }
640                    
641                    try { c = (char)Integer.parseInt(s.substring(index, index + 3), 8); }
642                    catch(Exception x) { Client.getLogger().info("Broken escape sequence!"); }
643                    
644                    return c;
645            }
646            
647            /**
648             * Determines whether the character at the specified position
649             * is escaped with backslash.
650             */
651            public static boolean
652            isEscaped(String s, int index) {
653                    if (index < 0 || index >= s.length()) return false;
654                    int count = 0;
655                    for (int i = index - 1; i >= 0; i--) {
656                            if (s.charAt(i) != '\\') break;
657                            count++;
658                    }
659                    return count % 2 != 0;
660            }
661            
662            /**
663             * Returns the index of the first occurrence of the specified non-escaped character
664             * in the specified string, starting at <b>index</b>, or -1 if nothing is found.
665             */
666            private static int
667            findNonEscapedChar(String s, int index, char c) {
668                    if(s == null) return -1;
669                    int pos = index;
670                    if (pos < 0 || pos >= s.length()) return -1;
671                    
672                    for(;;) {
673                            int i = s.indexOf(c, pos);
674                            if (i == -1) break;
675                            if (!isEscaped(s, i)) return i;
676                            pos = i + 1;
677                            if (pos >= s.length()) break;
678                    }
679                    
680                    return -1;
681            }
682            
683            /**
684             * Returns the index of the first occurrence of a file separator
685             * in the specified escaped path, starting at <b>index</b>, or -1 if nothing is found.
686             */
687            private static int
688            findFileSeparator(String path, int index) {
689                    return findNonEscapedChar(path, index, '/');
690            }
691            
692            /**
693             * Gets the position of the last file separator in the specified
694             * escaped path, or -1 if failed.
695             */
696            private static int
697            getLastFileSeparator(String path) {
698                    if(path == null || path.length() == 0) return -1;
699                    int pos = path.length() - 1;
700                    
701                    for(;;) {
702                            pos = path.lastIndexOf('/', pos);
703                            if(pos == -1) return -1;
704                            if(!isEscaped(path, pos)) return pos;
705                            pos--;
706                    }
707            }
708            
709            /**
710             * Determines whether the specified escaped path ends with a file separator.
711             */
712            protected static boolean
713            hasEndingFileSeparator(String path) {
714                    if(path == null || path.length() < 2) return false;
715                    
716                    int last = path.length() - 1;
717                    if(path.charAt(last) == '/' && !isEscaped(path, last)) return true;
718                    
719                    return false;
720            }
721            
722            /**
723             * If the specified escaped path ends with a file separator,
724             * a new string is returned with the ending file separator removed.
725             */
726            protected static String
727            removeEndingFileSeparator(String path) {
728                    if(path == null || path.length() < 2) return path;
729                    
730                    int last = path.length() - 1;
731                    if(path.charAt(last) == '/' && !isEscaped(path, last)) {
732                            path = path.substring(0, path.length() - 1);
733                    }
734                    
735                    return path;
736            }
737            
738            /**
739             * Gets the parent directory of the specified escaped path.
740             */
741            public static String
742            getParentDirectory(String path) {
743                    if(path == null || path.length() == 0) return null;
744                    if(path.charAt(0) != '/') return null;
745                    if(path.length() == 1) return null;
746                    
747                    path = removeEndingFileSeparator(path);
748                    
749                    int i = getLastFileSeparator(path);
750                    if(i == 0) return "/";
751                    return path.substring(0, i);
752            }
753            
754            /**
755             * Extracts the file name from the specified escaped path.
756             * If the path does not ends with a file name, <code>null</code> is returned.
757             */
758            public static String
759            getFileName(String path) {
760                    if(path == null || path.length() < 2) return null;
761                    int i = getLastFileSeparator(path);
762                    if(i == -1) return null;
763                    if(i == path.length() - 1) return null;
764                    return path.substring(i + 1);
765            }
766            
767            /**
768             * Returns an array containing all directories in the specified escaped path.
769             */
770            public static String[]
771            getDirectoryList(String path) {
772                    if(path == null || path.length() == 0) return null;
773                    if(path.charAt(0) != '/') return null;
774                    Vector<String> v = new Vector<String>();
775                    v.add("/");
776                    if(path.length() == 1) return v.toArray(new String[v.size()]);
777                    
778                    if(!hasEndingFileSeparator(path)) path += "/";
779                    int i = 1;
780                    int j = findFileSeparator(path, i);
781                    
782                    while(j != -1) {
783                            v.add(path.substring(i, j));
784                            
785                            i = j + 1;
786                            if(i >= path.length()) return v.toArray(new String[v.size()]);
787                            j = findFileSeparator(path, i);
788                    }
789                    
790                    return null;
791            }
792  }  }

Legend:
Removed from v.784  
changed lines
  Added in v.1393

  ViewVC Help
Powered by ViewVC