001    package railo.commons.lang;
002    
003    
004    
005    /**
006            Der CFMLString ist eine Hilfe fuer die Transformer, 
007            er repraesentiert den CFML Code und bietet Methoden an, 
008            um alle noetigen Informationen auszulesen und Manipulationen durchzufuehren. 
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 uebergeben 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 erhaelt den CFML Code als 
048             * char[] und uebertraegt 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 zurueck 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 naechste 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 naechsten 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 naechsten 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 zurueck.
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 zurueck.
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 zurueck ob das naechste 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 zurueck ob das naechste 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 zurueck ob das naechste 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 zurueck ob das aktuelle Zeichen zwischen den Angegebenen liegt.
206             * @param left Linker (unterer) Wert.
207             * @param right Rechter (oberer) Wert.
208             * @return Gibt zurueck 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 zurueck ob das aktuelle Zeichen eine Zahl ist.
217             * @return Gibt zurueck 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 zurueck ob das aktuelle Zeichen eine Zahl ist.
226             * @return Gibt zurueck 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 zurueck ob das aktuelle Zeichen ein Buchstabe ist.
235             * @return Gibt zurueck 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 zurueck ob das aktuelle Zeichen ein Special Buchstabe ist (_,�,$,�).
283         * @return Gibt zurueck 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 zurueck 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 zurueck 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 zurueck 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 zurueck ob das aktuelle und die folgenden Zeichen die selben sind, 
335             * wie in der angegebenen Zeichenkette, 
336             * wenn ja wird der Zeiger um die Laenge 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 zurueck ob das aktuelle und die folgenden Zeichen die selben sind gefolgt nicht von einem word character, 
379             * wenn ja wird der Zeiger um die Laenge 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 zurueck 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 zurueck 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 zurueck 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 zurueck 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 zurueck ob first den folgenden Zeichen entspricht, 
432             * gefolgt von Leerzeichen und second,
433             * wenn ja wird der Zeiger um die Laenge 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 zurueck ob der Zeiger vorwaerts 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 zurueck 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 zurueck ob der Zeiger vorwaerts 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 zurueck ob first den folgenden Zeichen entspricht, 
481             * gefolgt von Leerzeichen und second,
482             * wenn ja wird der Zeiger um die Laenge 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 zurueck ob der Zeiger vorwaerts 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 zurueck 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 zurueck 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 zurueck ob first den folgenden Zeichen entspricht, 
513             * gefolgt von Leerzeichen und second,
514             * wenn ja wird der Zeiger um die Laenge 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 zurueck ob der Zeiger vorwaerts 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 zurueck ob sich vor dem aktuellen Zeichen Leerzeichen befinden.
597             * @return Gibt zurueck 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 zurueck 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 naechsten Zeile, 
618             * gibt zurueck 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 zurueck, 
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 zurueck, 
644             * ausgehend von start mit einer maximalen Laenge count.
645             * @param start Von wo aus die Untermenge ausgegeben werden soll.
646             * @param count Wie lange die zurueckgegebene 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 zurueck, 
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 zurueck, 
665             * ausgehend von start mit einer maximalen Laenge count.
666             * @param start Von wo aus die Untermenge ausgegeben werden soll.
667             * @param count Wie lange die zurueckgegebene 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 zurueck, 
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 zurueck, 
686            * ausgehend von start mit einer maximalen Laenge count.
687            * @param start Von wo aus die Untermenge ausgegeben werden soll.
688            * @param count Wie lange die zurueckgegebene 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            @Override
712            public String toString() {
713                    return new String(this.text);
714            }
715            
716            /**
717             * Gibt die aktuelle Position des Zeigers innerhalb des CFMLString zurueck.
718             * @return Position des Zeigers
719             */
720            public int getPos() {
721                    return pos;
722            }
723            
724            /**
725             * Setzt die Position des Zeigers innerhalb des CFMLString, ein ungueltiger index wird ignoriert.
726              * @param pos Position an die der Zeiger gestellt werde soll.
727             */
728            public void setPos(int pos) {
729                    this.pos= pos;
730            }
731    
732            /**
733             * Gibt zurueck ob der Zeiger auf dem letzten Zeichen steht.
734             * @return Gibt zurueck ob der Zeiger auf dem letzten Zeichen steht.
735             */
736            public boolean isLast() {
737                    return pos==text.length-1;
738            }
739            
740            /**
741             * Gibt zurueck ob der Zeiger nach dem letzten Zeichen steht.
742             * @return Gibt zurueck ob der Zeiger nach dem letzten Zeichen steht.
743             */
744            public boolean isAfterLast() {
745                    return pos>=text.length;
746            }
747            /**
748             * Gibt zurueck ob der Zeiger einen korrekten Index hat.
749             * @return Gibt zurueck ob der Zeiger einen korrekten Index hat.
750             */
751            public boolean isValidIndex() {
752                    return pos<text.length;
753            }
754            
755            /**
756             * Gibt zurueck, ausgehend von der aktuellen Position, 
757             * wann das naechste Zeichen folgt das gleich ist wie die Eingabe, 
758             * falls keines folgt wird �1 zurueck gegeben. 
759             * Gross- und Kleinschreibung der Zeichen werden igoriert.
760             * @param c gesuchtes Zeichen
761             * @return Zeichen das gesucht werden soll.
762             */
763            public int indexOfNext(char c) {
764                    for(int i=pos;i<lcText.length;i++) {
765                            if(lcText[i]==c) return i;
766                    }
767                    return -1;
768            }
769            
770            /**
771             * Gibt das letzte Wort das sich vor dem aktuellen Zeigerstand befindet zurueck, 
772             * falls keines existiert wird null zurueck gegeben.
773             * @return Word vor dem aktuellen Zeigerstand.
774             */
775            public String lastWord() {
776                    int size = 1;
777                    while (pos - size > 0 && lcText[pos - size] == ' ') {
778                            size++;
779                    }
780                    while (pos - size > 0
781                            && lcText[pos - size] != ' '
782                            && lcText[pos - size] != ';') {
783                            size++;
784                    }
785                    return this.substring((pos - size + 1), (pos - 1));
786            }
787    
788            /**
789             * Gibt die Laenge des CFMLString zurueck.
790             * @return Laenge des CFMLString.
791             */
792            public int length() {
793                    return text.length;
794            }
795    
796            /**
797             * Prueft ob das uebergebene Objekt diesem Objekt entspricht.
798             * @param o Object zum vergleichen.
799             * @return Ist das uebergebene Objekt das selbe wie dieses.
800             */
801            public boolean equals(Object o) {
802                    if(!(o instanceof ParserString))return false;
803                    return o.toString().equals(this.toString());
804            }
805    
806    }