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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1326 - (hide annotations) (download)
Fri Sep 7 11:03:52 2007 UTC (16 years, 7 months ago) by iliev
File size: 16011 byte(s)
* Client: getAudioOutputDriverInfo is now public and accepts a dependences
  list of parameters
* Client: getMidiInputDriverInfo is now public and accepts a dependences
  list of parameters
* bugfix: parameters with unset values are now not sent to LinuxSampler

1 iliev 596 /*
2     * jlscp - a java LinuxSampler control protocol API
3     *
4 iliev 1326 * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5 iliev 596 *
6     * This file is part of jlscp.
7     *
8     * jlscp is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License version 2
10     * as published by the Free Software Foundation.
11     *
12     * jlscp is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with jlscp; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20     * MA 02111-1307 USA
21     */
22    
23     package org.linuxsampler.lscp;
24    
25     import java.io.IOException;
26    
27     import java.util.Vector;
28    
29    
30     /**
31     * This class contains only helper functions that are used from the other classes in this library.
32     * @author Grigor Iliev
33     */
34     final class Parser {
35 iliev 1139 /** Forbits the instantiatrion of this class */
36     private Parser() { }
37    
38 iliev 596 /**
39     * Parses an integer value.
40     * @param s The integer value to be parsed.
41     * @throws LscpException If the string does not contain valid integer value.
42     */
43     protected static int
44     parseInt(String s) throws LscpException {
45     try { return Integer.parseInt(s); }
46     catch(NumberFormatException x) {
47     throw new LscpException(LscpI18n.getLogMsg("Parser.notInt!", s), x);
48     }
49     }
50    
51     /**
52     * Parses a float value.
53     * @param s The float value to be parsed.
54     * @throws LscpException If the string does not contain valid float value.
55     */
56     protected static float
57     parseFloat(String s) throws LscpException {
58     try { return Float.parseFloat(s); }
59     catch(NumberFormatException x) {
60     throw new LscpException(LscpI18n.getLogMsg("Parser.notFloat!", s));
61     }
62     }
63    
64     /**
65     * Parses a comma separated list.
66     *
67     * @param list The comma separated list.
68     * @return A <code>String</code> array containing all items in the list.
69     */
70     protected static String[]
71 iliev 1139 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 iliev 596 if(list == null || list.length() == 0) return new String[0];
82     int pos = 0;
83     int idx;
84     Vector<String> v = new Vector<String>();
85 iliev 1139 while((idx = list.indexOf(separator, pos)) > 0) {
86 iliev 596 v.add(list.substring(pos, idx));
87     pos = idx + 1;
88     }
89    
90     if(pos < list.length()) v.add(list.substring(pos));
91     return v.toArray(new String[v.size()]);
92     }
93    
94     /**
95     * Parses a comma separated list with boolean values.
96     *
97     * @param list The comma separated list with boolean values.
98     * @return A <code>Boolean</code> array containing all items in the list.
99     */
100     protected static Boolean[]
101     parseBoolList(String list) {
102     String[] ar = parseList(list);
103    
104     Boolean[] bar = new Boolean[ar.length];
105     for(int i = 0; i < ar.length; i++) {
106     bar[i] = Boolean.parseBoolean(ar[i]);
107     }
108    
109     return bar;
110     }
111    
112     /**
113     * Parses a comma separated list with integer values.
114     *
115     * @param list The comma separated list with integer values.
116     * @return A <code>Integer</code> array containing all items in the list.
117     *
118     * @throws LscpException if the list contains value(s) from different type.
119     */
120     protected static Integer[]
121 iliev 1139 parseIntList(String list) throws LscpException { return parseIntList(list, ','); }
122    
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 iliev 596
136     Integer[] iar = new Integer[ar.length];
137     for(int i = 0; i < ar.length; i++) iar[i] = parseInt(ar[i]);
138    
139     return iar;
140     }
141    
142     /**
143     * Parses a comma separated list with float values.
144     *
145     * @param list The comma separated list with float values.
146     * @return A <code>Float</code> array containing all items in the list.
147     *
148     * @throws LscpException if the list contains value(s) from different type.
149     */
150     protected static Float[]
151     parseFloatList(String list) throws LscpException {
152     String[] ar = parseList(list);
153    
154     Float[] far = new Float[ar.length];
155     for(int i = 0; i < ar.length; i++) far[i] = parseFloat(ar[i]);
156    
157     return far;
158     }
159 iliev 1326
160 iliev 596 /**
161 iliev 1326 * Parses a comma separated list whose items are not encapsulated into apostrophes.
162 iliev 596 * @param list The comma separated list.
163     * @return A <code>String</code> array containing all items in the list.
164     * @throws LscpException if the list is broken.
165     */
166     protected static String[]
167     parseStringList(String list) throws LscpException {
168 iliev 1326 list = removeQuotation(list);
169     return parseList(list);
170 iliev 1202 }
171    
172     /**
173 iliev 1326 * Parses a comma separated list whose items are encapsulated into apostrophes.
174     * @param list The comma separated list.
175     * @return A <code>String</code> array containing all items in the list.
176     * @throws LscpException if the list is broken.
177     */
178     protected static String[]
179     parseQuotedStringList(String list) throws LscpException {
180     return parseQuotedStringList(list, ',');
181     }
182    
183     /**
184 iliev 1202 * Parses a list whose items are encapsulated into apostrophes.
185     * @param list The list of strings.
186     * @param separator Provides the character used as separator.
187     * @return A <code>String</code> array containing all items in the list.
188     * @throws LscpException if the list is broken.
189     */
190     protected static String[]
191 iliev 1326 parseQuotedStringList(String list, char separator) throws LscpException {
192 iliev 596 if(list == null || list.length() == 0) return new String[0];
193     int q1 = 0, q2 = 0;
194     Vector<String> v = new Vector<String>();
195    
196     for(;;) {
197     if(list.charAt(q1) != '\'')
198     throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
199     q2 = list.indexOf('\'', q1 + 1);
200     if(q2 == -1) throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
201     v.add(list.substring(q1 + 1, q2));
202    
203     if(q2 + 1 >= list.length()) break;
204    
205 iliev 1202 if(list.charAt(q2 + 1) != separator)
206 iliev 596 throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
207     q1 = q2 + 2;
208     if(q1 >= list.length())
209     throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
210     }
211    
212     return v.toArray(new String[v.size()]);
213     }
214    
215     protected static String[][]
216     parseListOfStringLists(String list) throws LscpException {
217     if(list.length() == 0) return new String[0][0];
218    
219     String[][] s2S;
220     if(!list.startsWith("''") && !list.startsWith("\"\"")) {
221     s2S = new String[1][];
222 iliev 1326 s2S[0] = parseQuotedStringList(list);
223 iliev 596 return s2S;
224     }
225    
226     int i = 0, i2 = 0;
227     Vector<String> v = new Vector<String>();
228    
229     for(;;) {
230     i2 = getEndListIndex(i, list);
231     v.add(list.substring(i + 1, i2));
232     if(i2 == list.length() - 1) break;
233     if(list.charAt(i2 + 1) != ',')
234     throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
235     i = i2 + 2;
236     }
237    
238     s2S = new String[v.size()][];
239 iliev 1326 for(i = 0; i < v.size(); i++) s2S[i] = parseQuotedStringList(v.get(i));
240 iliev 596
241     return s2S;
242     }
243    
244 iliev 1139 /**
245     * Parses a comma separated list whose items are encapsulated into curly braces.
246     *
247     * @param list The comma separated list.
248     * @return A <code>String</code> array containing all items in the list.
249     *
250     * @throws LscpException if the list is broken.
251     */
252     protected static String[]
253     parseArray(String list) throws LscpException {
254     if(list == null || list.length() == 0) return new String[0];
255     int q1 = 0, q2 = 0;
256     Vector<String> v = new Vector<String>();
257    
258     for(;;) {
259     if(list.charAt(q1) != '{')
260     throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
261     q2 = list.indexOf('}', q1 + 1);
262     if(q2 == -1) throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
263     v.add(list.substring(q1 + 1, q2));
264    
265     if(q2 + 1 >= list.length()) break;
266    
267     if(list.charAt(q2 + 1) != ',')
268     throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
269     q1 = q2 + 2;
270     if(q1 >= list.length())
271     throw new LscpException(LscpI18n.getLogMsg("Parser.EOL!"));
272     }
273    
274     return v.toArray(new String[v.size()]);
275     }
276    
277 iliev 596 /** Helper function used by <code>parseListOfStringLists</code>. */
278     private static int
279     getEndListIndex(int start, String list) throws LscpException {
280     int i = start + 1;
281     char q = list.charAt(0); // quote symbol
282     if(list.charAt(start) != q)
283     throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
284    
285     if(list.charAt(i) == '\'') { // Check for empty list
286     if(i == list.length() - 1 || list.charAt(i + 1) == ',') return i;
287     }
288    
289     for(;;) {
290     if(list.charAt(i) != q)
291     throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
292     i = list.indexOf(q, i + 1);
293     if(i == -1 || i == list.length() - 1)
294     throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
295    
296     if(list.charAt(i + 1) == q) return i + 1;
297    
298     if(list.charAt(i + 1) != ',')
299     throw new LscpException(LscpI18n.getLogMsg("Parser.brokenList!"));
300     i += 2;
301     }
302     }
303    
304    
305     /**
306     * Gets the type of the parameter represented by the specified result set.
307     * @param resultSet A <code>String</code> array containing the information categories
308     * of a multi-line result set.
309     * @return The type of the parameter represented by the specified result set or
310     * <code>null</code> if the specified result set does not contain
311     * <code>TYPE</code> category.
312     */
313     protected static ParameterType
314     parseType(String[] resultSet) {
315     if(resultSet == null || resultSet.length == 0) return null;
316     for(String s : resultSet) {
317     if(s.startsWith("TYPE: ")) {
318     String type = s.substring("TYPE: ".length(), s.length());
319     if(type.equals("BOOL")) return ParameterType.BOOL;
320     if(type.equals("INT")) return ParameterType.INT;
321     if(type.equals("FOAT")) return ParameterType.FLOAT;
322     if(type.equals("STRING")) return ParameterType.STRING;
323     }
324     }
325     return null;
326     }
327    
328     /**
329     * Determines whether the parameter represented by the specified result set allows
330     * only one value or a list of values.
331     * @param resultSet A <code>String</code> array containing the information categories
332     * of a multi-line result set.
333     * @return <code>false</code> if the parameter represented by the specified result set
334     * allows only one value and <code>true</code> if allows a list of values.
335     */
336     protected static Boolean
337     parseMultiplicity(String[] resultSet) {
338     if(resultSet == null || resultSet.length == 0) return null;
339    
340     for(String s : resultSet) {
341     if(s.startsWith("MULTIPLICITY: ")) return Boolean.parseBoolean (
342     s.substring("MULTIPLICITY: ".length(), s.length())
343     );
344     }
345    
346     return null;
347     }
348    
349     /**
350     * Parses an empty result set and returns an appropriate <code>ResultSet</code> object.
351     * Notice that the result set may be of type warning or error.
352     * @param ln A <code>String</code> representing the single line result set to be parsed.
353     * @return A <code>ResultSet</code> object.
354     * @throws LscpException If LSCP protocol error occurs.
355     * @throws LSException If the LinuxSampler instance returns error message.
356     */
357     protected static ResultSet
358     parseEmptyResultSet(String ln) throws LscpException, LSException {
359     ResultSet rs = new ResultSet();
360    
361     if(ln.equals("OK")) {
362     return rs;
363     } else if(ln.startsWith("OK[") && ln.endsWith("]")) {
364     ln = ln.substring("OK[".length(), ln.length() - 1);
365     try {
366     rs.setIndex(Integer.parseInt(ln));
367     return rs;
368     } catch(NumberFormatException x) {
369     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"), x);
370     }
371     } else if(ln.startsWith("WRN")) {
372     parseWarning(ln, rs);
373     Client.getLogger().warning(rs.getMessage());
374     return rs;
375     } else if(ln.startsWith("ERR:")) {
376     parseError(ln, rs);
377     throw new LSException(rs.getCode(), rs.getMessage());
378     }
379    
380     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!") );
381     }
382    
383     /**
384     * Parses warning message.
385     * @param ln The warning message to be parsed.
386     * @param rs A <code>ResultSet</code> instance where the warning must be stored.
387     * @throws LscpException If LSCP protocol corruption occurs.
388     */
389     protected static void
390     parseWarning(String ln, ResultSet rs) throws LscpException {
391     if(!ln.startsWith("WRN"))
392     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
393    
394     int i, j;
395     rs.setWarning(true);
396    
397     if(ln.charAt(3) == '[') {
398     i = ln.indexOf(']');
399     if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
400    
401     try {
402     j = Integer.parseInt(ln.substring("WRN[".length(), i));
403     rs.setIndex(j);
404     } catch(NumberFormatException x) {
405     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"), x);
406     }
407    
408     if(ln.charAt(i + 1) != ':')
409     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
410     }
411    
412     i = ln.indexOf(':');
413     if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
414     j = ln.indexOf(':', i + 1);
415     if(j == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
416    
417     try { rs.setCode(Integer.parseInt(ln.substring(i + 1, j))); }
418     catch(NumberFormatException x) {
419     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"), x);
420     }
421    
422     rs.setMessage(ln.substring(j + 1));
423     }
424    
425     /**
426     * Parses error message.
427     * @param ln The error message to be parsed.
428     * @param rs A <code>ResultSet</code> instance where the error must be stored.
429     * @throws LscpException If LSCP protocol corruption occurs.
430     */
431     protected static void
432     parseError(String ln, ResultSet rs) throws LscpException {
433     if(!ln.startsWith("ERR:"))
434     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
435    
436     int i = ln.indexOf(':', "ERR:".length());
437     if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
438    
439     try { rs.setCode(Integer.parseInt(ln.substring("ERR:".length(), i))); }
440     catch(NumberFormatException x) {
441     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"), x);
442     }
443    
444     rs.setMessage(ln.substring(i + 1));
445     }
446    
447     /**
448     * Gets the info character string to the specified information category.
449     * @param resultSet A <code>String</code> array containing the information categories
450     * of a multi-line result set.
451     * @param category Specifies the category whose info character string to be returned.
452     * @return The info character string to the specified information category or
453     * <code>null</code> if the specified result set does not contain that category.
454     */
455     protected static String
456     getCategoryInfo(String[] resultSet, String category) {
457     String c = category + ": ";
458     for(String s : resultSet)
459     if(s.startsWith(c)) return s.substring(c.length(), s.length());
460    
461     return null;
462     }
463 iliev 784
464     /**
465     * Eliminates the quotation marks if the string is quoted.
466     * @return New string without quotation marks if the string is quoted; else
467     * the same string is returned.
468     */
469     protected static String
470     removeQuotation(String s) {
471     if(s == null || s.length() < 2) return s;
472     char q = s.charAt(0);
473     char q2 = s.charAt(s.length() - 1);
474     if((q == '\'' && q2 == '\'') || (q == '"' && q2 == '"'))
475     return s.substring(1, s.length() - 1);
476    
477     return s;
478     }
479 iliev 1307
480     /**
481     * Returns the provided string with added escape sequences where necessary.
482     */
483     protected static String
484     getEscapedString(String s) {
485     StringBuffer sb = new StringBuffer();
486     for(int i = 0; i < s.length(); i++) {
487     switch(s.charAt(i)) {
488     case '\n': sb.append("\\n"); break;
489     case '\r': sb.append("\\r"); break;
490     case '\f': sb.append("\\f"); break;
491     case '\t': sb.append("\\t"); break;
492     case 0x0B: sb.append("\\v"); break;
493     case '\'': sb.append("\\'"); break;
494     case '\"': sb.append("\\\""); break;
495     case '\\': sb.append("\\\\"); break;
496     default : sb.append(s.charAt(i));
497     }
498     }
499    
500     return sb.toString();
501     }
502 iliev 596 }

  ViewVC Help
Powered by ViewVC