1 /**
2 * AUTOHIT 2003
3 * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Additional license information can be found in the documentation.
19 * @author Erich P Gatejen
20 */
21 package autohit.vm.process;
22
23 import java.io.BufferedInputStream;
24 import java.io.BufferedOutputStream;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.io.StringReader;
28 import java.io.StringWriter;
29
30 import autohit.common.Constants;
31 import autohit.vm.VMCore;
32 import autohit.vm.VMException;
33
34 /**
35 * String processing routines.
36 *
37 * @author Erich P. Gatejen
38 * @version 1.0 <i>Version History </i> <code>EPG - Rewrite - 13Sep03</code>
39 */
40 public class StringProcessors {
41
42 private final static int STATE_FREE = 0;
43 private final static int STATE_VAR_ONE = 1;
44 private final static int STATE_VAR_IN = 2;
45 private final static int STATE_BUFFER_ONE = 3;
46 private final static int STATE_BUFFER_IN = 4;
47 private final static int STATE_UNIOBJ_ONE = 5;
48 private final static int STATE_UNIOBJ_IN = 6;
49
50 /**
51 * Process String (as a byte stream) to Core (as a byte stream). If there is a problem, you'll get a VMException.
52 * @param s
53 * String to eval
54 * @param core
55 * The Core to use
56 * @return The completed string
57 * @throws VMException
58 */
59 public static void evalStreams2Core(InputStream in, OutputStream out, VMCore core)
60 throws Exception {
61
62 StringBuffer working = null;
63 String result = null;
64 String variable;
65 Object thingthang;
66 int state = STATE_FREE;
67
68 BufferedInputStream bin = new BufferedInputStream(in);
69 BufferedOutputStream bout = new BufferedOutputStream(out);
70 int current = bin.read();
71 while (current >= 0) {
72
73 switch (state) {
74
75 case STATE_FREE :
76 switch (current) {
77 case Constants.VARIABLE :
78 state = STATE_VAR_ONE;
79 break;
80 case Constants.UNIOBJECT :
81 state = STATE_UNIOBJ_ONE;
82 break;
83 case Constants.BUFFER :
84 state = STATE_BUFFER_ONE;
85 break;
86 default :
87 bout.write(current);
88 break;
89 }
90 break;
91
92 case STATE_VAR_ONE :
93 switch (current) {
94 case Constants.VARIABLE :
95 // escaped
96 bout.write(Constants.VARIABLE);
97 state = STATE_FREE;
98 break;
99 case Constants.UNIOBJECT :
100 case Constants.BUFFER :
101 default :
102 working = new StringBuffer();
103 working.append((char) current);
104 state = STATE_VAR_IN;
105 break;
106 }
107 break;
108
109 case STATE_VAR_IN :
110 switch (current) {
111 case Constants.VARIABLE :
112 variable = working.toString();
113 if (core.exists(variable)) {
114 thingthang = core.fetch(variable);
115 if (thingthang instanceof String) {
116 bout.write( ((String)(thingthang)).getBytes() );
117 } else {
118 // Blech! Something bad in this object
119 throw new VMException(
120 "Not an evaluatable type in variable. name="
121 + working,
122 VMException.CODE_VM_PROCESSOR_ERROR);
123 }
124 }
125 state = STATE_FREE;
126 break;
127 case Constants.UNIOBJECT :
128 case Constants.BUFFER :
129 default :
130 working.append((char) current);
131 break;
132 }
133 break;
134
135 case STATE_BUFFER_ONE :
136 switch (current) {
137 case Constants.BUFFER :
138 bout.write(Constants.BUFFER);
139 state = STATE_FREE;
140 break;
141 case Constants.VARIABLE :
142 case Constants.UNIOBJECT :
143 default :
144 working = new StringBuffer();
145 working.append((char) current);
146 state = STATE_BUFFER_IN;
147 break;
148 }
149 break;
150
151 case STATE_BUFFER_IN :
152 switch (current) {
153 case Constants.BUFFER :
154 variable = working.toString();
155 if (core.exists(variable)) {
156 thingthang = core.fetch(variable);
157 if (thingthang instanceof StringBuffer) {
158 bout.write( ((StringBuffer)(thingthang)).toString().getBytes() );
159 } else {
160 // Blech! Something bad in this object
161 throw new VMException(
162 "Not an evaluatable type in buffer.. name="
163 + working,
164 VMException.CODE_VM_PROCESSOR_ERROR);
165 }
166 }
167 state = STATE_FREE;
168 break;
169 case Constants.UNIOBJECT :
170 case Constants.VARIABLE :
171 default :
172 working.append((char) current);
173 break;
174 }
175 break;
176
177 case STATE_UNIOBJ_ONE :
178 switch (current) {
179 case Constants.UNIOBJECT :
180 bout.write(Constants.UNIOBJECT);
181 state = STATE_FREE;
182 break;
183 case Constants.VARIABLE :
184 case Constants.BUFFER :
185 default :
186 //working.append((char)current);
187 state = STATE_UNIOBJ_IN; // THIS WILL BE AN ERROR
188 break;
189 }
190 break;
191
192 case STATE_UNIOBJ_IN :
193 switch (current) {
194
195 case Constants.UNIOBJECT :
196 throw new VMException(
197 "UNIOBJECT not supported in SimVM",
198 VMException.CODE_VM_PROCESSOR_FAULT);
199 case Constants.VARIABLE :
200 case Constants.BUFFER :
201 default :
202 // IGNORE, SINCE THIS WILL BE AN ERROR.
203 break;
204 }
205 break;
206
207 default :
208 throw new VMException(
209 "evalString2Core hit impossible state. state="
210 + state,
211 VMException.CODE_VM_SOFTWARE_DETECTED_FAULT);
212
213 }
214 current = bin.read();
215 }
216
217 //CHECK STATES
218 switch (state) {
219 case STATE_FREE :
220 // HAPPY HAPPY
221 break;
222 case STATE_VAR_ONE :
223 case STATE_VAR_IN :
224 String vmessage;
225 if (working.length() > 30) {
226 vmessage = new String("Unbounded VARIABLE (oversize) '"
227 + working.toString().substring(30) + "'");
228 } else {
229 vmessage = new String("Unbounded VARIABLE '"
230 + working.toString() + "'");
231 }
232 throw new VMException(vmessage,
233 VMException.CODE_VM_PROCESSOR_ERROR_UNBOUNDED);
234
235 case STATE_BUFFER_ONE :
236 case STATE_BUFFER_IN :
237 String bmessage;
238 if (working.length() > 30) {
239 bmessage = new String("Unbounded BUFFER (oversize) '"
240 + working.toString().substring(30) + "'");
241 } else {
242 bmessage = new String("Unbounded BUFFER '"
243 + working.toString() + "'");
244 }
245 throw new VMException(bmessage,
246 VMException.CODE_VM_PROCESSOR_ERROR_UNBOUNDED);
247
248 case STATE_UNIOBJ_ONE :
249 case STATE_UNIOBJ_IN :
250 String umessage;
251 if (working.length() > 30) {
252 umessage = new String("Unbounded UNIOBJ (oversize) '"
253 + working.toString().substring(30) + "'");
254 } else {
255 umessage = new String("Unbounded UNIOBJ '"
256 + working.toString() + "'");
257 }
258 throw new VMException(umessage,
259 VMException.CODE_VM_PROCESSOR_ERROR_UNBOUNDED);
260 default :
261 throw new VMException(
262 "evalString2Core hit impossible state. state=" + state,
263 VMException.CODE_VM_SOFTWARE_DETECTED_FAULT);
264 }
265 bout.flush();
266
267 }
268
269 /**
270 * Process String to Core (as a character stream). If there is a problem, you'll get a VMException.
271 *
272 * @param s
273 * String to eval
274 * @param core
275 * The Core to use
276 * @return The completed string
277 * @throws VMException
278 */
279 public static String evalString2Core(String s, VMCore core)
280 throws Exception {
281
282 StringBuffer working = null;
283 String result = null;
284 String variable;
285 Object thingthang;
286 int state = STATE_FREE;
287
288 StringReader rin = new StringReader(s);
289 StringWriter rout = new StringWriter();
290 int current = rin.read();
291 while (current >= 0) {
292
293 switch (state) {
294
295 case STATE_FREE :
296 switch (current) {
297 case Constants.VARIABLE :
298 state = STATE_VAR_ONE;
299 break;
300 case Constants.UNIOBJECT :
301 state = STATE_UNIOBJ_ONE;
302 break;
303 case Constants.BUFFER :
304 state = STATE_BUFFER_ONE;
305 break;
306 default :
307 rout.write(current);
308 break;
309 }
310 break;
311
312 case STATE_VAR_ONE :
313 switch (current) {
314 case Constants.VARIABLE :
315 // escaped
316 rout.write(Constants.VARIABLE);
317 state = STATE_FREE;
318 break;
319 case Constants.UNIOBJECT :
320 case Constants.BUFFER :
321 default :
322 working = new StringBuffer();
323 working.append((char) current);
324 state = STATE_VAR_IN;
325 break;
326 }
327 break;
328
329 case STATE_VAR_IN :
330 switch (current) {
331 case Constants.VARIABLE :
332 variable = working.toString();
333 if (core.exists(variable)) {
334 thingthang = core.fetch(variable);
335 if (thingthang instanceof String) {
336 rout.write((String) (thingthang));
337 } else {
338 // Blech! Something bad in this object
339 throw new VMException(
340 "Not an evaluatable type in variable. name="
341 + working,
342 VMException.CODE_VM_PROCESSOR_ERROR);
343 }
344 }
345 state = STATE_FREE;
346 break;
347 case Constants.UNIOBJECT :
348 case Constants.BUFFER :
349 default :
350 working.append((char) current);
351 break;
352 }
353 break;
354
355 case STATE_BUFFER_ONE :
356 switch (current) {
357 case Constants.BUFFER :
358 rout.write(Constants.BUFFER);
359 state = STATE_FREE;
360 break;
361 case Constants.VARIABLE :
362 case Constants.UNIOBJECT :
363 default :
364 working = new StringBuffer();
365 working.append((char) current);
366 state = STATE_BUFFER_IN;
367 break;
368 }
369 break;
370
371 case STATE_BUFFER_IN :
372 switch (current) {
373 case Constants.BUFFER :
374 variable = working.toString();
375 if (core.exists(variable)) {
376 thingthang = core.fetch(variable);
377 if (thingthang instanceof StringBuffer) {
378 rout.write(((StringBuffer) (thingthang))
379 .toString());
380 } else {
381 // Blech! Something bad in this object
382 throw new VMException(
383 "Not an evaluatable type in buffer.. name="
384 + working,
385 VMException.CODE_VM_PROCESSOR_ERROR);
386 }
387 }
388 state = STATE_FREE;
389 break;
390 case Constants.UNIOBJECT :
391 case Constants.VARIABLE :
392 default :
393 working.append((char) current);
394 break;
395 }
396 break;
397
398 case STATE_UNIOBJ_ONE :
399 switch (current) {
400 case Constants.UNIOBJECT :
401 rout.write(Constants.UNIOBJECT);
402 state = STATE_FREE;
403 break;
404 case Constants.VARIABLE :
405 case Constants.BUFFER :
406 default :
407 //working.append((char)current);
408 state = STATE_UNIOBJ_IN; // THIS WILL BE AN ERROR
409 break;
410 }
411 break;
412
413 case STATE_UNIOBJ_IN :
414 switch (current) {
415
416 case Constants.UNIOBJECT :
417 throw new VMException(
418 "UNIOBJECT not supported in SimVM",
419 VMException.CODE_VM_PROCESSOR_FAULT);
420 case Constants.VARIABLE :
421 case Constants.BUFFER :
422 default :
423 // IGNORE, SINCE THIS WILL BE AN ERROR.
424 break;
425 }
426 break;
427
428 default :
429 throw new VMException(
430 "evalString2Core hit impossible state. state="
431 + state,
432 VMException.CODE_VM_SOFTWARE_DETECTED_FAULT);
433
434 }
435 current = rin.read();
436 }
437
438 //CHECK STATES
439 switch (state) {
440 case STATE_FREE :
441 result = rout.toString();
442 break;
443 case STATE_VAR_ONE :
444 case STATE_VAR_IN :
445 String vmessage;
446 if (working.length() > 30) {
447 vmessage = new String("Unbounded VARIABLE (oversize) '"
448 + working.toString().substring(30) + "'");
449 } else {
450 vmessage = new String("Unbounded VARIABLE '"
451 + working.toString() + "'");
452 }
453 throw new VMException(vmessage,
454 VMException.CODE_VM_PROCESSOR_ERROR_UNBOUNDED);
455
456 case STATE_BUFFER_ONE :
457 case STATE_BUFFER_IN :
458 String bmessage;
459 if (working.length() > 30) {
460 bmessage = new String("Unbounded BUFFER (oversize) '"
461 + working.toString().substring(30) + "'");
462 } else {
463 bmessage = new String("Unbounded BUFFER '"
464 + working.toString() + "'");
465 }
466 throw new VMException(bmessage,
467 VMException.CODE_VM_PROCESSOR_ERROR_UNBOUNDED);
468
469 case STATE_UNIOBJ_ONE :
470 case STATE_UNIOBJ_IN :
471 String umessage;
472 if (working.length() > 30) {
473 umessage = new String("Unbounded UNIOBJ (oversize) '"
474 + working.toString().substring(30) + "'");
475 } else {
476 umessage = new String("Unbounded UNIOBJ '"
477 + working.toString() + "'");
478 }
479 throw new VMException(umessage,
480 VMException.CODE_VM_PROCESSOR_ERROR_UNBOUNDED);
481 default :
482 throw new VMException(
483 "evalString2Core hit impossible state. state=" + state,
484 VMException.CODE_VM_SOFTWARE_DETECTED_FAULT);
485 }
486 return result;
487
488 }
489
490 /**
491 * Process String to Core. If there is a problem, you'll get a VMException.
492 * OLD VERSION
493 *
494 * @param s
495 * String to eval
496 * @param core
497 * The Core to use
498 * @return The completed string
499 * @throws VMException
500 */
501 public static String evalString2CoreOLD(String s, VMCore core)
502 throws Exception {
503
504 StringBuffer buff = new StringBuffer();
505 String result = null;
506 String working;
507 Object thingthang;
508 int end = s.length();
509 int otherside;
510
511 try {
512
513 for (int i = 0; i < end; i++) {
514
515 switch (s.charAt(i)) {
516
517 case Constants.VARIABLE :
518 otherside = s.indexOf(Constants.VARIABLE, i + 1);
519 if ((otherside < 0) || (otherside < i)) {
520 throw new VMException(
521 "Unbounded VARIABLE",
522 VMException.CODE_VM_PROCESSOR_ERROR_UNBOUNDED);
523 }
524 if (otherside == (i + 1)) {
525 //escaped char
526 buff.append(Constants.VARIABLE);
527 i++; //skip escaped
528 } else {
529 working = s.substring(i + 1, otherside);
530 i = i + working.length() + 1;
531
532 if (core.exists(working)) {
533 thingthang = core.fetch(working);
534 if (thingthang instanceof String) {
535 buff.append((String) thingthang);
536 } else {
537 // Blech! Something bad in this object
538 throw new VMException(
539 "Not an evaluatable type in variable. name="
540 + working,
541 VMException.CODE_VM_PROCESSOR_ERROR);
542 }
543 } //else {
544 // The variable doesn't exist. FAULT.
545 // throw new Exception(
546 // "Variable does not exist. name="
547 // + working);
548 //}
549 }
550 break;
551
552 case Constants.UNIOBJECT :
553 if ((i + 1 < end)
554 && (s.charAt(i + 1) == Constants.UNIOBJECT)) {
555 //escaped char
556 buff.append(Constants.UNIOBJECT);
557 i++; //skip escaped
558 } else {
559 throw new VMException(
560 "UNIOBJECT not supported in SimVM",
561 VMException.CODE_VM_PROCESSOR_FAULT);
562 }
563 break;
564
565 case Constants.BUFFER :
566 otherside = s.indexOf(Constants.BUFFER, i + 1);
567 if ((otherside < 0) || (otherside < i)) {
568 throw new VMException(
569 "Unbounded BUFFER name",
570 VMException.CODE_VM_PROCESSOR_ERROR_UNBOUNDED);
571 }
572 if (otherside == (i + 1)) {
573 //escaped char
574 buff.append(Constants.BUFFER);
575 i++; //skip escaped
576 } else {
577 working = s.substring(i + 1, otherside);
578 i = i + working.length() + 1;
579
580 if (core.exists(working)) {
581 thingthang = core.fetch(working);
582 if (thingthang instanceof StringBuffer) {
583 buff.append(((StringBuffer) thingthang)
584 .toString());
585 } else {
586 // Blech! Something bad in this object
587 throw new VMException(
588 "Not an evaluatable type in buffer. name="
589 + working,
590 VMException.CODE_VM_PROCESSOR_ERROR_NOTFOUND);
591 }
592 } else {
593 // The variable doesn't exist. FAULT.
594 throw new VMException(
595 "Buffer does not exist. name="
596 + working,
597 VMException.CODE_VM_PROCESSOR_ERROR_NOTFOUND);
598 }
599 }
600 break;
601
602 default :
603 buff.append(s.charAt(i));
604 }
605 }
606
607 // return it
608 result = buff.toString();
609
610 } catch (VMException ev) {
611 throw ev;
612 } catch (Exception ee) {
613 throw new VMException("Exception while evaluating. message="
614 + ee.getMessage(),
615 VMException.CODE_VM_PROCESSOR_ERROR_NOTFOUND, ee);
616 }
617 return result;
618
619 }
620
621 }
|