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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1326 - (show annotations) (download)
Fri Sep 7 11:03:52 2007 UTC (16 years, 6 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 /*
2 * jlscp - a java LinuxSampler control protocol API
3 *
4 * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5 *
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 /** Forbits the instantiatrion of this class */
36 private Parser() { }
37
38 /**
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 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];
82 int pos = 0;
83 int idx;
84 Vector<String> v = new Vector<String>();
85 while((idx = list.indexOf(separator, pos)) > 0) {
86 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 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
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
160 /**
161 * Parses a comma separated list whose items are not encapsulated into apostrophes.
162 * @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 list = removeQuotation(list);
169 return parseList(list);
170 }
171
172 /**
173 * 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 * 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 parseQuotedStringList(String list, char separator) throws LscpException {
192 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 if(list.charAt(q2 + 1) != separator)
206 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 s2S[0] = parseQuotedStringList(list);
223 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 for(i = 0; i < v.size(); i++) s2S[i] = parseQuotedStringList(v.get(i));
240
241 return s2S;
242 }
243
244 /**
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 /** 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
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
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 }

  ViewVC Help
Powered by ViewVC