001    package railo.commons.lang;
002    
003    
004    
005    /**
006            Der CFMLString ist eine Hilfe f�r die Transformer, 
007            er repr�sentiert den CFML Code und bietet Methoden an, 
008            um alle n�tigen Informationen auszulesen und Manipulationen durchzuf�hren. 
009            Dies um, innerhalb des Transformer, wiederkehrende Zeichenketten-Manipulationen zu abstrahieren.
010     *
011     */
012    public final class ParserString {
013    
014            /**
015             * Mindestens einen Space
016             */
017            public static final short AT_LEAST_ONE_SPACE=0;
018            
019            /**
020             * Mindestens ein Space
021             */
022            public static final short ZERO_OR_MORE_SPACE=1;
023            
024            /**
025             * Field <code>pos</code>
026             */
027            protected int pos=0;
028            /**
029             * Field <code>text</code>
030             */
031            protected char[] text;
032            /**
033             * Field <code>lcText</code>
034             */
035            protected char[] lcText;
036            
037            
038            /**
039             * Diesen Konstruktor kann er CFML Code als Zeichenkette �bergeben werden.
040             * @param text CFML Code
041             */
042            public ParserString(String text) {
043                    init(text);
044            }
045            
046            /**
047             * Gemeinsame Initialmethode der drei Konstruktoren, diese erh�lt den CFML Code als 
048             * char[] und �bertr�gt ihn, in die interen Datenhaltung. 
049             * @param str
050             */
051            protected void init(String str) {
052                    int len=str.length();
053                    text=new char[len];
054                    lcText=new char[len];
055    
056                    for(int i=0;i<len;i++) {
057                            char c=str.charAt(i);
058                            text[i]=c;
059                            if(c=='\n' || c=='\r' || c=='\t') {
060                                    lcText[i]=' ';
061                            }
062                            else lcText[i]=((c>='a' && c<='z') || (c>='0' && c<='9'))?c:Character.toLowerCase(c);
063                    }
064            }
065    
066            /**
067             * Gibt zur�ck ob, 
068             * ausgehend von der aktuellen Position des internen Zeigers im Text,
069             * noch ein Zeichen vorangestellt ist.
070             * @return boolean Existiert ein weieters Zeichen nach dem Zeiger.
071             */
072            public boolean hasNext()  {
073                    return pos+1<text.length;
074            }
075            public boolean hasNextNext()  {
076                    return pos+2<text.length;
077            }
078    
079            public boolean hasPrevious()  {
080                    return pos-1>=0;
081            }
082            public boolean hasPreviousPrevious()  {
083                    return pos-2>=0;
084            }
085    
086            /**
087             * Stellt den internen Zeiger auf die n�chste Position. 
088             * �berlappungen ausserhalb des Index des Textes werden ignoriert.
089            */
090            public void next(){
091                    pos++;
092            }
093            /**
094             * Stellt den internen Zeiger auf die vorhergehnde Position. 
095             * �berlappungen ausserhalb des Index des Textes werden ignoriert.
096             */
097            public void previous(){
098                    pos--;
099            }
100    
101            /**
102             * Gibt das Zeichen (Character) an der aktuellen Position des Zeigers aus.
103             * @return char Das Zeichen auf dem der Zeiger steht.
104             */
105            public char getCurrent() {
106                    return text[pos];
107            }
108    
109            /**
110             * Gibt das Zeichen (Character) an der n�chsten Position des Zeigers aus.
111             * @return char Das Zeichen auf dem der Zeiger steht plus 1.
112             */
113            public char getNext() {
114                    return text[pos+1];
115            }
116            
117            /**
118             * Gibt das Zeichen, als Kleinbuchstaben, an der aktuellen Position des Zeigers aus.
119             * @return char Das Zeichen auf dem der Zeiger steht als Kleinbuchstaben.
120             */
121            public char getCurrentLower() {
122                    return lcText[pos];
123            }
124            
125            /**
126             * Gibt das Zeichen, als Grossbuchstaben, an der aktuellen Position des Zeigers aus.
127             * @return char Das Zeichen auf dem der Zeiger steht als Grossbuchstaben.
128             */
129            public char getCurrentUpper() {
130                    return Character.toUpperCase(text[pos]);
131            }
132            
133            /**
134             * Gibt das Zeichen, als Kleinbuchstaben, an der n�chsten Position des Zeigers aus.
135             * @return char Das Zeichen auf dem der Zeiger steht plus 1 als Kleinbuchstaben.
136             */
137            public char getNextLower() {
138                    return lcText[pos];
139            }
140    
141            /**
142             * Gibt das Zeichen an der angegebenen Position zur�ck.
143             * @param pos Position des auszugebenen Zeichen.
144             * @return char Das Zeichen an der angegebenen Position.
145             */
146            public char charAt(int pos) {
147                    return text[pos];
148            }
149            
150            /**
151             * Gibt das Zeichen, als Kleinbuchstaben, an der angegebenen Position zur�ck.
152             * @param pos Position des auszugebenen Zeichen.
153             * @return char Das Zeichen an der angegebenen Position als Kleinbuchstaben.
154             */
155            public char charAtLower(int pos) {
156                    return lcText[pos];
157            }
158    
159            /**
160             * Gibt zur�ck ob das n�chste Zeichen das selbe ist wie das Eingegebene.
161             * @param c Zeichen zum Vergleich.
162             * @return boolean 
163             */
164            public boolean isNext(char c) {
165                    if(!hasNext()) return false;
166                    return lcText[pos+1]==c;
167            }
168            
169            public boolean isPrevious(char c) {
170                    if(!hasPrevious()) return false;
171                    return lcText[pos-1]==c;
172            }
173    
174            /**
175             * Gibt zur�ck ob das n�chste Zeichen das selbe ist wie das Eingegebene.
176             * @param c Zeichen zum Vergleich.
177             * @return boolean 
178             */
179            public boolean isCurrentIgnoreSpace(char c) {
180                    if(!hasNext()) return false;
181                    int start=getPos();
182                    removeSpace();
183                    
184                    boolean is=isCurrent(c);
185                    setPos(start);
186                    return is;
187            }
188    
189            /**
190             * Gibt zur�ck ob das n�chste Zeichen das selbe ist wie das Eingegebene.
191             * @param c Zeichen zum Vergleich.
192             * @return boolean 
193             */
194            public boolean isCurrentIgnoreSpace(String str) {
195                    if(!hasNext()) return false;
196                    int start=getPos();
197                    removeSpace();
198                    
199                    boolean is=isCurrent(str);
200                    setPos(start);
201                    return is;
202            }
203            
204            /**
205             * Gibt zur�ck ob das aktuelle Zeichen zwischen den Angegebenen liegt.
206             * @param left Linker (unterer) Wert.
207             * @param right Rechter (oberer) Wert.
208             * @return Gibt zur�ck ob das aktuelle Zeichen zwischen den Angegebenen liegt.
209             */
210            public boolean isCurrentBetween(char left, char right) {
211                    if(!isValidIndex()) return false;
212                    return lcText[pos]>=left && lcText[pos]<=right;
213            }
214            
215            /**
216             * Gibt zur�ck ob das aktuelle Zeichen eine Zahl ist.
217             * @return Gibt zur�ck ob das aktuelle Zeichen eine Zahl ist.
218             */
219            public boolean isCurrentDigit() {
220                    if(!isValidIndex()) return false;
221                    return (lcText[pos]>='0' && lcText[pos]<='9');
222            }
223            
224            /**
225             * Gibt zur�ck ob das aktuelle Zeichen eine Zahl ist.
226             * @return Gibt zur�ck ob das aktuelle Zeichen eine Zahl ist.
227             */
228            public boolean isCurrentQuoter() {
229                    if(!isValidIndex()) return false;
230                    return lcText[pos]=='"' || lcText[pos]=='\'';
231            }
232            
233            /**
234             * Gibt zur�ck ob das aktuelle Zeichen ein Buchstabe ist.
235             * @return Gibt zur�ck ob das aktuelle Zeichen ein Buchstabe ist.
236             */
237            public boolean isCurrentLetter() {
238                    if(!isValidIndex()) return false;
239                    return lcText[pos]>='a' && lcText[pos]<='z';
240            }
241            public boolean isCurrentNumber() {
242                    if(!isValidIndex()) return false;
243                    return lcText[pos]>='0' && lcText[pos]<='9';
244            }
245            
246            public boolean isCurrentWhiteSpace() {
247                    if(!isValidIndex()) return false;
248                    return (lcText[pos]==' ' || lcText[pos]=='\t' || lcText[pos]=='\b' || lcText[pos]=='\r' || lcText[pos]=='\n');
249                    // return lcText[pos]>='a' && lcText[pos]<='z';
250            }
251            
252            public boolean forwardIfCurrentWhiteSpace() {
253                    boolean rtn=false;
254                    while(isCurrentWhiteSpace()) {
255                            pos++;
256                            rtn=true;
257                    } 
258                    return rtn;
259            }
260            
261            public boolean isNextWhiteSpace() {
262                    if(!hasNext()) return false;
263                    return (lcText[pos+1]==' ' || lcText[pos+1]=='\t' || lcText[pos+1]=='\b' || lcText[pos+1]=='\r' || lcText[pos+1]=='\n');
264            }
265            
266            public boolean isNextNextWhiteSpace() {
267                    if(!hasNextNext()) return false;
268                    return (lcText[pos+2]==' ' || lcText[pos+2]=='\t' || lcText[pos+2]=='\b' || lcText[pos+2]=='\r' || lcText[pos+2]=='\n');
269            }
270            
271            public boolean isPreviousWhiteSpace() {
272                    if(!hasPrevious()) return false;
273                    return (lcText[pos-1]==' ' || lcText[pos-1]=='\t' || lcText[pos-1]=='\b' || lcText[pos-1]=='\r' || lcText[pos-1]=='\n');
274            }
275            
276            public boolean isPreviousPreviousWhiteSpace() {
277                    if(!hasPreviousPrevious()) return false;
278                    return (lcText[pos-2]==' ' || lcText[pos-2]=='\t' || lcText[pos-2]=='\b' || lcText[pos-2]=='\r' || lcText[pos-2]=='\n');
279            }
280            
281        /**
282         * Gibt zur�ck ob das aktuelle Zeichen ein Special Buchstabe ist (_,�,$,�).
283         * @return Gibt zur�ck ob das aktuelle Zeichen ein Buchstabe ist.
284         */
285        public boolean isCurrentSpecial() {
286            if(!isValidIndex()) return false;
287            return lcText[pos]=='_' || lcText[pos]=='$' || lcText[pos]=='�' || lcText[pos]=='�';
288        }
289            
290            /**
291             * Gibt zur�ck ob das aktuelle Zeichen das selbe ist wie das Eingegebene.
292             * @param c char Zeichen zum Vergleich.
293             * @return boolean
294             */
295            public boolean isCurrent(char c) {
296                    if(!isValidIndex()) return false;
297                    return lcText[pos]==c;
298            }
299    
300            public boolean isLast(char c) {
301                    if(lcText.length==0) return false;
302                    return lcText[lcText.length-1]==c;
303            }
304            
305            /**
306             * Stellt den Zeiger eins nach vorn, wenn das aktuelle Zeichen das selbe ist wie das Eingegebene, 
307             * gibt zur�ck ob es das selbe Zeichen war oder nicht.
308             * @param c char Zeichen zum Vergleich.
309             * @return boolean
310             */
311            public boolean forwardIfCurrent(char c) {
312                    if(isCurrent(c)) {
313                            pos++;
314                            return true;
315                    } 
316                    return false;
317            }
318            
319            /**
320             * Gibt zur�ck ob das aktuelle und die folgenden Zeichen die selben sind,
321             * wie in der angegebenen Zeichenkette.
322             * @param str String Zeichen zum Vergleich.
323             * @return boolean
324             */
325            public boolean isCurrent(String str) {
326                    if(pos+str.length()>text.length) return false;
327                    for(int i=str.length()-1;i>=0;i--)   {
328                            if(str.charAt(i)!=lcText[pos+i]) return false;
329                    }
330                    return true;    
331            }
332            
333            /**
334             * Gibt zur�ck ob das aktuelle und die folgenden Zeichen die selben sind, 
335             * wie in der angegebenen Zeichenkette, 
336             * wenn ja wird der Zeiger um die L�nge des String nach vorne gesetzt.
337             * @param str String Zeichen zum Vergleich.
338             * @return boolean
339             */
340            public boolean forwardIfCurrent(String str) {
341                    boolean is=isCurrent(str);
342                    if(is)pos+=str.length();
343                    return is;
344            }
345            
346    
347            
348    
349            public boolean forwardIfCurrent(String str, boolean startWithSpace) {
350                    if(!startWithSpace) return forwardIfCurrent(str);
351                    
352                    int start=pos;
353                    if(!removeSpace())return false;
354                    
355                    if(!forwardIfCurrent(str)){
356                            pos=start;
357                            return false;
358                    }
359                    return true;
360            }
361    
362            
363            public boolean forwardIfCurrent(String first,String second,String third, boolean startWithSpace) {
364                    if(!startWithSpace) return forwardIfCurrent(first, second, third);
365                    int start=pos;
366                    
367                    if(!removeSpace())return false;
368                    
369                    if(!forwardIfCurrent(first,second,third)){
370                            pos=start;
371                            return false;
372                    }
373                    return true;    
374            }
375            
376    
377            /**
378             * Gibt zur�ck ob das aktuelle und die folgenden Zeichen die selben sind gefolgt nicht von einem word character, 
379             * wenn ja wird der Zeiger um die L�nge des String nach vorne gesetzt.
380             * @param str String Zeichen zum Vergleich.
381             * @return boolean
382             */
383            public boolean forwardIfCurrentAndNoWordAfter(String str) {
384                    int c=pos;
385                    if(forwardIfCurrent(str)) {
386                            if(!isCurrentLetter() && !isCurrent('_'))return true;
387                    }
388                    pos=c;
389                    return false;
390            }
391            public boolean forwardIfCurrentAndNoWordNumberAfter(String str) {
392                    int c=pos;
393                    if(forwardIfCurrent(str)) {
394                            if(!isCurrentLetter() && !isCurrentLetter() && !isCurrent('_'))return true;
395                    }
396                    pos=c;
397                    return false;
398            }
399            
400            /**
401             * Gibt zur�ck ob first den folgenden Zeichen entspricht, gefolgt von Leerzeichen und second.
402             * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen).
403             * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen).
404             * @return Gibt zur�ck ob die eingegebenen Werte dem Inhalt beim aktuellen Stand des Zeigers entsprechen.
405             */
406            public boolean isCurrent(String first,char second) {
407                    int start=pos;
408                    if(!forwardIfCurrent(first)) return false; 
409                    removeSpace();
410                    boolean rtn=isCurrent(second); 
411                    pos=start;
412                    return rtn;                     
413            }
414            
415            /**
416             * Gibt zur�ck ob first den folgenden Zeichen entspricht, gefolgt von Leerzeichen und second.
417             * @param first Erstes Zeichen zum Vergleich (Vor den Leerzeichen).
418             * @param second Zweites Zeichen zum Vergleich (Nach den Leerzeichen).
419             * @return Gibt zur�ck ob die eingegebenen Werte dem Inhalt beim aktuellen Stand des Zeigers entsprechen.
420             */
421            public boolean isCurrent(char first,char second) {
422                    int start=pos;
423                    if(!forwardIfCurrent(first)) return false; 
424                    removeSpace();
425                    boolean rtn=isCurrent(second); 
426                    pos=start;
427                    return rtn;                     
428            }
429            
430            /**
431             * Gibt zur�ck ob first den folgenden Zeichen entspricht, 
432             * gefolgt von Leerzeichen und second,
433             * wenn ja wird der Zeiger um die L�nge der �bereinstimmung nach vorne gestellt.
434             * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen).
435             * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen).
436             * @return Gibt zur�ck ob der Zeiger vorw�rts geschoben wurde oder nicht.
437             */
438            public boolean forwardIfCurrent(String first,char second) {
439                    int start=pos;
440                    if(!forwardIfCurrent(first)) return false; 
441                    removeSpace();
442                    boolean rtn=forwardIfCurrent(second); 
443                    if(!rtn)pos=start;
444                    return rtn;     
445            }
446            
447            /**
448             * Gibt zur�ck ob ein Wert folgt und vor und hinterher Leerzeichen folgen.
449             * @param before Definition der Leerzeichen vorher.
450             * @param val Gefolgter Wert der erartet wird.
451             * @param after Definition der Leerzeichen nach dem Wert.
452             * @return Gibt zur�ck ob der Zeiger vorw�rts geschoben wurde oder nicht.
453             */
454            public boolean forwardIfCurrent(short before, String val,short after) {
455                    int start=pos;
456                    // space before
457                    if(before==AT_LEAST_ONE_SPACE) {
458                            if(!removeSpace()) return false;
459                    }
460                    else removeSpace();
461                    
462                    // value
463                    if(!forwardIfCurrent(val)) {
464                            setPos(start);
465                            return false;
466                    }
467                    
468                    // space after
469                    if(after==AT_LEAST_ONE_SPACE) {
470                            if(!removeSpace()) { 
471                                    setPos(start);
472                                    return false; 
473                            } 
474                    }
475                    else removeSpace();
476                    return true;
477            }
478            
479            /**
480             * Gibt zur�ck ob first den folgenden Zeichen entspricht, 
481             * gefolgt von Leerzeichen und second,
482             * wenn ja wird der Zeiger um die L�nge der �bereinstimmung nach vorne gestellt.
483             * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen).
484             * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen).
485             * @return Gibt zur�ck ob der Zeiger vorw�rts geschoben wurde oder nicht.
486             */
487            public boolean forwardIfCurrent(char first,char second) {
488                    int start=pos;
489                    if(!forwardIfCurrent(first)) return false; 
490                    removeSpace();
491                    boolean rtn=forwardIfCurrent(second); 
492                    if(!rtn)pos=start;
493                    return rtn;     
494            }
495            
496            /**
497             * Gibt zur�ck ob first den folgenden Zeichen entspricht, gefolgt von Leerzeichen und second.
498             * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen).
499             * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen).
500             * @return Gibt zur�ck ob die eingegebenen Werte dem Inhalt beim aktuellen Stand des Zeigers entsprechen.
501             */
502            public boolean isCurrent(String first,String second) {
503                    int start=pos;
504                    if(!forwardIfCurrent(first)) return false; 
505                    removeSpace();
506                    boolean rtn=isCurrent(second); 
507                    pos=start;
508                    return rtn;                     
509            }
510            
511            /**
512             * Gibt zur�ck ob first den folgenden Zeichen entspricht, 
513             * gefolgt von Leerzeichen und second,
514             * wenn ja wird der Zeiger um die L�nge der �bereinstimmung nach vorne gestellt.
515             * @param first Erste Zeichen zum Vergleich (Vor den Leerzeichen).
516             * @param second Zweite Zeichen zum Vergleich (Nach den Leerzeichen).
517             * @return Gibt zur�ck ob der Zeiger vorw�rts geschoben wurde oder nicht.
518             */
519            public boolean forwardIfCurrent(String first,String second) {
520                    int start=pos;
521                    
522                    if(!forwardIfCurrent(first)) return false; 
523                    
524                    if(!removeSpace()){
525                            pos=start;
526                            return false;
527                    }
528                    boolean rtn=forwardIfCurrent(second); 
529                    if(!rtn)pos=start;
530                    return rtn;     
531            }
532            
533            public boolean forwardIfCurrent(String first,String second,String third) {
534                    int start=pos;
535                    if(!forwardIfCurrent(first)) return false; 
536                    
537                    if(!removeSpace()){
538                            pos=start;
539                            return false;
540                    }
541                    
542                    if(!forwardIfCurrent(second)){
543                            pos=start;
544                            return false;
545                    }
546                    
547                    if(!removeSpace()){
548                            pos=start;
549                            return false;
550                    }
551                    
552                    boolean rtn=forwardIfCurrent(third); 
553                    if(!rtn)pos=start;
554                    return rtn;     
555            }
556            
557            public boolean forwardIfCurrent(String first,String second,String third, String forth) {
558                    int start=pos;
559                    if(!forwardIfCurrent(first)) return false; 
560                    
561                    if(!removeSpace()){
562                            pos=start;
563                            return false;
564                    }
565                    
566                    if(!forwardIfCurrent(second)){
567                            pos=start;
568                            return false;
569                    }
570                    
571                    if(!removeSpace()){
572                            pos=start;
573                            return false;
574                    }
575                    
576                    
577                    if(!forwardIfCurrent(third)){
578                            pos=start;
579                            return false;
580                    }
581                    
582                    if(!removeSpace()){
583                            pos=start;
584                            return false;
585                    }
586                    
587                    boolean rtn=forwardIfCurrent(forth); 
588                    if(!rtn)pos=start;
589                    return rtn;     
590                    
591            }
592            
593            
594            
595            /**
596             * Gibt zur�ck ob sich vor dem aktuellen Zeichen Leerzeichen befinden.
597             * @return Gibt zur�ck ob sich vor dem aktuellen Zeichen Leerzeichen befinden.
598             */
599            public boolean hasSpaceBefore() {
600                    return pos > 0 && lcText[pos - 1] == ' ';
601            }
602            
603            /**
604             * Stellt den Zeiger nach vorne, wenn er sich innerhalb von Leerzeichen befindet, 
605             * bis die Leerzeichen fertig sind. 
606             * @return Gibt zur�ck ob der Zeiger innerhalb von Leerzeichen war oder nicht.
607             */
608            public boolean removeSpace() {
609                    int start=pos;
610                    while(pos<text.length && lcText[pos]==' ') {
611                            pos++;
612                    }
613                    return (start<pos);
614            }
615            
616            /**
617             * Stellt den internen Zeiger an den Anfang der n�chsten Zeile, 
618             * gibt zur�ck ob eine weitere Zeile existiert oder ob es bereits die letzte Zeile war.
619             * @return Existiert eine weitere Zeile.
620             */
621            public boolean nextLine() {
622                    while(isValidIndex() && text[pos]!='\n') {
623                            next();
624                    }
625                    if(isValidIndex() && text[pos]=='\n') {
626                            next();
627                            return isValidIndex();
628                    }
629                    return false;
630            }
631            
632            /**
633             * Gibt eine Untermenge des CFMLString als Zeichenkette zur�ck, 
634             * ausgehend von start bis zum Ende des CFMLString.
635             * @param start Von wo aus die Untermege ausgegeben werden soll.
636             * @return Untermenge als Zeichenkette
637             */
638            public String substring(int start) {
639                    return substring(start,text.length-start);
640            }
641    
642            /**
643             * Gibt eine Untermenge des CFMLString als Zeichenkette zur�ck, 
644             * ausgehend von start mit einer maximalen L�nge count.
645             * @param start Von wo aus die Untermenge ausgegeben werden soll.
646             * @param count Wie lange die zur�ckgegebene Zeichenkette maximal sein darf.
647             * @return Untermenge als Zeichenkette.
648             */
649            public String substring(int start, int count) {
650                    return String.valueOf(text,start,count);
651            }
652    
653            /**
654             * Gibt eine Untermenge des CFMLString als Zeichenkette in Kleinbuchstaben zur�ck, 
655             * ausgehend von start bis zum Ende des CFMLString.
656             * @param start Von wo aus die Untermenge ausgegeben werden soll.
657             * @return  Untermenge als Zeichenkette in Kleinbuchstaben.
658             */
659            public String substringLower(int start) {
660                    return substringLower(start,text.length-start);
661            }
662    
663            /**
664             * Gibt eine Untermenge des CFMLString als Zeichenkette in Kleinbuchstaben zur�ck, 
665             * ausgehend von start mit einer maximalen L�nge count.
666             * @param start Von wo aus die Untermenge ausgegeben werden soll.
667             * @param count Wie lange die zur�ckgegebene Zeichenkette maximal sein darf.
668             * @return  Untermenge als Zeichenkette in Kleinbuchstaben.
669             */
670            public String substringLower(int start, int count) {
671                    return String.valueOf(lcText,start,count);
672            }
673            
674            /**
675             * Gibt eine Untermenge des CFMLString als CFMLString zur�ck, 
676             * ausgehend von start bis zum Ende des CFMLString.
677             * @param start Von wo aus die Untermenge ausgegeben werden soll.
678             * @return Untermenge als CFMLString
679             */
680            public ParserString subCFMLString(int start) {
681                    return subCFMLString(start,text.length-start);
682            }
683            
684            /**
685            * Gibt eine Untermenge des CFMLString als CFMLString zur�ck, 
686            * ausgehend von start mit einer maximalen L�nge count.
687            * @param start Von wo aus die Untermenge ausgegeben werden soll.
688            * @param count Wie lange die zur�ckgegebene Zeichenkette maximal sein darf.
689            * @return Untermenge als CFMLString
690            */
691       public ParserString subCFMLString(int start, int count) {
692                    return new ParserString(String.valueOf(text,start,count));
693                    /*
694                     NICE die untermenge direkter ermiiteln, das problem hierbei sind die lines
695                    
696                    int endPos=start+count;
697                    int LineFrom=-1;
698                    int LineTo=-1;
699                    for(int i=0;i<lines.length;i++) {
700                            if()
701                    }
702            
703                    return new CFMLString(
704                    0, 
705                    String.valueOf(text,start,count).toCharArray(), 
706                    String.valueOf(lcText,start,count).toCharArray(), 
707                    lines);
708                    */
709       }
710            
711            /** Gibt den CFMLString als String zur�ck.
712             * @see java.lang.Object#toString()
713             */
714            public String toString() {
715                    return new String(this.text);
716            }
717            
718            /**
719             * Gibt die aktuelle Position des Zeigers innerhalb des CFMLString zur�ck.
720             * @return Position des Zeigers
721             */
722            public int getPos() {
723                    return pos;
724            }
725            
726            /**
727             * Setzt die Position des Zeigers innerhalb des CFMLString, ein ung�ltiger index wird ignoriert.
728              * @param pos Position an die der Zeiger gestellt werde soll.
729             */
730            public void setPos(int pos) {
731                    this.pos= pos;
732            }
733    
734            /**
735             * Gibt zur�ck ob der Zeiger auf dem letzten Zeichen steht.
736             * @return Gibt zur�ck ob der Zeiger auf dem letzten Zeichen steht.
737             */
738            public boolean isLast() {
739                    return pos==text.length-1;
740            }
741            
742            /**
743             * Gibt zur�ck ob der Zeiger nach dem letzten Zeichen steht.
744             * @return Gibt zur�ck ob der Zeiger nach dem letzten Zeichen steht.
745             */
746            public boolean isAfterLast() {
747                    return pos>=text.length;
748            }
749            /**
750             * Gibt zur�ck ob der Zeiger einen korrekten Index hat.
751             * @return Gibt zur�ck ob der Zeiger einen korrekten Index hat.
752             */
753            public boolean isValidIndex() {
754                    return pos<text.length;
755            }
756            
757            /**
758             * Gibt zur�ck, ausgehend von der aktuellen Position, 
759             * wann das n�chste Zeichen folgt das gleich ist wie die Eingabe, 
760             * falls keines folgt wird �1 zur�ck gegeben. 
761             * Gross- und Kleinschreibung der Zeichen werden igoriert.
762             * @param c gesuchtes Zeichen
763             * @return Zeichen das gesucht werden soll.
764             */
765            public int indexOfNext(char c) {
766                    for(int i=pos;i<lcText.length;i++) {
767                            if(lcText[i]==c) return i;
768                    }
769                    return -1;
770            }
771            
772            /**
773             * Gibt das letzte Wort das sich vor dem aktuellen Zeigerstand befindet zur�ck, 
774             * falls keines existiert wird null zur�ck gegeben.
775             * @return Word vor dem aktuellen Zeigerstand.
776             */
777            public String lastWord() {
778                    int size = 1;
779                    while (pos - size > 0 && lcText[pos - size] == ' ') {
780                            size++;
781                    }
782                    while (pos - size > 0
783                            && lcText[pos - size] != ' '
784                            && lcText[pos - size] != ';') {
785                            size++;
786                    }
787                    return this.substring((pos - size + 1), (pos - 1));
788            }
789    
790            /**
791             * Gibt die L�nge des CFMLString zur�ck.
792             * @return L�nge des CFMLString.
793             */
794            public int length() {
795                    return text.length;
796            }
797    
798            /**
799             * Pr�ft ob das �bergebene Objekt diesem Objekt entspricht.
800             * @param o Object zum vergleichen.
801             * @return Ist das �bergebene Objekt das selbe wie dieses.
802             */
803            public boolean equals(Object o) {
804                    if(!(o instanceof ParserString))return false;
805                    return o.toString().equals(this.toString());
806            }
807    
808    }